Initial commit of Command & Conquer Renegade source code.

This commit is contained in:
LFeenanEA
2025-02-27 16:39:46 +00:00
parent 74ab8fa5e0
commit 58ed459113
4918 changed files with 1366710 additions and 0 deletions

View File

@@ -0,0 +1,122 @@
# Microsoft Developer Studio Project File - Name="AMC_imp" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=AMC_imp - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "AMC_IMP.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "AMC_IMP.mak" CFG="AMC_imp - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "AMC_imp - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "AMC_imp - Win32 Hybrid" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/Commando/Code/Tools/AMC_IMP", LGHAAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "AMC_imp - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\Release"
# PROP BASE Intermediate_Dir ".\Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ".\Release"
# PROP Intermediate_Dir ".\Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MD /W3 /GX /Z7 /O2 /I "..\asf_imp" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comctl32.lib core.lib geom.lib maxutil.lib /nologo /subsystem:windows /dll /pdb:"Release/amc_imp.pdb" /machine:I386 /out:"Release/amc_imp.dli"
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "AMC_imp - Win32 Hybrid"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Hybrid"
# PROP BASE Intermediate_Dir "Hybrid"
# PROP BASE Ignore_Export_Lib 0
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Hybrid"
# PROP Intermediate_Dir "Hybrid"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /Z7 /O2 /I "c:\3dsmax2\maxsdk\include" /I "..\asf_imp" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /Z7 /O2 /I "..\asf_imp" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib core.lib geom.lib util.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Hybrid\amc_imp.dli"
# ADD LINK32 odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comctl32.lib core.lib geom.lib maxutil.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"Hybrid\amc_imp.dli"
# SUBTRACT LINK32 /pdb:none
!ENDIF
# Begin Target
# Name "AMC_imp - Win32 Release"
# Name "AMC_imp - Win32 Hybrid"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
# Begin Source File
SOURCE=.\AMC_import.cpp
# End Source File
# Begin Source File
SOURCE=.\AMC_import.def
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# Begin Source File
SOURCE=.\exception.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# Begin Source File
SOURCE=.\AMC_import.rc
# End Source File
# End Group
# End Target
# End Project

View File

@@ -0,0 +1,855 @@
/*
** Command & Conquer Renegade(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/>.
*/
//----------------------------------------------------------------------------
// amc_import.cpp
//
// Acclaim Motion Capture import module
//
// James McNeill
//
// Created October 1996
//
// Copyright (c) 1996 Westwood Studios
//----------------------------------------------------------------------------
#include <Max.h>
#include <istdplug.h>
#include <fstream.h>
#include "resource.h"
#include "exception.h"
#include "asf_data.h"
const float ANGLE_MULTIPLIER = 1.7453293e-2f; // degrees to radians
const first_frame_time = 320;
const amc_ticks_per_frame = 80;
static int max_ticks_per_frame = 160;
static HINSTANCE hInstance;
static TCHAR * GetString ( int id )
{
static TCHAR buf[256];
if (hInstance)
return LoadString(hInstance, id, buf, sizeof(buf)) ? buf : NULL;
return NULL;
}
static int MessageBox ( int s1, int s2, int option = MB_OK )
{
TSTR str1(GetString(s1));
TSTR str2(GetString(s2));
return MessageBox(GetActiveWindow(), str1, str2, option);
}
static int Alert ( int s1, int s2 = IDS_LIB_SHORT_DESC, int option = MB_OK )
{
return MessageBox(s1, s2, option);
}
//----------------------------------------------------------------------------
// AMC_Import
//----------------------------------------------------------------------------
class AMC_Import : public SceneImport
{
public:
AMC_Import();
~AMC_Import();
int ExtCount(); // Number of extensions supported
const TCHAR * Ext(int n); // Extension #n
const TCHAR * LongDesc(); // Long ASCII description
const TCHAR * ShortDesc(); // Short ASCII description
const TCHAR * AuthorName(); // ASCII Author name
const TCHAR * CopyrightMessage(); // ASCII Copyright message
const TCHAR * OtherMessage1(); // Other message #1
const TCHAR * OtherMessage2(); // Other message #2
unsigned int Version(); // Version number * 100
void ShowAbout(HWND); // Show DLL's "About..." box
int DoImport
(
const TCHAR * name,
ImpInterface * i,
Interface * gi,
BOOL suppressPrompts
);
};
//----------------------------------------------------------------------------
// DllMain
//----------------------------------------------------------------------------
static int controlsInit = FALSE;
BOOL WINAPI DllMain
(
HINSTANCE hinstDLL,
ULONG fdwReason,
LPVOID lpvReserved
)
{
hInstance = hinstDLL;
if ( !controlsInit )
{
controlsInit = TRUE;
InitCustomControls(hInstance);
InitCommonControls();
}
switch(fdwReason)
{
case DLL_PROCESS_ATTACH: break;
case DLL_THREAD_ATTACH: break;
case DLL_THREAD_DETACH: break;
case DLL_PROCESS_DETACH: break;
}
return TRUE;
}
//----------------------------------------------------------------------------
// AMC_ClassDesc
//----------------------------------------------------------------------------
class AMC_ClassDesc : public ClassDesc
{
public:
int IsPublic() { return 1; }
void * Create(BOOL loading = FALSE) { return new AMC_Import; }
const TCHAR * ClassName() { return GetString(IDS_SHORT_DESC); }
SClass_ID SuperClassID() { return SCENE_IMPORT_CLASS_ID; }
Class_ID ClassID() { return Class_ID(0x5be11422, 0x6e0177f0); }
const TCHAR* Category() { return GetString(IDS_CATEGORY); }
};
static AMC_ClassDesc AMC_desc;
//----------------------------------------------------------------------------
// This is the interface to Jaguar:
//----------------------------------------------------------------------------
__declspec( dllexport ) const TCHAR * LibDescription()
{
return GetString(IDS_LIB_LONG_DESC);
}
__declspec( dllexport ) int LibNumberClasses()
{
return 1;
}
__declspec( dllexport ) ClassDesc * LibClassDesc(int i)
{
switch(i)
{
case 0: return & AMC_desc; break;
default: return 0; break;
}
}
// Return version so can detect obsolete DLLs
__declspec( dllexport ) ULONG LibVersion()
{
return VERSION_3DSMAX;
}
//
// ASF import module functions follow:
//
AMC_Import::AMC_Import() {}
AMC_Import::~AMC_Import() {}
int AMC_Import::ExtCount()
{
return 1;
}
// Extensions supported for import/export modules
const TCHAR * AMC_Import::Ext(int n)
{
return _T("AMC");
}
const TCHAR * AMC_Import::LongDesc()
{
return GetString(IDS_LONG_DESC);
}
const TCHAR * AMC_Import::ShortDesc()
{
return GetString(IDS_SHORT_DESC);
}
const TCHAR * AMC_Import::AuthorName()
{
return GetString(IDS_AUTHOR_NAME);
}
const TCHAR * AMC_Import::CopyrightMessage()
{
return GetString(IDS_COPYRIGHT);
}
const TCHAR * AMC_Import::OtherMessage1()
{
return _T("");
}
const TCHAR * AMC_Import::OtherMessage2()
{
return _T("");
}
unsigned int AMC_Import::Version()
{
return 100;
}
void AMC_Import::ShowAbout(HWND hWnd)
{
}
//----------------------------------------------------------------------------
// Key_Class
//----------------------------------------------------------------------------
struct Key_Class
{
TimeValue Time;
Quat Orientation;
Point3 Position;
};
//----------------------------------------------------------------------------
// Bone
//----------------------------------------------------------------------------
class Bone
{
public:
Bone ( const char * name, Bone * next )
{
Name = new char [ strlen (name) + 1 ];
strcpy ( Name, name );
Next = next;
Max_keys = 1;
Number_of_keys = 0;
Key = NULL;
}
~Bone ()
{
delete [] Name;
if ( Key != NULL )
delete [] Key;
}
void alloc_key_space ( Interface * gi )
{
if ( Key == NULL && Max_keys > 0 )
Key = new Key_Class [ Max_keys ];
// Find the bone's I-node.
// TODO: check to ensure we got the inode!
INode * inode = gi->GetINodeByName ( Name );
if (inode) {
// Add a key at frame zero to hold the original position.
Quat rotation ( 0.0f, 0.0f, 0.0f, 1.0f );
Matrix3 localTM = inode->GetNodeTM (0) *
Inverse (inode->GetParentTM (0));
rotation *= localTM;
add_key ( 0, rotation, Point3 (0,0,0) );
}
}
void inc_max_keys () { ++ Max_keys; }
void add_key ( TimeValue time, const Quat & rot, const Point3 & pos )
{
if ( Key != NULL && Number_of_keys < Max_keys )
{
Key [Number_of_keys].Time = time;
Key [Number_of_keys].Orientation = rot;
Key [Number_of_keys].Position = pos;
++ Number_of_keys;
}
}
void put_keys_into_max ( ImpInterface * imp_i, Interface * i );
Bone * next () const { return Next; }
char * name () const { return Name; }
protected:
char * Name;
Bone * Next;
unsigned Max_keys;
unsigned Number_of_keys;
Key_Class * Key;
};
//----------------------------------------------------------------------------
// Bone::put_keys_into_max
//----------------------------------------------------------------------------
void Bone::put_keys_into_max ( ImpInterface * imp_i, Interface * i )
{
unsigned k;
// Find the bone's I-node.
INode * inode = i->GetINodeByName ( Name );
if ( inode == NULL )
return;
// Make each quaternion be on the same side of the hypersphere as its
// predecessor.
for ( k = 1; k < Number_of_keys; ++ k )
{
Key [k].Orientation.MakeClosest ( Key [k-1].Orientation );
}
// Make each rotation relative to the previous one.
if ( Number_of_keys > 1 )
{
for ( unsigned k = Number_of_keys - 1; k > 0; -- k )
{
Key [k].Orientation = Key [k].Orientation / Key [k-1].Orientation;
}
}
// Add the keys to the bone's rotation controller.
// Replace the rotation controller if it is not the right type.
Control * c = inode->GetTMController ()->GetRotationController ();
if ( c && c->ClassID () != Class_ID (TCBINTERP_ROTATION_CLASS_ID, 0) )
{
Control *tcb = (Control*) i->CreateInstance ( CTRL_ROTATION_CLASS_ID,
Class_ID (TCBINTERP_ROTATION_CLASS_ID,0) );
if ( ! inode->GetTMController ()->SetRotationController(tcb) )
{
tcb->DeleteThis();
}
}
c = inode->GetTMController ()->GetRotationController ();
// c->SetORT ( ORT_LOOP, ORT_BEFORE );
// c->SetORT ( ORT_LOOP, ORT_AFTER );
IKeyControl * keys = GetKeyControlInterface ( c );
keys->SetNumKeys ( Number_of_keys );
// Create keys.
for ( k = 0; k < Number_of_keys; ++ k )
{
ITCBRotKey key;
key.tens = 0.0f;
key.cont = 0.0f;
key.bias = 0.0f;
key.easeIn = 0.0f;
key.easeOut = 0.0f;
key.time = Key [k].Time;
key.val = (AngAxis) Key [k].Orientation;
keys->SetKey ( k, & key );
}
keys->SortKeys ();
// &&& This is a hack; add position keys for the root node.
// Another hack: The positions are multiplied by a scale factor which
// should be derived from the ASF file.
float length_multiplier;
if ( strcmp ( Name, "root" ) == 0 )
{
// Since this is the root node, check for an AppData chunk defining
// the length multiplier.
// This "length multiplier" will convert whatever numbers are in the file
// into *inches*. We later convert this to whatever units Max is using...
AppDataChunk * chunk = inode->GetAppDataChunk
(
Class_ID(0x74975aa6, 0x1810323f),
SCENE_IMPORT_CLASS_ID,
2
);
if ( chunk == NULL )
{
// (gth) HACK HACK HACK! For some time, I had removed this 'length_multiplier'
// Many commando animations were created without the multiplier which was 1.0 / 0.0254
// so, shove that multiplier in if one wasn't found... This only comes into play
// when loading a motion into a max file that use the old importer to create the
// base pose.
length_multiplier = 1.0f / 0.0254f;
}
else
{
Position_Key_Scale_Chunk * data_p = (Position_Key_Scale_Chunk *) chunk->data;
length_multiplier = data_p->Position_Key_Scale;
}
// Account for the current units setting of Max (e.g. 1 unit = 1 Meter)
length_multiplier /= (float)GetMasterScale(UNITS_INCHES);
// Make sure we have the right kind of controller.
c = inode->GetTMController ()->GetPositionController ();
if ( c && c->ClassID () != Class_ID (TCBINTERP_POSITION_CLASS_ID, 0) )
{
Control *tcb = (Control*) i->CreateInstance ( CTRL_POSITION_CLASS_ID,
Class_ID (TCBINTERP_POSITION_CLASS_ID,0) );
if ( ! inode->GetTMController ()->SetPositionController(tcb) )
{
tcb->DeleteThis();
}
}
c = inode->GetTMController ()->GetPositionController ();
// c->SetORT ( ORT_LOOP, ORT_BEFORE );
// c->SetORT ( ORT_LOOP, ORT_AFTER );
keys = GetKeyControlInterface ( c );
keys->SetNumKeys ( Number_of_keys );
// Create keys.
for ( k = 0; k < Number_of_keys; ++ k )
{
ITCBPoint3Key key;
key.tens = 0.0f;
key.cont = 0.0f;
key.bias = 0.0f;
key.easeIn = 0.0f;
key.easeOut = 0.0f;
key.time = Key [k].Time;
key.val = Key [k].Position * length_multiplier;
keys->SetKey ( k, & key );
}
keys->SortKeys ();
}
}
//----------------------------------------------------------------------------
// Key_Manager
//----------------------------------------------------------------------------
class Key_Manager
{
public:
Key_Manager () { Bones = NULL; }
~Key_Manager ();
// Call this first to increment the maximum number of keys for a given
// bone.
void inc_max_keys ( const char * bone_name );
// After all the maximums are set properly, call this to allocate space
// for holding the keys.
void alloc_key_space ( Interface * gi );
// After allocating space, add keys by calling this.
void add_key
(
const char * bone_name,
TimeValue time,
const Quat & rot,
const Point3 & pos
);
// Once all the keys have been added, call this to massage them and
// put them into 3D Studio.
void put_keys_into_max ( ImpInterface *, Interface * );
protected:
Bone * Bones;
};
//----------------------------------------------------------------------------
// Key_Manager::~Key_Manager
//----------------------------------------------------------------------------
Key_Manager::~Key_Manager ()
{
Bone * p = Bones;
while ( p != NULL )
{
Bone * delete_p = p;
p = p->next ();
delete delete_p;
}
}
//----------------------------------------------------------------------------
// Key_Manager::inc_max_keys
//----------------------------------------------------------------------------
void Key_Manager::inc_max_keys ( const char * name )
{
for ( Bone * p = Bones; p != NULL; p = p->next () )
{
if ( strcmp ( p->name (), name ) == 0 )
break;
}
if ( p == NULL )
{
// This is a new bone; add it to the list.
p = new Bone ( name, Bones );
Bones = p;
}
p->inc_max_keys ();
}
//----------------------------------------------------------------------------
// Key_Manager::alloc_key_space
//----------------------------------------------------------------------------
void Key_Manager::alloc_key_space ( Interface * gi )
{
for ( Bone * p = Bones; p != NULL; p = p->next () )
{
p->alloc_key_space ( gi );
}
}
//----------------------------------------------------------------------------
// Key_Manager::add_key
//----------------------------------------------------------------------------
void Key_Manager::add_key
(
const char * name,
TimeValue time,
const Quat & rot,
const Point3 & pos
)
{
for ( Bone * p = Bones; p != NULL; p = p->next () )
{
if ( strcmp ( p->name (), name ) == 0 )
break;
}
if ( p != NULL )
{
p->add_key ( time, rot, pos );
}
}
//----------------------------------------------------------------------------
// Key_Manager::put_keys_into_max
//----------------------------------------------------------------------------
void Key_Manager::put_keys_into_max ( ImpInterface * imp_i, Interface * i )
{
for ( Bone * p = Bones; p != NULL; p = p->next () )
{
p->put_keys_into_max ( imp_i, i );
}
}
//----------------------------------------------------------------------------
// get_name
//----------------------------------------------------------------------------
void get_name
(
char * & line_p,
char * & name_p
)
{
name_p = line_p;
while ( ! isspace (*line_p) )
++ line_p;
*line_p = '\0';
++ line_p;
}
//----------------------------------------------------------------------------
// read_frames
//----------------------------------------------------------------------------
static void read_frames
(
FILE * file,
ImpInterface * iface,
Interface * gi
)
{
char line [ 512 ];
Key_Manager key_manager;
// Start by identifying the bones in the system and the number of keys
// for each.
long start_pos = ftell ( file );
while (1)
{
char * rv = fgets ( line, sizeof line, file );
if ( rv == NULL )
break;
if ( ! isdigit (line [0]) )
{
char * line_p = line;
char * name_p;
get_name ( line_p, name_p );
key_manager.inc_max_keys ( name_p );
}
}
// Prepare to scan the file again. Allocate space to hold the keys.
fseek ( file, start_pos, SEEK_SET );
key_manager.alloc_key_space ( gi );
int frame_time = 0;
while (1)
{
char * rv = fgets ( line, sizeof line, file );
if ( rv == NULL )
break;
if ( isdigit (line [0]) )
{
// This line marks the start of a new frame.
int frame_number = strtol ( line, NULL, 10 );
frame_time = (frame_number - 1) * amc_ticks_per_frame +
first_frame_time;
}
else
{
// This line contains a bone's data for the current frame.
// Get the name of the bone whose key is being defined.
char * line_p = line;
char * name_p;
get_name ( line_p, name_p );
// Find the I-node with the name given in the input file.
INode * inode = gi->GetINodeByName ( name_p );
#if 0
if ( inode == NULL )
{
char message [ 256 ];
sprintf ( message, "Can't find node named \"%s\".",
name_p );
MessageBox ( GetActiveWindow (), message, "Parse error",
MB_OK );
return;
}
#else
if ( inode == NULL) {
continue;
}
#endif
// From the I-node, get the appdata chunk that defines the order
// in which rotations should be applied.
AppDataChunk * chunk = inode->GetAppDataChunk
(
Class_ID(0x74975aa6, 0x1810323f),
SCENE_IMPORT_CLASS_ID,
1
);
if ( chunk == NULL )
{
char message [ 256 ];
sprintf ( message, "\"%s\" has no app data chunk.",
name_p );
MessageBox ( GetActiveWindow (), message, "Parse error",
MB_OK );
return;
}
ASF_Data_Chunk * data_p = (ASF_Data_Chunk *) chunk->data;
// Read in angle settings and build a transform matrix from them.
Quat rotation (0.0f,0.0f,0.0f,1.0f);
Point3 translation ( 0, 0, 0 );
for ( unsigned i = 0; i < data_p->Number_of_axes; ++ i )
{
float value;
value = (float) strtod ( line_p, & line_p );
switch ( data_p->Axis [i] )
{
case ROTATE_X:
rotation *= (Quat) AngAxis ( Point3 (1, 0, 0),
-value * ANGLE_MULTIPLIER );
break;
case ROTATE_Y:
rotation *= (Quat) AngAxis ( Point3 (0, 1, 0),
-value * ANGLE_MULTIPLIER );
break;
case ROTATE_Z:
rotation *= (Quat) AngAxis ( Point3 (0, 0, 1),
-value * ANGLE_MULTIPLIER );
break;
case TRANSLATE_X:
translation.x = value;
break;
case TRANSLATE_Y:
translation.y = value;
break;
case TRANSLATE_Z:
translation.z = value;
break;
case TRANSLATE_LENGTH:
default:
break;
}
}
Matrix3 localTM = inode->GetNodeTM (0) *
Inverse (inode->GetParentTM (0));
rotation *= localTM;
if ( frame_time % max_ticks_per_frame == 0 )
key_manager.add_key ( name_p, frame_time, rotation, translation );
}
}
key_manager.put_keys_into_max ( iface, gi );
gi->SetAnimRange ( Interval (0, frame_time) );
}
//----------------------------------------------------------------------------
// amc_load
//----------------------------------------------------------------------------
static int amc_load
(
const TCHAR * filename,
ImpInterface * iface,
Interface * gi
)
{
char line [ 512 ];
// Load the motion-capture data file.
FILE * file = fopen ( filename, "r" );
// Ignore the first line.
fgets ( line, sizeof line, file );
// Match the second line to ":FULLY-SPECIFIED".
fgets ( line, sizeof line, file );
if ( strcmp ( line, ":FULLY-SPECIFIED\n" ) != 0 )
{
MessageBox ( GetActiveWindow (), "First line.", "Parse error",
MB_OK );
return -1;
}
// Match the third line to ":DEGREES".
fgets ( line, sizeof line, file );
if ( strcmp ( line, ":DEGREES\n" ) != 0 )
{
MessageBox ( GetActiveWindow (), "Second line.", "Parse error",
MB_OK );
return -1;
}
// Build the data structures to hold the rotation keys.
read_frames ( file, iface, gi );
fclose ( file );
return 1;
}
//----------------------------------------------------------------------------
// AMC_Import::DoImport
//----------------------------------------------------------------------------
int AMC_Import::DoImport
(
const TCHAR * filename,
ImpInterface * iface,
Interface * gi,
BOOL
)
{
max_ticks_per_frame = GetTicksPerFrame ();
int status = amc_load ( filename, iface, gi );
if ( status == 0 )
status = IMPEXP_CANCEL;
return (status <= 0) ? IMPEXP_FAIL : status;
}

View File

@@ -0,0 +1,8 @@
LIBRARY amc_imp
EXPORTS
LibDescription @1
LibNumberClasses @2
LibClassDesc @3
LibVersion @4
SECTIONS
.data READ WRITE

View File

@@ -0,0 +1,100 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#define APSTUDIO_HIDDEN_SYMBOLS
#include "windows.h"
#undef APSTUDIO_HIDDEN_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
"#include ""windows.h""\r\n"
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE DISCARDABLE
BEGIN
IDS_LIB_SHORT_DESC "AMC Import"
IDS_LIB_LONG_DESC "Acclaim Motion Capture Import DLL"
IDS_IMPORTING_AMC "Importing AMC"
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_ERR_OPENING_FILE "Error opening file"
IDS_TH_OUTOFMEMORY "Out of memory"
IDS_SHORT_DESC "AMC File"
IDS_LONG_DESC "Acclaim Motion Capture File"
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_CATEGORY "Scene Import"
IDS_AUTHOR_NAME "James McNeill"
IDS_COPYRIGHT "Copyright 1996 Westwood Studios"
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_NODE_CREATION_ERROR "Node creation error."
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@@ -0,0 +1,45 @@
/*
** Command & Conquer Renegade(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/>.
*/
class Exception
{
public:
virtual const char * message () const
{
return "General exception.";
}
};
class Parse_Error : public Exception
{
public:
Parse_Error ( const char * message ) :
Message (message)
{}
virtual const char * message () const
{
return Message;
}
protected:
const char * Message;
};

View File

@@ -0,0 +1,63 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by AMC_import.rc
//
#define IDD_IMPORTOPTIONS 101
#define IDC_OBJ_LAYER 1000
#define IDC_OBJ_COLOR 1001
#define IDC_OBJ_ENTITY 1002
#define IDC_REMOVEDOUBLES 1004
#define IDC_FILLPOLYLINES 1005
#define IDC_AUTOSMOOTH 1006
#define IDC_WELDENTRY 1007
#define IDC_WELDSPINNER 1008
#define IDC_SMOOTHSPINNER 1009
#define IDC_SMOOTHENTRY 1010
#define IDC_ARCSPINNER 1011
#define IDC_ARCENTRY 1012
#define IDC_WELD 1013
#define IDC_UNIFYNORMALS 1014
#define IDC_DBG1 1015
#define IDS_TH_SCENEIMPORT 40217
#define IDS_CATEGORY 40217
#define IDS_TH_TOM_HUDSON 40222
#define IDS_AUTHOR_NAME 40222
#define IDS_TH_COPYRIGHT_YOST_GROUP 40223
#define IDS_COPYRIGHT 40223
#define IDS_TH_ERR_OPENING_FILE 40225
#define IDS_ERR_OPENING_FILE 40225
#define IDS_TH_OUTOFMEMORY 40230
#define IDS_TH_AUTOCAD 40236
#define IDS_SHORT_DESC 40236
#define IDS_TH_AUTOCADDXFFILE 40238
#define IDS_LONG_DESC 40238
#define IDS_TH_DXFIMP 40240
#define IDS_LIB_SHORT_DESC 40240
#define IDS_TH_DXFIMPORTDLL 40241
#define IDS_LIB_LONG_DESC 40241
#define IDS_TH_PARTIALREAD 40242
#define IDS_TH_UNKNOWNERR 40243
#define IDS_TH_FINALIZING 40244
#define IDS_TH_IMPORTINGDXF 40245
#define IDS_IMPORTING_CME 40245
#define IDS_IMPORTING_ASF 40245
#define IDS_IMPORTING_AMC 40245
#define IDS_TH_INVALIDRATSNEST 40253
#define IDS_TH_INVALIDSPLINEMESH 40254
#define IDS_TH_INVALID3DMESH 40255
#define IDS_TH_ERRORINDXF 40256
#define IDS_BAD_HEADER 40257
#define IDS_UNEXPECTED_EOF 40258
#define IDS_NODE_CREATION_ERROR 40259
#define IDC_STATIC -1
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1016
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@@ -0,0 +1,73 @@
/*
** Command & Conquer Renegade(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/>.
*/
#if !defined(AFX_WDVIEW_H__41C157F8_5631_11D1_8CDB_006097C6A583__INCLUDED_)
#define AFX_WDVIEW_H__41C157F8_5631_11D1_8CDB_006097C6A583__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
// WDView.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CWDumpEditView view
class CWDumpEditView : public CEditView
{
protected:
CWDumpEditView(); // protected constructor used by dynamic creation
DECLARE_DYNCREATE(CWDumpEditView)
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CWDumpEditView)
protected:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint);
//}}AFX_VIRTUAL
// Implementation
protected:
virtual ~CWDumpEditView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
// Generated message map functions
protected:
char * Build_Hex_Text(unsigned char *Source, int Length);
//{{AFX_MSG(CWDumpEditView)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_WDVIEW_H__41C157F8_5631_11D1_8CDB_006097C6A583__INCLUDED_)

View File

@@ -0,0 +1,135 @@
# Microsoft Developer Studio Project File - Name="asf_imp" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=asf_imp - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "ASF_IMP.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "ASF_IMP.mak" CFG="asf_imp - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "asf_imp - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "asf_imp - Win32 Hybrid" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/Commando/Code/Tools/ASF_IMP", SGHAAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "asf_imp - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\Release"
# PROP BASE Intermediate_Dir ".\Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MD /W3 /GX /Z7 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comctl32.lib core.lib geom.lib maxutil.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/asf_imp.dli"
# SUBTRACT LINK32 /nodefaultlib
!ELSEIF "$(CFG)" == "asf_imp - Win32 Hybrid"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Hybrid"
# PROP BASE Intermediate_Dir "Hybrid"
# PROP BASE Ignore_Export_Lib 0
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Hybrid"
# PROP Intermediate_Dir "Hybrid"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /Z7 /O2 /I "c:\3dsmax2\maxsdk\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /Z7 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib core.lib geom.lib util.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Hybrid/asf_imp.dli"
# SUBTRACT BASE LINK32 /nodefaultlib
# ADD LINK32 odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comctl32.lib core.lib geom.lib maxutil.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"Hybrid\asf_imp.dli"
# SUBTRACT LINK32 /nodefaultlib
!ENDIF
# Begin Target
# Name "asf_imp - Win32 Release"
# Name "asf_imp - Win32 Hybrid"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
# Begin Source File
SOURCE=.\ASF_import.cpp
# End Source File
# Begin Source File
SOURCE=.\ASF_import.def
# End Source File
# Begin Source File
SOURCE=.\Read_ASF.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# Begin Source File
SOURCE=.\asf_data.h
# End Source File
# Begin Source File
SOURCE=.\exception.h
# End Source File
# Begin Source File
SOURCE=.\read_asf.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# Begin Source File
SOURCE=.\ASF_import.rc
# End Source File
# End Group
# End Target
# End Project

View File

@@ -0,0 +1,280 @@
/*
** Command & Conquer Renegade(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/>.
*/
//----------------------------------------------------------------------------
// asf_import.cpp
//
// Acclaim Skeleton File import module
//
// James McNeill
//
// Created October 1996
//
// Copyright (c) 1996 Westwood Studios
//----------------------------------------------------------------------------
#include <Max.h>
#include <istdplug.h>
#include <splshape.h>
#include <dummy.h>
#include "asf_resource.h"
#include "asf_data.h"
#include "read_asf.h"
#include "exception.h"
static HINSTANCE hInstance;
static TCHAR * GetString ( int id )
{
static TCHAR buf[256];
if (hInstance)
return LoadString(hInstance, id, buf, sizeof(buf)) ? buf : NULL;
return NULL;
}
static int MessageBox ( int s1, int s2, int option = MB_OK )
{
TSTR str1(GetString(s1));
TSTR str2(GetString(s2));
return MessageBox(GetActiveWindow(), str1, str2, option);
}
static int Alert ( int s1, int s2 = IDS_LIB_SHORT_DESC, int option = MB_OK )
{
return MessageBox(s1, s2, option);
}
//----------------------------------------------------------------------------
// ASF_Import
//----------------------------------------------------------------------------
class ASF_Import : public SceneImport
{
public:
ASF_Import();
~ASF_Import();
int ExtCount(); // Number of extensions supported
const TCHAR * Ext(int n); // Extension #n
const TCHAR * LongDesc(); // Long ASCII description
const TCHAR * ShortDesc(); // Short ASCII description
const TCHAR * AuthorName(); // ASCII Author name
const TCHAR * CopyrightMessage(); // ASCII Copyright message
const TCHAR * OtherMessage1(); // Other message #1
const TCHAR * OtherMessage2(); // Other message #2
unsigned int Version(); // Version number * 100
void ShowAbout(HWND); // Show DLL's "About..." box
int DoImport
(
const TCHAR * name,
ImpInterface * i,
Interface * gi,
BOOL suppressPrompts=FALSE
);
};
//----------------------------------------------------------------------------
// DllMain
//----------------------------------------------------------------------------
static int controlsInit = FALSE;
BOOL WINAPI DllMain
(
HINSTANCE hinstDLL,
ULONG fdwReason,
LPVOID lpvReserved
)
{
hInstance = hinstDLL;
if ( !controlsInit )
{
controlsInit = TRUE;
InitCustomControls(hInstance);
InitCommonControls();
}
switch(fdwReason)
{
case DLL_PROCESS_ATTACH: break;
case DLL_THREAD_ATTACH: break;
case DLL_THREAD_DETACH: break;
case DLL_PROCESS_DETACH: break;
}
return TRUE;
}
//----------------------------------------------------------------------------
// ASF_ClassDesc
//----------------------------------------------------------------------------
class ASF_ClassDesc : public ClassDesc
{
public:
int IsPublic() { return 1; }
void * Create(BOOL loading = FALSE) { return new ASF_Import; }
const TCHAR * ClassName() { return GetString(IDS_SHORT_DESC); }
SClass_ID SuperClassID() { return SCENE_IMPORT_CLASS_ID; }
Class_ID ClassID() { return Class_ID(0x74975aa6, 0x1810323f); }
const TCHAR* Category() { return GetString(IDS_CATEGORY); }
};
static ASF_ClassDesc ASF_desc;
//----------------------------------------------------------------------------
// This is the interface to Jaguar:
//----------------------------------------------------------------------------
__declspec( dllexport ) const TCHAR * LibDescription()
{
return GetString(IDS_LIB_LONG_DESC);
}
__declspec( dllexport ) int LibNumberClasses()
{
return 1;
}
__declspec( dllexport ) ClassDesc * LibClassDesc(int i)
{
switch(i)
{
case 0: return & ASF_desc; break;
default: return 0; break;
}
}
// Return version so can detect obsolete DLLs
__declspec( dllexport ) ULONG LibVersion()
{
return VERSION_3DSMAX;
}
//
// ASF import module functions follow:
//
ASF_Import::ASF_Import() {}
ASF_Import::~ASF_Import() {}
int ASF_Import::ExtCount()
{
return 1;
}
// Extensions supported for import/export modules
const TCHAR * ASF_Import::Ext(int n)
{
if ( n == 0 ) return _T("ASF");
else return _T("");
}
const TCHAR * ASF_Import::LongDesc()
{
return GetString(IDS_LONG_DESC);
}
const TCHAR * ASF_Import::ShortDesc()
{
return GetString(IDS_SHORT_DESC);
}
const TCHAR * ASF_Import::AuthorName()
{
return GetString(IDS_AUTHOR_NAME);
}
const TCHAR * ASF_Import::CopyrightMessage()
{
return GetString(IDS_COPYRIGHT);
}
const TCHAR * ASF_Import::OtherMessage1()
{
return _T("");
}
const TCHAR * ASF_Import::OtherMessage2()
{
return _T("");
}
unsigned int ASF_Import::Version()
{
return 100;
}
void ASF_Import::ShowAbout(HWND hWnd)
{
}
//----------------------------------------------------------------------------
// asf_load
//----------------------------------------------------------------------------
static int asf_load
(
const TCHAR * filename,
ImpInterface * iface,
Interface * gi
)
{
// Load the skeleton definition file.
try
{
Skeleton_Class skeleton ( filename, iface, gi );
}
catch ( const Parse_Error & error )
{
MessageBox ( GetActiveWindow (), error.message (), "Parse error",
MB_OK );
return -1;
}
// Create a matching skeleton in 3DS Max.
return 1;
}
//----------------------------------------------------------------------------
// ASF_Import::DoImport
//----------------------------------------------------------------------------
int ASF_Import::DoImport
(
const TCHAR * filename,
ImpInterface * iface,
Interface * gi,
BOOL
)
{
int status;
status = asf_load ( filename, iface, gi );
if(status == 0)
status = IMPEXP_CANCEL;
return (status <= 0) ? IMPEXP_FAIL : status;
}

View File

@@ -0,0 +1,8 @@
LIBRARY asf_imp
EXPORTS
LibDescription @1
LibNumberClasses @2
LibClassDesc @3
LibVersion @4
SECTIONS
.data READ WRITE

View File

@@ -0,0 +1,147 @@
//Microsoft Developer Studio generated resource script.
//
#include "asf_resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#define APSTUDIO_HIDDEN_SYMBOLS
#include "windows.h"
#undef APSTUDIO_HIDDEN_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_IMPORTOPTIONS DIALOG DISCARDABLE 0, 0, 123, 266
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Import DXF File"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,67,231,50,14
PUSHBUTTON "Cancel",IDCANCEL,67,247,50,14
GROUPBOX "Derive Objects From:",IDC_STATIC,6,4,112,50
CONTROL "&Layer",IDC_OBJ_LAYER,"Button",BS_AUTORADIOBUTTON |
WS_TABSTOP,44,17,29,10
CONTROL "&Color",IDC_OBJ_COLOR,"Button",BS_AUTORADIOBUTTON,44,28,
28,10
CONTROL "&Entity",IDC_OBJ_ENTITY,"Button",BS_AUTORADIOBUTTON,44,
38,30,10
GROUPBOX "Weld Vertices:",IDC_STATIC,6,57,112,41
RTEXT "Weld Threshold:",IDC_STATIC,13,72,55,8
CONTROL "",IDC_WELDENTRY,"CustEdit",WS_TABSTOP,69,71,36,10
CONTROL "",IDC_WELDSPINNER,"SpinnerControl",0x0,106,71,7,10
CONTROL "&Weld",IDC_WELD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
47,83,30,10
GROUPBOX "Auto-Smooth:",IDC_STATIC,6,102,112,40
RTEXT "Smooth Angle:",IDC_STATIC,16,117,48,8
CONTROL "",IDC_SMOOTHENTRY,"CustEdit",WS_TABSTOP,65,117,36,10
CONTROL "",IDC_SMOOTHSPINNER,"SpinnerControl",0x0,102,117,7,10
CONTROL "&Auto-Smooth",IDC_AUTOSMOOTH,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,34,128,53,10
GROUPBOX "Arc Degrees:",IDC_STATIC,6,146,112,30
RTEXT "&Degrees:",IDC_STATIC,23,161,31,8
CONTROL "00",IDC_ARCENTRY,"CustEdit",WS_TABSTOP,56,160,36,10
CONTROL "",IDC_ARCSPINNER,"SpinnerControl",0x0,93,160,7,10
GROUPBOX "Miscellaneous:",IDC_STATIC,6,180,112,46
CONTROL "&Remove Double Faces",IDC_REMOVEDOUBLES,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,19,193,85,10
CONTROL "&Fill Polylines",IDC_FILLPOLYLINES,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,19,203,52,10
CONTROL "&Unify Normals",IDC_UNIFYNORMALS,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,19,213,56,10
END
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"asf_resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
"#include ""windows.h""\r\n"
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE DISCARDABLE
BEGIN
IDS_LIB_SHORT_DESC "ASF Import"
IDS_LIB_LONG_DESC "Acclaim Skeleton Format Import DLL"
IDS_IMPORTING_ASF "Importing ASF"
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_ERR_OPENING_FILE "Error opening file"
IDS_TH_OUTOFMEMORY "Out of memory"
IDS_SHORT_DESC "ASF File"
IDS_LONG_DESC "Acclaim Skeleton Format File"
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_CATEGORY "Scene Import"
IDS_AUTHOR_NAME "James McNeill"
IDS_COPYRIGHT "Copyright 1996 Westwood Studios"
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_BAD_HEADER "Bad header in CME file."
IDS_UNEXPECTED_EOF "Unexpected end of file in CME file."
IDS_NODE_CREATION_ERROR "Node creation error."
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@@ -0,0 +1,62 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by ASF_import.rc
//
#define IDD_IMPORTOPTIONS 101
#define IDC_OBJ_LAYER 1000
#define IDC_OBJ_COLOR 1001
#define IDC_OBJ_ENTITY 1002
#define IDC_REMOVEDOUBLES 1004
#define IDC_FILLPOLYLINES 1005
#define IDC_AUTOSMOOTH 1006
#define IDC_WELDENTRY 1007
#define IDC_WELDSPINNER 1008
#define IDC_SMOOTHSPINNER 1009
#define IDC_SMOOTHENTRY 1010
#define IDC_ARCSPINNER 1011
#define IDC_ARCENTRY 1012
#define IDC_WELD 1013
#define IDC_UNIFYNORMALS 1014
#define IDC_DBG1 1015
#define IDS_TH_SCENEIMPORT 40217
#define IDS_CATEGORY 40217
#define IDS_TH_TOM_HUDSON 40222
#define IDS_AUTHOR_NAME 40222
#define IDS_TH_COPYRIGHT_YOST_GROUP 40223
#define IDS_COPYRIGHT 40223
#define IDS_TH_ERR_OPENING_FILE 40225
#define IDS_ERR_OPENING_FILE 40225
#define IDS_TH_OUTOFMEMORY 40230
#define IDS_TH_AUTOCAD 40236
#define IDS_SHORT_DESC 40236
#define IDS_TH_AUTOCADDXFFILE 40238
#define IDS_LONG_DESC 40238
#define IDS_TH_DXFIMP 40240
#define IDS_LIB_SHORT_DESC 40240
#define IDS_TH_DXFIMPORTDLL 40241
#define IDS_LIB_LONG_DESC 40241
#define IDS_TH_PARTIALREAD 40242
#define IDS_TH_UNKNOWNERR 40243
#define IDS_TH_FINALIZING 40244
#define IDS_TH_IMPORTINGDXF 40245
#define IDS_IMPORTING_CME 40245
#define IDS_IMPORTING_ASF 40245
#define IDS_TH_INVALIDRATSNEST 40253
#define IDS_TH_INVALIDSPLINEMESH 40254
#define IDS_TH_INVALID3DMESH 40255
#define IDS_TH_ERRORINDXF 40256
#define IDS_BAD_HEADER 40257
#define IDS_UNEXPECTED_EOF 40258
#define IDS_NODE_CREATION_ERROR 40259
#define IDC_STATIC -1
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1016
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@@ -0,0 +1,818 @@
/*
** Command & Conquer Renegade(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/>.
*/
#include <Max.h>
#include <istdplug.h>
#include "asf_data.h"
#include "read_asf.h"
#include "exception.h"
//----------------------------------------------------------------------------
// ASF_Lexer::ASF_Lexer
//----------------------------------------------------------------------------
ASF_Lexer::ASF_Lexer
(
const char * file_name
):
Input_file ( file_name, "r" )
{
Current_char = tolower ( fgetc ( Input_file.fp ) );
advance ();
}
//----------------------------------------------------------------------------
// ASF_Lexer::skip_whitespace
//----------------------------------------------------------------------------
// Skip whitespace and comments, leaving the Current_char pointing to the
// first non-whitespace character in the input stream.
//----------------------------------------------------------------------------
void ASF_Lexer::skip_whitespace ()
{
while (1)
{
if ( Current_char == '#' ) // Strip out comments
{
while ( Current_char != '\n' && Current_char != EOF )
Current_char = tolower ( fgetc ( Input_file.fp ) );
}
else if ( (isspace ( Current_char ) && Current_char != '\n') ||
Current_char == ',' ||
Current_char == '(' ||
Current_char == ')' )
{
Current_char = tolower ( fgetc ( Input_file.fp ) );
}
else
{
break;
}
}
}
//----------------------------------------------------------------------------
// ASF_Lexer::advance
//----------------------------------------------------------------------------
// Advance to the next token in the input stream.
//----------------------------------------------------------------------------
void ASF_Lexer::advance ()
{
skip_whitespace ();
if ( Current_char == EOF )
{
Current_type = EOF_MARKER;
strcpy ( Current_text, "<end of file>" );
return;
}
if ( Current_char == '\n' )
{
Current_type = NEWLINE;
strcpy ( Current_text, "<newline>" );
Current_char = tolower ( fgetc ( Input_file.fp ) );
return;
}
Current_type = TOKEN;
// Read characters into the token text buffer.
int i = 0;
while ( ! isspace (Current_char) &&
Current_char != '#' &&
Current_char != ',' &&
Current_char != '(' &&
Current_char != ')' &&
Current_char != EOF )
{
if ( i >= (MAX_TOKEN_LENGTH - 1) )
{
// Abort -- maximum token length exceeded.
throw Parse_Error ( "Maximum token length exceeded." );
}
Current_text [i] = Current_char;
++ i;
Current_char = tolower ( fgetc ( Input_file.fp ) );
}
Current_text [i] = '\0';
}
//----------------------------------------------------------------------------
// Skeleton_Class::Skeleton_Class
//----------------------------------------------------------------------------
Skeleton_Class::Skeleton_Class
(
const char * file_name,
ImpInterface * iface,
Interface * gi
) :
Angle_multiplier (DEGREES_TO_RADIANS),
Length_multiplier (1.0f),
First_bone (NULL),
Import_interface (iface),
Max_interface (gi)
{
ASF_Lexer lexer ( file_name );
parse_units_block ( lexer );
parse_root_block ( lexer );
parse_bonedata_block ( lexer );
parse_hierarchy_block ( lexer );
}
//----------------------------------------------------------------------------
// Skeleton_Class::~Skeleton_Class
//----------------------------------------------------------------------------
Skeleton_Class::~Skeleton_Class ()
{
Bone_Class * p = First_bone;
while ( p != NULL )
{
Bone_Class * delete_p = p;
p = p->next_bone ();
delete delete_p;
}
}
//----------------------------------------------------------------------------
// Skeleton_Class::parse_units_block
//----------------------------------------------------------------------------
void Skeleton_Class::parse_units_block ( ASF_Lexer & lexer )
{
skip_unrecognized_blocks ( lexer );
match_token ( lexer, ":units" );
match_newline ( lexer );
BOOL mass_defined = FALSE;
BOOL length_defined = FALSE;
BOOL angle_defined = FALSE;
while (1)
{
verify_token ( lexer );
if ( strcmp ( lexer.text (), "mass" ) == 0 )
{
if ( mass_defined )
throw Parse_Error ( "Multiple mass definitions." );
lexer.advance ();
skip_token ( lexer ); // Ignore the mass definition.
match_newline ( lexer );
mass_defined = TRUE;
}
else if ( strcmp ( lexer.text (), "length" ) == 0 )
{
if ( length_defined )
throw Parse_Error ( "Multiple length definitions." );
lexer.advance ();
verify_token ( lexer );
Length_multiplier = 1.0f / float_token ( lexer );
match_newline ( lexer );
length_defined = TRUE;
}
else if ( strcmp ( lexer.text (), "angle" ) == 0 )
{
if ( angle_defined )
throw Parse_Error ( "Multiple angle definitions." );
lexer.advance ();
verify_token ( lexer );
if ( strcmp ( lexer.text (), "deg" ) == 0 )
Angle_multiplier = DEGREES_TO_RADIANS;
else if ( strcmp ( lexer.text (), "rad" ) == 0 )
Angle_multiplier = 1.0f;
else
throw Parse_Error
( "\"deg\" or \"rad\" expected after angle keyword." );
lexer.advance ();
match_newline ( lexer );
angle_defined = TRUE;
}
else
{
break;
}
}
}
//----------------------------------------------------------------------------
// Skeleton_Class::parse_root_block
//----------------------------------------------------------------------------
void Skeleton_Class::parse_root_block ( ASF_Lexer & lexer )
{
skip_unrecognized_blocks ( lexer );
match_token ( lexer, ":root" );
match_newline ( lexer );
// Create a root bone.
Bone_Class * new_bone = new Bone_Class;
new_bone->set_name ( "root" );
// The rotation order for orientation offset.
match_token ( lexer, "axis" );
skip_token ( lexer ); // &&& get rotation order for orientation offset.
match_newline ( lexer );
// The order of transformations for root.
match_token ( lexer, "order" );
for ( int i = 0; i < 6; ++ i )
{
verify_token ( lexer );
if ( strcmp ( lexer.text (), "rx" ) == 0 )
new_bone->add_axis ( ROTATE_X );
else if ( strcmp ( lexer.text (), "ry" ) == 0 )
new_bone->add_axis ( ROTATE_Y );
else if ( strcmp ( lexer.text (), "rz" ) == 0 )
new_bone->add_axis ( ROTATE_Z );
else if ( strcmp ( lexer.text (), "tx" ) == 0 )
new_bone->add_axis ( TRANSLATE_X );
else if ( strcmp ( lexer.text (), "ty" ) == 0 )
new_bone->add_axis ( TRANSLATE_Y );
else if ( strcmp ( lexer.text (), "tz" ) == 0 )
new_bone->add_axis ( TRANSLATE_Z );
else
throw Parse_Error ( "Unrecognized order token in :root." );
lexer.advance ();
}
match_newline ( lexer );
// Translation data for root node.
match_token ( lexer, "position" );
skip_token ( lexer ); // &&&
skip_token ( lexer ); // &&&
skip_token ( lexer ); // &&&
match_newline ( lexer );
// Rotation data to orient the skeleton.
match_token ( lexer, "orientation" );
float rot0 = float_token ( lexer ) * Angle_multiplier;
float rot1 = float_token ( lexer ) * Angle_multiplier;
float rot2 = float_token ( lexer ) * Angle_multiplier;
match_newline ( lexer );
Matrix3 axis_tm;
axis_tm.IdentityMatrix ();
axis_tm.RotateX ( rot0 );
axis_tm.RotateY ( rot1 );
axis_tm.RotateZ ( rot2 );
new_bone->set_axis_tm ( axis_tm );
new_bone->set_direction ( Point3 (0,0,0) );
new_bone->set_length ( 0.0f );
add_bone_to_list ( new_bone );
new_bone->create_node ( Import_interface, Max_interface );
// Add an AppData chunk to the root node to indicate how much to scale
// its position keys.
Position_Key_Scale_Chunk * data_p = (Position_Key_Scale_Chunk *)
malloc ( sizeof (Position_Key_Scale_Chunk) );
data_p->Position_Key_Scale = Length_multiplier;
new_bone->add_app_data ( 2, data_p, sizeof (Position_Key_Scale_Chunk) );
}
//----------------------------------------------------------------------------
// Skeleton_Class::parse_bonedata_block
//----------------------------------------------------------------------------
void Skeleton_Class::parse_bonedata_block ( ASF_Lexer & lexer )
{
skip_unrecognized_blocks ( lexer );
match_token ( lexer, ":bonedata" );
match_newline ( lexer );
// Parse bone definition blocks.
while (1)
{
verify_token ( lexer );
if ( strcmp ( lexer.text (), "begin" ) == 0 )
{
parse_bone ( lexer );
}
else
{
break;
}
}
}
//----------------------------------------------------------------------------
// Skeleton_Class::parse_hierarchy_block
//----------------------------------------------------------------------------
void Skeleton_Class::parse_hierarchy_block ( ASF_Lexer & lexer )
{
skip_unrecognized_blocks ( lexer );
match_token ( lexer, ":hierarchy" );
match_newline ( lexer );
match_token ( lexer, "begin" );
match_newline ( lexer );
while (1)
{
verify_token ( lexer );
if ( strcmp ( lexer.text (), "end" ) == 0 )
{
break;
}
else
{
parse_hierarchy_line ( lexer );
}
}
lexer.advance ();
match_newline ( lexer );
}
//----------------------------------------------------------------------------
// Skeleton_Class::parse_hierarchy_line
//----------------------------------------------------------------------------
void Skeleton_Class::parse_hierarchy_line ( ASF_Lexer & lexer )
{
verify_token ( lexer );
Bone_Class * parent_bone = find_bone ( lexer.text () );
if ( parent_bone == NULL )
throw Parse_Error ( "Undefined parent bone." );
lexer.advance ();
while ( lexer.type () == TOKEN )
{
Bone_Class * child_bone = find_bone ( lexer.text () );
if ( child_bone == NULL )
throw Parse_Error ( "Undefined child bone." );
child_bone->set_parent ( parent_bone );
lexer.advance ();
}
match_newline ( lexer );
}
//----------------------------------------------------------------------------
// Skeleton_Class::find_bone
//----------------------------------------------------------------------------
Bone_Class * Skeleton_Class::find_bone ( const char * name )
{
Bone_Class * p = First_bone;
while ( p != NULL )
{
if ( strcmp ( name, p->name () ) == 0 )
break;
p = p->next_bone ();
}
return p;
}
//----------------------------------------------------------------------------
// lh_to_rh
//----------------------------------------------------------------------------
static Point3 lh_to_rh ( Point3 point )
{
Point3 new_point;
new_point.x = point.x;
new_point.y = -point.z;
new_point.z = point.y;
return new_point;
}
//----------------------------------------------------------------------------
// Skeleton_Class::parse_bone
//----------------------------------------------------------------------------
void Skeleton_Class::parse_bone ( ASF_Lexer & lexer )
{
match_token ( lexer, "begin" );
match_newline ( lexer );
// Create a new bone object.
Bone_Class * new_bone = new Bone_Class;
// Optional ID number.
verify_token ( lexer );
if ( strcmp ( lexer.text (), "id" ) == 0 )
{
lexer.advance ();
skip_token ( lexer ); // Ignore the bone ID number for now.
match_newline ( lexer );
}
// Name.
match_token ( lexer, "name" );
verify_token ( lexer );
new_bone->set_name ( lexer.text () );
lexer.advance ();
match_newline ( lexer );
// Direction vector.
match_token ( lexer, "direction" );
Point3 direction;
direction.x = float_token ( lexer );
direction.y = float_token ( lexer );
direction.z = float_token ( lexer );
new_bone->set_direction ( direction );
match_newline ( lexer );
// Length.
match_token ( lexer, "length" );
new_bone->set_length ( float_token ( lexer ) * Length_multiplier / (float)GetMasterScale(UNITS_INCHES));
match_newline ( lexer );
// Rotation axis in world coordinates, with order of rotations.
match_token ( lexer, "axis" );
float rot0 = float_token ( lexer ) * Angle_multiplier;
float rot1 = float_token ( lexer ) * Angle_multiplier;
float rot2 = float_token ( lexer ) * Angle_multiplier;
// &&& Ultimately this should handle any order of rotations.
match_token ( lexer, "xyz" );
match_newline ( lexer );
Matrix3 axis_tm;
axis_tm.IdentityMatrix ();
axis_tm.RotateX ( rot0 );
axis_tm.RotateY ( rot1 );
axis_tm.RotateZ ( rot2 );
new_bone->set_axis_tm ( axis_tm );
// Optional mass of skinbody associated with this bone.
verify_token ( lexer );
if ( strcmp ( lexer.text (), "bodymass" ) == 0 )
{
lexer.advance ();
skip_token ( lexer ); // Ignore the bodymass.
match_newline ( lexer );
}
// Optional position of center of mass along the bone.
verify_token ( lexer );
if ( strcmp ( lexer.text (), "cofmass" ) == 0 )
{
lexer.advance ();
skip_token ( lexer ); // Ignore the center of mass position.
match_newline ( lexer );
}
// Optional degrees of freedom.
verify_token ( lexer );
if ( strcmp ( lexer.text (), "dof" ) == 0 )
{
lexer.advance ();
if ( lexer.type () == TOKEN && strcmp ( lexer.text (), "rx" ) == 0 )
{
new_bone->add_axis ( ROTATE_X );
lexer.advance ();
}
if ( lexer.type () == TOKEN && strcmp ( lexer.text (), "ry" ) == 0 )
{
new_bone->add_axis ( ROTATE_Y );
lexer.advance ();
}
if ( lexer.type () == TOKEN && strcmp ( lexer.text (), "rz" ) == 0 )
{
new_bone->add_axis ( ROTATE_Z );
lexer.advance ();
}
if ( lexer.type () == TOKEN && strcmp ( lexer.text (), "l" ) == 0 )
{
new_bone->add_axis ( TRANSLATE_LENGTH );
lexer.advance ();
}
match_newline ( lexer );
// Limits for the given degrees of freedom.
match_token ( lexer, "limits" );
// &&&
while ( strcmp ( lexer.text (), "end" ) != 0 )
lexer.advance ();
}
match_token ( lexer, "end" );
match_newline ( lexer );
// Add the bone to the list of bones.
add_bone_to_list ( new_bone );
new_bone->create_node ( Import_interface, Max_interface );
}
//----------------------------------------------------------------------------
// Skeleton_Class::skip_unrecognized_blocks
//----------------------------------------------------------------------------
// It is assumed that the current lexeme is the first on a line.
//----------------------------------------------------------------------------
void Skeleton_Class::skip_unrecognized_blocks
(
ASF_Lexer & lexer
)
{
while (1)
{
if ( lexer.type () == EOF_MARKER )
break;
if ( strcmp ( lexer.text (), ":units" ) == 0 )
break;
if ( strcmp ( lexer.text (), ":root" ) == 0 )
break;
if ( strcmp ( lexer.text (), ":bonedata" ) == 0 )
break;
if ( strcmp ( lexer.text (), ":hierarchy" ) == 0 )
break;
skip_to_next_line ( lexer );
}
}
//----------------------------------------------------------------------------
// Skeleton_Class::skip_to_next_line
//----------------------------------------------------------------------------
void Skeleton_Class::skip_to_next_line
(
ASF_Lexer & lexer
)
{
while ( lexer.type () != NEWLINE &&
lexer.type () != EOF_MARKER )
lexer.advance ();
if ( lexer.type () == NEWLINE )
lexer.advance ();
}
//----------------------------------------------------------------------------
// Skeleton_Class::match_newline
//----------------------------------------------------------------------------
void Skeleton_Class::match_newline
(
ASF_Lexer & lexer
)
{
char message_buffer [ 512 ];
if ( lexer.type () != NEWLINE )
{
sprintf ( message_buffer, "Expected newline; found \"%s\" instead.",
lexer.text () );
throw Parse_Error ( message_buffer );
}
lexer.advance ();
}
//----------------------------------------------------------------------------
// Skeleton_Class::verify_token
//----------------------------------------------------------------------------
void Skeleton_Class::verify_token
(
ASF_Lexer & lexer
)
{
char message_buffer [ 512 ];
if ( lexer.type () != TOKEN )
{
sprintf ( message_buffer, "Expected token; found \"%s\" instead.",
lexer.text () );
throw Parse_Error ( message_buffer );
}
}
//----------------------------------------------------------------------------
// Skeleton_Class::skip_token
//----------------------------------------------------------------------------
void Skeleton_Class::skip_token
(
ASF_Lexer & lexer
)
{
verify_token ( lexer );
lexer.advance ();
}
//----------------------------------------------------------------------------
// Skeleton_Class::float_token
//----------------------------------------------------------------------------
float Skeleton_Class::float_token
(
ASF_Lexer & lexer
)
{
verify_token ( lexer );
float value = (float) strtod ( lexer.text (), NULL );
lexer.advance ();
return value;
}
//----------------------------------------------------------------------------
// Skeleton_Class::match_token
//----------------------------------------------------------------------------
void Skeleton_Class::match_token
(
ASF_Lexer & lexer,
const char * token_text
)
{
char message_buffer [ 512 ];
verify_token ( lexer );
if ( strcmp ( lexer.text (), token_text ) != 0 )
{
sprintf ( message_buffer, "Expected \"%s\"; found \"%s\" instead.",
token_text, lexer.text () );
throw Parse_Error ( message_buffer );
}
lexer.advance ();
}
//----------------------------------------------------------------------------
// Skeleton_Class::add_bone_to_list
//----------------------------------------------------------------------------
void Skeleton_Class::add_bone_to_list
(
Bone_Class * new_bone
)
{
new_bone->set_next_bone ( First_bone );
First_bone = new_bone;
}
//----------------------------------------------------------------------------
// Bone_Class::create_node
//----------------------------------------------------------------------------
void Bone_Class::create_node
(
ImpInterface * import_interface,
Interface * max_interface
)
{
Node = import_interface->CreateNode ();
Node->SetName ( Name );
// Create a box object.
GeomObject * obj = (GeomObject *) max_interface->CreateInstance
( GEOMOBJECT_CLASS_ID, Class_ID (BOXOBJ_CLASS_ID, 0) );
IParamArray *iBoxParams = obj->GetParamBlock();
assert(iBoxParams);
// Set the value of width, height and length.
int width_index = obj->GetParamBlockIndex(BOXOBJ_WIDTH);
assert(width_index >= 0);
iBoxParams->SetValue(width_index,TimeValue(0),Length / 4);
int height_index = obj->GetParamBlockIndex(BOXOBJ_HEIGHT);
assert(height_index >= 0);
iBoxParams->SetValue(height_index,TimeValue(0),Length);
int length_index = obj->GetParamBlockIndex(BOXOBJ_LENGTH);
assert(length_index >= 0);
iBoxParams->SetValue(length_index,TimeValue(0),Length / 4);
Node->Reference ( (Object *) obj );
Node->GetINode ()->SetNodeTM ( 0, Axis_tm );
// Add the node to the scene.
import_interface->AddNodeToScene ( Node );
// Add an AppData chunk to the inode to indicate which transformation
// axes are active.
ASF_Data_Chunk * data_p = (ASF_Data_Chunk *)
malloc ( sizeof (ASF_Data_Chunk) );
*data_p = Active_axes;
add_app_data ( 1, data_p, sizeof (ASF_Data_Chunk) );
}
//----------------------------------------------------------------------------
// Bone_Class::set_parent
//----------------------------------------------------------------------------
void Bone_Class::set_parent ( Bone_Class * parent_bone )
{
Parent_bone = parent_bone;
parent_bone->Node->GetINode ()->AttachChild ( Node->GetINode () );
// Build the child node's transform matrix.
Matrix3 parent_tm = Node->GetINode ()->GetParentTM ( 0 );
Matrix3 child_tm = Axis_tm;
child_tm.Translate ( Normalize (parent_bone->Direction) *
parent_bone->Length );
child_tm.Translate ( parent_tm.GetTrans () );
Node->GetINode ()->SetNodeTM ( 0, child_tm );
}
//----------------------------------------------------------------------------
// Bone_Class::add_app_data
//----------------------------------------------------------------------------
void Bone_Class::add_app_data ( int chunk_id, void * data, int data_size )
{
Node->GetINode ()->AddAppDataChunk
(
Class_ID(0x74975aa6, 0x1810323f),
SCENE_IMPORT_CLASS_ID,
chunk_id,
data_size,
data
);
}

View File

@@ -0,0 +1,61 @@
/*
** Command & Conquer Renegade(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/>.
*/
//----------------------------------------------------------------------------
// Axes
//----------------------------------------------------------------------------
enum Axis_Names
{
ROTATE_X,
ROTATE_Y,
ROTATE_Z,
TRANSLATE_X,
TRANSLATE_Y,
TRANSLATE_Z,
TRANSLATE_LENGTH
};
//----------------------------------------------------------------------------
// ASF_Data_Chunk
//----------------------------------------------------------------------------
struct ASF_Data_Chunk
{
ASF_Data_Chunk () : Number_of_axes (0) {}
void add_axis ( Axis_Names new_axis )
{
if ( Number_of_axes < 7 )
{
Axis [Number_of_axes] = new_axis;
++ Number_of_axes;
}
}
unsigned Number_of_axes;
Axis_Names Axis [ 7 ];
};
//----------------------------------------------------------------------------
// Position_Key_Scale_Chunk
//----------------------------------------------------------------------------
struct Position_Key_Scale_Chunk
{
float Position_Key_Scale;
};

View File

@@ -0,0 +1,45 @@
/*
** Command & Conquer Renegade(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/>.
*/
class Exception
{
public:
virtual const char * message () const
{
return "General exception.";
}
};
class Parse_Error : public Exception
{
public:
Parse_Error ( const char * message ) :
Message (message)
{}
virtual const char * message () const
{
return Message;
}
protected:
const char * Message;
};

View File

@@ -0,0 +1,194 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//----------------------------------------------------------------------------
// File_Class
//----------------------------------------------------------------------------
class File_Class
{
public:
FILE * fp;
File_Class ( const char * filename, const char * mode )
{
fp = fopen ( filename, mode );
}
~File_Class ()
{
if ( fp != NULL )
fclose ( fp );
fp = NULL;
}
};
//----------------------------------------------------------------------------
// ASF_Lexeme_Type
//----------------------------------------------------------------------------
enum ASF_Lexeme_Type
{
EOF_MARKER,
TOKEN,
NEWLINE
};
//----------------------------------------------------------------------------
// ASF_Lexer
//----------------------------------------------------------------------------
#define MAX_TOKEN_LENGTH 512
class ASF_Lexer
{
public:
ASF_Lexer ( const char * file_name );
ASF_Lexeme_Type type () const { return Current_type; }
const char * text () const { return Current_text; }
void advance ();
protected:
void skip_whitespace ();
File_Class Input_file;
int Current_char;
ASF_Lexeme_Type Current_type;
char Current_text [ MAX_TOKEN_LENGTH ];
};
//----------------------------------------------------------------------------
// Bone_Class
//----------------------------------------------------------------------------
class Bone_Class
{
public:
Bone_Class ():
Name (""),
Direction (Point3 (0,0,0)),
Parent_bone (NULL),
Next_bone (NULL),
Length (0.0f)
{
Axis_tm.IdentityMatrix ();
}
~Bone_Class () { delete [] Name; }
void set_name ( const char * name )
{
Name = new char [ strlen (name) + 1 ];
strcpy ( Name, name );
}
void set_next_bone ( Bone_Class * next_bone )
{
Next_bone = next_bone;
}
void set_length ( float length ) { Length = length; }
void set_direction ( Point3 direction ) { Direction = direction; }
void set_axis_tm ( const Matrix3 & axis_tm ) { Axis_tm = axis_tm; }
void add_axis ( Axis_Names axis ) { Active_axes.add_axis ( axis ); }
void set_parent ( Bone_Class * parent_bone );
const char * name () const { return Name; }
Bone_Class * next_bone () const { return Next_bone; }
void create_node
(
ImpInterface * import_interface,
Interface * max_interface
);
void add_app_data ( int chunk_id, void * data, int data_size );
private:
char * Name;
Point3 Direction;
Matrix3 Axis_tm;
Bone_Class * Parent_bone;
Bone_Class * Next_bone;
ImpNode * Node;
float Length;
ASF_Data_Chunk Active_axes;
};
//----------------------------------------------------------------------------
// Skeleton_Class
//----------------------------------------------------------------------------
#define DEGREES_TO_RADIANS 1.7453293e-2f
class Skeleton_Class
{
public:
Skeleton_Class
(
const char * file_name,
ImpInterface *,
Interface *
);
~Skeleton_Class ();
protected:
void add_bone_to_list ( Bone_Class * new_bone );
Bone_Class * find_bone ( const char * name );
void parse_units_block ( ASF_Lexer & );
void parse_root_block ( ASF_Lexer & );
void parse_bonedata_block ( ASF_Lexer & );
void parse_hierarchy_block ( ASF_Lexer & );
void parse_hierarchy_line ( ASF_Lexer & );
void parse_bone ( ASF_Lexer & );
void skip_unrecognized_blocks ( ASF_Lexer & );
void skip_to_next_line ( ASF_Lexer & );
void match_newline ( ASF_Lexer & );
void match_token ( ASF_Lexer &, const char * );
void skip_token ( ASF_Lexer & );
void verify_token ( ASF_Lexer & );
float float_token ( ASF_Lexer & );
float Angle_multiplier; // Converts angle to radians.
float Length_multiplier;
ImpInterface * Import_interface;
Interface * Max_interface;
Bone_Class * First_bone;
};

View File

@@ -0,0 +1,772 @@
/*
** Command & Conquer Renegade(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/>.
*/
#include "blender2.h"
#include <istdplug.h>
#include "utilapi.h"
#include "appdata.h"
//----------------------------------------------------------------------------
// Blender_Class
//----------------------------------------------------------------------------
class Blender_Class : public UtilityObj
{
public:
Blender_Class();
void BeginEditParams(Interface *ip,IUtil *iu);
void EndEditParams(Interface *ip,IUtil *iu);
void SelectionSetChanged ( Interface * ip, IUtil * ui );
void DeleteThis() {}
void Init(HWND hWnd);
void Destroy(HWND hWnd);
void Close () { iu->CloseUtility (); }
void Get_Active_Time_Range ();
void Blend_Keys ();
void Loop_Controllers ();
void OutputObject(INode *node,TCHAR *fname);
private:
BOOL Is_Root ( INode * node );
float Heading_Delta_From_Quat ( Quat q );
void Set_Data_Chunk ( INode * node, const Blender_Data_Chunk & new_data );
void Remove_Data_Chunk ( INode * node );
int first_frame;
int first_match;
int last_frame;
int last_match;
ISpinnerControl * first_frame_spin;
ISpinnerControl * first_match_spin;
ISpinnerControl * last_frame_spin;
ISpinnerControl * last_match_spin;
IUtil * iu;
Interface *ip;
HWND hPanel;
};
//----------------------------------------------------------------------------
// the_blender
//----------------------------------------------------------------------------
static Blender_Class the_blender;
//----------------------------------------------------------------------------
// Blender_Desc_Class
//----------------------------------------------------------------------------
class Blender_Desc_Class:public ClassDesc
{
public:
int IsPublic() {return 1;}
void * Create(BOOL) {return &the_blender;}
const TCHAR * ClassName() {return _T("Key Blender");}
SClass_ID SuperClassID() {return UTILITY_CLASS_ID;}
Class_ID ClassID() {return Blender_Class_ID;}
const TCHAR* Category() {return _T("Westwood Tools");}
};
//----------------------------------------------------------------------------
// blender_desc
//----------------------------------------------------------------------------
static Blender_Desc_Class blender_desc;
//----------------------------------------------------------------------------
// BlenderDesc
//----------------------------------------------------------------------------
ClassDesc* BlenderDesc() {return &blender_desc;}
//----------------------------------------------------------------------------
// BlenderDlgProc
//----------------------------------------------------------------------------
static BOOL CALLBACK BlenderDlgProc
(
HWND hWnd,
UINT msg,
WPARAM wParam,
LPARAM lParam
)
{
switch (msg)
{
case WM_INITDIALOG:
the_blender.Init(hWnd);
break;
case WM_DESTROY:
the_blender.Destroy(hWnd);
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case ID_CLOSE:
the_blender.Close ();
break;
case ID_GET_ACTIVE_TIME_RANGE:
the_blender.Get_Active_Time_Range ();
break;
case ID_APPLY:
the_blender.Blend_Keys ();
break;
}
break;
default:
return FALSE;
}
return TRUE;
}
//----------------------------------------------------------------------------
// Blender_Class::Blender_Class
//----------------------------------------------------------------------------
Blender_Class::Blender_Class()
{
iu = NULL;
ip = NULL;
hPanel = NULL;
first_frame = 0;
first_match = 0;
last_frame = 0;
last_match = 0;
}
//----------------------------------------------------------------------------
// Blender_Class::BeginEditParams
//----------------------------------------------------------------------------
void Blender_Class::BeginEditParams(Interface *ip,IUtil *iu)
{
this->iu = iu;
this->ip = ip;
hPanel = ip->AddRollupPage
(
hInstance,
MAKEINTRESOURCE(IDD_ASCIIOUT_PANEL),
BlenderDlgProc,
_T("Key Blender"),
0
);
}
//----------------------------------------------------------------------------
// Blender_Class::EndEditParams
//----------------------------------------------------------------------------
void Blender_Class::EndEditParams ( Interface *ip, IUtil *iu )
{
this->iu = NULL;
this->ip = NULL;
ip->DeleteRollupPage(hPanel);
hPanel = NULL;
}
//----------------------------------------------------------------------------
// Blender_Class::SelectionSetChanged
//----------------------------------------------------------------------------
void Blender_Class::SelectionSetChanged ( Interface * ip, IUtil * iu )
{
if ( ip->GetSelNodeCount () == 0 )
{
EnableWindow ( GetDlgItem ( hPanel, ID_APPLY ), FALSE );
}
else
{
EnableWindow ( GetDlgItem ( hPanel, ID_APPLY ), TRUE );
}
}
//----------------------------------------------------------------------------
// Blender_Class::Init
//----------------------------------------------------------------------------
void Blender_Class::Init ( HWND hWnd )
{
if ( ip->GetSelNodeCount () == 0 )
{
EnableWindow ( GetDlgItem ( hWnd, ID_APPLY ), FALSE );
}
else
{
EnableWindow ( GetDlgItem ( hWnd, ID_APPLY ), TRUE );
}
int ticks_per_frame = GetTicksPerFrame ();
int start_frame = ip->GetAnimRange ().Start () / ticks_per_frame;
int end_frame = ip->GetAnimRange ().End () / ticks_per_frame;
first_frame = start_frame;
first_match = start_frame;
last_frame = end_frame;
last_match = start_frame;
first_frame_spin = SetupIntSpinner
(
hWnd,
IDC_FIRST_SPIN,
IDC_FIRST_EDIT,
-65536,
65535,
first_frame
);
first_frame_spin->SetResetValue ( first_frame );
first_match_spin = SetupIntSpinner
(
hWnd,
IDC_FIRST_MATCH_SPIN,
IDC_FIRST_MATCH_EDIT,
-65536,
65535,
first_match
);
first_match_spin->SetResetValue ( first_match );
last_frame_spin = SetupIntSpinner
(
hWnd,
IDC_LAST_SPIN,
IDC_LAST_EDIT,
-65536,
65535,
last_frame
);
last_frame_spin->SetResetValue ( last_frame );
last_match_spin = SetupIntSpinner
(
hWnd,
IDC_LAST_MATCH_SPIN,
IDC_LAST_MATCH_EDIT,
-65536,
65535,
last_match
);
last_match_spin->SetResetValue ( last_match );
}
//----------------------------------------------------------------------------
// Blender_Class::Destroy
//----------------------------------------------------------------------------
void Blender_Class::Destroy(HWND hWnd)
{
}
//----------------------------------------------------------------------------
// Blender_Class::Get_Active_Time_Range
//----------------------------------------------------------------------------
void Blender_Class::Get_Active_Time_Range ()
{
int ticks_per_frame = GetTicksPerFrame ();
int start_frame = ip->GetAnimRange ().Start () / ticks_per_frame;
int end_frame = ip->GetAnimRange ().End () / ticks_per_frame;
first_frame_spin->SetValue ( start_frame, FALSE );
last_frame_spin->SetValue ( end_frame, FALSE );
first_match_spin->SetValue ( start_frame, FALSE );
last_match_spin->SetValue ( start_frame, FALSE );
}
//----------------------------------------------------------------------------
// Blender_Class::Blend_Keys
//----------------------------------------------------------------------------
static const Quat zero (0.0,0.0,0.0,1.0);
void Blender_Class::Blend_Keys ()
{
Interval interval; // Used for returned validity intervals (which are not used).
int ticks_per_frame = GetTicksPerFrame ();
TimeValue start_time = first_frame_spin->GetIVal () * ticks_per_frame;
TimeValue end_time = last_frame_spin->GetIVal () * ticks_per_frame;
TimeValue start_match = first_match_spin->GetIVal () * ticks_per_frame;
TimeValue end_match = last_match_spin->GetIVal () * ticks_per_frame;
float t_scale = 1.0f / (float) (end_time - start_time);
BOOL bad_controller_found = FALSE;
theHold.Begin ();
SetCursor ( LoadCursor (NULL, IDC_WAIT) );
SuspendAnimate ();
AnimateOn ();
int number_of_nodes = ip->GetSelNodeCount ();
for ( int i = 0; i < number_of_nodes; ++ i )
{
// Get the inode.
INode * inode = ip->GetSelNode ( i );
Control * tm_controller = inode->GetTMController ();
if ( tm_controller == NULL )
continue;
Quat rot_start_delta = zero;
Quat rot_end_delta = zero;
Blender_Data_Chunk data;
data.position_delta = Point3 (0.0f, 0.0f, 0.0f);
data.heading_delta = 0.0f;
Control * c;
//--------------------------------------------------------------------
// Get the rotation controller and change its keys.
c = tm_controller->GetRotationController ();
if ( c != NULL )
{
if ( c->ClassID () != Class_ID (TCBINTERP_ROTATION_CLASS_ID, 0) )
{
#if 0
char m [ 256 ];
sprintf ( m, "Node %s has rotation controller ID %u.",
inode->GetName (), c->ClassID ().PartA () );
MessageBox ( GetActiveWindow (), m, "Debug", MB_OK );
#endif
bad_controller_found = TRUE;
}
else
{
Quat actual_start_orientation;
Quat desired_start_orientation;
Quat actual_end_orientation;
Quat desired_end_orientation;
c->GetValue ( start_time, & actual_start_orientation, interval );
c->GetValue ( start_match, & desired_start_orientation, interval );
c->GetValue ( end_time, & actual_end_orientation, interval );
c->GetValue ( end_match, & desired_end_orientation, interval );
// Ensure there are keys at the beginning and end of the blend interval.
c->SetValue ( start_time, & actual_start_orientation );
c->SetValue ( end_time, & actual_end_orientation );
actual_end_orientation.MakeClosest ( actual_start_orientation );
desired_start_orientation.MakeClosest ( actual_start_orientation );
desired_end_orientation.MakeClosest ( actual_end_orientation );
rot_start_delta = desired_start_orientation / actual_start_orientation;
rot_end_delta = desired_end_orientation / actual_end_orientation;
data.heading_delta = Heading_Delta_From_Quat
( actual_end_orientation / actual_start_orientation );
#if 1
int number_of_keys = c->NumKeys ();
for ( int j = 0; j < number_of_keys; ++ j )
{
TimeValue key_time = c->GetKeyTime ( j );
if ( key_time >= start_time && key_time <= end_time )
{
Quat orientation;
c->GetValue ( key_time, & orientation, interval );
float t = (float) (key_time - start_time) * t_scale;
Quat delta = Slerp ( rot_start_delta, zero, t ) *
Slerp ( zero, rot_end_delta, t );
orientation = orientation * delta;
c->SetValue ( key_time, & orientation );
}
}
#else
IKeyControl * keys = GetKeyControlInterface ( c );
if ( keys != NULL )
{
int number_of_keys = keys->GetNumKeys ();
Quat prev_key_absolute (0.0,0.0,0.0,1.0);
Quat new_prev_key_absolute (0.0,0.0,0.0,1.0);
for ( int j = 0; j < number_of_keys; ++ j )
{
ITCBRotKey key;
keys->GetKey ( j, & key );
Quat this_key_absolute = prev_key_absolute * (Quat) key.val;
Quat new_key_absolute = this_key_absolute;
if ( key.time >= start_time && key.time <= end_time )
{
float t = (float) (key.time - start_time) * t_scale;
Quat delta = Slerp ( rot_start_delta, zero, t ) *
Slerp ( zero, rot_end_delta, t );
new_key_absolute = this_key_absolute * delta;
key.val = new_key_absolute / new_prev_key_absolute;
keys->SetKey ( j, & key );
}
prev_key_absolute = this_key_absolute;
new_prev_key_absolute = new_key_absolute;
}
}
#endif
}
}
//--------------------------------------------------------------------
// Get the position controller and change its keys.
c = tm_controller->GetPositionController ();
if ( c != NULL )
{
if ( c->ClassID () != Class_ID (TCBINTERP_POSITION_CLASS_ID, 0) )
{
bad_controller_found = TRUE;
}
else
{
Point3 actual_start_position;
Point3 desired_start_position;
Point3 actual_end_position;
Point3 desired_end_position;
c->GetValue ( start_time, & actual_start_position, interval );
c->GetValue ( start_match, & desired_start_position, interval );
c->GetValue ( end_time, & actual_end_position, interval );
c->GetValue ( end_match, & desired_end_position, interval );
// Ensure there are keys at the beginning and end of the blend interval.
c->SetValue ( start_time, & actual_start_position );
c->SetValue ( end_time, & actual_end_position );
data.position_delta = actual_end_position - actual_start_position;
#if 1
int number_of_keys = c->NumKeys ();
for ( int j = 0; j < number_of_keys; ++ j )
{
TimeValue key_time = c->GetKeyTime ( j );
if ( key_time >= start_time && key_time <= end_time )
{
Point3 position;
c->GetValue ( key_time, & position, interval );
float t = (float) (key_time - start_time) * t_scale;
// Calculate the position the node would be in if it
// traveled in a straight line.
Point3 actual_position = actual_start_position * (1.0f - t) +
actual_end_position * t;
// Find the delta between the straight-line position and
// the real position.
Point3 delta = position - actual_position;
// Rotate the delta by the change in orientation
// at this time.
Quat rot_delta = Slerp ( rot_start_delta, zero, t ) *
Slerp ( zero, rot_end_delta, t );
Matrix3 rot_matrix;
rot_delta.MakeMatrix ( rot_matrix );
delta = delta * rot_matrix;
// Add the delta to the straight-line position on the
// desired line.
Point3 desired_position = desired_start_position * (1.0f - t) +
desired_end_position * t;
position = desired_position + delta;
// Store the new key value.
c->SetValue ( key_time, & position );
}
}
#else
IKeyControl * keys = GetKeyControlInterface ( c );
if ( keys != NULL )
{
int number_of_keys = keys->GetNumKeys ();
for ( int j = 0; j < number_of_keys; ++ j )
{
ITCBPoint3Key key;
keys->GetKey ( j, & key );
if ( key.time >= start_time && key.time <= end_time )
{
float t = (float) (key.time - start_time) * t_scale;
// Calculate the position the node would be in if it
// traveled in a straight line.
Point3 actual_position = actual_start_position * (1.0f - t) +
actual_end_position * t;
// Find the delta between the straight-line position and
// the real position.
Point3 delta = key.val - actual_position;
// Rotate the delta by the change in orientation
// at this time.
Quat rot_delta = Slerp ( rot_start_delta, zero, t ) *
Slerp ( zero, rot_end_delta, t );
Matrix3 rot_matrix;
rot_delta.MakeMatrix ( rot_matrix );
delta = delta * rot_matrix;
// Add the delta to the straight-line position on the
// desired line.
Point3 desired_position = desired_start_position * (1.0f - t) +
desired_end_position * t;
key.val = desired_position + delta;
// Store the new key value.
keys->SetKey ( j, & key );
}
}
}
#endif
}
}
// If this node is a root node (its parent is not selected), attach
// a data chunk that describes its motion during the blended section.
if ( Is_Root ( inode ) )
Set_Data_Chunk ( inode, data );
else
Remove_Data_Chunk ( inode );
inode->InvalidateTM ();
}
ResumeAnimate ();
TSTR undostr;
undostr.printf ( "Blend Keys" );
theHold.Accept ( undostr );
SetCursor ( LoadCursor (NULL, IDC_ARROW) );
ip->RedrawViews ( ip->GetTime () );
if ( bad_controller_found )
{
MessageBox ( GetActiveWindow (),
"Warning: Some controllers were not blended\n"
"because they were not TCB controllers.", "Warning", MB_OK );
}
}
//----------------------------------------------------------------------------
// Blender_Class::Is_Root
//----------------------------------------------------------------------------
BOOL Blender_Class::Is_Root ( INode * node )
{
node = node->GetParentNode ();
int number_of_nodes = ip->GetSelNodeCount ();
for ( int i = 0; i < number_of_nodes; ++ i )
{
if ( ip->GetSelNode ( i ) == node )
return FALSE;
}
return TRUE;
}
//----------------------------------------------------------------------------
// Blender_Class::Heading_Delta_From_Quat
//----------------------------------------------------------------------------
float Blender_Class::Heading_Delta_From_Quat ( Quat q )
{
Matrix3 rot_matrix;
q.MakeMatrix ( rot_matrix );
Point3 row = rot_matrix.GetRow ( 0 );
return (float) atan2 ( row.y, row.x );
}
//----------------------------------------------------------------------------
// Blender_Class::Set_Data_Chunk
//----------------------------------------------------------------------------
void Blender_Class::Set_Data_Chunk
(
INode * node,
const Blender_Data_Chunk & new_data
)
{
AppDataChunk * chunk = node->GetAppDataChunk
(
Blender_Class_ID,
UTILITY_CLASS_ID,
1
);
Blender_Data_Chunk * data;
if ( chunk != NULL )
{
data = (Blender_Data_Chunk *) chunk->data;
}
else
{
data = (Blender_Data_Chunk *) malloc ( sizeof (Blender_Data_Chunk) );
node->AddAppDataChunk
(
Blender_Class_ID,
UTILITY_CLASS_ID,
1,
sizeof (Blender_Data_Chunk),
data
);
}
*data = new_data;
#if 0
char m [ 256 ];
sprintf ( m, "Setting data chunk for %s:\n"
"Position delta = (%.1f, %.1f, %.1f)\n"
"Heading delta = %.1f",
node->GetName (),
data->position_delta.x,
data->position_delta.y,
data->position_delta.z,
data->heading_delta * 180 / PI );
MessageBox ( GetActiveWindow (), m, "Debug", MB_OK );
#endif
}
//----------------------------------------------------------------------------
// Blender_Class::Remove_Data_Chunk
//----------------------------------------------------------------------------
void Blender_Class::Remove_Data_Chunk ( INode * node )
{
node->RemoveAppDataChunk
(
Blender_Class_ID,
UTILITY_CLASS_ID,
1
);
}
//----------------------------------------------------------------------------
// Blender_Class::Loop_Controllers
//----------------------------------------------------------------------------
void Blender_Class::Loop_Controllers ()
{
int number_of_nodes = ip->GetSelNodeCount ();
for ( int i = 0; i < number_of_nodes; ++ i )
{
// Get the inode.
INode * inode = ip->GetSelNode ( i );
Control * tm_controller = inode->GetTMController ();
if ( tm_controller == NULL )
continue;
Control * c;
c = tm_controller->GetRotationController ();
if ( c )
{
c->SetORT ( ORT_LOOP, ORT_BEFORE );
c->SetORT ( ORT_LOOP, ORT_AFTER );
}
c = tm_controller->GetPositionController ();
if ( c )
{
c->SetORT ( ORT_LOOP, ORT_BEFORE );
c->SetORT ( ORT_LOOP, ORT_AFTER );
}
c = tm_controller->GetScaleController ();
if ( c )
{
c->SetORT ( ORT_LOOP, ORT_BEFORE );
c->SetORT ( ORT_LOOP, ORT_AFTER );
}
}
}

View File

@@ -0,0 +1,8 @@
LIBRARY blender
EXPORTS
LibDescription @1
LibNumberClasses @2
LibClassDesc @3
LibVersion @4
SECTIONS
.data READ WRITE

View File

@@ -0,0 +1,128 @@
# Microsoft Developer Studio Project File - Name="Blender2" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=Blender2 - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "Blender2.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "Blender2.mak" CFG="Blender2 - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Blender2 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "Blender2 - Win32 Hybrid" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/Commando/Code/Tools/Blender2", GIDCAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "Blender2 - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\Release"
# PROP BASE Intermediate_Dir ".\Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ".\Release"
# PROP Intermediate_Dir ".\Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "d:\3dsmax2\maxsdk\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comctl32.lib core.lib geom.lib maxutil.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release\blender.dlu" /libpath:"d:\3dsmax2\maxsdk\lib"
!ELSEIF "$(CFG)" == "Blender2 - Win32 Hybrid"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Hybrid"
# PROP BASE Intermediate_Dir "Hybrid"
# PROP BASE Ignore_Export_Lib 0
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Hybrid"
# PROP Intermediate_Dir "Hybrid"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "d:\3dsmax2\maxsdk\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "d:\3dsmax2\maxsdk\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib core.lib geom.lib util.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release\blender.dlu" /libpath:"d:\3dsmax2\maxsdk\lib"
# ADD LINK32 odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comctl32.lib core.lib geom.lib maxutil.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"Hybrid\blender.dlu" /libpath:"d:\3dsmax2\maxsdk\lib"
!ENDIF
# Begin Target
# Name "Blender2 - Win32 Release"
# Name "Blender2 - Win32 Hybrid"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
# Begin Source File
SOURCE=.\Blender2.cpp
# End Source File
# Begin Source File
SOURCE=.\Blender2.def
# End Source File
# Begin Source File
SOURCE=.\Blender2.rc
# End Source File
# Begin Source File
SOURCE=.\DLLMain.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# Begin Source File
SOURCE=.\appdata.h
# End Source File
# Begin Source File
SOURCE=.\Blender2.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@@ -0,0 +1,29 @@
/*
** Command & Conquer Renegade(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 _BLENDER_H
#define _BLENDER_H
#include "Max.h"
#include "resource.h"
extern ClassDesc* BlenderDesc ();
extern HINSTANCE hInstance;
#endif

View File

@@ -0,0 +1,99 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#define APSTUDIO_HIDDEN_SYMBOLS
#include "windows.h"
#undef APSTUDIO_HIDDEN_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
"#include ""windows.h""\r\n"
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
"\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_BLENDER_PANEL DIALOG DISCARDABLE 0, 0, 108, 110
STYLE WS_CHILD | WS_VISIBLE
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "First Frame:",IDC_STATIC,6,4,40,10
CONTROL "",IDC_FIRST_EDIT,"CustEdit",WS_TABSTOP,63,4,28,10
CONTROL "",IDC_FIRST_SPIN,"SpinnerControl",0x0,91,4,10,10
LTEXT "Match:",IDC_STATIC,6,16,53,10
CONTROL "",IDC_FIRST_MATCH_EDIT,"CustEdit",WS_TABSTOP,63,16,28,
10
CONTROL "",IDC_FIRST_MATCH_SPIN,"SpinnerControl",0x0,91,16,10,10
LTEXT "Last Frame:",IDC_STATIC,6,33,40,10
CONTROL "",IDC_LAST_EDIT,"CustEdit",WS_TABSTOP,63,33,28,10
CONTROL "",IDC_LAST_SPIN,"SpinnerControl",0x0,91,33,10,10
LTEXT "Match:",IDC_STATIC,6,45,53,10
CONTROL "",IDC_LAST_MATCH_EDIT,"CustEdit",WS_TABSTOP,63,45,28,10
CONTROL "",IDC_LAST_MATCH_SPIN,"SpinnerControl",0x0,91,45,10,10
PUSHBUTTON "Blend",ID_APPLY,6,61,95,13
PUSHBUTTON "Get Active Time Range",ID_GET_ACTIVE_TIME_RANGE,6,77,95,
13
LTEXT "James McNeill",IDC_STATIC,5,95,47,11
PUSHBUTTON "Close",ID_CLOSE,55,93,46,13
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@@ -0,0 +1,85 @@
/*
** Command & Conquer Renegade(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/>.
*/
#include "blender2.h"
HINSTANCE hInstance;
static BOOL controlsInit = FALSE;
#define DLLEXPORT __declspec(dllexport)
//----------------------------------------------------------------------------
// DllMain
//----------------------------------------------------------------------------
BOOL WINAPI DllMain
(
HINSTANCE hinstDLL,
ULONG,
LPVOID
)
{
hInstance = hinstDLL;
if ( ! controlsInit )
{
controlsInit = TRUE;
InitCustomControls(hInstance); // jaguar controls
InitCommonControls(); // initialize Chicago controls
}
return TRUE;
}
//----------------------------------------------------------------------------
// LibDescription
//----------------------------------------------------------------------------
DLLEXPORT const TCHAR * LibDescription()
{
return _T("Animation Key Blender Utility");
}
//----------------------------------------------------------------------------
// LibNumberClasses
//----------------------------------------------------------------------------
DLLEXPORT int LibNumberClasses()
{
return 1;
}
//----------------------------------------------------------------------------
// LibClassDesc
//----------------------------------------------------------------------------
DLLEXPORT ClassDesc * LibClassDesc(int i)
{
return BlenderDesc ();
}
//----------------------------------------------------------------------------
// LibVersion
//----------------------------------------------------------------------------
DLLEXPORT ULONG LibVersion()
{
return VERSION_3DSMAX;
}

View File

@@ -0,0 +1,25 @@
/*
** Command & Conquer Renegade(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/>.
*/
const Class_ID Blender_Class_ID (0x15850983, 0x15c65c7b);
struct Blender_Data_Chunk
{
Point3 position_delta;
float heading_delta;
};

View File

@@ -0,0 +1,89 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by Blender2.rc
//
#define ID_APPLY 2
#define ID_LOOP 3
#define ID_GET_ACTIVE_TIME_RANGE 3
#define IDD_COLORCLIP_PANEL 101
#define IDD_COLORCLIP_FLOATER 102
#define IDD_ASCIIOUT_PANEL 103
#define IDD_BLENDER_PANEL 103
#define IDD_UTILTEST_PANEL 104
#define IDD_APPDATA_PANEL 105
#define IDC_COLORCLIP_NEWFLOAT 1000
#define IDC_ASCIIOUT_PICK 1002
#define IDC_TESTER_MAKEOBJECT 1003
#define IDC_TESTER_MAKEGROUP 1004
#define IDC_APPDATA_EDIT 1004
#define IDC_TESTER_GROUPOBJS 1005
#define IDC_APPDATA_GET 1005
#define IDC_TESTER_OPENGROUP 1006
#define IDC_APPDATA_PUT 1006
#define IDC_TESTER_CLOSEGROUP 1007
#define IDC_TESTER_EXPLODEGROUP 1008
#define IDC_TESTER_UNGROUP 1009
#define IDC_TESTER_SAVETOFILE 1010
#define IDC_TESTER_LOADFROMFILE 1011
#define IDC_TESTER_SETENV 1012
#define IDC_TESTER_SETWAV 1013
#define IDS_TESTER_ANIMON 1014
#define IDS_TESTER_ANIMOFF 1015
#define ID_CLOSE 1015
#define IDS_TESTER_RENDER 1016
#define IDC_POSITION_CHECK 1016
#define IDC_ROTATION_CHECK 1017
#define IDC_KEY_EDIT 1026
#define IDC_MATCH_EDIT 1027
#define IDC_POS_LOW_EDIT 1028
#define IDC_FIRST_EDIT 1028
#define IDC_POS_HIGH_EDIT 1029
#define IDC_ROT_LOW_EDIT 1030
#define IDC_FIRST_MATCH_EDIT 1030
#define IDC_ROT_HIGH_EDIT 1031
#define IDC_LAST_EDIT 1031
#define IDC_LAST_MATCH_EDIT 1032
#define IDC_COLOR_SWATCH1 1039
#define IDC_COLOR_SWATCH2 1040
#define IDC_COLOR_SWATCH3 1041
#define IDC_COLOR_SWATCH4 1042
#define IDC_COLOR_SWATCH5 1043
#define IDC_COLOR_SWATCH6 1044
#define IDC_COLOR_SWATCH7 1045
#define IDC_COLOR_SWATCH8 1046
#define IDC_KEY_SPIN 1046
#define IDC_COLOR_SWATCH9 1047
#define IDC_MATCH_SPIN 1047
#define IDC_COLOR_SWATCH10 1048
#define IDC_POS_LOW_SPIN 1048
#define IDC_FIRST_SPIN 1048
#define IDC_COLOR_SWATCH11 1049
#define IDC_POS_HIGH_SPIN 1049
#define IDC_COLOR_SWATCH12 1050
#define IDC_ROT_LOW_SPIN 1050
#define IDC_FIRST_MATCH_SPIN 1050
#define IDC_ROT_HIGH_SPIN 1051
#define IDC_LAST_SPIN 1051
#define IDC_LAST_MATCH_SPIN 1052
#define IDC_APPDATA_SLOTSPIN 1202
#define IDC_APPDATA_SLOT 1203
#define IDC_APPDATA_SLOTLABEL 1204
#define IDS_RB_ASCIIOBJECTOUT 30619
#define IDS_RB_ASCIIFILES 30620
#define IDS_RB_SAVEOBJECT 30621
#define IDS_RB_COLORCLIPBOARD 30622
#define IDS_RB_COLORNUM 30623
#define IDS_RB_APPDATATEST 30624
#define IDS_RB_FILEEXISTS 30625
#define IDC_STATIC -1
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 103
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1018
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@@ -0,0 +1,279 @@
/*
** Command & Conquer Renegade(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 : ChunkView *
* *
* $Archive:: /Commando/Code/Tools/ChunkView/ChunkDataView.cpp $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 9/28/99 9:48a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// ChunkDataView.cpp : implementation file
//
#include "stdafx.h"
#include "ChunkView.h"
#include "ChunkDataView.h"
#include "ChunkViewDoc.h"
#include "ChunkFileImage.h"
#include "HexToString.h"
#include <assert.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CChunkDataView
IMPLEMENT_DYNCREATE(CChunkDataView, CListView)
CChunkDataView::CChunkDataView() :
WordSize(WORD_SIZE_BYTE),
DisplayMode(DISPLAY_MODE_HEX)
{
}
CChunkDataView::~CChunkDataView()
{
}
BEGIN_MESSAGE_MAP(CChunkDataView, CListView)
//{{AFX_MSG_MAP(CChunkDataView)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CChunkDataView drawing
void CChunkDataView::OnDraw(CDC* pDC)
{
CDocument* pDoc = GetDocument();
// TODO: add draw code here
}
/////////////////////////////////////////////////////////////////////////////
// CChunkDataView diagnostics
#ifdef _DEBUG
void CChunkDataView::AssertValid() const
{
CListView::AssertValid();
}
void CChunkDataView::Dump(CDumpContext& dc) const
{
CListView::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CChunkDataView message handlers
void CChunkDataView::OnInitialUpdate()
{
CListView::OnInitialUpdate();
CListCtrl &list = GetListCtrl();
long flags = list.GetStyle();
flags |= LVS_REPORT;
SetWindowLong(list.GetSafeHwnd(), GWL_STYLE, flags);
//list.SetFont ();
::SendMessage (list, WM_SETFONT, (WPARAM)GetStockObject (ANSI_FIXED_FONT), 0L);
}
void CChunkDataView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
if (this == pSender) return;
// Get the document and currently selected chunk
CListCtrl &list = GetListCtrl();
CChunkViewDoc * doc= (CChunkViewDoc *)GetDocument();
const ChunkImageClass * chunk = doc->Get_Cur_Chunk();
// Reset the list
list.DeleteAllItems();
// Rebuild the list view
if (chunk != NULL) {
Display_Chunk(chunk);
}
}
void CChunkDataView::Display_Chunk(const ChunkImageClass * chunk)
{
CListCtrl &list = GetListCtrl();
CChunkViewDoc * doc= (CChunkViewDoc *)GetDocument();
if (chunk->Get_Data() == NULL) {
Display_Chunk_Sub_Chunks(chunk);
} else {
switch (DisplayMode) {
case DISPLAY_MODE_HEX:
Display_Chunk_Hex(chunk);
break;
case DISPLAY_MODE_MICROCHUNKS:
Display_Chunk_Micro_Chunks(chunk);
break;
};
}
}
void CChunkDataView::Display_Chunk_Sub_Chunks(const ChunkImageClass * chunk)
{
char _buf[256];
Reset_Columns();
CListCtrl &list = GetListCtrl();
static LV_COLUMN IDColumn = { LVCF_TEXT | LVCF_WIDTH | LVCF_FMT, LVCFMT_LEFT, 160, "Chunk ID", 0,0 };
static LV_COLUMN LengthColumn = { LVCF_TEXT | LVCF_WIDTH | LVCF_FMT, LVCFMT_LEFT, 160, "Chunk Length", 0,0 };
list.InsertColumn(0, &IDColumn);
list.InsertColumn(1, &LengthColumn);
for (int i=0; i<chunk->Get_Child_Count(); i++) {
const ChunkImageClass * child = chunk->Get_Child(i);
sprintf(_buf,"0x%08X",child->Get_ID());
int list_item = list.InsertItem(i, _buf);
sprintf(_buf,"0x%08X",child->Get_Length());
list.SetItemText(list_item, 1, _buf);
}
}
void CChunkDataView::Display_Chunk_Hex(const ChunkImageClass * chunk)
{
Reset_Columns();
CListCtrl &list = GetListCtrl();
static LV_COLUMN HexColumn = { LVCF_TEXT | LVCF_WIDTH | LVCF_FMT, LVCFMT_LEFT, 750, "Hex Dump", 0,0 };
list.InsertColumn(0, &HexColumn);
HexToStringClass * hexconverter = Create_Hex_Converter(chunk->Get_Data(),chunk->Get_Length());
assert(hexconverter != NULL);
int rowcounter = 0;
while (!hexconverter->Is_Done()) {
list.InsertItem(rowcounter++,hexconverter->Get_Next_Line());
}
Destroy_Hex_Converter(hexconverter);
}
void CChunkDataView::Display_Chunk_Micro_Chunks(const ChunkImageClass * chunk)
{
Reset_Columns();
CListCtrl &list = GetListCtrl();
static LV_COLUMN IDColumn = { LVCF_TEXT | LVCF_WIDTH | LVCF_FMT, LVCFMT_LEFT, 48, "ID", 0,0 };
static LV_COLUMN LengthColumn = { LVCF_TEXT | LVCF_WIDTH | LVCF_FMT, LVCFMT_LEFT, 48, "Size", 0,0 };
static LV_COLUMN DataColumn = { LVCF_TEXT | LVCF_WIDTH | LVCF_FMT, LVCFMT_LEFT, 750, "Micro Chunk Data", 0,0 };
list.InsertColumn(0, &IDColumn);
list.InsertColumn(1, &LengthColumn);
list.InsertColumn(2, &DataColumn);
int rowcounter = 0;
const uint8 * workptr = chunk->Get_Data();
static char _buf[256];
while (workptr < chunk->Get_Data() + chunk->Get_Length()) {
uint8 micro_id = *workptr++;
uint8 micro_size = *workptr++;
// Add a line for the id
CString tmp_string;
tmp_string.Format("%02x",micro_id);
int list_item = list.InsertItem(rowcounter++, tmp_string);
// Set the size (second column)
tmp_string.Format("%02x",micro_size);
list.SetItemText(list_item, 1, tmp_string);
// Set the first line of hex data
HexToStringClass * hexconverter = Create_Hex_Converter(workptr,micro_size);
tmp_string = hexconverter->Get_Next_Line();
list.SetItemText(list_item, 2, tmp_string);
while (!hexconverter->Is_Done()) {
tmp_string = hexconverter->Get_Next_Line();
list_item = list.InsertItem(rowcounter++, "");
list.SetItemText(list_item, 2, tmp_string);
}
workptr += micro_size;
Destroy_Hex_Converter(hexconverter);
}
}
void CChunkDataView::Reset_Columns(void)
{
CListCtrl &list = GetListCtrl();
BOOL hascolumns = TRUE;
while (hascolumns) {
hascolumns = list.DeleteColumn(0);
}
}
HexToStringClass * CChunkDataView::Create_Hex_Converter(const uint8 * data,const uint32 size)
{
HexToStringClass * hexconv = NULL;
switch(WordSize) {
case WORD_SIZE_LONG:
hexconv = new HexToStringLongClass(data,size);
break;
case WORD_SIZE_SHORT:
hexconv = new HexToStringShortClass(data,size);
break;
default:
hexconv = new HexToStringByteClass(data,size);
break;
}
return hexconv;
}
void CChunkDataView::Destroy_Hex_Converter(HexToStringClass * hexconv)
{
assert(hexconv != NULL);
delete hexconv;
}

View File

@@ -0,0 +1,128 @@
/*
** Command & Conquer Renegade(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 : ChunkView *
* *
* $Archive:: /Commando/Code/Tools/ChunkView/ChunkDataView.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 9/28/99 9:48a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if !defined(AFX_CHUNKDATAVIEW_H__FD83E2D7_72AE_11D3_BB4D_00902742EA14__INCLUDED_)
#define AFX_CHUNKDATAVIEW_H__FD83E2D7_72AE_11D3_BB4D_00902742EA14__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// ChunkDataView.h : header file
//
#include "bittype.h"
class ChunkImageClass;
class HexToStringClass;
/////////////////////////////////////////////////////////////////////////////
// CChunkDataView view
class CChunkDataView : public CListView
{
protected:
CChunkDataView(); // protected constructor used by dynamic creation
DECLARE_DYNCREATE(CChunkDataView)
// Attributes
public:
enum WordSizeType
{
WORD_SIZE_BYTE = 0,
WORD_SIZE_SHORT = 1,
WORD_SIZE_LONG = 2
};
enum DisplayModeType
{
DISPLAY_MODE_HEX = 0,
DISPLAY_MODE_MICROCHUNKS,
};
void Set_Word_Size(WordSizeType wordsize) { WordSize = wordsize; OnUpdate(NULL,0,NULL); }
WordSizeType Get_Word_Size(void) { return WordSize; }
void Set_Display_Mode(DisplayModeType displaymode) { DisplayMode = displaymode; OnUpdate(NULL,0,NULL); }
DisplayModeType Get_Display_Mode(void) { return DisplayMode; }
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CChunkDataView)
public:
virtual void OnInitialUpdate();
protected:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint);
//}}AFX_VIRTUAL
// Implementation
protected:
virtual ~CChunkDataView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
void Display_Chunk(const ChunkImageClass * chunk);
void Display_Chunk_Sub_Chunks(const ChunkImageClass * chunk);
void Display_Chunk_Hex(const ChunkImageClass * chunk);
void Display_Chunk_Micro_Chunks(const ChunkImageClass * chunk);
void Reset_Columns(void);
HexToStringClass * Create_Hex_Converter(const uint8 * data,const uint32 size);
void Destroy_Hex_Converter(HexToStringClass * hexconv);
DisplayModeType DisplayMode;
WordSizeType WordSize;
// Generated message map functions
protected:
//{{AFX_MSG(CChunkDataView)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_CHUNKDATAVIEW_H__FD83E2D7_72AE_11D3_BB4D_00902742EA14__INCLUDED_)

View File

@@ -0,0 +1,223 @@
/*
** Command & Conquer Renegade(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 : ChunkView *
* *
* $Archive:: /Commando/Code/Tools/ChunkView/ChunkFileImage.cpp $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 9/28/99 9:48a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "stdafx.h"
#include <assert.h>
#include "ChunkFileImage.h"
#include "rawfile.h"
#include "chunkio.h"
ChunkFileImageClass::ChunkFileImageClass(void) :
RootNode(NULL)
{
}
ChunkFileImageClass::~ChunkFileImageClass(void)
{
Reset();
}
void ChunkFileImageClass::Reset(void)
{
// have to handle the fact that there isn't one root node,
ChunkImageClass * node_to_delete = RootNode;
while (node_to_delete) {
ChunkImageClass * sibling = node_to_delete->Sibling;
delete node_to_delete;
node_to_delete = sibling;
}
}
void ChunkFileImageClass::Load(const char * filename)
{
RawFileClass file(filename);
file.Open();
ChunkLoadClass cload(&file);
cload.Open_Chunk();
RootNode = new ChunkImageClass;
RootNode->Load(cload);
cload.Close_Chunk();
// while we have more top-level chunks, load them and link them
// to the root through its sibling pointer
while (cload.Open_Chunk()) {
ChunkImageClass * root_sibling = new ChunkImageClass;
root_sibling->Load(cload);
RootNode->Add_Sibling(root_sibling);
cload.Close_Chunk();
}
file.Close();
}
ChunkImageClass::ChunkImageClass(void) :
Child(NULL),
Sibling(NULL),
Data(NULL),
ID(0),
Length(0)
{
}
ChunkImageClass::~ChunkImageClass(void)
{
// Delete our children
ChunkImageClass * child = Child;
while (child) {
ChunkImageClass * child_sibling = child->Sibling;
delete child;
child = child_sibling;
}
// Delete our data
if (Data != NULL) {
delete Data;
}
}
void ChunkImageClass::Load(ChunkLoadClass & cload)
{
ID = cload.Cur_Chunk_ID();
Length = cload.Cur_Chunk_Length();
if (cload.Contains_Chunks()) {
while (cload.Open_Chunk()) {
ChunkImageClass * new_child = new ChunkImageClass;
new_child->Load(cload);
Add_Child(new_child);
cload.Close_Chunk();
}
} else {
if (Length > 0) {
Data = new uint8[Length];
cload.Read(Data,Length);
}
}
}
void ChunkImageClass::Add_Child(ChunkImageClass * new_child)
{
assert(new_child != NULL);
assert(new_child->Sibling == NULL);
// need to add to the tail...
if (Child == NULL) {
Child = new_child;
} else {
Child->Add_Sibling(new_child);
}
}
void ChunkImageClass::Add_Sibling(ChunkImageClass * new_sibling)
{
// Need to add to the tail so we display chunks in
// the same order they appear in the file, so we
// search for the tail.
ChunkImageClass * tail = this;
while (tail->Sibling != NULL) {
tail = tail->Sibling;
}
tail->Sibling = new_sibling;
assert(new_sibling->Sibling == NULL);
}
int ChunkImageClass::Get_Child_Count(void) const
{
int count = 0;
ChunkImageClass * child = Child;
while (child != NULL) {
count++;
child = child->Sibling;
}
return count;
}
const ChunkImageClass * ChunkImageClass::Get_Child(int i) const
{
int count = 0;
ChunkImageClass * child = Child;
while (child != NULL && count < i) {
count++;
child = child->Sibling;
}
assert(count == i);
return child;
}
int ChunkImageClass::Get_Sibling_Count(void) const
{
// NOTE: counts 'this' as a sibling.
int count = 0;
const ChunkImageClass * sibling = this;
while (sibling != NULL) {
count++;
sibling = sibling->Sibling;
}
return count;
}
const ChunkImageClass * ChunkImageClass::Get_Sibling(int i) const
{
// NOTE: sibling(0) is 'this' (just makes some other code simpler...)
int count = 0;
const ChunkImageClass * sibling = this;
while (sibling != NULL && count < i) {
count++;
sibling = sibling->Sibling;
}
assert(count == i);
return sibling;
}

View File

@@ -0,0 +1,100 @@
/*
** Command & Conquer Renegade(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 : ChunkView *
* *
* $Archive:: /Commando/Code/Tools/ChunkView/ChunkFileImage.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 9/28/99 9:48a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef CHUNKFILEIMAGE_H
#define CHUNKFILEIMAGE_H
#include "bittype.h"
class ChunkLoadClass;
class ChunkImageClass;
class ChunkFileImageClass
{
public:
ChunkFileImageClass(void);
~ChunkFileImageClass(void);
void Reset(void);
void Load(const char * filename);
const ChunkImageClass * Get_Root(void) const { return RootNode; }
protected:
ChunkImageClass * RootNode;
};
class ChunkImageClass
{
public:
ChunkImageClass(void);
~ChunkImageClass(void);
void Load(ChunkLoadClass & cload);
void Add_Child(ChunkImageClass * child);
uint32 Get_ID(void) const { return ID; }
uint32 Get_Length(void) const { return Length; }
const uint8 * Get_Data(void) const { return Data; }
int Get_Child_Count(void) const;
const ChunkImageClass * Get_Child(int i) const;
int Get_Sibling_Count(void) const;
const ChunkImageClass * Get_Sibling(int i) const;
protected:
void Add_Sibling(ChunkImageClass * sibling);
ChunkImageClass * Child;
ChunkImageClass * Sibling;
unsigned char * Data;
unsigned long ID;
unsigned long Length;
friend class ChunkFileImageClass;
};
#endif

View File

@@ -0,0 +1,145 @@
/*
** Command & Conquer Renegade(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 : ChunkView *
* *
* $Archive:: /Commando/Code/Tools/ChunkView/ChunkTreeView.cpp $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 9/28/99 9:48a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// ChunkTreeView.cpp : implementation file
//
#include "stdafx.h"
#include "ChunkView.h"
#include "ChunkTreeView.h"
#include "ChunkViewDoc.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CChunkTreeView
IMPLEMENT_DYNCREATE(CChunkTreeView, CTreeView)
CChunkTreeView::CChunkTreeView()
{
}
CChunkTreeView::~CChunkTreeView()
{
}
BEGIN_MESSAGE_MAP(CChunkTreeView, CTreeView)
//{{AFX_MSG_MAP(CChunkTreeView)
ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CChunkTreeView drawing
void CChunkTreeView::OnDraw(CDC* pDC)
{
CDocument* pDoc = GetDocument();
// TODO: add draw code here
}
/////////////////////////////////////////////////////////////////////////////
// CChunkTreeView diagnostics
#ifdef _DEBUG
void CChunkTreeView::AssertValid() const
{
CTreeView::AssertValid();
}
void CChunkTreeView::Dump(CDumpContext& dc) const
{
CTreeView::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CChunkTreeView message handlers
void CChunkTreeView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
// Reset the entire tree view
CTreeCtrl &tree = GetTreeCtrl();
tree.DeleteAllItems();
// Set the style attributes
long flags = tree.GetStyle();
flags |= TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS | TVS_SHOWSELALWAYS | TVS_DISABLEDRAGDROP;
SetWindowLong(tree.GetSafeHwnd(), GWL_STYLE, flags);
// Get the chunk tree
CChunkViewDoc * doc = (CChunkViewDoc *)GetDocument();
const ChunkImageClass * chunk = doc->Get_File_Image().Get_Root();
// Build the tree control to reflect the chunk tree
for (int i=0; i<chunk->Get_Sibling_Count(); i++) {
Insert_Chunk(chunk->Get_Sibling(i));
}
}
void CChunkTreeView::Insert_Chunk(const ChunkImageClass * chunk, HTREEITEM Parent)
{
char name[256];
sprintf(name,"Chunk ID: 0x%08X Length: %d",chunk->Get_ID(),chunk->Get_Length());
CTreeCtrl &tree = GetTreeCtrl();
HTREEITEM tree_item = tree.InsertItem(name, Parent);
tree.SetItem(tree_item, TVIF_PARAM,0,0,0,0,0, (long) chunk);
for (int i=0; i<chunk->Get_Child_Count(); i++) {
Insert_Chunk(chunk->Get_Child(i),tree_item);
}
}
void CChunkTreeView::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
CChunkViewDoc * doc = (CChunkViewDoc *)GetDocument();
doc->Set_Cur_Chunk((ChunkImageClass *) pNMTreeView->itemNew.lParam);
doc->UpdateAllViews(this); // update all of the other views
*pResult = 0;
}

View File

@@ -0,0 +1,96 @@
/*
** Command & Conquer Renegade(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 : ChunkView *
* *
* $Archive:: /Commando/Code/Tools/ChunkView/ChunkTreeView.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 9/28/99 9:48a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if !defined(AFX_CHUNKTREEVIEW_H__FD83E2D6_72AE_11D3_BB4D_00902742EA14__INCLUDED_)
#define AFX_CHUNKTREEVIEW_H__FD83E2D6_72AE_11D3_BB4D_00902742EA14__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// ChunkTreeView.h : header file
//
class ChunkImageClass;
/////////////////////////////////////////////////////////////////////////////
// CChunkTreeView view
class CChunkTreeView : public CTreeView
{
protected:
CChunkTreeView(); // protected constructor used by dynamic creation
DECLARE_DYNCREATE(CChunkTreeView)
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CChunkTreeView)
protected:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint);
//}}AFX_VIRTUAL
// Implementation
protected:
virtual ~CChunkTreeView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
void Insert_Chunk(const ChunkImageClass * chunk, HTREEITEM Parent = TVI_ROOT);
// Generated message map functions
protected:
//{{AFX_MSG(CChunkTreeView)
afx_msg void OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_CHUNKTREEVIEW_H__FD83E2D6_72AE_11D3_BB4D_00902742EA14__INCLUDED_)

View File

@@ -0,0 +1,189 @@
/*
** Command & Conquer Renegade(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 : ChunkView *
* *
* $Archive:: /Commando/Code/Tools/ChunkView/ChunkView.cpp $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 9/28/99 9:48a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// ChunkView.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "ChunkView.h"
#include "MainFrm.h"
#include "ChunkViewDoc.h"
#include "ChunkViewView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CChunkViewApp
BEGIN_MESSAGE_MAP(CChunkViewApp, CWinApp)
//{{AFX_MSG_MAP(CChunkViewApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
// Standard file based document commands
ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CChunkViewApp construction
CChunkViewApp::CChunkViewApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
/////////////////////////////////////////////////////////////////////////////
// The one and only CChunkViewApp object
CChunkViewApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CChunkViewApp initialization
BOOL CChunkViewApp::InitInstance()
{
AfxEnableControlContainer();
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
// Change the registry key under which our settings are stored.
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization.
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
LoadStdProfileSettings(6); // Load standard INI file options (including MRU)
// Register the application's document templates. Document templates
// serve as the connection between documents, frame windows and views.
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CChunkViewDoc),
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CChunkViewView));
AddDocTemplate(pDocTemplate);
// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
return FALSE;
// The one and only window has been initialized, so show and update it.
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
// No message handlers
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
// App command to run the dialog
void CChunkViewApp::OnAppAbout()
{
CAboutDlg aboutDlg;
aboutDlg.DoModal();
}
/////////////////////////////////////////////////////////////////////////////
// CChunkViewApp message handlers

View File

@@ -0,0 +1,204 @@
# Microsoft Developer Studio Project File - Name="ChunkView" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
CFG=ChunkView - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "ChunkView.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "ChunkView.mak" CFG="ChunkView - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "ChunkView - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "ChunkView - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/Commando/Code/Tools/ChunkView", POHCAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "ChunkView - Win32 Release"
# PROP BASE Use_MFC 6
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 6
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\wwlib" /I "..\..\wwdebug" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL"
# ADD RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386
# ADD LINK32 wwlib.lib wwdebug.lib /nologo /subsystem:windows /machine:I386 /libpath:"..\..\Libs\Release"
!ELSEIF "$(CFG)" == "ChunkView - Win32 Debug"
# PROP BASE Use_MFC 6
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 6
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\wwlib" /I "..\..\wwdebug" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL"
# ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386
# ADD LINK32 wwlib.lib wwdebug.lib /nologo /subsystem:windows /debug /machine:I386 /libpath:"..\..\Libs\Debug"
!ENDIF
# Begin Target
# Name "ChunkView - Win32 Release"
# Name "ChunkView - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\ChunkDataView.cpp
# End Source File
# Begin Source File
SOURCE=.\ChunkFileImage.cpp
# End Source File
# Begin Source File
SOURCE=.\ChunkTreeView.cpp
# End Source File
# Begin Source File
SOURCE=.\ChunkView.cpp
# End Source File
# Begin Source File
SOURCE=.\ChunkView.rc
# End Source File
# Begin Source File
SOURCE=.\ChunkViewDoc.cpp
# End Source File
# Begin Source File
SOURCE=.\ChunkViewView.cpp
# End Source File
# Begin Source File
SOURCE=.\HexToString.cpp
# End Source File
# Begin Source File
SOURCE=.\MainFrm.cpp
# End Source File
# Begin Source File
SOURCE=.\StdAfx.cpp
# ADD CPP /Yc"stdafx.h"
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\ChunkDataView.h
# End Source File
# Begin Source File
SOURCE=.\ChunkFileImage.h
# End Source File
# Begin Source File
SOURCE=.\ChunkTreeView.h
# End Source File
# Begin Source File
SOURCE=.\ChunkView.h
# End Source File
# Begin Source File
SOURCE=.\ChunkViewDoc.h
# End Source File
# Begin Source File
SOURCE=.\ChunkViewView.h
# End Source File
# Begin Source File
SOURCE=.\HexToString.h
# End Source File
# Begin Source File
SOURCE=.\MainFrm.h
# End Source File
# Begin Source File
SOURCE=.\Resource.h
# End Source File
# Begin Source File
SOURCE=.\StdAfx.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# Begin Source File
SOURCE=.\res\ChunkView.ico
# End Source File
# Begin Source File
SOURCE=.\res\ChunkView.rc2
# End Source File
# Begin Source File
SOURCE=.\res\ChunkViewDoc.ico
# End Source File
# Begin Source File
SOURCE=.\res\Toolbar.bmp
# End Source File
# End Group
# Begin Source File
SOURCE=.\ReadMe.txt
# End Source File
# End Target
# End Project

View File

@@ -0,0 +1,86 @@
/*
** Command & Conquer Renegade(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 : ChunkView *
* *
* $Archive:: /Commando/Code/Tools/ChunkView/ChunkView.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 9/28/99 9:48a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// ChunkView.h : main header file for the CHUNKVIEW application
//
#if !defined(AFX_CHUNKVIEW_H__53C69A64_72AB_11D3_BB4D_00902742EA14__INCLUDED_)
#define AFX_CHUNKVIEW_H__53C69A64_72AB_11D3_BB4D_00902742EA14__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif
#include "resource.h" // main symbols
/////////////////////////////////////////////////////////////////////////////
// CChunkViewApp:
// See ChunkView.cpp for the implementation of this class
//
class CChunkViewApp : public CWinApp
{
public:
CChunkViewApp();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CChunkViewApp)
public:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL
// Implementation
//{{AFX_MSG(CChunkViewApp)
afx_msg void OnAppAbout();
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_CHUNKVIEW_H__53C69A64_72AB_11D3_BB4D_00902742EA14__INCLUDED_)

View File

@@ -0,0 +1,372 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"#define _AFX_NO_SPLITTER_RESOURCES\r\n"
"#define _AFX_NO_OLE_RESOURCES\r\n"
"#define _AFX_NO_TRACKER_RESOURCES\r\n"
"#define _AFX_NO_PROPERTY_RESOURCES\r\n"
"\r\n"
"#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
"#ifdef _WIN32\r\n"
"LANGUAGE 9, 1\r\n"
"#pragma code_page(1252)\r\n"
"#endif //_WIN32\r\n"
"#include ""res\\ChunkView.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
"#include ""afxres.rc"" // Standard components\r\n"
"#endif\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDR_MAINFRAME ICON DISCARDABLE "res\\ChunkView.ico"
IDR_CHUNKVTYPE ICON DISCARDABLE "res\\ChunkViewDoc.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//
IDR_MAINFRAME BITMAP MOVEABLE PURE "res\\Toolbar.bmp"
/////////////////////////////////////////////////////////////////////////////
//
// Toolbar
//
IDR_MAINFRAME TOOLBAR DISCARDABLE 24, 24
BEGIN
BUTTON ID_FILE_OPEN
SEPARATOR
BUTTON ID_DISPLAY_HEX
BUTTON ID_DISPLAY_MICROCHUNKS
SEPARATOR
BUTTON ID_WORDMODE_BYTE
BUTTON ID_WORDMODE_SHORT
BUTTON ID_WORDMODE_LONG
END
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDR_MAINFRAME MENU PRELOAD DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "&Open...\tCtrl+O", ID_FILE_OPEN
MENUITEM SEPARATOR
MENUITEM "Recent File", ID_FILE_MRU_FILE1, GRAYED
MENUITEM SEPARATOR
MENUITEM "E&xit", ID_APP_EXIT
END
POPUP "&View"
BEGIN
MENUITEM "&Toolbar", ID_VIEW_TOOLBAR
MENUITEM "&Status Bar", ID_VIEW_STATUS_BAR
END
POPUP "&Help"
BEGIN
MENUITEM "&About ChunkView...", ID_APP_ABOUT
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//
IDR_MAINFRAME ACCELERATORS PRELOAD MOVEABLE PURE
BEGIN
"N", ID_FILE_NEW, VIRTKEY, CONTROL
"O", ID_FILE_OPEN, VIRTKEY, CONTROL
"S", ID_FILE_SAVE, VIRTKEY, CONTROL
"Z", ID_EDIT_UNDO, VIRTKEY, CONTROL
"X", ID_EDIT_CUT, VIRTKEY, CONTROL
"C", ID_EDIT_COPY, VIRTKEY, CONTROL
"V", ID_EDIT_PASTE, VIRTKEY, CONTROL
VK_BACK, ID_EDIT_UNDO, VIRTKEY, ALT
VK_DELETE, ID_EDIT_CUT, VIRTKEY, SHIFT
VK_INSERT, ID_EDIT_COPY, VIRTKEY, CONTROL
VK_INSERT, ID_EDIT_PASTE, VIRTKEY, SHIFT
VK_F6, ID_NEXT_PANE, VIRTKEY
VK_F6, ID_PREV_PANE, VIRTKEY, SHIFT
END
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_ABOUTBOX DIALOG DISCARDABLE 0, 0, 235, 55
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About ChunkView"
FONT 8, "MS Sans Serif"
BEGIN
ICON IDR_MAINFRAME,IDC_STATIC,11,17,20,20
LTEXT "ChunkView Version 1.0",IDC_STATIC,40,10,119,8,
SS_NOPREFIX
LTEXT "Copyright (C) 1999",IDC_STATIC,40,25,119,8
DEFPUSHBUTTON "OK",IDOK,178,7,50,14,WS_GROUP
END
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904B0"
BEGIN
VALUE "CompanyName", "\0"
VALUE "FileDescription", "ChunkView MFC Application\0"
VALUE "FileVersion", "1, 0, 0, 1\0"
VALUE "InternalName", "ChunkView\0"
VALUE "LegalCopyright", "Copyright (C) 1999\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "ChunkView.EXE\0"
VALUE "ProductName", "ChunkView Application\0"
VALUE "ProductVersion", "1, 0, 0, 1\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // !_MAC
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_ABOUTBOX, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 228
TOPMARGIN, 7
BOTTOMMARGIN, 48
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE PRELOAD DISCARDABLE
BEGIN
IDR_MAINFRAME "ChunkView\n\nChunkV\n\n\nChunkView.Document\nChunkV Document"
END
STRINGTABLE PRELOAD DISCARDABLE
BEGIN
AFX_IDS_APP_TITLE "ChunkView"
AFX_IDS_IDLEMESSAGE "Ready"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_INDICATOR_EXT "EXT"
ID_INDICATOR_CAPS "CAP"
ID_INDICATOR_NUM "NUM"
ID_INDICATOR_SCRL "SCRL"
ID_INDICATOR_OVR "OVR"
ID_INDICATOR_REC "REC"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_FILE_NEW "Create a new document\nNew"
ID_FILE_OPEN "Open an existing document\nOpen"
ID_FILE_CLOSE "Close the active document\nClose"
ID_FILE_SAVE "Save the active document\nSave"
ID_FILE_SAVE_AS "Save the active document with a new name\nSave As"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_APP_ABOUT "Display program information, version number and copyright\nAbout"
ID_APP_EXIT "Quit the application; prompts to save documents\nExit"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_FILE_MRU_FILE1 "Open this document"
ID_FILE_MRU_FILE2 "Open this document"
ID_FILE_MRU_FILE3 "Open this document"
ID_FILE_MRU_FILE4 "Open this document"
ID_FILE_MRU_FILE5 "Open this document"
ID_FILE_MRU_FILE6 "Open this document"
ID_FILE_MRU_FILE7 "Open this document"
ID_FILE_MRU_FILE8 "Open this document"
ID_FILE_MRU_FILE9 "Open this document"
ID_FILE_MRU_FILE10 "Open this document"
ID_FILE_MRU_FILE11 "Open this document"
ID_FILE_MRU_FILE12 "Open this document"
ID_FILE_MRU_FILE13 "Open this document"
ID_FILE_MRU_FILE14 "Open this document"
ID_FILE_MRU_FILE15 "Open this document"
ID_FILE_MRU_FILE16 "Open this document"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_NEXT_PANE "Switch to the next window pane\nNext Pane"
ID_PREV_PANE "Switch back to the previous window pane\nPrevious Pane"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_WINDOW_SPLIT "Split the active window into panes\nSplit"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_EDIT_CLEAR "Erase the selection\nErase"
ID_EDIT_CLEAR_ALL "Erase everything\nErase All"
ID_EDIT_COPY "Copy the selection and put it on the Clipboard\nCopy"
ID_EDIT_CUT "Cut the selection and put it on the Clipboard\nCut"
ID_EDIT_FIND "Find the specified text\nFind"
ID_EDIT_PASTE "Insert Clipboard contents\nPaste"
ID_EDIT_REPEAT "Repeat the last action\nRepeat"
ID_EDIT_REPLACE "Replace specific text with different text\nReplace"
ID_EDIT_SELECT_ALL "Select the entire document\nSelect All"
ID_EDIT_UNDO "Undo the last action\nUndo"
ID_EDIT_REDO "Redo the previously undone action\nRedo"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_VIEW_TOOLBAR "Show or hide the toolbar\nToggle ToolBar"
ID_VIEW_STATUS_BAR "Show or hide the status bar\nToggle StatusBar"
END
STRINGTABLE DISCARDABLE
BEGIN
AFX_IDS_SCSIZE "Change the window size"
AFX_IDS_SCMOVE "Change the window position"
AFX_IDS_SCMINIMIZE "Reduce the window to an icon"
AFX_IDS_SCMAXIMIZE "Enlarge the window to full size"
AFX_IDS_SCNEXTWINDOW "Switch to the next document window"
AFX_IDS_SCPREVWINDOW "Switch to the previous document window"
AFX_IDS_SCCLOSE "Close the active window and prompts to save the documents"
END
STRINGTABLE DISCARDABLE
BEGIN
AFX_IDS_SCRESTORE "Restore the window to normal size"
AFX_IDS_SCTASKLIST "Activate Task List"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_DISPLAY_HEX "Set the display mode to HEX"
ID_DISPLAY_MICROCHUNKS "Set the display mode to micro chunks"
ID_WORDMODE_LONG "Display hex data as longs"
ID_WORDMODE_SHORT "Display hex data as 16bit values"
ID_WORDMODE_BYTE "Display hex data as bytes"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#define _AFX_NO_SPLITTER_RESOURCES
#define _AFX_NO_OLE_RESOURCES
#define _AFX_NO_TRACKER_RESOURCES
#define _AFX_NO_PROPERTY_RESOURCES
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE 9, 1
#pragma code_page(1252)
#endif //_WIN32
#include "res\ChunkView.rc2" // non-Microsoft Visual C++ edited resources
#include "afxres.rc" // Standard components
#endif
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@@ -0,0 +1,140 @@
/*
** Command & Conquer Renegade(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 : ChunkView *
* *
* $Archive:: /Commando/Code/Tools/ChunkView/ChunkViewDoc.cpp $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 9/28/99 9:48a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// ChunkViewDoc.cpp : implementation of the CChunkViewDoc class
//
#include "stdafx.h"
#include "ChunkView.h"
#include "ChunkViewDoc.h"
#include "MainFrm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CChunkViewDoc
IMPLEMENT_DYNCREATE(CChunkViewDoc, CDocument)
BEGIN_MESSAGE_MAP(CChunkViewDoc, CDocument)
//{{AFX_MSG_MAP(CChunkViewDoc)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CChunkViewDoc construction/destruction
CChunkViewDoc::CChunkViewDoc() :
m_pCurChunk(NULL)
{
// TODO: add one-time construction code here
}
CChunkViewDoc::~CChunkViewDoc()
{
}
BOOL CChunkViewDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
// TODO: add reinitialization code here
// (SDI documents will reuse this document)
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CChunkViewDoc serialization
void CChunkViewDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
}
else
{
m_ChunkFileImage.Load(ar.m_strFileName);
}
}
/////////////////////////////////////////////////////////////////////////////
// CChunkViewDoc diagnostics
#ifdef _DEBUG
void CChunkViewDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CChunkViewDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CChunkViewDoc commands
const ChunkFileImageClass & CChunkViewDoc::Get_File_Image(void)
{
return m_ChunkFileImage;
}
void CChunkViewDoc::Set_Cur_Chunk(ChunkImageClass * cur_chunk)
{
// The ChunkTreeView calls this when the user clicks on a particular chunk
if (m_pCurChunk != cur_chunk) {
m_pCurChunk = cur_chunk;
}
}
const ChunkImageClass * CChunkViewDoc::Get_Cur_Chunk(void)
{
return m_pCurChunk;
}

View File

@@ -0,0 +1,103 @@
/*
** Command & Conquer Renegade(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 : ChunkView *
* *
* $Archive:: /Commando/Code/Tools/ChunkView/ChunkViewDoc.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 9/28/99 9:48a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// ChunkViewDoc.h : interface of the CChunkViewDoc class
//
/////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_CHUNKVIEWDOC_H__53C69A6A_72AB_11D3_BB4D_00902742EA14__INCLUDED_)
#define AFX_CHUNKVIEWDOC_H__53C69A6A_72AB_11D3_BB4D_00902742EA14__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "ChunkFileImage.h"
class CChunkViewDoc : public CDocument
{
protected: // create from serialization only
CChunkViewDoc();
DECLARE_DYNCREATE(CChunkViewDoc)
// Attributes
public:
// Operations
public:
const ChunkFileImageClass & Get_File_Image(void);
const ChunkImageClass * Get_Cur_Chunk(void);
void Set_Cur_Chunk(ChunkImageClass * cur_chunk);
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CChunkViewDoc)
public:
virtual BOOL OnNewDocument();
virtual void Serialize(CArchive& ar);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CChunkViewDoc();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
ChunkFileImageClass m_ChunkFileImage;
ChunkImageClass * m_pCurChunk;
// Generated message map functions
protected:
//{{AFX_MSG(CChunkViewDoc)
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_CHUNKVIEWDOC_H__53C69A6A_72AB_11D3_BB4D_00902742EA14__INCLUDED_)

View File

@@ -0,0 +1,116 @@
/*
** Command & Conquer Renegade(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 : ChunkView *
* *
* $Archive:: /Commando/Code/Tools/ChunkView/ChunkViewView.cpp $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 9/28/99 9:48a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// ChunkViewView.cpp : implementation of the CChunkViewView class
//
#include "stdafx.h"
#include "ChunkView.h"
#include "ChunkViewDoc.h"
#include "ChunkViewView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CChunkViewView
IMPLEMENT_DYNCREATE(CChunkViewView, CView)
BEGIN_MESSAGE_MAP(CChunkViewView, CView)
//{{AFX_MSG_MAP(CChunkViewView)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CChunkViewView construction/destruction
CChunkViewView::CChunkViewView()
{
}
CChunkViewView::~CChunkViewView()
{
}
BOOL CChunkViewView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CChunkViewView drawing
void CChunkViewView::OnDraw(CDC* pDC)
{
CChunkViewDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}
/////////////////////////////////////////////////////////////////////////////
// CChunkViewView diagnostics
#ifdef _DEBUG
void CChunkViewView::AssertValid() const
{
CView::AssertValid();
}
void CChunkViewView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CChunkViewDoc* CChunkViewView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CChunkViewDoc)));
return (CChunkViewDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CChunkViewView message handlers

View File

@@ -0,0 +1,101 @@
/*
** Command & Conquer Renegade(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 : ChunkView *
* *
* $Archive:: /Commando/Code/Tools/ChunkView/ChunkViewView.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 9/28/99 9:48a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// ChunkViewView.h : interface of the CChunkViewView class
//
/////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_CHUNKVIEWVIEW_H__53C69A6C_72AB_11D3_BB4D_00902742EA14__INCLUDED_)
#define AFX_CHUNKVIEWVIEW_H__53C69A6C_72AB_11D3_BB4D_00902742EA14__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CChunkViewView : public CView
{
protected: // create from serialization only
CChunkViewView();
DECLARE_DYNCREATE(CChunkViewView)
// Attributes
public:
CChunkViewDoc* GetDocument();
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CChunkViewView)
public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CChunkViewView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
// Generated message map functions
protected:
//{{AFX_MSG(CChunkViewView)
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#ifndef _DEBUG // debug version in ChunkViewView.cpp
inline CChunkViewDoc* CChunkViewView::GetDocument()
{ return (CChunkViewDoc*)m_pDocument; }
#endif
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_CHUNKVIEWVIEW_H__53C69A6C_72AB_11D3_BB4D_00902742EA14__INCLUDED_)

View File

@@ -0,0 +1,212 @@
/*
** Command & Conquer Renegade(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 : ChunkView *
* *
* $Archive:: /Commando/Code/Tools/ChunkView/HexToString.cpp $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 9/28/99 9:48a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "stdafx.h"
#include "HexToString.h"
#include <ctype.h>
const int BYTES_PER_LINE = 16;
const int SHORTS_PER_LINE = 8;
const int LONGS_PER_LINE = 4;
HexToStringClass::HexToStringClass(const uint8 * data,uint32 size) :
Data(data),
Size(size)
{
}
/*******************************************************************************************
**
** HexToStringByteClass
**
*******************************************************************************************/
HexToStringByteClass::HexToStringByteClass(const uint8 * data,uint32 size) :
HexToStringClass(data,size)
{
Reset();
}
void HexToStringByteClass::Reset(void)
{
CurPos = Data;
}
bool HexToStringByteClass::Is_Done(void)
{
return CurPos >= Data + Size;
}
CString HexToStringByteClass::Get_Next_Line(void)
{
if (Is_Done()) return CString("");
int i;
CString line_string;
CString tmp_string;
const uint8 * workptr = CurPos;
uint32 offset = (uint32)(CurPos - Data);
int bytes_to_eat = min(BYTES_PER_LINE,Size - offset);
// print hex dump
line_string.Format("%08x: ",offset);
for (i=0; i<bytes_to_eat; i++) {
tmp_string.Format("%02X ",*workptr++);
line_string += tmp_string;
}
// print blanks at end of buffer
for (i=0; i<BYTES_PER_LINE - bytes_to_eat; i++)
{
line_string += CString(" ");
}
// spaces separate the hex from the characters
line_string += CString(" ");
workptr = CurPos;
// print the characters
for (i=0; i<bytes_to_eat; i++) {
if (isalnum(*workptr)) {
tmp_string.Format("%c",*workptr);
} else {
tmp_string.Format(".");
}
line_string += tmp_string;
workptr++;
}
CurPos = workptr;
return line_string;
}
/*******************************************************************************************
**
** HexToStringShortClass
**
*******************************************************************************************/
HexToStringShortClass::HexToStringShortClass(const uint8 * data,uint32 size) :
HexToStringClass(data,size)
{
// Round size down to the nearest word
Size &= ~1;
Reset();
}
void HexToStringShortClass::Reset(void)
{
CurPos = (uint16*)Data;
}
bool HexToStringShortClass::Is_Done(void)
{
uint32 offset = (uint32)((uint8*)CurPos - Data);
return offset >= Size;
}
CString HexToStringShortClass::Get_Next_Line(void)
{
if (Is_Done()) return CString("");
int i;
CString line_string;
CString tmp_string;
const uint16 * workptr = CurPos;
uint32 offset = (uint32)((uint8*)CurPos - Data);
int shorts_to_eat = min(SHORTS_PER_LINE,(Size - offset) / sizeof(uint16)); //yeah shorts_to_eat!
// print hex dump
line_string.Format("%08x: ",offset);
for (i=0; i<shorts_to_eat; i++) {
tmp_string.Format("%04X ",*workptr++);
line_string += tmp_string;
}
CurPos = workptr;
return line_string;
}
/*******************************************************************************************
**
** HexToStringLongClass
**
*******************************************************************************************/
HexToStringLongClass::HexToStringLongClass(const uint8 * data,uint32 size) :
HexToStringClass(data,size)
{
// Round size down to the nearest long
Size &= ~3;
Reset();
}
void HexToStringLongClass::Reset(void)
{
CurPos = (uint32*)Data;
}
bool HexToStringLongClass::Is_Done(void)
{
uint32 offset = (uint32)((uint8*)CurPos - Data);
return offset >= Size;
}
CString HexToStringLongClass::Get_Next_Line(void)
{
if (Is_Done()) return CString("");
int i;
CString line_string;
CString tmp_string;
const uint32 * workptr = CurPos;
uint32 offset = (uint32)((uint8*)CurPos - Data);
int longs_to_eat = min(LONGS_PER_LINE,(Size - offset)/sizeof(uint32));
// print hex dump
line_string.Format("%08x: ",offset);
for (i=0; i<longs_to_eat; i++) {
tmp_string.Format("%08X ",*workptr++);
line_string += tmp_string;
}
CurPos = workptr;
return line_string;
}

View File

@@ -0,0 +1,109 @@
/*
** Command & Conquer Renegade(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 : ChunkView *
* *
* $Archive:: /Commando/Code/Tools/ChunkView/HexToString.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 9/28/99 9:48a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef HEXTOSTRING_H
#define HEXTOSTRING_H
#include "stdafx.h"
#include "bittype.h"
class HexToStringClass
{
public:
HexToStringClass(const uint8 * data,uint32 size);
virtual bool Is_Done(void) = 0;
virtual CString Get_Next_Line(void) = 0;
protected:
const uint8 * Data;
uint32 Size;
};
class HexToStringByteClass : public HexToStringClass
{
public:
HexToStringByteClass(const uint8 * data,uint32 size);
bool Is_Done(void);
CString Get_Next_Line(void);
private:
void Reset(void);
const uint8 * CurPos;
};
class HexToStringShortClass : public HexToStringClass
{
public:
HexToStringShortClass(const uint8 * data,uint32 size);
bool Is_Done(void);
CString Get_Next_Line(void);
private:
void Reset(void);
const uint16 * CurPos;
};
class HexToStringLongClass : public HexToStringClass
{
public:
HexToStringLongClass(const uint8 * data,uint32 size);
bool Is_Done(void);
CString Get_Next_Line(void);
private:
void Reset(void);
const uint32 * CurPos;
};
#endif

View File

@@ -0,0 +1,233 @@
/*
** Command & Conquer Renegade(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 : ChunkView *
* *
* $Archive:: /Commando/Code/Tools/ChunkView/MainFrm.cpp $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 9/28/99 9:46a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// MainFrm.cpp : implementation of the CMainFrame class
//
#include "stdafx.h"
#include "ChunkView.h"
#include "MainFrm.h"
#include "ChunkDataView.h"
#include "ChunkTreeView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CMainFrame
IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
ON_COMMAND(ID_DISPLAY_HEX, OnDisplayHex)
ON_UPDATE_COMMAND_UI(ID_DISPLAY_HEX, OnUpdateDisplayHex)
ON_COMMAND(ID_DISPLAY_MICROCHUNKS, OnDisplayMicrochunks)
ON_UPDATE_COMMAND_UI(ID_DISPLAY_MICROCHUNKS, OnUpdateDisplayMicrochunks)
ON_COMMAND(ID_WORDMODE_BYTE, OnWordmodeByte)
ON_UPDATE_COMMAND_UI(ID_WORDMODE_BYTE, OnUpdateWordmodeByte)
ON_COMMAND(ID_WORDMODE_SHORT, OnWordmodeShort)
ON_UPDATE_COMMAND_UI(ID_WORDMODE_SHORT, OnUpdateWordmodeShort)
ON_COMMAND(ID_WORDMODE_LONG, OnWordmodeLong)
ON_UPDATE_COMMAND_UI(ID_WORDMODE_LONG, OnUpdateWordmodeLong)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
static UINT indicators[] =
{
ID_SEPARATOR, // status line indicator
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};
/////////////////////////////////////////////////////////////////////////////
// CMainFrame construction/destruction
CMainFrame::CMainFrame()
{
// TODO: add member initialization code here
}
CMainFrame::~CMainFrame()
{
}
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (!m_wndToolBar.CreateEx(this) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
if (!m_wndReBar.Create(this) ||
!m_wndReBar.AddBar(&m_wndToolBar))
{
TRACE0("Failed to create rebar\n");
return -1; // fail to create
}
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar\n");
return -1; // fail to create
}
// TODO: Remove this if you don't want tool tips
m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
CBRS_TOOLTIPS | CBRS_FLYBY);
return 0;
}
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CMainFrame diagnostics
#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
CFrameWnd::AssertValid();
}
void CMainFrame::Dump(CDumpContext& dc) const
{
CFrameWnd::Dump(dc);
}
#endif //_DEBUG
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
// Create the main splitter window for the application
BOOL ok = m_wndSplitter.CreateStatic (this, 1, 2);
ASSERT(ok);
if (!ok) return FALSE;
// Create the two sub views
ok &= m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CChunkTreeView),CSize(200,10),pContext);
ok &= m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CChunkDataView),CSize(340,10),pContext);
ASSERT(ok);
if (!ok) return FALSE;
return TRUE;
}
CChunkDataView * CMainFrame::Get_Data_View(void)
{
return (CChunkDataView *)m_wndSplitter.GetPane(0,1);
}
CChunkTreeView * CMainFrame::Get_Tree_View(void)
{
return (CChunkTreeView *)m_wndSplitter.GetPane(0,0);
}
void CMainFrame::OnDisplayHex()
{
Get_Data_View()->Set_Display_Mode(CChunkDataView::DISPLAY_MODE_HEX);
}
void CMainFrame::OnUpdateDisplayHex(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(Get_Data_View()->Get_Display_Mode() == CChunkDataView::DISPLAY_MODE_HEX);
}
void CMainFrame::OnDisplayMicrochunks()
{
Get_Data_View()->Set_Display_Mode(CChunkDataView::DISPLAY_MODE_MICROCHUNKS);
}
void CMainFrame::OnUpdateDisplayMicrochunks(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(Get_Data_View()->Get_Display_Mode() == CChunkDataView::DISPLAY_MODE_MICROCHUNKS);
}
void CMainFrame::OnWordmodeByte()
{
Get_Data_View()->Set_Word_Size(CChunkDataView::WORD_SIZE_BYTE);
}
void CMainFrame::OnUpdateWordmodeByte(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(Get_Data_View()->Get_Word_Size() == CChunkDataView::WORD_SIZE_BYTE);
}
void CMainFrame::OnWordmodeShort()
{
Get_Data_View()->Set_Word_Size(CChunkDataView::WORD_SIZE_SHORT);
}
void CMainFrame::OnUpdateWordmodeShort(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(Get_Data_View()->Get_Word_Size() == CChunkDataView::WORD_SIZE_SHORT);
}
void CMainFrame::OnWordmodeLong()
{
Get_Data_View()->Set_Word_Size(CChunkDataView::WORD_SIZE_LONG);
}
void CMainFrame::OnUpdateWordmodeLong(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(Get_Data_View()->Get_Word_Size() == CChunkDataView::WORD_SIZE_LONG);
}

View File

@@ -0,0 +1,116 @@
/*
** Command & Conquer Renegade(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 : ChunkView *
* *
* $Archive:: /Commando/Code/Tools/ChunkView/MainFrm.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 9/28/99 9:48a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// MainFrm.h : interface of the CMainFrame class
//
/////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_MAINFRM_H__53C69A68_72AB_11D3_BB4D_00902742EA14__INCLUDED_)
#define AFX_MAINFRM_H__53C69A68_72AB_11D3_BB4D_00902742EA14__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CChunkDataView;
class CChunkTreeView;
class CMainFrame : public CFrameWnd
{
protected: // create from serialization only
CMainFrame();
DECLARE_DYNCREATE(CMainFrame)
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMainFrame)
public:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CMainFrame();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
CChunkDataView * Get_Data_View(void);
CChunkTreeView * Get_Tree_View(void);
protected: // control bar embedded members
CStatusBar m_wndStatusBar;
CToolBar m_wndToolBar;
CReBar m_wndReBar;
CSplitterWnd m_wndSplitter;
// Generated message map functions
protected:
//{{AFX_MSG(CMainFrame)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnDisplayHex();
afx_msg void OnUpdateDisplayHex(CCmdUI* pCmdUI);
afx_msg void OnDisplayMicrochunks();
afx_msg void OnUpdateDisplayMicrochunks(CCmdUI* pCmdUI);
afx_msg void OnWordmodeByte();
afx_msg void OnUpdateWordmodeByte(CCmdUI* pCmdUI);
afx_msg void OnWordmodeShort();
afx_msg void OnUpdateWordmodeShort(CCmdUI* pCmdUI);
afx_msg void OnWordmodeLong();
afx_msg void OnUpdateWordmodeLong(CCmdUI* pCmdUI);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_MAINFRM_H__53C69A68_72AB_11D3_BB4D_00902742EA14__INCLUDED_)

View File

@@ -0,0 +1,45 @@
/*
** Command & Conquer Renegade(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 : ChunkView *
* *
* $Archive:: /Commando/Code/Tools/ChunkView/StdAfx.cpp $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 9/28/99 9:46a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// stdafx.cpp : source file that includes just the standard includes
// ChunkView.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"

View File

@@ -0,0 +1,65 @@
/*
** Command & Conquer Renegade(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 : ChunkView *
* *
* $Archive:: /Commando/Code/Tools/ChunkView/StdAfx.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 9/28/99 9:48a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#if !defined(AFX_STDAFX_H__53C69A66_72AB_11D3_BB4D_00902742EA14__INCLUDED_)
#define AFX_STDAFX_H__53C69A66_72AB_11D3_BB4D_00902742EA14__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <afxdisp.h> // MFC Automation classes
#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
#include <afxcview.h> // MFC views
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__53C69A66_72AB_11D3_BB4D_00902742EA14__INCLUDED_)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,13 @@
//
// CHUNKVIEW.RC2 - resources Microsoft Visual C++ does not edit directly
//
#ifdef APSTUDIO_INVOKED
#error this file is not editable by Microsoft Visual C++
#endif //APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
// Add manually edited resources here...
/////////////////////////////////////////////////////////////////////////////

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1,24 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by ChunkView.rc
//
#define IDD_ABOUTBOX 100
#define IDR_MAINFRAME 128
#define IDR_CHUNKVTYPE 129
#define ID_DISPLAY_HEX 32771
#define ID_DISPLAY_MICROCHUNKS 32772
#define ID_WORDMODE_LONG 32773
#define ID_WORDMODE_SHORT 32774
#define ID_WORDMODE_BYTE 32775
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_3D_CONTROLS 1
#define _APS_NEXT_RESOURCE_VALUE 130
#define _APS_NEXT_COMMAND_VALUE 32776
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@@ -0,0 +1,815 @@
/*
** Command & Conquer Renegade(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/>.
*/
#include "clipboard.h"
#include <istdplug.h>
#include "utilapi.h"
//----------------------------------------------------------------------------
// Node_Key
//----------------------------------------------------------------------------
class Node_Key
{
public:
Node_Key ( int nr_frames, const char * name, Node_Key * next );
~Node_Key ();
void set_position ( int frame, Point3 pos )
{
if ( frame >= 0 && frame < nr_frames_ )
position_ [frame] = pos;
}
void set_orientation ( int frame, Quat facing )
{
if ( frame >= 0 && frame < nr_frames_ )
orientation_ [frame] = facing;
}
const Point3 & position ( int frame )
{
if ( frame < 0 || frame >= nr_frames_ )
frame = 0;
return position_ [frame];
}
const Quat & orientation ( int frame )
{
if ( frame < 0 || frame >= nr_frames_ )
frame = 0;
return orientation_ [frame];
}
const char * name () { return name_; }
int nr_frames () { return nr_frames_; }
Node_Key * next () { return next_; }
private:
char * name_;
int nr_frames_;
Point3 * position_;
Quat * orientation_;
Node_Key * next_;
};
//----------------------------------------------------------------------------
// Node_Key::Node_Key
//----------------------------------------------------------------------------
Node_Key::Node_Key
(
int nr_frames,
const char * name,
Node_Key * next
):
nr_frames_ (nr_frames),
next_ (next)
{
position_ = new Point3 [ nr_frames ];
orientation_ = new Quat [ nr_frames ];
name_ = new char [ strlen (name) + 1 ];
strcpy ( name_, name );
}
//----------------------------------------------------------------------------
// Node_Key::~Node_Key
//----------------------------------------------------------------------------
Node_Key::~Node_Key ()
{
delete [] position_;
delete [] orientation_;
delete [] name_;
}
//----------------------------------------------------------------------------
// Pose
//----------------------------------------------------------------------------
const MAX_NAME = 64;
class Pose
{
public:
Pose ( Interface * ip, const char * new_name, int first_frame, int last_frame );
~Pose ()
{
delete_keys ();
}
const char * name () const { return name_; }
void Add_Objects_To_List ( HWND hWnd );
void Paste_Keys ( Interface * ip );
Pose * next;
private:
void delete_keys ();
Node_Key * first_key;
char name_ [ MAX_NAME ];
int ticks_per_frame_;
};
//----------------------------------------------------------------------------
// Clipboard_Class
//----------------------------------------------------------------------------
class Clipboard_Class : public UtilityObj
{
public:
Clipboard_Class ();
~Clipboard_Class ();
void BeginEditParams(Interface *ip,IUtil *iu);
void EndEditParams(Interface *ip,IUtil *iu);
void SelectionSetChanged ( Interface * ip, IUtil * iu );
void DeleteThis() {}
void Init(HWND hWnd);
void Destroy(HWND hWnd);
void Close () { iu->CloseUtility (); }
void Create ( HWND );
void Paste ( HWND );
void Delete ( HWND );
BOOL Is_Empty () const { return first_pose == NULL; }
void Update_Object_List ( HWND hWnd );
private:
void Update_Pose_List ( HWND hWnd );
IUtil * iu;
Interface *ip;
HWND hPanel;
Pose * first_pose;
};
//----------------------------------------------------------------------------
// the_clipboard
//----------------------------------------------------------------------------
static Clipboard_Class the_clipboard;
//----------------------------------------------------------------------------
// Static data used for communicating to/from the name dialog.
//----------------------------------------------------------------------------
static char pose_name [ MAX_NAME ];
static int first_frame;
static int last_frame;
static int current_frame;
//----------------------------------------------------------------------------
// Clipboard_Desc_Class
//----------------------------------------------------------------------------
class Clipboard_Desc_Class:public ClassDesc
{
public:
int IsPublic() {return 1;}
void * Create(BOOL) {return &the_clipboard;}
const TCHAR * ClassName() {return _T("Key Clipboard");}
SClass_ID SuperClassID() {return UTILITY_CLASS_ID;}
Class_ID ClassID() {return Class_ID(0x5eb13907, 0x1d931bb4);}
const TCHAR* Category() {return _T("Westwood Tools");}
};
//----------------------------------------------------------------------------
// clipboard_desc
//----------------------------------------------------------------------------
static Clipboard_Desc_Class clipboard_desc;
//----------------------------------------------------------------------------
// ClipboardDesc
//----------------------------------------------------------------------------
ClassDesc* ClipboardDesc() {return &clipboard_desc;}
//----------------------------------------------------------------------------
// ClipboardDlgProc
//----------------------------------------------------------------------------
static BOOL CALLBACK ClipboardDlgProc
(
HWND hWnd,
UINT msg,
WPARAM wParam,
LPARAM lParam
)
{
switch (msg)
{
case WM_INITDIALOG:
the_clipboard.Init(hWnd);
break;
case WM_DESTROY:
the_clipboard.Destroy(hWnd);
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case ID_CLOSE:
the_clipboard.Close ();
break;
case ID_CREATE:
the_clipboard.Create ( hWnd );
break;
case ID_PASTE:
the_clipboard.Paste ( hWnd );
break;
case ID_DELETE:
the_clipboard.Delete ( hWnd );
break;
case IDC_POSE_LIST:
if ( HIWORD(wParam) == CBN_SELCHANGE )
the_clipboard.Update_Object_List ( hWnd );
break;
}
break;
default:
return FALSE;
}
return TRUE;
}
//----------------------------------------------------------------------------
// Pose_Name_Message_Handler
//----------------------------------------------------------------------------
static BOOL CALLBACK Pose_Name_Message_Handler
(
HWND hWnd,
UINT msg,
WPARAM wParam,
LPARAM lParam
)
{
static ISpinnerControl * first_frame_spin;
static ISpinnerControl * last_frame_spin;
switch (msg)
{
case WM_INITDIALOG:
CenterWindow ( hWnd, GetParent (hWnd) );
SetFocus ( GetDlgItem (hWnd, IDC_NAME) );
first_frame_spin = SetupIntSpinner
(
hWnd,
IDC_FIRST_FRAME_SPIN,
IDC_FIRST_FRAME_EDIT,
first_frame,
last_frame,
current_frame
);
first_frame_spin->SetResetValue ( current_frame );
last_frame_spin = SetupIntSpinner
(
hWnd,
IDC_LAST_FRAME_SPIN,
IDC_LAST_FRAME_EDIT,
first_frame,
last_frame,
current_frame
);
last_frame_spin->SetResetValue ( current_frame );
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
if ( SendDlgItemMessage ( hWnd, IDC_NAME, WM_GETTEXTLENGTH, 0, 0 ) == 0 )
EndDialog ( hWnd, 0 );
SendDlgItemMessage ( hWnd, IDC_NAME, WM_GETTEXT, MAX_NAME,
(LPARAM) pose_name );
first_frame = first_frame_spin->GetIVal ();
last_frame = last_frame_spin->GetIVal ();
EndDialog ( hWnd, 1 );
break;
case IDCANCEL:
EndDialog ( hWnd, 0 );
break;
}
return TRUE;
case CC_SPINNER_CHANGE:
// Do checking on the range spinners to make sure the low value never
// exceeds the high value.
switch ( LOWORD(wParam) )
{
case IDC_FIRST_FRAME_SPIN:
if ( first_frame_spin->GetIVal () > last_frame_spin->GetIVal () )
{
last_frame_spin->SetValue ( first_frame_spin->GetIVal (),
FALSE );
}
break;
case IDC_LAST_FRAME_SPIN:
if ( last_frame_spin->GetIVal () < first_frame_spin->GetIVal () )
{
first_frame_spin->SetValue ( last_frame_spin->GetIVal (),
FALSE );
}
break;
}
return TRUE;
}
return FALSE;
}
//----------------------------------------------------------------------------
// Clipboard_Class::Clipboard_Class
//----------------------------------------------------------------------------
Clipboard_Class::Clipboard_Class()
{
iu = NULL;
ip = NULL;
hPanel = NULL;
first_pose = NULL;
}
//----------------------------------------------------------------------------
// Clipboard_Class::~Clipboard_Class
//----------------------------------------------------------------------------
Clipboard_Class::~Clipboard_Class ()
{
while ( first_pose != NULL )
{
Pose * delete_p = first_pose;
first_pose = first_pose->next;
delete delete_p;
}
}
//----------------------------------------------------------------------------
// Clipboard_Class::BeginEditParams
//----------------------------------------------------------------------------
void Clipboard_Class::BeginEditParams(Interface *ip,IUtil *iu)
{
this->iu = iu;
this->ip = ip;
hPanel = ip->AddRollupPage
(
hInstance,
MAKEINTRESOURCE(IDD_CLIPBOARD_PANEL),
ClipboardDlgProc,
_T("Key Clipboard"),
0
);
}
//----------------------------------------------------------------------------
// Clipboard_Class::EndEditParams
//----------------------------------------------------------------------------
void Clipboard_Class::EndEditParams ( Interface *ip, IUtil *iu )
{
this->iu = NULL;
this->ip = NULL;
ip->DeleteRollupPage(hPanel);
hPanel = NULL;
}
//----------------------------------------------------------------------------
// Clipboard_Class::SelectionSetChanged
//----------------------------------------------------------------------------
void Clipboard_Class::SelectionSetChanged ( Interface * ip, IUtil * iu )
{
if ( ip->GetSelNodeCount () == 0 )
{
EnableWindow ( GetDlgItem ( hPanel, ID_CREATE ), FALSE );
}
else
{
EnableWindow ( GetDlgItem ( hPanel, ID_CREATE ), TRUE );
}
}
//----------------------------------------------------------------------------
// Clipboard_Class::Init
//----------------------------------------------------------------------------
void Clipboard_Class::Init ( HWND hWnd )
{
Update_Pose_List ( hWnd );
SendDlgItemMessage ( hWnd, IDC_POSE_LIST, CB_SETCURSEL, 0, 0 );
Update_Object_List ( hWnd );
if ( ip->GetSelNodeCount () == 0 )
{
EnableWindow ( GetDlgItem ( hWnd, ID_CREATE ), FALSE );
}
else
{
EnableWindow ( GetDlgItem ( hWnd, ID_CREATE ), TRUE );
}
if ( Is_Empty () )
{
EnableWindow ( GetDlgItem ( hWnd, ID_PASTE ), FALSE );
EnableWindow ( GetDlgItem ( hWnd, ID_DELETE ), FALSE );
}
else
{
EnableWindow ( GetDlgItem ( hWnd, ID_PASTE ), TRUE );
EnableWindow ( GetDlgItem ( hWnd, ID_DELETE ), TRUE );
}
}
//----------------------------------------------------------------------------
// Clipboard_Class::Destroy
//----------------------------------------------------------------------------
void Clipboard_Class::Destroy(HWND hWnd) {}
//----------------------------------------------------------------------------
// Clipboard_Class::Create
//----------------------------------------------------------------------------
void Clipboard_Class::Create ( HWND hWnd )
{
// Set up the data that will appear in the name dialog.
const int ticks_per_frame = GetTicksPerFrame ();
first_frame = ip->GetAnimRange ().Start () / ticks_per_frame;
last_frame = ip->GetAnimRange ().End () / ticks_per_frame;
current_frame = ip->GetTime () / ticks_per_frame;
// Put up the name dialog.
int rv = DialogBoxParam
(
hInstance,
MAKEINTRESOURCE ( IDD_POSE_NAME ),
hWnd,
Pose_Name_Message_Handler,
0
);
if ( rv == 0 )
return;
Pose * new_pose = new Pose ( ip, pose_name, first_frame, last_frame );
new_pose->next = first_pose;
first_pose = new_pose;
Update_Pose_List ( hWnd );
SendDlgItemMessage ( hWnd, IDC_POSE_LIST, CB_SETCURSEL, 0, 0 );
Update_Object_List ( hWnd );
EnableWindow ( GetDlgItem ( hWnd, ID_PASTE ), TRUE );
EnableWindow ( GetDlgItem ( hWnd, ID_DELETE ), TRUE );
}
//----------------------------------------------------------------------------
// Clipboard_Class::Paste
//----------------------------------------------------------------------------
void Clipboard_Class::Paste ( HWND hWnd )
{
SetCursor ( LoadCursor (NULL, IDC_WAIT) );
int sel = SendDlgItemMessage ( hWnd, IDC_POSE_LIST, CB_GETCURSEL, 0, 0 );
if ( sel == CB_ERR )
return;
// Find the selected pose.
Pose * p = first_pose;
while ( sel > 0 && p != NULL )
{
p = p->next;
-- sel;
}
if ( p == NULL )
return;
p->Paste_Keys ( ip );
SetCursor ( LoadCursor (NULL, IDC_ARROW) );
}
//----------------------------------------------------------------------------
// Clipboard_Class::Delete
//----------------------------------------------------------------------------
void Clipboard_Class::Delete ( HWND hWnd )
{
int sel = SendDlgItemMessage ( hWnd, IDC_POSE_LIST, CB_GETCURSEL, 0, 0 );
if ( sel != CB_ERR )
{
// Delete the pose's name from the list box.
SendDlgItemMessage ( hWnd, IDC_POSE_LIST, CB_DELETESTRING, sel, 0 );
SendDlgItemMessage ( hWnd, IDC_POSE_LIST, CB_SETCURSEL, 0, 0 );
// Find the selected pose and delete it.
Pose ** pointer_to_p = & first_pose;
Pose * p = first_pose;
while ( sel > 0 && p != NULL )
{
pointer_to_p = & p->next;
p = p->next;
-- sel;
}
if ( p != NULL )
{
*pointer_to_p = p->next;
delete p;
}
Update_Object_List ( hWnd );
}
if ( Is_Empty () )
{
EnableWindow ( GetDlgItem ( hWnd, ID_PASTE ), FALSE );
EnableWindow ( GetDlgItem ( hWnd, ID_DELETE ), FALSE );
}
}
//----------------------------------------------------------------------------
// Clipboard_Class::Update_Pose_List
//----------------------------------------------------------------------------
void Clipboard_Class::Update_Pose_List ( HWND hWnd )
{
// Delete any strings in the combo box.
SendDlgItemMessage ( hWnd, IDC_POSE_LIST, CB_RESETCONTENT, 0, 0 );
// Rebuild the combo box.
for ( Pose * p = first_pose; p != NULL; p = p->next )
{
SendDlgItemMessage ( hWnd, IDC_POSE_LIST, CB_ADDSTRING, 0,
(LPARAM) (LPCTSTR) p->name () );
}
}
//----------------------------------------------------------------------------
// Clipboard_Class::Update_Object_List
//----------------------------------------------------------------------------
void Clipboard_Class::Update_Object_List ( HWND hWnd )
{
// Delete any strings in the combo box.
SendDlgItemMessage ( hWnd, IDC_OBJECT_LIST, LB_RESETCONTENT, 0, 0 );
// Add strings from the objects in the currently selected pose.
int sel = SendDlgItemMessage ( hWnd, IDC_POSE_LIST, CB_GETCURSEL, 0, 0 );
if ( sel != CB_ERR )
{
Pose * p = first_pose;
while ( sel > 0 && p != NULL )
{
p = p->next;
-- sel;
}
if ( p != NULL )
{
p->Add_Objects_To_List ( hWnd );
}
}
}
//----------------------------------------------------------------------------
// Pose::Pose
//----------------------------------------------------------------------------
Pose::Pose ( Interface * ip, const char * name, int first_frame, int last_frame ):
first_key (NULL),
next (NULL),
ticks_per_frame_ (GetTicksPerFrame ())
{
int number_of_nodes = ip->GetSelNodeCount ();
int nr_frames = (last_frame - first_frame) + 1;
TimeValue start_time = first_frame * ticks_per_frame_;
char frame_count [ 16 ];
sprintf ( frame_count, " (%d)", nr_frames );
strncpy ( name_, name, MAX_NAME - 6 );
strncat ( name_, frame_count, 5 );
name_ [MAX_NAME - 1] = '\0';
for ( int i = 0; i < number_of_nodes; ++ i )
{
// Get the inode.
INode * inode = ip->GetSelNode ( i );
Control * tm_controller = inode->GetTMController ();
if ( tm_controller == NULL )
continue;
Node_Key * new_key = new Node_Key
(
nr_frames,
inode->GetName (),
first_key
);
first_key = new_key;
// Store the position and rotation keys.
Point3 node_position ( 0.0, 0.0, 0.0 );
Quat node_orientation ( 0.0, 0.0, 0.0, 1.0 );
for ( int frame = 0; frame < nr_frames; ++ frame )
{
TimeValue key_time = frame * ticks_per_frame_ + start_time;
Control * c;
// Copy rotation keys.
c = tm_controller->GetRotationController ();
if ( c != NULL )
c->GetValue ( key_time, & node_orientation, FOREVER );
else
node_orientation = Quat (0.0, 0.0, 0.0, 1.0);
// Copy position keys.
c = tm_controller->GetPositionController ();
if ( c != NULL )
c->GetValue ( key_time, & node_position, FOREVER );
else
node_position = Point3 (0.0, 0.0, 0.0);
new_key->set_position ( frame, node_position );
new_key->set_orientation ( frame, node_orientation );
}
}
}
//----------------------------------------------------------------------------
// Pose::Paste_Keys
//----------------------------------------------------------------------------
void Pose::Paste_Keys ( Interface * ip )
{
TimeValue current_time = ip->GetTime ();
theHold.Begin ();
SuspendAnimate ();
AnimateOn ();
Node_Key * p = first_key;
while ( p != NULL )
{
INode * inode = ip->GetINodeByName ( p->name () );
if ( inode != NULL )
{
Control * tm_controller = inode->GetTMController ();
if ( tm_controller != NULL )
{
for ( int frame = 0; frame < p->nr_frames (); ++ frame )
{
TimeValue key_time = current_time + frame * ticks_per_frame_;
Control * c;
// Paste rotation keys.
c = tm_controller->GetRotationController ();
if ( c != NULL )
{
c->EnableORTs (FALSE);
Quat orientation = p->orientation (frame);
c->SetValue ( key_time, & orientation );
c->EnableORTs (TRUE);
}
// Paste position keys.
c = tm_controller->GetPositionController ();
if ( c != NULL )
{
c->EnableORTs (FALSE);
Point3 position = p->position (frame);
c->SetValue ( key_time, & position );
c->EnableORTs (TRUE);
}
}
}
}
p = p->next ();
}
ResumeAnimate ();
TSTR undostr;
undostr.printf ( "Paste Keys" );
theHold.Accept ( undostr );
ip->RedrawViews ( current_time );
}
//----------------------------------------------------------------------------
// Pose::delete_keys
//----------------------------------------------------------------------------
void Pose::delete_keys ()
{
while ( first_key != NULL )
{
Node_Key * delete_p = first_key;
first_key = first_key->next ();
delete delete_p;
}
}
//----------------------------------------------------------------------------
// Pose::Add_Objects_To_List
//----------------------------------------------------------------------------
void Pose::Add_Objects_To_List ( HWND hWnd )
{
for ( Node_Key * k = first_key; k != NULL; k = k->next () )
{
SendDlgItemMessage ( hWnd, IDC_OBJECT_LIST, LB_ADDSTRING, 0,
(LPARAM) (LPCTSTR) k->name () );
}
}

View File

@@ -0,0 +1,8 @@
LIBRARY clipbord
EXPORTS
LibDescription @1
LibNumberClasses @2
LibClassDesc @3
LibVersion @4
SECTIONS
.data READ WRITE

View File

@@ -0,0 +1,130 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#define APSTUDIO_HIDDEN_SYMBOLS
#include "windows.h"
#undef APSTUDIO_HIDDEN_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
"#include ""windows.h""\r\n"
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
"\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_CLIPBOARD_PANEL DIALOG DISCARDABLE 0, 0, 108, 150
STYLE WS_CHILD | WS_VISIBLE
FONT 8, "MS Sans Serif"
BEGIN
PUSHBUTTON "Close",ID_CLOSE,58,132,46,13
LTEXT "Animation:",IDC_ANIMATION,4,2,101,8
COMBOBOX IDC_POSE_LIST,4,12,101,61,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP
LTEXT "Objects in animation:",IDC_STATIC,4,27,101,8
LISTBOX IDC_OBJECT_LIST,3,38,101,44,LBS_SORT | LBS_NOSEL |
WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Create...",ID_CREATE,4,84,100,13
PUSHBUTTON "Paste",ID_PASTE,4,100,100,13
PUSHBUTTON "Delete",ID_DELETE,4,116,100,13
LTEXT "James McNeill",IDC_STATIC,4,134,49,8
END
IDD_POSE_NAME DIALOG DISCARDABLE 0, 0, 186, 63
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Pose Name"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Name:",IDC_STATIC,7,7,23,10
EDITTEXT IDC_NAME,31,7,148,12,ES_AUTOHSCROLL
LTEXT "First frame:",IDC_STATIC,7,26,37,10
CONTROL "",IDC_FIRST_FRAME_EDIT,"CustEdit",WS_TABSTOP,47,25,28,
10
CONTROL "",IDC_FIRST_FRAME_SPIN,"SpinnerControl",0x0,75,25,10,10
LTEXT "Last frame:",IDC_STATIC,99,25,37,10
CONTROL "",IDC_LAST_FRAME_EDIT,"CustEdit",WS_TABSTOP,141,25,28,
10
CONTROL "",IDC_LAST_FRAME_SPIN,"SpinnerControl",0x0,169,25,10,10
PUSHBUTTON "Cancel",IDCANCEL,74,42,50,14
DEFPUSHBUTTON "OK",IDOK,129,42,50,14
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_POSE_NAME, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 179
TOPMARGIN, 7
BOTTOMMARGIN, 56
END
END
#endif // APSTUDIO_INVOKED
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@@ -0,0 +1,124 @@
# Microsoft Developer Studio Project File - Name="Clipbord" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=Clipbord - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "Clipbord.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "Clipbord.mak" CFG="Clipbord - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Clipbord - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "Clipbord - Win32 Hybrid" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/Commando/Code/Tools/Clipbord", PIDCAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "Clipbord - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\Release"
# PROP BASE Intermediate_Dir ".\Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ".\Release"
# PROP Intermediate_Dir ".\Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "d:\3dsmax2\maxsdk\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comctl32.lib core.lib geom.lib maxutil.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release\clipbord.dlu" /libpath:"d:\3dsmax2\maxsdk\lib"
!ELSEIF "$(CFG)" == "Clipbord - Win32 Hybrid"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Hybrid"
# PROP BASE Intermediate_Dir "Hybrid"
# PROP BASE Ignore_Export_Lib 0
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Hybrid"
# PROP Intermediate_Dir "Hybrid"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "d:\3dsmax2\maxsdk\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "d:\3dsmax2\maxsdk\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib core.lib geom.lib util.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release\clipbord.dlu" /libpath:"d:\3dsmax2\maxsdk\lib"
# ADD LINK32 odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comctl32.lib core.lib geom.lib maxutil.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"Hybrid\clipbord.dlu" /libpath:"d:\3dsmax2\maxsdk\lib"
!ENDIF
# Begin Target
# Name "Clipbord - Win32 Release"
# Name "Clipbord - Win32 Hybrid"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
# Begin Source File
SOURCE=.\Clipboard.cpp
# End Source File
# Begin Source File
SOURCE=.\Clipboard.def
# End Source File
# Begin Source File
SOURCE=.\Clipboard.rc
# End Source File
# Begin Source File
SOURCE=.\DLLMain.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# Begin Source File
SOURCE=.\clipboard.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@@ -0,0 +1,85 @@
/*
** Command & Conquer Renegade(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/>.
*/
#include "clipboard.h"
HINSTANCE hInstance;
static BOOL controlsInit = FALSE;
#define DLLEXPORT __declspec(dllexport)
//----------------------------------------------------------------------------
// DllMain
//----------------------------------------------------------------------------
BOOL WINAPI DllMain
(
HINSTANCE hinstDLL,
ULONG,
LPVOID
)
{
hInstance = hinstDLL;
if ( ! controlsInit )
{
controlsInit = TRUE;
InitCustomControls(hInstance); // jaguar controls
InitCommonControls(); // initialize Chicago controls
}
return TRUE;
}
//----------------------------------------------------------------------------
// LibDescription
//----------------------------------------------------------------------------
DLLEXPORT const TCHAR * LibDescription()
{
return _T("Animation Key Clipboard Utility");
}
//----------------------------------------------------------------------------
// LibNumberClasses
//----------------------------------------------------------------------------
DLLEXPORT int LibNumberClasses()
{
return 1;
}
//----------------------------------------------------------------------------
// LibClassDesc
//----------------------------------------------------------------------------
DLLEXPORT ClassDesc * LibClassDesc(int i)
{
return ClipboardDesc ();
}
//----------------------------------------------------------------------------
// LibVersion
//----------------------------------------------------------------------------
DLLEXPORT ULONG LibVersion()
{
return VERSION_3DSMAX;
}

View File

@@ -0,0 +1,29 @@
/*
** Command & Conquer Renegade(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 _BLENDER_H
#define _BLENDER_H
#include "Max.h"
#include "resource.h"
extern ClassDesc* ClipboardDesc ();
extern HINSTANCE hInstance;
#endif

View File

@@ -0,0 +1,92 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by Clipboard.rc
//
#define ID_APPLY 2
#define IDD_COLORCLIP_PANEL 101
#define IDD_COLORCLIP_FLOATER 102
#define IDD_ASCIIOUT_PANEL 103
#define IDD_BLENDER_PANEL 103
#define IDD_CLIPBOARD_PANEL 103
#define IDD_UTILTEST_PANEL 104
#define IDD_POSE_NAME 104
#define IDD_APPDATA_PANEL 105
#define IDC_COLORCLIP_NEWFLOAT 1000
#define IDC_ASCIIOUT_PICK 1002
#define IDC_TESTER_MAKEOBJECT 1003
#define IDC_TESTER_MAKEGROUP 1004
#define IDC_APPDATA_EDIT 1004
#define IDC_TESTER_GROUPOBJS 1005
#define IDC_APPDATA_GET 1005
#define IDC_TESTER_OPENGROUP 1006
#define IDC_APPDATA_PUT 1006
#define IDC_TESTER_CLOSEGROUP 1007
#define IDC_TESTER_EXPLODEGROUP 1008
#define IDC_TESTER_UNGROUP 1009
#define IDC_TESTER_SAVETOFILE 1010
#define IDC_TESTER_LOADFROMFILE 1011
#define IDC_TESTER_SETENV 1012
#define IDC_TESTER_SETWAV 1013
#define IDS_TESTER_ANIMON 1014
#define IDS_TESTER_ANIMOFF 1015
#define ID_CLOSE 1015
#define IDS_TESTER_RENDER 1016
#define IDC_POSITION_CHECK 1016
#define ID_CREATE 1016
#define IDC_ROTATION_CHECK 1017
#define IDC_POSE_LIST 1017
#define ID_PASTE 1018
#define IDC_OBJECT_LIST 1019
#define IDC_NAME 1020
#define ID_DELETE 1021
#define IDC_ANIMATION 1022
#define IDC_KEY_EDIT 1026
#define IDC_FIRST_FRAME_EDIT 1026
#define IDC_MATCH_EDIT 1027
#define IDC_LAST_FRAME_EDIT 1027
#define IDC_POS_LOW_EDIT 1028
#define IDC_POS_HIGH_EDIT 1029
#define IDC_ROT_LOW_EDIT 1030
#define IDC_ROT_HIGH_EDIT 1031
#define IDC_COLOR_SWATCH1 1039
#define IDC_COLOR_SWATCH2 1040
#define IDC_COLOR_SWATCH3 1041
#define IDC_COLOR_SWATCH4 1042
#define IDC_COLOR_SWATCH5 1043
#define IDC_COLOR_SWATCH6 1044
#define IDC_COLOR_SWATCH7 1045
#define IDC_COLOR_SWATCH8 1046
#define IDC_KEY_SPIN 1046
#define IDC_FIRST_FRAME_SPIN 1046
#define IDC_COLOR_SWATCH9 1047
#define IDC_MATCH_SPIN 1047
#define IDC_LAST_FRAME_SPIN 1047
#define IDC_COLOR_SWATCH10 1048
#define IDC_POS_LOW_SPIN 1048
#define IDC_COLOR_SWATCH11 1049
#define IDC_POS_HIGH_SPIN 1049
#define IDC_COLOR_SWATCH12 1050
#define IDC_ROT_LOW_SPIN 1050
#define IDC_ROT_HIGH_SPIN 1051
#define IDC_APPDATA_SLOTSPIN 1202
#define IDC_APPDATA_SLOT 1203
#define IDC_APPDATA_SLOTLABEL 1204
#define IDS_RB_ASCIIOBJECTOUT 30619
#define IDS_RB_ASCIIFILES 30620
#define IDS_RB_SAVEOBJECT 30621
#define IDS_RB_COLORCLIPBOARD 30622
#define IDS_RB_COLORNUM 30623
#define IDS_RB_APPDATATEST 30624
#define IDS_RB_FILEEXISTS 30625
#define IDC_STATIC -1
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 105
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1023
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@@ -0,0 +1,90 @@
/*
** Command & Conquer Renegade(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/>.
*/
// CommandoUpdate.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "CommandoUpdate.h"
#include "CommandoUpdateDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CCommandoUpdateApp
BEGIN_MESSAGE_MAP(CCommandoUpdateApp, CWinApp)
//{{AFX_MSG_MAP(CCommandoUpdateApp)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCommandoUpdateApp construction
CCommandoUpdateApp::CCommandoUpdateApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
/////////////////////////////////////////////////////////////////////////////
// The one and only CCommandoUpdateApp object
CCommandoUpdateApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CCommandoUpdateApp initialization
BOOL CCommandoUpdateApp::InitInstance()
{
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
CCommandoUpdateDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}

View File

@@ -0,0 +1,164 @@
# Microsoft Developer Studio Project File - Name="CommandoUpdate" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
CFG=CommandoUpdate - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "CommandoUpdate.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "CommandoUpdate.mak" CFG="CommandoUpdate - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "CommandoUpdate - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "CommandoUpdate - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/Commando/Code/Tools/CommandoUpdate", BFWBAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "CommandoUpdate - Win32 Release"
# PROP BASE Use_MFC 5
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 5
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Yu"stdafx.h" /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386
# ADD LINK32 /nologo /subsystem:windows /machine:I386 /out:"Release/RenegadeUpdate.exe"
!ELSEIF "$(CFG)" == "CommandoUpdate - Win32 Debug"
# PROP BASE Use_MFC 5
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 5
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /Yu"stdafx.h" /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386
# ADD LINK32 /nologo /subsystem:windows /debug /machine:I386 /out:"Debug/RenegadeUpdate.exe"
!ENDIF
# Begin Target
# Name "CommandoUpdate - Win32 Release"
# Name "CommandoUpdate - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\CommandoUpdate.cpp
# End Source File
# Begin Source File
SOURCE=.\CommandoUpdate.rc
# End Source File
# Begin Source File
SOURCE=.\CommandoUpdateDlg.cpp
# End Source File
# Begin Source File
SOURCE=.\FileCopyDialog.cpp
# End Source File
# Begin Source File
SOURCE=.\StdAfx.cpp
# ADD CPP /Yc"stdafx.h"
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\CommandoUpdate.h
# End Source File
# Begin Source File
SOURCE=.\CommandoUpdateDlg.h
# End Source File
# Begin Source File
SOURCE=.\FileCopyDialog.h
# End Source File
# Begin Source File
SOURCE=.\Resource.h
# End Source File
# Begin Source File
SOURCE=.\StdAfx.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# Begin Source File
SOURCE=.\res\CommandoUpdate.ico
# End Source File
# Begin Source File
SOURCE=.\res\CommandoUpdate.rc2
# End Source File
# Begin Source File
SOURCE=.\res\icon1.ico
# End Source File
# End Group
# Begin Source File
SOURCE=.\res\Filecopy.avi
# End Source File
# Begin Source File
SOURCE=.\ReadMe.txt
# End Source File
# End Target
# End Project

View File

@@ -0,0 +1,67 @@
/*
** Command & Conquer Renegade(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/>.
*/
// CommandoUpdate.h : main header file for the COMMANDOUPDATE application
//
#if !defined(AFX_COMMANDOUPDATE_H__4305AC4E_1EAB_11D3_A038_00104B791122__INCLUDED_)
#define AFX_COMMANDOUPDATE_H__4305AC4E_1EAB_11D3_A038_00104B791122__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif
#include "resource.h" // main symbols
/////////////////////////////////////////////////////////////////////////////
// CCommandoUpdateApp:
// See CommandoUpdate.cpp for the implementation of this class
//
class CCommandoUpdateApp : public CWinApp
{
public:
CCommandoUpdateApp();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CCommandoUpdateApp)
public:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL
// Implementation
//{{AFX_MSG(CCommandoUpdateApp)
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_COMMANDOUPDATE_H__4305AC4E_1EAB_11D3_A038_00104B791122__INCLUDED_)

View File

@@ -0,0 +1,264 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"#define _AFX_NO_SPLITTER_RESOURCES\r\n"
"#define _AFX_NO_OLE_RESOURCES\r\n"
"#define _AFX_NO_TRACKER_RESOURCES\r\n"
"#define _AFX_NO_PROPERTY_RESOURCES\r\n"
"\r\n"
"#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
"#ifdef _WIN32\r\n"
"LANGUAGE 9, 1\r\n"
"#pragma code_page(1252)\r\n"
"#endif //_WIN32\r\n"
"#include ""res\\CommandoUpdate.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
"#include ""afxres.rc"" // Standard components\r\n"
"#endif\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDR_MAINFRAME ICON DISCARDABLE "res\\CommandoUpdate.ico"
IDI_COPY ICON DISCARDABLE "res\\icon1.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_COMMANDOUPDATE_DIALOG DIALOGEX 0, 0, 332, 282
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "Renegade Update"
FONT 8, "MS Sans Serif"
BEGIN
ICON IDI_COPY,IDC_STATIC,7,7,21,20
LTEXT "Select the Renegade applications you wish to update on your machine. Note: If you select 'Clean' all files in the application directory WILL BE DELETED.",
IDC_STATIC,42,7,283,26
GROUPBOX "&Tools",IDC_STATIC,7,39,318,95
CONTROL "&Level Editor",IDC_EDITOR_CHECK,"Button",
BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,16,56,62,10
CONTROL "Clean",IDC_EDITOR_CLEAN_CHECK,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,90,56,34,10
PUSHBUTTON "<directory>",IDC_EDITOR_DIR_BUTTON,131,52,179,14
CONTROL "Ligh&tmap",IDC_LIGHTMAP_CHECK,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,16,75,62,10
CONTROL "Clean",IDC_LIGHTMAP_CLEAN_CHECK,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,90,75,34,10
PUSHBUTTON "<directory>",IDC_LIGHTMAP_DIR_BUTTON,131,71,179,14
CONTROL "&Vis Farm Slave",IDC_VISFARM_CHECK,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,16,94,62,10
CONTROL "Clean",IDC_VISFARM_CLEAN_CHECK,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,90,94,34,10
PUSHBUTTON "<directory>",IDC_VISFARM_DIR_BUTTON,131,91,179,14
CONTROL "&Mix Viewer",IDC_MIXVIEW_CHECK,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,16,114,62,10
CONTROL "Clean",IDC_MIXVIEW_CLEAN_CHECK,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,90,114,34,10
PUSHBUTTON "<directory>",IDC_MIXVIEW_DIR_BUTTON,131,111,179,14
GROUPBOX "&Game",IDC_STATIC,7,139,318,68
GROUPBOX "M&ultiplay",IDC_STATIC,7,214,318,38
CONTROL "Multiplay &Build",IDC_MULTIPLAY_CHECK,"Button",
BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,16,231,68,10
CONTROL "Clean",IDC_MULTIPLAY_CLEAN_CHECK,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,90,231,34,10
PUSHBUTTON "<directory>",IDC_MULTIPLAY_DIR_BUTTON,131,227,179,14
DEFPUSHBUTTON "OK",IDOK,74,261,50,14,WS_GROUP
PUSHBUTTON "Cancel",IDCANCEL,140,261,50,14
PUSHBUTTON "Defaults",IDC_DEFAULTS,206,261,50,14
CONTROL "&Engine",IDC_GAME_CHECK,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,16,154,46,10
CONTROL "Le&vels",IDC_GAME_LEVELS_CHECK,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,16,172,43,10
CONTROL "M&ovies",IDC_GAME_MOVIES_CHECK,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,16,189,43,10
CONTROL "Clean",IDC_GAME_CLEAN_CHECK,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,90,161,34,10
PUSHBUTTON "<directory>",IDC_GAME_DIR_BUTTON,131,157,179,14
END
IDD_FILE_COPY DIALOGEX 0, 0, 210, 79
STYLE DS_MODALFRAME | DS_SETFOREGROUND | WS_POPUP | WS_VISIBLE | WS_CAPTION
EXSTYLE WS_EX_APPWINDOW
CAPTION "Updating Application..."
FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN
CONTROL "Animate1",IDC_ANIMATE_CTRL,"SysAnimate32",ACS_CENTER |
ACS_TRANSPARENT | ACS_AUTOPLAY | WS_TABSTOP,7,23,196,34
LTEXT "Comparing directories...",IDC_FILENAME_TEXT,7,60,196,8
LTEXT "Application:",IDC_CURRENT_APP,7,7,196,8
END
IDD_DIR_SELECT_DIALOG DIALOG DISCARDABLE 36, 24, 268, 134
STYLE DS_MODALFRAME | DS_3DLOOK | DS_CONTEXTHELP | WS_POPUP | WS_CAPTION |
WS_SYSMENU
CAPTION "Open"
FONT 8, "MS Shell Dlg"
BEGIN
LTEXT "&Folder Name:",1090,6,6,76,9
EDITTEXT 1152,6,16,90,12,ES_AUTOHSCROLL | ES_OEMCONVERT
LTEXT "",1088,110,16,96,9,SS_NOPREFIX
LISTBOX 1121,110,32,96,68,LBS_SORT | LBS_OWNERDRAWFIXED |
LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL |
WS_TABSTOP
LTEXT "Dri&ves:",1091,110,104,96,9
COMBOBOX 1137,110,114,96,68,CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED |
CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_VSCROLL |
WS_TABSTOP
DEFPUSHBUTTON "OK",IDOK,212,6,50,14,WS_GROUP
PUSHBUTTON "Cancel",IDCANCEL,212,24,50,14,WS_GROUP
PUSHBUTTON "&Help",1038,212,46,50,14,WS_GROUP
END
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904B0"
BEGIN
VALUE "CompanyName", "\0"
VALUE "FileDescription", "CommandoUpdate MFC Application\0"
VALUE "FileVersion", "1, 0, 0, 1\0"
VALUE "InternalName", "CommandoUpdate\0"
VALUE "LegalCopyright", "Copyright (C) 1999\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "CommandoUpdate.EXE\0"
VALUE "ProductName", "CommandoUpdate Application\0"
VALUE "ProductVersion", "1, 0, 0, 1\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // !_MAC
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_COMMANDOUPDATE_DIALOG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 325
TOPMARGIN, 7
BOTTOMMARGIN, 275
END
IDD_FILE_COPY, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 203
TOPMARGIN, 7
BOTTOMMARGIN, 72
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// AVI
//
IDR_FILECOPY_AVI AVI DISCARDABLE "res\\Filecopy.avi"
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#define _AFX_NO_SPLITTER_RESOURCES
#define _AFX_NO_OLE_RESOURCES
#define _AFX_NO_TRACKER_RESOURCES
#define _AFX_NO_PROPERTY_RESOURCES
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE 9, 1
#pragma code_page(1252)
#endif //_WIN32
#include "res\CommandoUpdate.rc2" // non-Microsoft Visual C++ edited resources
#include "afxres.rc" // Standard components
#endif
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@@ -0,0 +1,974 @@
/*
** Command & Conquer Renegade(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/>.
*/
// CommandoUpdateDlg.cpp : implementation file
//
#include "stdafx.h"
#include "CommandoUpdate.h"
#include "CommandoUpdateDlg.h"
#include "FileCopyDialog.H"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
//
// Data Tables
//
/////////////////////////////////////////////////////////////////////////////
typedef struct
{
FileCopyDialogClass *dialog;
CString src_dir;
CString dest_dir;
bool is_recursive;
bool result;
} UPDATE_INFO;
typedef struct
{
LPCTSTR title;
LPCTSTR src;
LPCTSTR default_dir;
LPCTSTR reg_key;
UINT ctrl_id;
UINT clean_ctrl_id;
UINT dir_ctrl_id;
bool clean_default;
bool is_recursive;
} APP_INFO;
typedef enum
{
APP_EDITOR = 0,
APP_GAME_ENGINE,
APP_GAME_LEVELS,
APP_GAME_MOVIES,
APP_LIGHTMAP,
APP_VISFARM,
APP_MIXVIEW,
APP_MULTIPLAY,
APP_MAX,
} APPLICATION_IDS;
const APP_INFO APPLICATIONS[APP_MAX] =
{
{ "Level Editor", "\\\\mobius\\project7\\projects\\renegade\\programming\\tools\\level edit", "c:\\commando\\leveledit", "LevelEdit\\Install", IDC_EDITOR_CHECK, IDC_EDITOR_CLEAN_CHECK, IDC_EDITOR_DIR_BUTTON, true, false },
{ "Game Engine", "\\\\havoc\\rock\\projects\\renegade\\asset management\\current build", "c:\\commando\\run", "Commando\\Install", IDC_GAME_CHECK, IDC_GAME_CLEAN_CHECK, IDC_GAME_DIR_BUTTON, false, true },
{ "Game Levels", "\\\\havoc\\rock\\projects\\renegade\\asset management\\current levels", "c:\\commando\\run", "Commando\\Install", IDC_GAME_LEVELS_CHECK, IDC_GAME_CLEAN_CHECK, IDC_GAME_DIR_BUTTON, false, true },
{ "Game Movies", "\\\\havoc\\rock\\projects\\renegade\\asset management\\cinematics", "c:\\commando\\run", "Commando\\Install", IDC_GAME_MOVIES_CHECK, IDC_GAME_CLEAN_CHECK, IDC_GAME_DIR_BUTTON, false, true },
{ "Lightmap", "\\\\mobius\\project7\\projects\\renegade\\programming\\tools\\lightmap", "c:\\commando\\lightmap", "LightMap\\Install", IDC_LIGHTMAP_CHECK, IDC_LIGHTMAP_CLEAN_CHECK, IDC_LIGHTMAP_DIR_BUTTON, true, false },
{ "Vis Farm", "\\\\mobius\\project7\\projects\\renegade\\programming\\tools\\vis farm", "c:\\commando\\vis farm", "VisFarm\\Install", IDC_VISFARM_CHECK, IDC_VISFARM_CLEAN_CHECK, IDC_VISFARM_DIR_BUTTON, false, false },
{ "Mix Viewer", "\\\\mobius\\project7\\projects\\renegade\\programming\\tools\\mixview", "c:\\commando\\mixview", "MixView\\Install", IDC_MIXVIEW_CHECK, IDC_MIXVIEW_CLEAN_CHECK, IDC_MIXVIEW_DIR_BUTTON, false, false },
{ "Multiplay", "\\\\tanya\\game\\projects\\renegade\\run", "c:\\renegade\\mplay", "MPlay\\Install", IDC_MULTIPLAY_CHECK, IDC_MULTIPLAY_CLEAN_CHECK, IDC_MULTIPLAY_DIR_BUTTON, false, true }
};
const char * const INSTALL_REG_VALUE = "Path";
const char * const DATA_SUB_DIR = "\\Data";
const char * const MOVIE_SUB_DIR = "\\Data\\Movies";
const char * const SRDLL_SUB_DIR = "\\SrDLL";
/////////////////////////////////////////////////////////////////////////////
//
// Local prototypes
//
/////////////////////////////////////////////////////////////////////////////
bool Update_App (CWnd *parent_wnd, LPCTSTR title, LPCTSTR src_dir, LPCTSTR dest_dir, bool is_recursive);
bool Clean_Directory (LPCTSTR local_dir, bool is_recursive);
bool Get_Install_Directory (HWND hparent_wnd, LPCTSTR title, CString &folder);
bool Delete_File (LPCTSTR filename);
/////////////////////////////////////////////////////////////////////////////
// CCommandoUpdateDlg dialog
CCommandoUpdateDlg::CCommandoUpdateDlg(CWnd* pParent /*=NULL*/)
: CDialog(CCommandoUpdateDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CCommandoUpdateDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CCommandoUpdateDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CCommandoUpdateDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CCommandoUpdateDlg, CDialog)
//{{AFX_MSG_MAP(CCommandoUpdateDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_DEFAULTS, OnDefaults)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCommandoUpdateDlg message handlers
BOOL CCommandoUpdateDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
//
// Check/uncheck the applications by default
//
for (int index = 0; index < APP_MAX; index ++) {
const APP_INFO &app_info = APPLICATIONS[index];
HKEY hreg_key = NULL;
CString reg_key_name;
reg_key_name.Format ("Software\\Westwood Studios\\%s", app_info.reg_key);
TCHAR path[MAX_PATH] = { 0 };
//
// Is this application installed?
//
if (::RegOpenKeyEx (HKEY_CURRENT_USER, reg_key_name, 0L, KEY_READ, &hreg_key) == ERROR_SUCCESS) {
SendDlgItemMessage (app_info.ctrl_id, BM_SETCHECK, (WPARAM)TRUE);
//
// Read the installation directory from the registry
//
DWORD size = sizeof (path);
::RegQueryValueEx (hreg_key, INSTALL_REG_VALUE, 0L, NULL, (BYTE *)path, &size);
::RegCloseKey (hreg_key);
} else {
::EnableWindow (::GetDlgItem (m_hWnd, app_info.clean_ctrl_id), false);
::EnableWindow (::GetDlgItem (m_hWnd, app_info.dir_ctrl_id), false);
}
//
// Set the text of the install directory buttons
//
if (path[0] == 0) {
::lstrcpy (path, app_info.default_dir);
}
SetDlgItemText (app_info.dir_ctrl_id, path);
//
// Check the clean option (by default) if necessary
//
if (app_info.clean_default) {
SendDlgItemMessage (app_info.clean_ctrl_id, BM_SETCHECK, (WPARAM)TRUE);
}
}
return TRUE;
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CCommandoUpdateDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CCommandoUpdateDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
//////////////////////////////////////////////////////////////////////////////////
//
// OnOK
//
//////////////////////////////////////////////////////////////////////////////////
void
CCommandoUpdateDlg::OnOK (void)
{
//
// Install/upgrade each application
//
bool success = true;
for (int index = 0; (index < APP_MAX) && success; index ++) {
const APP_INFO &app_info = APPLICATIONS[index];
//
// Does the user want to install this application?
//
if (SendDlgItemMessage (app_info.ctrl_id, BM_GETCHECK) == 1) {
HKEY hreg_key = NULL;
CString reg_key_name;
reg_key_name.Format ("Software\\Westwood Studios\\%s", app_info.reg_key);
//
// Get the path where this application is installed
//
CString local_path;
GetDlgItemText (app_info.dir_ctrl_id, local_path);
// Ensure the path doesn't contain a terminating delimiter
if (local_path[::lstrlen (local_path) - 1] == '\\') {
local_path.Delete (::lstrlen (local_path) - 1, 1);
}
if (success) {
CWaitCursor wait_cursor;
//
// Clean the old version if necessary
//
if (SendDlgItemMessage (app_info.clean_ctrl_id, BM_GETCHECK) == 1) {
//
// Special case the "game engine only" option. Note: we only want
// to clean the data subdir if we aren't cleaning the game directory
//
if (index == APP_GAME_LEVELS || index == APP_GAME_MOVIES) {
if (SendDlgItemMessage (APPLICATIONS[APP_GAME_ENGINE].ctrl_id, BM_GETCHECK) == 0) {
if (index == APP_GAME_MOVIES) {
CString data_dir = local_path + MOVIE_SUB_DIR;
::Clean_Directory (data_dir, app_info.is_recursive);
} else {
CString data_dir = local_path + DATA_SUB_DIR;
::Clean_Directory (data_dir, app_info.is_recursive);
}
}
} else {
::Clean_Directory (local_path, app_info.is_recursive);
}
}
//
// Special case the "game levels" option
//
if (index == APP_GAME_LEVELS) {
CString data_dir = local_path + DATA_SUB_DIR;
CString src_data_dir = app_info.src;
CString data_title = "Game Levels";
success &= ::Update_App (this, data_title, src_data_dir, data_dir, app_info.is_recursive);
} else if (index == APP_GAME_MOVIES) {
CString data_dir = local_path + MOVIE_SUB_DIR;
CString src_data_dir = app_info.src;
CString data_title = "Game Movies";
success &= ::Update_App (this, data_title, src_data_dir, data_dir, app_info.is_recursive);
} else {
//
// Update the application's files
//
success &= ::Update_App (this, app_info.title, app_info.src, local_path, app_info.is_recursive);
}
//
// Write the app's installation dir to the registry if we
// installed it correctly.
//
if (success) {
success &= (::RegCreateKeyEx ( HKEY_CURRENT_USER,
reg_key_name,
0L,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hreg_key,
NULL) == ERROR_SUCCESS);
if (success) {
::RegSetValueEx ( hreg_key,
INSTALL_REG_VALUE,
0L,
REG_SZ,
(BYTE *)(LPCTSTR)local_path,
local_path.GetLength () + 1);
::RegCloseKey (hreg_key);
}
}
}
}
}
CDialog::OnOK ();
return ;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Get_Install_Directory
//
//////////////////////////////////////////////////////////////////////////////////
bool
Get_Install_Directory (HWND hparent_wnd, LPCTSTR title, CString &folder)
{
bool retval = false;
// Browse for the folder
BROWSEINFO browse_info = { 0 };
browse_info.hwndOwner = hparent_wnd;
browse_info.lpszTitle = title;
browse_info.ulFlags = BIF_RETURNONLYFSDIRS;
LPITEMIDLIST pidl = ::SHBrowseForFolder (&browse_info);
if (pidl != NULL) {
// Convert the 'PIDL' into a string
char path[MAX_PATH];
retval = (::SHGetPathFromIDList (pidl, path) == TRUE);
if (retval) {
folder = path;
}
// Free the 'PIDL'
LPMALLOC pmalloc = NULL;
if (SUCCEEDED (::SHGetMalloc (&pmalloc))) {
pmalloc->Free (pidl);
pmalloc->Release ();
}
}
//CFileDialog dialog (TRUE, ".pth", "test.pth", OFN_PATHMUSTEXIST | OFN_EXPLORER, "files *.*|*.*||", CWnd::FromHandle(hparent_wnd));
//CFileDialog dialog (TRUE, ".pth", "test.pth", OFN_PATHMUSTEXIST | OFN_EXPLORER | OFN_ENABLETEMPLATEHANDLE, "files *.*|*.*||", CWnd::FromHandle(hparent_wnd));
//dialog.m_ofn.lpTemplateName = MAKEINTRESOURCE (IDD_DIR_SELECT_DIALOG);
//dialog.m_ofn.hInstance = ::AfxGetInstanceHandle ();
//HRSRC resource = ::FindResource (::AfxGetInstanceHandle (), MAKEINTRESOURCE (IDD_DIR_SELECT_DIALOG), RT_DIALOG);
//dialog.m_ofn.hInstance = (HINSTANCE)::LoadResource (::AfxGetInstanceHandle (), resource);
//dialog.DoModal ();
/*TCHAR path[MAX_PATH] = { 0 };
OPENFILENAME ofn = { 0 };
ofn.lStructSize = sizeof (ofn);
ofn.Flags = OFN_PATHMUSTEXIST | OFN_ENABLETEMPLATE;
ofn.hInstance = ::AfxGetInstanceHandle ();
ofn.lpTemplateName = MAKEINTRESOURCE (IDD_DIR_SELECT_DIALOG);
ofn.hwndOwner = hparent_wnd;
ofn.lpstrFile = path;
ofn.nMaxFile = sizeof (path);
GetOpenFileName (&ofn);
::CommDlgExtendedError ();*/
//retval = (dialog.DoModal () == IDOK);
// Return the true/false result code
return retval;
}
////////////////////////////////////////////////////////////////////////////
//
// Strip_Filename_From_Path
//
////////////////////////////////////////////////////////////////////////////
CString
Strip_Filename_From_Path (LPCTSTR path)
{
// Copy the path to a buffer we can modify
TCHAR temp_path[MAX_PATH];
::lstrcpy (temp_path, path);
// Find the last occurance of the directory deliminator
LPTSTR filename = ::strrchr (temp_path, '\\');
if (filename != NULL) {
// Strip off the filename
filename[0] = 0;
}
// Return the path only
return CString (temp_path);
}
////////////////////////////////////////////////////////////////////////////
//
// Delete_File
//
////////////////////////////////////////////////////////////////////////////
bool
Delete_File (LPCTSTR filename)
{
// Assume failure
bool retval = false;
ASSERT (filename != NULL);
if (filename != NULL) {
// Strip the readonly bit off if necessary
DWORD attributes = ::GetFileAttributes (filename);
if ((attributes != 0xFFFFFFFF) &&
((attributes & FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY))
{
::SetFileAttributes (filename, attributes & (~FILE_ATTRIBUTE_READONLY));
}
// Perform the delete operation!
if ((attributes != 0xFFFFFFFF) &&
((attributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY))
{
retval = ::RemoveDirectory (filename) == TRUE;
} else {
retval = ::DeleteFile (filename) == TRUE;
}
}
// Return the true/false result code
return retval;
}
////////////////////////////////////////////////////////////////////////////
//
// Copy_File
//
////////////////////////////////////////////////////////////////////////////
bool
Copy_File
(
LPCTSTR existing_filename,
LPCTSTR new_filename,
bool bforce_copy
)
{
// Assume failure
bool retval = false;
ASSERT (existing_filename != NULL);
ASSERT (new_filename != NULL);
if ((existing_filename != NULL) &&
(new_filename != NULL)) {
// Make sure we aren't copying over ourselves
bool allow_copy = (::lstrcmpi (existing_filename, new_filename) != 0);
// Strip the readonly bit off if necessary
DWORD attributes = ::GetFileAttributes (new_filename);
if (allow_copy &&
(attributes != 0xFFFFFFFF) &&
((attributes & FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY)) {
if (bforce_copy) {
::SetFileAttributes (new_filename, attributes & (~FILE_ATTRIBUTE_READONLY));
} else {
allow_copy = false;
}
}
// Perform the copy operation!
if (allow_copy) {
retval = (::CopyFile (existing_filename, new_filename, FALSE) == TRUE);
}
}
// Return the true/false result code
return retval;
}
__inline void Delimit_Path (CString &path)
{
if (path[::lstrlen (path) - 1] != '\\') {
path += CString ("\\");
}
return ;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Clean_Directory
//
//////////////////////////////////////////////////////////////////////////////////
bool
Clean_Directory (LPCTSTR local_dir, bool is_recursive)
{
bool retval = true;
// Build a search mask from the directory
CString search_mask = CString (local_dir) + "\\*.*";
// Loop through all the files in this directory and add them
// to our list
CStringList file_list;
BOOL bcontinue = TRUE;
WIN32_FIND_DATA find_info = { 0 };
for (HANDLE hfind = ::FindFirstFile (search_mask, &find_info);
(hfind != INVALID_HANDLE_VALUE) && bcontinue;
bcontinue = ::FindNextFile (hfind, &find_info)) {
// If this file isn't a directory, add it to the list
if (!(find_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
CString filename = find_info.cFileName;
file_list.AddTail (filename);
} else if (is_recursive && find_info.cFileName[0] != '.') {
//
// Recurse into this subdirectory
//
CString full_path = local_dir;
::Delimit_Path (full_path);
full_path += find_info.cFileName;
Clean_Directory (full_path, is_recursive);
//
// Add this directory to the list so it will get
// deleted with the files...
//
CString filename = find_info.cFileName;
file_list.AddTail (filename);
}
}
// Close the search handle
if (hfind != NULL) {
::FindClose (hfind);
}
//
// Now loop through all the files and delete them
//
for (POSITION pos = file_list.GetHeadPosition (); pos != NULL; ) {
CString &filename = file_list.GetNext (pos);
CString full_path = local_dir + CString ("\\") + filename;
if (::Delete_File (full_path) == FALSE) {
CString message;
message.Format ("Cannot delete %s. This may result in an incomplete update. Please make sure no applications are running before running the update.", full_path);
::MessageBox (NULL, message, "Delete Error", MB_SETFOREGROUND | MB_TOPMOST | MB_ICONEXCLAMATION | MB_OK);
retval = false;
}
}
return retval;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Create_Dir_If_Necessary
//
//////////////////////////////////////////////////////////////////////////////////
void
Create_Dir_If_Necessary (LPCTSTR path)
{
if (::GetFileAttributes (path) == 0xFFFFFFFF) {
Create_Dir_If_Necessary (::Strip_Filename_From_Path (path));
::CreateDirectory (path, NULL);
}
return ;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Build_File_List
//
//////////////////////////////////////////////////////////////////////////////////
void
Build_File_List (LPCTSTR search_path, CStringList &file_list)
{
//
// Loop through all the files in this directory and add them
// to our list
//
BOOL keep_going = TRUE;
WIN32_FIND_DATA find_info = { 0 };
for (HANDLE hfind = ::FindFirstFile (search_path, &find_info);
(hfind != INVALID_HANDLE_VALUE) && keep_going;
keep_going = ::FindNextFile (hfind, &find_info))
{
//
// If this file isn't a directory, add it to the list
//
if (!(find_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
CString filename = find_info.cFileName;
file_list.AddTail (filename);
}
}
// Close the search handle
if (hfind != NULL) {
::FindClose (hfind);
}
return ;
}
////////////////////////////////////////////////////////////////////////////
//
// Quick_Compare_Files
//
////////////////////////////////////////////////////////////////////////////
int
Quick_Compare_Files
(
LPCTSTR file1,
LPCTSTR file2
)
{
// Assume they are the same
int compare = 0;
// Params OK?
ASSERT (file1 != NULL);
ASSERT (file2 != NULL);
if ((file1 != NULL) && (file2 != NULL)) {
// Attempt to open file1
HANDLE hfile1 = ::CreateFile (file1,
0,
0,
NULL,
OPEN_EXISTING,
0L,
NULL);
// Attempt to open file2
HANDLE hfile2 = ::CreateFile (file2,
0,
0,
NULL,
OPEN_EXISTING,
0L,
NULL);
if ((hfile1 != INVALID_HANDLE_VALUE) && (hfile2 != INVALID_HANDLE_VALUE)) {
// Get information about these 2 files.
BY_HANDLE_FILE_INFORMATION file1_info = { 0 };
BY_HANDLE_FILE_INFORMATION file2_info = { 0 };
::GetFileInformationByHandle (hfile1, &file1_info);
::GetFileInformationByHandle (hfile2, &file2_info);
// Compare the time these files were last written to
compare = ::CompareFileTime (&file1_info.ftLastWriteTime, &file2_info.ftLastWriteTime);
} else if ((hfile1 == INVALID_HANDLE_VALUE) && (hfile2 != INVALID_HANDLE_VALUE)) {
compare = -1;
} else if ((hfile1 != INVALID_HANDLE_VALUE) && (hfile2 == INVALID_HANDLE_VALUE)) {
compare = 1;
}
if (hfile1 != INVALID_HANDLE_VALUE) {
::CloseHandle (hfile1);
}
if (hfile2 != INVALID_HANDLE_VALUE) {
::CloseHandle (hfile2);
}
}
// Same as strcmp, -1 if file1 is older than file2, 0 if equal, 1 if file1 is newer than file2
return compare;
}
//////////////////////////////////////////////////////////////////////////////////
//
// FileNeedsCopying
//
//////////////////////////////////////////////////////////////////////////////////
bool
FileNeedsCopying (LPCTSTR src_path, LPCTSTR dest_path)
{
return (Quick_Compare_Files (src_path, dest_path) != 0);
}
//////////////////////////////////////////////////////////////////////////////////
//
// Update_App_Directory
//
//////////////////////////////////////////////////////////////////////////////////
bool
Update_App_Directory
(
FileCopyDialogClass * dialog,
LPCTSTR src_dir,
LPCTSTR dest_dir,
bool is_recursive
)
{
bool retval = true;
//
// Build search masks from the src and dest directories
//
CString remote_search_mask = src_dir;
remote_search_mask += "\\*.*";
//
// Loop through all the files in this directory and add them
// to our list
//
BOOL keep_going = TRUE;
WIN32_FIND_DATA find_info = { 0 };
CStringList file_list;
for (HANDLE hfind = ::FindFirstFile (remote_search_mask, &find_info);
(hfind != INVALID_HANDLE_VALUE) && keep_going && retval;
keep_going = ::FindNextFile (hfind, &find_info))
{
//
// If this file isn't a directory, add it to the list
//
if (!(find_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
CString filename = find_info.cFileName;
file_list.AddTail (filename);
} else if (is_recursive && find_info.cFileName[0] != '.') {
//
// Recurse into this subdirectory
//
CString full_src_path = src_dir;
CString full_dest_path = dest_dir;
::Delimit_Path (full_src_path);
::Delimit_Path (full_dest_path);
full_src_path += find_info.cFileName;
full_dest_path += find_info.cFileName;
retval &= ::Update_App_Directory ( dialog,
full_src_path,
full_dest_path,
is_recursive);
}
}
// Close the search handle
if (hfind != NULL) {
::FindClose (hfind);
}
//
// Now loop through all the files and copy them to the src
//
for (POSITION pos = file_list.GetHeadPosition (); pos != NULL && retval; ) {
CString &filename = file_list.GetNext (pos);
CString src_file = src_dir + CString ("\\") + filename;
CString dest_file = dest_dir + CString ("\\") + filename;
//
// Make sure the destination directory exists
//
::Create_Dir_If_Necessary (dest_dir);
//
// Do a file comparison to determine whether or not to copy the file
//
if (::FileNeedsCopying (src_file, dest_file)) {
//
// Update the dialog
//
dialog->Set_Current_File (filename);
//
// Copy the file
//
if (::Copy_File (src_file, dest_file, true) == FALSE) {
CString message;
message.Format ("Cannot copy %s to %s. Please make sure no applications are running before running the update.", src_file, dest_file);
::MessageBox (NULL, message, "Copy Error", MB_SETFOREGROUND | MB_TOPMOST | MB_ICONEXCLAMATION | MB_OK);
retval = false;
}
}
}
return retval;
}
//////////////////////////////////////////////////////////////////////////////////
//
// fnUpdateAppDirectory
//
//////////////////////////////////////////////////////////////////////////////////
UINT
fnUpdateAppDirectory (LPVOID pParam)
{
UPDATE_INFO *info = (UPDATE_INFO *)pParam;
ASSERT (info != NULL);
if (info != NULL) {
//
// Begin updating this directory...
//
info->result = ::Update_App_Directory ( info->dialog,
info->src_dir,
info->dest_dir,
info->is_recursive);
//
// Kill the updating dialog
//
::PostMessage (info->dialog->m_hWnd, WM_USER + 101, 0, 0L);
}
return 1;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Update_App
//
//////////////////////////////////////////////////////////////////////////////////
bool
Update_App
(
CWnd * parent_wnd,
LPCTSTR title,
LPCTSTR src_dir,
LPCTSTR dest_dir,
bool is_recursive
)
{
CWaitCursor wait_cursor;
FileCopyDialogClass dialog (parent_wnd);
dialog.Set_Current_Application (title);
//
// Kick off a worker thread to do the actual file copy
//
UPDATE_INFO *info = new UPDATE_INFO;
info->dialog = &dialog;
info->src_dir = src_dir;
info->dest_dir = dest_dir;
info->is_recursive = is_recursive;
::AfxBeginThread (fnUpdateAppDirectory, (LPVOID)info);
//
// Display a dialog to monitor the progress
//
dialog.DoModal ();
bool retval = info->result;
delete info;
return retval;
}
//////////////////////////////////////////////////////////////////////////////////
//
// OnCommand
//
//////////////////////////////////////////////////////////////////////////////////
BOOL
CCommandoUpdateDlg::OnCommand
(
WPARAM wParam,
LPARAM lParam
)
{
bool found = false;
for (int index = 0; (index < APP_MAX) && (found == false); index ++) {
const APP_INFO &app_info = APPLICATIONS[index];
if (LOWORD (wParam) == app_info.ctrl_id) {
bool enable = (SendDlgItemMessage (LOWORD(wParam), BM_GETCHECK) == 1);
if (index == APP_GAME_ENGINE) {
enable |= (SendDlgItemMessage (APPLICATIONS[APP_GAME_LEVELS].ctrl_id, BM_GETCHECK) == 1);
enable |= (SendDlgItemMessage (APPLICATIONS[APP_GAME_MOVIES].ctrl_id, BM_GETCHECK) == 1);
} else if (index == APP_GAME_LEVELS || index == APP_GAME_MOVIES) {
enable |= (SendDlgItemMessage (APPLICATIONS[APP_GAME_ENGINE].ctrl_id, BM_GETCHECK) == 1);
}
//
// Enable or disable the clean and directory buttons
//
::EnableWindow (::GetDlgItem (m_hWnd, app_info.clean_ctrl_id), enable);
::EnableWindow (::GetDlgItem (m_hWnd, app_info.dir_ctrl_id), enable);
} else if (LOWORD (wParam) == app_info.dir_ctrl_id) {
//
// Change the installation directoy
//
CString directory;
CString dlg_title;
dlg_title.Format ("Select a directory to install the %s to.", app_info.title);
if (Get_Install_Directory (m_hWnd, dlg_title, directory)) {
SetDlgItemText (app_info.dir_ctrl_id, directory);
}
found = true;
}
}
return CDialog::OnCommand(wParam, lParam);
}
//////////////////////////////////////////////////////////////////////////////////
//
// OnDefaults
//
//////////////////////////////////////////////////////////////////////////////////
void
CCommandoUpdateDlg::OnDefaults (void)
{
for (int index = 0; index < APP_MAX; index ++) {
const APP_INFO &app_info = APPLICATIONS[index];
if (SendDlgItemMessage (app_info.ctrl_id, BM_GETCHECK) != 0) {
SetDlgItemText (app_info.dir_ctrl_id, app_info.default_dir);
}
}
return ;
}

View File

@@ -0,0 +1,69 @@
/*
** Command & Conquer Renegade(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/>.
*/
// CommandoUpdateDlg.h : header file
//
#if !defined(AFX_COMMANDOUPDATEDLG_H__4305AC50_1EAB_11D3_A038_00104B791122__INCLUDED_)
#define AFX_COMMANDOUPDATEDLG_H__4305AC50_1EAB_11D3_A038_00104B791122__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
/////////////////////////////////////////////////////////////////////////////
// CCommandoUpdateDlg dialog
class CCommandoUpdateDlg : public CDialog
{
// Construction
public:
CCommandoUpdateDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CCommandoUpdateDlg)
enum { IDD = IDD_COMMANDOUPDATE_DIALOG };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CCommandoUpdateDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
//}}AFX_VIRTUAL
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
//{{AFX_MSG(CCommandoUpdateDlg)
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
virtual void OnOK();
afx_msg void OnDefaults();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_COMMANDOUPDATEDLG_H__4305AC50_1EAB_11D3_A038_00104B791122__INCLUDED_)

View File

@@ -0,0 +1,99 @@
/*
** Command & Conquer Renegade(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/>.
*/
// FileCopyDialog.cpp : implementation file
//
#include "stdafx.h"
#include "CommandoUpdate.h"
#include "FileCopyDialog.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// FileCopyDialogClass dialog
FileCopyDialogClass::FileCopyDialogClass(CWnd* pParent /*=NULL*/)
: CDialog(FileCopyDialogClass::IDD, pParent)
{
//{{AFX_DATA_INIT(FileCopyDialogClass)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void FileCopyDialogClass::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(FileCopyDialogClass)
DDX_Control(pDX, IDC_ANIMATE_CTRL, m_AnimateCtrl);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(FileCopyDialogClass, CDialog)
//{{AFX_MSG_MAP(FileCopyDialogClass)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//////////////////////////////////////////////////////////////////////////////
//
// WindowProc
//
//////////////////////////////////////////////////////////////////////////////
LRESULT
FileCopyDialogClass::WindowProc
(
UINT message,
WPARAM wParam,
LPARAM lParam
)
{
if (message == WM_USER + 101) {
EndDialog (TRUE);
}
return CDialog::WindowProc(message, wParam, lParam);
}
//////////////////////////////////////////////////////////////////////////////
//
// OnInitDialog
//
//////////////////////////////////////////////////////////////////////////////
BOOL
FileCopyDialogClass::OnInitDialog (void)
{
CDialog::OnInitDialog();
CString app_title;
app_title.Format ("Application: %s", m_AppTitle);
SetDlgItemText (IDC_CURRENT_APP, app_title);
m_AnimateCtrl.Open (IDR_FILECOPY_AVI);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}

View File

@@ -0,0 +1,72 @@
/*
** Command & Conquer Renegade(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/>.
*/
#if !defined(AFX_FILECOPYDIALOG_H__4305AC5C_1EAB_11D3_A038_00104B791122__INCLUDED_)
#define AFX_FILECOPYDIALOG_H__4305AC5C_1EAB_11D3_A038_00104B791122__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// FileCopyDialog.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// FileCopyDialogClass dialog
class FileCopyDialogClass : public CDialog
{
// Construction
public:
FileCopyDialogClass(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(FileCopyDialogClass)
enum { IDD = IDD_FILE_COPY };
CAnimateCtrl m_AnimateCtrl;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(FileCopyDialogClass)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(FileCopyDialogClass)
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
public:
void Set_Current_File (LPCTSTR filename) { if (m_hWnd != NULL) SetDlgItemText (IDC_FILENAME_TEXT, filename); }
void Set_Current_Application (LPCTSTR filename) { m_AppTitle = filename; }
private:
CString m_AppTitle;
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_FILECOPYDIALOG_H__4305AC5C_1EAB_11D3_A038_00104B791122__INCLUDED_)

View File

@@ -0,0 +1,26 @@
/*
** Command & Conquer Renegade(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/>.
*/
// stdafx.cpp : source file that includes just the standard includes
// CommandoUpdate.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"

View File

@@ -0,0 +1,44 @@
/*
** Command & Conquer Renegade(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/>.
*/
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#if !defined(AFX_STDAFX_H__4305AC52_1EAB_11D3_A038_00104B791122__INCLUDED_)
#define AFX_STDAFX_H__4305AC52_1EAB_11D3_A038_00104B791122__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__4305AC52_1EAB_11D3_A038_00104B791122__INCLUDED_)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,13 @@
//
// COMMANDOUPDATE.RC2 - resources Microsoft Visual C++ does not edit directly
//
#ifdef APSTUDIO_INVOKED
#error this file is not editable by Microsoft Visual C++
#endif //APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
// Add manually edited resources here...
/////////////////////////////////////////////////////////////////////////////

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

View File

@@ -0,0 +1,51 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by CommandoUpdate.rc
//
#define IDC_DEFAULTS 3
#define IDD_COMMANDOUPDATE_DIALOG 102
#define IDD_FILE_COPY 103
#define IDR_MAINFRAME 128
#define IDI_COPY 129
#define IDR_FILECOPY_AVI 129
#define IDC_EDITOR_CHECK 1000
#define IDC_ANIMATE_CTRL 1000
#define IDC_GAME_CHECK 1001
#define IDC_FILENAME_TEXT 1001
#define IDC_VIEWER_CHECK 1002
#define IDC_CURRENT_APP 1002
#define IDC_GAME_LEVELS_CHECK 1002
#define IDC_MAX_PLUGIN_CHECK 1003
#define IDC_GAME_MOVIES_CHECK 1003
#define IDC_EDITOR_CLEAN_CHECK 1004
#define IDC_GAME_CLEAN_CHECK 1005
#define IDC_VIEWER_CLEAN_CHECK 1006
#define IDC_MULTIPLAY_CHECK 1006
#define IDC_WDUMP_CHECK 1007
#define IDC_MULTIPLAY_CLEAN_CHECK 1007
#define IDC_MAX_PLUGIN_CLEAN_CHECK 1008
#define IDC_WDUMP_CLEAN_CHECK 1009
#define IDC_LIGHTMAP_CHECK 1010
#define IDC_LIGHTMAP_CLEAN_CHECK 1011
#define IDC_EDITOR_DIR_BUTTON 1012
#define IDC_VISFARM_CHECK 1013
#define IDC_GAME_DIR_BUTTON 1014
#define IDC_VISFARM_CLEAN_CHECK 1015
#define IDC_MIXVIEW_CHECK 1016
#define IDC_MIXVIEW_CLEAN_CHECK 1017
#define IDC_LIGHTMAP_DIR_BUTTON 1018
#define IDD_DIR_SELECT_DIALOG 1019
#define IDC_VISFARM_DIR_BUTTON 1019
#define IDC_MIXVIEW_DIR_BUTTON 1020
#define IDC_MULTIPLAY_DIR_BUTTON 1021
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 130
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1013
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@@ -0,0 +1,90 @@
/*
** Command & Conquer Renegade(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/>.
*/
// CopyLocked.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "CopyLocked.h"
#include "CopyLockedDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CCopyLockedApp
BEGIN_MESSAGE_MAP(CCopyLockedApp, CWinApp)
//{{AFX_MSG_MAP(CCopyLockedApp)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCopyLockedApp construction
CCopyLockedApp::CCopyLockedApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
/////////////////////////////////////////////////////////////////////////////
// The one and only CCopyLockedApp object
CCopyLockedApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CCopyLockedApp initialization
BOOL CCopyLockedApp::InitInstance()
{
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
CCopyLockedDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}

View File

@@ -0,0 +1,178 @@
# Microsoft Developer Studio Project File - Name="CopyLocked" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
CFG=CopyLocked - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "CopyLocked.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "CopyLocked.mak" CFG="CopyLocked - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "CopyLocked - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "CopyLocked - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/Commando/Code/Tools/CopyLocked", GPDBAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "CopyLocked - Win32 Release"
# PROP BASE Use_MFC 5
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 5
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Yu"stdafx.h" /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386
# ADD LINK32 /nologo /subsystem:windows /machine:I386
!ELSEIF "$(CFG)" == "CopyLocked - Win32 Debug"
# PROP BASE Use_MFC 5
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 5
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /Yu"stdafx.h" /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386
# ADD LINK32 /nologo /subsystem:windows /debug /machine:I386
!ENDIF
# Begin Target
# Name "CopyLocked - Win32 Release"
# Name "CopyLocked - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\CopyLocked.cpp
# End Source File
# Begin Source File
SOURCE=.\CopyLocked.rc
# End Source File
# Begin Source File
SOURCE=.\CopyLockedDlg.cpp
# End Source File
# Begin Source File
SOURCE=.\StdAfx.cpp
# ADD CPP /Yc"stdafx.h"
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\CopyLocked.h
# End Source File
# Begin Source File
SOURCE=.\CopyLockedDlg.h
# End Source File
# Begin Source File
SOURCE=.\Resource.h
# End Source File
# Begin Source File
SOURCE=.\StdAfx.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# Begin Source File
SOURCE=.\res\CopyLocked.ico
# End Source File
# Begin Source File
SOURCE=.\res\CopyLocked.rc2
# End Source File
# End Group
# Begin Source File
SOURCE=.\res\Mfc42.dll
# End Source File
# Begin Source File
SOURCE=.\res\Mfc42d.dll
# End Source File
# Begin Source File
SOURCE=.\res\Msvcp50.dll
# End Source File
# Begin Source File
SOURCE=.\res\Msvcp50d.dll
# End Source File
# Begin Source File
SOURCE=.\res\Msvcp60.dll
# End Source File
# Begin Source File
SOURCE=.\res\Msvcp60d.dll
# End Source File
# Begin Source File
SOURCE=.\res\Msvcrt.dll
# End Source File
# Begin Source File
SOURCE=.\res\Msvcrtd.dll
# End Source File
# Begin Source File
SOURCE=.\ReadMe.txt
# End Source File
# End Target
# End Project

View File

@@ -0,0 +1,67 @@
/*
** Command & Conquer Renegade(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/>.
*/
// CopyLocked.h : main header file for the COPYLOCKED application
//
#if !defined(AFX_COPYLOCKED_H__21287A7D_8B06_11D2_9FE3_00104B791122__INCLUDED_)
#define AFX_COPYLOCKED_H__21287A7D_8B06_11D2_9FE3_00104B791122__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif
#include "resource.h" // main symbols
/////////////////////////////////////////////////////////////////////////////
// CCopyLockedApp:
// See CopyLocked.cpp for the implementation of this class
//
class CCopyLockedApp : public CWinApp
{
public:
CCopyLockedApp();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CCopyLockedApp)
public:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL
// Implementation
//{{AFX_MSG(CCopyLockedApp)
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_COPYLOCKED_H__21287A7D_8B06_11D2_9FE3_00104B791122__INCLUDED_)

View File

@@ -0,0 +1,190 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"#define _AFX_NO_SPLITTER_RESOURCES\r\n"
"#define _AFX_NO_OLE_RESOURCES\r\n"
"#define _AFX_NO_TRACKER_RESOURCES\r\n"
"#define _AFX_NO_PROPERTY_RESOURCES\r\n"
"\r\n"
"#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
"#ifdef _WIN32\r\n"
"LANGUAGE 9, 1\r\n"
"#pragma code_page(1252)\r\n"
"#endif //_WIN32\r\n"
"#include ""res\\CopyLocked.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
"#include ""afxres.rc"" // Standard components\r\n"
"#endif\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDR_MAINFRAME ICON DISCARDABLE "res\\CopyLocked.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_COPYLOCKED_DIALOG DIALOGEX 0, 0, 223, 66
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "Copy Locked Files"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,48,45,50,14
PUSHBUTTON "Cancel",IDCANCEL,124,45,50,14
LTEXT "This program will install the MSVC 6.0 core components onto your machine. You must reboot your machine in order to use these components.",
IDC_STATIC,7,7,209,29
END
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904B0"
BEGIN
VALUE "CompanyName", "\0"
VALUE "FileDescription", "CopyLocked MFC Application\0"
VALUE "FileVersion", "1, 0, 0, 1\0"
VALUE "InternalName", "CopyLocked\0"
VALUE "LegalCopyright", "Copyright (C) 1998\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "CopyLocked.EXE\0"
VALUE "ProductName", "CopyLocked Application\0"
VALUE "ProductVersion", "1, 0, 0, 1\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // !_MAC
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_COPYLOCKED_DIALOG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 216
TOPMARGIN, 7
BOTTOMMARGIN, 59
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// FILE
//
msvcrtd.dll FILE DISCARDABLE "res\\Msvcrtd.dll"
Mfc42d.dll FILE DISCARDABLE "res\\Mfc42d.dll"
Msvcp50.dll FILE DISCARDABLE "res\\Msvcp50.dll"
Msvcp50d.dll FILE DISCARDABLE "res\\Msvcp50d.dll"
Msvcp60.dll FILE DISCARDABLE "res\\Msvcp60.dll"
Msvcp60d.dll FILE DISCARDABLE "res\\Msvcp60d.dll"
Msvcrt.dll FILE DISCARDABLE "res\\Msvcrt.dll"
Mfc42.dll FILE DISCARDABLE "res\\Mfc42.dll"
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#define _AFX_NO_SPLITTER_RESOURCES
#define _AFX_NO_OLE_RESOURCES
#define _AFX_NO_TRACKER_RESOURCES
#define _AFX_NO_PROPERTY_RESOURCES
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE 9, 1
#pragma code_page(1252)
#endif //_WIN32
#include "res\CopyLocked.rc2" // non-Microsoft Visual C++ edited resources
#include "afxres.rc" // Standard components
#endif
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@@ -0,0 +1,177 @@
/*
** Command & Conquer Renegade(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/>.
*/
// CopyLockedDlg.cpp : implementation file
//
#include "stdafx.h"
#include "CopyLocked.h"
#include "CopyLockedDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CCopyLockedDlg dialog
CCopyLockedDlg::CCopyLockedDlg(CWnd* pParent /*=NULL*/)
: CDialog(CCopyLockedDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CCopyLockedDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CCopyLockedDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CCopyLockedDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CCopyLockedDlg, CDialog)
//{{AFX_MSG_MAP(CCopyLockedDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCopyLockedDlg message handlers
BOOL CCopyLockedDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CCopyLockedDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CCopyLockedDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
LPCTSTR _filenames[] = {
"Msvcrtd.dll",
"Mfc42d.dll",
"Msvcp50.dll",
"Msvcp50d.dll",
"Msvcp60.dll",
"Msvcp60d.dll",
"Msvcrt.dll",
"Mfc42.dll" };
void
CCopyLockedDlg::OnOK()
{
// TODO: Add extra validation here
CWaitCursor wait_cursor;
TCHAR temp_path[MAX_PATH];
::GetTempPath (sizeof (temp_path), temp_path);
for (int index = 0; index < sizeof (_filenames)/sizeof (LPCTSTR); index ++) {
HRSRC hresource = ::FindResource (::AfxGetInstanceHandle (), _filenames[index], "FILE");
HGLOBAL hglobal = ::LoadResource (::AfxGetInstanceHandle (), hresource);
LPVOID pbuffer = ::LockResource (hglobal);
if(pbuffer != NULL) {
CString full_path = CString (temp_path);
if (temp_path[::lstrlen (temp_path)-1] != '\\') {
full_path += "\\";
}
full_path += CString (_filenames[index]);
HANDLE hfile = ::CreateFile (full_path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
if (hfile != INVALID_HANDLE_VALUE) {
DWORD dwbyteswritten = 0L;
DWORD dwsizeofres = ::SizeofResource (::AfxGetInstanceHandle (), hresource);
::WriteFile (hfile, pbuffer, dwsizeofres, &dwbyteswritten, NULL);
::CloseHandle (hfile);
if (dwbyteswritten == dwsizeofres) {
TCHAR system_path[MAX_PATH];
::GetSystemDirectory (system_path, sizeof (system_path));
CString new_path = CString (system_path);
if (new_path[::lstrlen (new_path)-1] != '\\') {
new_path += "\\";
}
new_path += CString (_filenames[index]);
::MoveFileEx (full_path, new_path, MOVEFILE_DELAY_UNTIL_REBOOT | MOVEFILE_REPLACE_EXISTING);
::MoveFileEx (full_path, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
}
}
}
}
::MessageBox (m_hWnd, "In order to complete the install, you need to reboot your machine.", "Reboot", MB_OK | MB_ICONEXCLAMATION);
//::ExitWindowsEx (EWX_REBOOT, 0);
CDialog::OnOK();
return ;
}

View File

@@ -0,0 +1,67 @@
/*
** Command & Conquer Renegade(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/>.
*/
// CopyLockedDlg.h : header file
//
#if !defined(AFX_COPYLOCKEDDLG_H__21287A7F_8B06_11D2_9FE3_00104B791122__INCLUDED_)
#define AFX_COPYLOCKEDDLG_H__21287A7F_8B06_11D2_9FE3_00104B791122__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
/////////////////////////////////////////////////////////////////////////////
// CCopyLockedDlg dialog
class CCopyLockedDlg : public CDialog
{
// Construction
public:
CCopyLockedDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CCopyLockedDlg)
enum { IDD = IDD_COPYLOCKED_DIALOG };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CCopyLockedDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
//{{AFX_MSG(CCopyLockedDlg)
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
virtual void OnOK();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_COPYLOCKEDDLG_H__21287A7F_8B06_11D2_9FE3_00104B791122__INCLUDED_)

View File

@@ -0,0 +1,26 @@
/*
** Command & Conquer Renegade(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/>.
*/
// stdafx.cpp : source file that includes just the standard includes
// CopyLocked.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"

View File

@@ -0,0 +1,44 @@
/*
** Command & Conquer Renegade(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/>.
*/
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#if !defined(AFX_STDAFX_H__21287A81_8B06_11D2_9FE3_00104B791122__INCLUDED_)
#define AFX_STDAFX_H__21287A81_8B06_11D2_9FE3_00104B791122__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__21287A81_8B06_11D2_9FE3_00104B791122__INCLUDED_)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,13 @@
//
// COPYLOCKED.RC2 - resources Microsoft Visual C++ does not edit directly
//
#ifdef APSTUDIO_INVOKED
#error this file is not editable by Microsoft Visual C++
#endif //APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
// Add manually edited resources here...
/////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,17 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by CopyLocked.rc
//
#define IDD_COPYLOCKED_DIALOG 102
#define IDR_MAINFRAME 128
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 138
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@@ -0,0 +1,208 @@
/*
** Command & Conquer Renegade(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 : LevelEdit *
* *
* $Archive:: /Commando/Code/Tools/LevelEdit/AttenuationSphere.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 5/04/00 9:58a $*
* *
* $Revision:: 3 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "StdAfx.h"
#include "AttenuationSphere.h"
#include "SphereObj.h"
#include "Utils.h"
#include "Node.h"
#include "SceneEditor.h"
///////////////////////////////////////////////////////////////////////////////
//
// AttenuationSphereClass
//
///////////////////////////////////////////////////////////////////////////////
AttenuationSphereClass::AttenuationSphereClass (void)
: m_IsInScene (false),
m_Color (1, 1, 1),
m_Radius (1.0F),
m_Opacity (1.0F)
{
return ;
}
///////////////////////////////////////////////////////////////////////////////
//
// ~AttenuationSphereClass
//
///////////////////////////////////////////////////////////////////////////////
AttenuationSphereClass::~AttenuationSphereClass (void)
{
Remove_From_Scene ();
return ;
}
///////////////////////////////////////////////////////////////////////////////
//
// Display_Around_Node
//
///////////////////////////////////////////////////////////////////////////////
void
AttenuationSphereClass::Display_Around_Node (const NodeClass &node)
{
RenderObjClass *render_obj = node.Peek_Render_Obj ();
if (render_obj != NULL) {
Display_Around_Node (*render_obj);
}
return ;
}
///////////////////////////////////////////////////////////////////////////////
//
// Display_Around_Node
//
///////////////////////////////////////////////////////////////////////////////
void
AttenuationSphereClass::Display_Around_Node (const RenderObjClass &render_obj)
{
//
// Make sure we have a sphere object
//
SphereRenderObjClass *sphere = (SphereRenderObjClass *)Peek_Model ();
if (sphere == NULL) {
sphere = new SphereRenderObjClass;
sphere->Set_Flag (SphereRenderObjClass::USE_ALPHA_VECTOR, false);
Set_Model (sphere);
Set_Color (m_Color);
Set_Radius (m_Radius);
Set_Opacity (m_Opacity);
MEMBER_RELEASE (sphere);
}
//
// Update the sphere's position
//
Set_Transform (render_obj.Get_Transform ());
//
// Put the sphere into the scene
//
if (m_IsInScene == false) {
::Get_Scene_Editor ()->Add_Dynamic_Object (this);
m_IsInScene = true;
}
return ;
}
///////////////////////////////////////////////////////////////////////////////
//
// Remove_From_Scene
//
///////////////////////////////////////////////////////////////////////////////
void
AttenuationSphereClass::Remove_From_Scene (void)
{
//
// Remove the sphere from the scene
//
if (m_IsInScene) {
::Get_Scene_Editor ()->Remove_Object (this);
m_IsInScene = false;
}
return ;
}
///////////////////////////////////////////////////////////////////////////////
//
// Set_Color
//
///////////////////////////////////////////////////////////////////////////////
void
AttenuationSphereClass::Set_Color (const Vector3 &color)
{
SphereRenderObjClass *sphere = (SphereRenderObjClass *)Peek_Model ();
SANITY_CHECK (sphere != NULL) {
return ;
}
m_Color = color;
sphere->Set_Color (m_Color);
return ;
}
///////////////////////////////////////////////////////////////////////////////
//
// Set_Radius
//
///////////////////////////////////////////////////////////////////////////////
void
AttenuationSphereClass::Set_Radius (float radius)
{
SphereRenderObjClass *sphere = (SphereRenderObjClass *)Peek_Model ();
SANITY_CHECK (sphere != NULL) {
return ;
}
m_Radius = radius;
sphere->Set_Extent (Vector3 (m_Radius, m_Radius, m_Radius));
sphere->Set_Transform (sphere->Get_Transform ());
Update_Cull_Box ();
return ;
}
///////////////////////////////////////////////////////////////////////////////
//
// Set_Opacity
//
///////////////////////////////////////////////////////////////////////////////
void
AttenuationSphereClass::Set_Opacity (float opacity)
{
SphereRenderObjClass *sphere = (SphereRenderObjClass *)Peek_Model ();
SANITY_CHECK (sphere != NULL) {
return ;
}
m_Opacity = opacity;
sphere->Set_Alpha (m_Opacity);
return ;
}

View File

@@ -0,0 +1,94 @@
/*
** Command & Conquer Renegade(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 : LevelEdit *
* *
* $Archive:: /Commando/Code/Tools/LevelEdit/AttenuationSphere.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 4/04/00 8:02p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __ATTENUATIONSPHERE_H
#define __ATTENUATIONSPHERE_H
#include "Utils.h"
#include "EditorPhys.h"
#include "Vector3.h"
// Forward declarations
class NodeClass;
///////////////////////////////////////////////////////////////////////////////
//
// AttenuationSphereClass
//
///////////////////////////////////////////////////////////////////////////////
class AttenuationSphereClass : public EditorPhysClass
{
public:
////////////////////////////////////////////////////////
// Public contsructors/destructors
////////////////////////////////////////////////////////
AttenuationSphereClass (void);
virtual ~AttenuationSphereClass (void);
////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////
void Display_Around_Node (const NodeClass &node);
void Display_Around_Node (const RenderObjClass &render_obj);
void Remove_From_Scene (void);
void Set_Color (const Vector3 &color);
void Set_Radius (float radius);
void Set_Opacity (float opacity);
private:
////////////////////////////////////////////////////////
// Private member data
////////////////////////////////////////////////////////
bool m_IsInScene;
Vector3 m_Color;
float m_Radius;
float m_Opacity;
};
#endif //__ATTENUATIONSPHERE_H

View File

@@ -0,0 +1,870 @@
/*
** Command & Conquer Renegade(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 : LevelEdit *
* *
* $Archive:: /Commando/Code/Tools/LevelEdit/Box3D.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 3/28/01 3:11p $*
* *
* $Revision:: 9 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
//
//
// Following is a diagram specifying which entries in the m_Verticies array
// correspond to which verticies in the box (in object space).
// I don't know how well this diagram is going to hold up to different editors/font sizes, etc
// so I apologize in advance if its unreadable... ;>
//
//
// 2 --------------- 3
// /| /|
// / | / |
// / | / |
// 6 --------------- 7 |
// | | | |
// | | | |
// | 1|_________|___| 0
// | / | /
// | / | /
// |/ |/
// 5 --------------- 4
//
//
//
//
#include "stdafx.h"
#include "box3d.h"
#include "coltest.h"
#include "tri.h"
#include "leveleditdoc.h"
#include "cameramgr.h"
#include "camera.h"
/////////////////////////////////////////////////////////////////////////////////////////
// Local constants and typedefs
/////////////////////////////////////////////////////////////////////////////////////////
typedef enum
{
FACE_FRONT = 0,
FACE_BACK,
FACE_TOP,
FACE_BOTTOM,
FACE_RIGHT,
FACE_LEFT,
FACE_COUNT
} FACE_INDEX;
const int FACE_VERTICIES[6][4] = {
{ 5, 4, 6, 7 }, { 0, 1, 3, 2 },
{ 3, 2, 7, 6 }, { 4, 5, 0, 1 },
{ 1, 5, 2, 6 }, { 4, 0, 7, 3 }
};
const float MIN_SIZE = 0.01F;
/////////////////////////////////////////////////////////////////////////////////////////
// Local prototypes
/////////////////////////////////////////////////////////////////////////////////////////
static bool Find_Intersection_Point (const AABoxClass &box, const Vector3 &p0, const Vector3 &p1, float *percent, Vector3 *intersection_point);
/////////////////////////////////////////////////////////////////////////////////////////
//
// Create_Model
//
/////////////////////////////////////////////////////////////////////////////////////////
void
Box3DClass::Create_Model (void)
{
//
// Assign a default vertex material for the model
//
VertexMaterialClass *vmat = new VertexMaterialClass ();
vmat->Set_Lighting (false);
vmat->Set_Ambient(0,0,0);
vmat->Set_Diffuse(0,0,0);
vmat->Set_Specular(0,0,0);
vmat->Set_Emissive(1,1,1);
vmat->Set_Opacity(0.5F);
vmat->Set_Shininess(0.0f);
//vmat->Set_Opacity (0.5F);
Set_Vertex_Material (vmat);
MEMBER_RELEASE (vmat);
//
// Use an alpha shader so the box will be transparent
//
Set_Shader (ShaderClass::_PresetAlphaSolidShader);
Enable_Sort ();
float half_width = m_Dimensions.Y / 2.0F;
float half_height = m_Dimensions.Z / 2.0F;
float half_depth = m_Dimensions.X / 2.0F;
// Determine the object space coords of our 8 verticies
m_Verticies[0].X = -half_depth;
m_Verticies[0].Y = half_width;
m_Verticies[0].Z = -half_height;
m_Verticies[1].X = -half_depth;
m_Verticies[1].Y = -half_width;
m_Verticies[1].Z = -half_height;
m_Verticies[2].X = -half_depth;
m_Verticies[2].Y = -half_width;
m_Verticies[2].Z = half_height;
m_Verticies[3].X = -half_depth;
m_Verticies[3].Y = half_width;
m_Verticies[3].Z = half_height;
m_Verticies[4].X = half_depth;
m_Verticies[4].Y = half_width;
m_Verticies[4].Z = -half_height;
m_Verticies[5].X = half_depth;
m_Verticies[5].Y = -half_width;
m_Verticies[5].Z = -half_height;
m_Verticies[6].X = half_depth;
m_Verticies[6].Y = -half_width;
m_Verticies[6].Z = half_height;
m_Verticies[7].X = half_depth;
m_Verticies[7].Y = half_width;
m_Verticies[7].Z = half_height;
//Set_Vertex_Color (Vector3 (0.0F, 0.0F, ((float)(iface)) * 0.15F));
Set_Vertex_Color (Vector4 (0.0F, 0.5F, 0.0F, 0.5f));
//Set_Vertex_Alpha (0.5F);
// Loop through all the faces and create them from triangle strips.
for (int iface = 0; iface < FACE_COUNT; iface ++) {
Begin_Tri_Strip ();
Easy_Vertex (m_Verticies[FACE_VERTICIES[iface][0]]);
Easy_Vertex (m_Verticies[FACE_VERTICIES[iface][1]]);
Easy_Vertex (m_Verticies[FACE_VERTICIES[iface][2]]);
Easy_Vertex (m_Verticies[FACE_VERTICIES[iface][3]]);
End_Tri_Strip ();
}
Set_Collision_Type (COLLISION_TYPE_0);
return ;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Set_Dimensions
//
/////////////////////////////////////////////////////////////////////////////////////////
void
Box3DClass::Set_Dimensions (const Vector3 &dimensions)
{
Set_Width (dimensions.Y);
Set_Height (dimensions.Z);
Set_Depth (dimensions.X);
Update_Verticies ();
return ;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Set_Width
//
/////////////////////////////////////////////////////////////////////////////////////////
void
Box3DClass::Set_Width (float width)
{
width = ::fabs (width);
// Determine if the widht actually changed or not
float curr_width = m_Dimensions.Y;
if (curr_width != width) {
// Recalc the obj-space positions of our 8 verticies
float half_width = width / 2.0F;
m_Verticies[0].Y = half_width;
m_Verticies[1].Y = -half_width;
m_Verticies[2].Y = -half_width;
m_Verticies[3].Y = half_width;
m_Verticies[4].Y = half_width;
m_Verticies[5].Y = -half_width;
m_Verticies[6].Y = -half_width;
m_Verticies[7].Y = half_width;
// Keep a flag around that will tell us we need
// to update the verticies in the model when we're ready
m_bDirty = true;
m_Dimensions.Y = width;
}
return ;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Set_Height
//
/////////////////////////////////////////////////////////////////////////////////////////
void
Box3DClass::Set_Height (float height)
{
height = ::fabs (height);
// Determine if the height actually changed or not
float curr_height = m_Dimensions.Z;
if (curr_height != height) {
// Recalc the obj-space positions of our 8 verticies
float half_height = height / 2.0F;
m_Verticies[0].Z = -half_height;
m_Verticies[1].Z = -half_height;
m_Verticies[2].Z = half_height;
m_Verticies[3].Z = half_height;
m_Verticies[4].Z = -half_height;
m_Verticies[5].Z = -half_height;
m_Verticies[6].Z = half_height;
m_Verticies[7].Z = half_height;
// Keep a flag around that will tell us we need
// to update the verticies in the model when we're ready
m_bDirty = true;
m_Dimensions.Z = height;
}
return ;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Set_Depth
//
/////////////////////////////////////////////////////////////////////////////////////////
void
Box3DClass::Set_Depth (float depth)
{
depth = ::fabs (depth);
// Determine if the depth actually changed or not
float curr_depth = m_Dimensions.X;
if (curr_depth != depth) {
// Recalc the obj-space positions of our 8 verticies
float half_depth = depth / 2.0F;
m_Verticies[0].X = -half_depth;
m_Verticies[1].X = -half_depth;
m_Verticies[2].X = -half_depth;
m_Verticies[3].X = -half_depth;
m_Verticies[4].X = half_depth;
m_Verticies[5].X = half_depth;
m_Verticies[6].X = half_depth;
m_Verticies[7].X = half_depth;
// Keep a flag around that will tell us we need
// to update the verticies in the model when we're ready
m_bDirty = true;
m_Dimensions.X = depth;
}
return ;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Update_Verticies
//
/////////////////////////////////////////////////////////////////////////////////////////
void
Box3DClass::Update_Verticies (void)
{
if (m_bDirty) {
// Loop through all 24 verticies in the model and
// update their obj-space positions
int ivertex = 0;
for (int iface = 0; iface < FACE_COUNT; iface ++) {
Easy_Move_Vertex (ivertex++, m_Verticies[FACE_VERTICIES[iface][0]]);
Easy_Move_Vertex (ivertex++, m_Verticies[FACE_VERTICIES[iface][1]]);
Easy_Move_Vertex (ivertex++, m_Verticies[FACE_VERTICIES[iface][2]]);
Easy_Move_Vertex (ivertex++, m_Verticies[FACE_VERTICIES[iface][3]]);
}
// We're no longer dirty
m_bDirty = false;
Set_Dirty_Bounds ();
Set_Dirty ();
Invalidate_Cached_Bounding_Volumes ();
Update_Cached_Bounding_Volumes ();
}
return ;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Get_Vertex_Lock_Position
//
/////////////////////////////////////////////////////////////////////////////////////////
Vector3
Box3DClass::Get_Vertex_Lock_Position (int vertex)
{
Vector3 position (0, 0, 0);
// Params OK?
if ((vertex >= 0) && (vertex < 8)) {
switch (vertex) {
case 0:
position = m_Verticies[6];
break;
case 1:
position = m_Verticies[7];
break;
case 2:
position = m_Verticies[4];
break;
case 3:
position = m_Verticies[5];
break;
case 4:
position = m_Verticies[2];
break;
case 5:
position = m_Verticies[3];
break;
case 6:
position = m_Verticies[0];
break;
case 7:
position = m_Verticies[1];
break;
}
// Convert the vertex position from obj space to world space
//position += Get_Transform ().Get_Translation ();
position = Get_Transform () * position;
}
// Return the vertex position
return position;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Position_Vertex
//
/////////////////////////////////////////////////////////////////////////////////////////
void
Box3DClass::Position_Vertex
(
int vertex,
const Vector3 &new_position
)
{
// Params OK?
if ((vertex >= 0) && (vertex < 8)) {
// Make a box from the vertex that we are 'locking' and
// the new position
Make_Box (Get_Vertex_Lock_Position (vertex), new_position);
}
return ;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Translate_Vertex
//
/////////////////////////////////////////////////////////////////////////////////////////
void
Box3DClass::Translate_Vertex
(
int vertex,
const Vector3 &translation
)
{
// Params OK?
if ((vertex >= 0) && (vertex < 8)) {
float new_width = m_Dimensions.Y;
float new_height = m_Dimensions.Z;
float new_depth = m_Dimensions.X;
// Modifiy the dimensions of the box
new_width += translation.Y * 2.0F;
new_height += translation.Z * 2.0F;
new_depth += translation.X * 2.0F;
// Modify the dimensions of the box if they are all valid
if ((new_width >= MIN_SIZE) &&
(new_height >= MIN_SIZE) &&
(new_depth >= MIN_SIZE)) {
Set_Dimensions (Vector3 (new_depth, new_width, new_height));
}
}
return ;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Make_Box
//
/////////////////////////////////////////////////////////////////////////////////////////
void
Box3DClass::Make_Box
(
const Vector3 &point1,
const Vector3 &point2
)
{
// Calculate the new center point for the box
Vector3 delta = point2 - point1;
Vector3 center = point1 + (delta / 2.0F);
// Recalc the box's position to be centered around the 2 points
Matrix3D transform = Get_Transform ();
transform.Set_Translation (center);
Set_Transform (transform);
// Convert the 2 points to object space
Matrix3D transform_inv;
transform.Get_Orthogonal_Inverse (transform_inv);
Vector3 obj_point1 = transform_inv * point1;
Vector3 obj_point2 = transform_inv * point2;
//Vector3 obj_point1 = point1 - center;
//Vector3 obj_point2 = point2 - center;
// Use these 2 points to determine the bottom left
// and upper right points of the box
Vector3 bottom_left;
Vector3 upper_right;
bottom_left.X = max (obj_point1.X, obj_point2.X);
bottom_left.Y = min (obj_point1.Y, obj_point2.Y);
bottom_left.Z = min (obj_point1.Z, obj_point2.Z);
upper_right.X = min (obj_point1.X, obj_point2.X);
upper_right.Y = max (obj_point1.Y, obj_point2.Y);
upper_right.Z = max (obj_point1.Z, obj_point2.Z);
// Given the bottom left and upper right coords, determine
// what each of the 8 verticies are...
m_Verticies[0].X = upper_right.X;
m_Verticies[0].Y = upper_right.Y;
m_Verticies[0].Z = bottom_left.Z;
m_Verticies[1].X = upper_right.X;
m_Verticies[1].Y = bottom_left.Y;
m_Verticies[1].Z = bottom_left.Z;
m_Verticies[2].X = upper_right.X;
m_Verticies[2].Y = bottom_left.Y;
m_Verticies[2].Z = upper_right.Z;
m_Verticies[3].X = upper_right.X;
m_Verticies[3].Y = upper_right.Y;
m_Verticies[3].Z = upper_right.Z;
m_Verticies[4].X = bottom_left.X;
m_Verticies[4].Y = upper_right.Y;
m_Verticies[4].Z = bottom_left.Z;
m_Verticies[5].X = bottom_left.X;
m_Verticies[5].Y = bottom_left.Y;
m_Verticies[5].Z = bottom_left.Z;
m_Verticies[6].X = bottom_left.X;
m_Verticies[6].Y = bottom_left.Y;
m_Verticies[6].Z = upper_right.Z;
m_Verticies[7].X = bottom_left.X;
m_Verticies[7].Y = upper_right.Y;
m_Verticies[7].Z = upper_right.Z;
// Recalc the box's dimensions and update its mesh
m_Dimensions = upper_right - bottom_left;
m_Dimensions.X = fabs (m_Dimensions.X);
m_Dimensions.Y = fabs (m_Dimensions.Y);
m_Dimensions.Z = fabs (m_Dimensions.Z);
m_bDirty = true;
Update_Verticies ();
return ;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Cast_Ray
//
/////////////////////////////////////////////////////////////////////////////////////////
bool
Box3DClass::Cast_Ray (RayCollisionTestClass & raytest)
{
if ((Get_Collision_Type() & raytest.CollisionType) == 0) return false;
Matrix3D world_to_obj;
Get_Transform().Get_Orthogonal_Inverse(world_to_obj);
RayCollisionTestClass objray(raytest,world_to_obj);
AABoxClass box;
box.Center.Set (0, 0, 0);
box.Extent = m_Dimensions * 0.5F;
bool hit = CollisionMath::Collide (objray.Ray, box, raytest.Result);
/*OBBoxClass obbox;
obbox.Center = Get_Transform ().Get_Translation ();
obbox.Extent = m_Dimensions * 0.5F;
obbox.Basis = Matrix3 (Get_Transform ());
CastResultStruct test_result = *raytest.Result;
bool obb_hit = CollisionMath::Collide (raytest.Ray, obbox, &test_result);
WWASSERT (hit == obb_hit);*/
//
// Transform result back into original coordinate system
//
if (hit) {
raytest.CollidedRenderObj = this;
if (raytest.Result->ComputeContactPoint) {
Matrix3D::Transform_Vector (Get_Transform (), raytest.Result->ContactPoint, &(raytest.Result->ContactPoint));
}
}
return hit;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Get_Obj_Space_Bounding_Box
//
/////////////////////////////////////////////////////////////////////////////////////////
void
Box3DClass::Get_Obj_Space_Bounding_Box(AABoxClass & box) const
{
box.Center = Vector3 (0,0,0);
box.Extent = m_Dimensions * 0.5F;
return ;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Set_Color
//
/////////////////////////////////////////////////////////////////////////////////////////
void
Box3DClass::Set_Color (const Vector3 &color)
{
for (int vertex = 0; vertex < VertCount; vertex ++) {
Change_Vertex_Color (vertex, Vector4 (color.X, color.Y, color.Z, 0.5F), 0);
}
return ;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Render
//
/////////////////////////////////////////////////////////////////////////////////////////
void
Box3DClass::Render (RenderInfoClass &rinfo)
{
// Only render if we if flagged visible
if (Is_Not_Hidden_At_All ()) {
DynamicMeshClass::Render (rinfo);
}
return ;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Get_Vertex_Position
//
/////////////////////////////////////////////////////////////////////////////////////////
Vector3
Box3DClass::Get_Vertex_Position (int vertex)
{
// The vertex position is simply the box's world position + the vertex offset
//Vector3 position = Get_Transform ().Get_Translation ();
//position += m_Verticies[vertex];
Vector3 position = Get_Transform () * m_Verticies[vertex];
// Return the vertex position
return position;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Drag_VertexXY
//
/////////////////////////////////////////////////////////////////////////////////////////
void
Box3DClass::Drag_VertexXY (int vertex_index, POINT point, const Vector3 &locked_vertex)
{
//
// The start of the ray is simply the camera's position
//
Vector3 ray_start = ::Get_Camera_Mgr ()->Get_Camera ()->Get_Transform ().Get_Translation ();
//
// Ensure the 'point' is correct for this mode (fullscreen/windowed)
//
float xpos = point.x;
float ypos = point.y;
::Constrain_Point_To_Aspect_Ratio (xpos, ypos);
//
// The 'end' of the ray is the world coordinates of the supplied point
//
Vector3 ray_end;
::Get_Camera_Mgr ()->Get_Camera ()->Device_To_World_Space (Vector2 (xpos, ypos), &ray_end);
ray_end = ray_start + ((ray_end-ray_start) * 1000.00F);
//
// If the ray isn't parallel to the z-axis, then move the corner vertex
//
if (fabs(ray_end.Z - ray_start.Z) > 1.0F) {
Vector3 vertex_pos = Get_Vertex_Position (vertex_index);
// Calculate the fraction of the distance along the ray where the
// Z value of the ray is the same as the Z value of the vertex we are moving.
// This simulates an intersection of the ray with the x-y plane at height 'z'.
double fraction = double(vertex_pos.Z - ray_start.Z) / double(ray_end.Z - ray_start.Z);
// Now calcuate the 2nd point based on this fraction.
// To do this we use the parameterized form of a line equation:
// P = P1 + (P2 - P1) * t
// (Where t is a percentage between 0 and 1)
Vector3 new_point = ray_start + ((ray_end - ray_start) * fraction);
Make_Box (locked_vertex, new_point);
}
return ;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
// Drag_VertexZ
//
/////////////////////////////////////////////////////////////////////////////////////////
void
Box3DClass::Drag_VertexZ (int vertex_index, POINT point, const Vector3 &locked_vertex)
{
//
// The start of the ray is simply the camera's position
//
Vector3 ray_start = ::Get_Camera_Mgr ()->Get_Camera ()->Get_Transform ().Get_Translation ();
//
// Ensure the 'point' is correct for this mode (fullscreen/windowed)
//
float xpos = point.x;
float ypos = point.y;
::Constrain_Point_To_Aspect_Ratio (xpos, ypos);
//
// The 'end' of the ray is the world coordinates of the supplied point
//
Vector3 ray_end;
::Get_Camera_Mgr ()->Get_Camera ()->Device_To_World_Space (Vector2 (xpos, ypos), &ray_end);
ray_end = ray_start + ((ray_end-ray_start) * 1000.00F);
//
// Determine which plane (y-z or x-z) to base the movement on
//
float deltax = ::fabs (ray_end.X - ray_start.X);
float deltay = ::fabs (ray_end.Y - ray_start.Y);
//
// Determine where the ray intersects this plane
//
double fraction = 0;
Vector3 vertex_pos = Get_Vertex_Position (vertex_index);
if ((deltax > deltay) && (deltax != 0.0F)) {
// Calculate the fraction of the distance along the ray where the
// X value of the ray is the same as the X value of the vertex.
// This simulates an intersection of the ray with the y-z plane at depth 'x'.
fraction = double(vertex_pos.X - ray_start.X) / double(ray_end.X - ray_start.X);
} else if ((deltay > deltax) && (deltay != 0.0F)) {
// Calculate the fraction of the distance along the ray where the
// X value of the ray is the same as the X value of the vertex.
// This simulates an intersection of the ray with the x-z plane at depth 'y'.
fraction = double(vertex_pos.Y - ray_start.Y) / double(ray_end.Y - ray_start.Y);
}
// If we calculated a valid fraction, then use it
// to determine the new vertex position.
if (min (deltax, deltay) != 0.0F) {
// Now calcuate the 2nd point based on this fraction.
// To do this we use the parameterized form of a line equation:
// P = P1 + (P2 - P1) * t
// (Where t is a percentage between 0 and 1)
Vector3 new_point = vertex_pos;
new_point.Z = ray_start.Z + ((ray_end.Z - ray_start.Z) * fraction);
Make_Box (locked_vertex, new_point);
}
return ;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Find_Intersection_Point
//
//////////////////////////////////////////////////////////////////////////////////
bool
Find_Intersection_Point
(
const AABoxClass & box,
const Vector3 & p0,
const Vector3 & p1,
float * percent,
Vector3 * intersection_point
)
{
bool retval = false;
//
// Find the locations of each of the 6 "planes"
// we will be testing against
//
float x1 = box.Center.X - box.Extent.X;
float x2 = box.Center.X + box.Extent.X;
float y1 = box.Center.Y - box.Extent.Y;
float y2 = box.Center.Y + box.Extent.Y;
float z1 = box.Center.Z - box.Extent.Z;
float z2 = box.Center.Z + box.Extent.Z;
float t_values[6] = { -1, -1, -1, -1, -1, -1 };
Vector3 delta = p1 - p0;
//
// Find the "t" values where the line intersects the
// 2 "Y-Z" planes
//
if (delta.X != 0) {
t_values[0] = (x1 - p0.X) / delta.X;
t_values[1] = (x2 - p0.X) / delta.X;
}
//
// Find the "t" values where the line intersects the
// 2 "X-Z" planes
//
if (delta.Y != 0) {
t_values[2] = (y1 - p0.Y) / delta.Y;
t_values[3] = (y2 - p0.Y) / delta.Y;
}
//
// Find the "t" values where the line intersects the
// 2 "X-Y" planes
//
if (delta.Z != 0) {
t_values[4] = (z1 - p0.Z) / delta.Z;
t_values[5] = (z2 - p0.Z) / delta.Z;
}
//
// Loop over all the "t" values we've calculated
//
(*percent) = 2.0F;
for (int index = 0; index < 6; index ++) {
//
// Is this "t" value the smallest in-range value we've
// found yet?
//
if ( t_values[index] >= 0 &&
t_values[index] <= 1.0F &&
t_values[index] < (*percent))
{
//
// Find the point which exists at this "t" value along the line segment
//
Vector3 point = p0 + delta * t_values[index];
//
// If this point isn't outside the box, then we'll consider it good enough
//
if ( (WWMath::Fabs (point.X - box.Center.X) <= (box.Extent.X + WWMATH_EPSILON)) &&
(WWMath::Fabs (point.Y - box.Center.Y) <= (box.Extent.Y + WWMATH_EPSILON)) &&
(WWMath::Fabs (point.Z - box.Center.Z) <= (box.Extent.Z + WWMATH_EPSILON)))
{
(*percent) = t_values[index];
(*intersection_point) = point;
retval = true;
}
}
}
return retval;
}

View File

@@ -0,0 +1,199 @@
/*
** Command & Conquer Renegade(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 : LevelEdit *
* *
* $Archive:: /Commando/Code/Tools/LevelEdit/Box3D.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 3/26/01 2:05p $*
* *
* $Revision:: 5 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __BOX3D_H
#define __BOX3D_H
#include "Dynamesh.H"
#include "EditorPhys.H"
#include "Utils.H"
/////////////////////////////////////////////////////////////////////////
// Forward declarations
/////////////////////////////////////////////////////////////////////////
class RayCollisionTestClass;
/////////////////////////////////////////////////////////////////////////
//
// Box3DClass
//
/////////////////////////////////////////////////////////////////////////
class Box3DClass : public DynamicMeshClass
{
public:
//////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////
Box3DClass (void)
: m_Dimensions (1, 1, 1),
m_bDirty (false),
DynamicMeshClass (12, 24) { Create_Model (); }
Box3DClass (float width, float height, float depth)
: m_Dimensions (depth, width, height),
m_bDirty (false),
DynamicMeshClass (12, 24) { Create_Model (); }
Box3DClass (const Vector3 &dimensions)
: m_Dimensions (dimensions),
m_bDirty (false),
DynamicMeshClass (12, 24) { Create_Model (); }
virtual ~Box3DClass (void) {}
//////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////
//
// Base class overrides
//
bool Cast_Ray (RayCollisionTestClass &raytest);
void Get_Obj_Space_Bounding_Box(AABoxClass & box) const;
void Render (RenderInfoClass &rinfo);
//
// Dimension methods
//
void Set_Dimensions (const Vector3 &dimensions);
void Set_Width (float width);
void Set_Height (float height);
void Set_Depth (float depth);
void Get_Dimensions (Vector3 &dimensions) const { dimensions = m_Dimensions; }
const Vector3 & Get_Dimensions (void) const { return m_Dimensions; }
float Get_Width (void) const { return m_Dimensions.Y; }
float Get_Height (void) const { return m_Dimensions.Z; }
float Get_Depth (void) const { return m_Dimensions.X; }
//
// Vertex methods
//
void Position_Vertex (int vertex, const Vector3 &new_position);
void Translate_Vertex (int vertex, const Vector3 &translation);
Vector3 Get_Vertex_Position (int vertex);
void Get_Vertex_Position (int vertex, Vector3 &position);
Vector3 Get_Vertex_Lock_Position (int vertex);
//
// Creation routines
//
void Make_Box (const Vector3 &point1, const Vector3 &point2);
void Set_Color (const Vector3 &color);
//
// Dynamic modification
//
void Drag_VertexXY (int vertex, POINT new_point, const Vector3 &locked_vertex);
void Drag_VertexZ (int vertex, POINT new_point, const Vector3 &locked_vertex);
protected:
//////////////////////////////////////////////////////////
// Protected methods
//////////////////////////////////////////////////////////
void Create_Model (void);
void Easy_Vertex (const Vector3 &vertex) { DynamicMeshClass::Vertex (vertex.X, vertex.Y, vertex.Z, 0, 0); }
void Easy_Move_Vertex (int vertex_index, const Vector3 &vertex) { DynamicMeshClass::Move_Vertex (vertex_index, vertex.X, vertex.Y, vertex.Z); }
void Update_Verticies (void);
private:
//////////////////////////////////////////////////////////
// Private member data
//////////////////////////////////////////////////////////
Vector3 m_Dimensions;
Vector3 m_Verticies[8];
bool m_bDirty;
};
/////////////////////////////////////////////////////////////////////////
//
// Box3DPhysClass
//
/////////////////////////////////////////////////////////////////////////
class Box3DPhysClass : public EditorPhysClass
{
public:
//////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////
Box3DPhysClass (void)
: m_pBox (NULL) { Initialize (1, 1, 1); }
Box3DPhysClass (const Vector3 &dimensions)
: m_pBox (NULL) { Initialize (dimensions.X, dimensions.Y, dimensions.Z); }
virtual ~Box3DPhysClass (void) { MEMBER_RELEASE (m_pBox); }
//////////////////////////////////////////////////////////
// Public operators/methods
//////////////////////////////////////////////////////////
operator Box3DClass * (void) const { return m_pBox; }
Box3DClass * Get_Box (void) const { return m_pBox; }
protected:
//////////////////////////////////////////////////////////
// Protected member data
//////////////////////////////////////////////////////////
void Initialize (float x, float y, float z) { m_pBox = new Box3DClass (x, y, z); Set_Model (m_pBox); }
private:
//////////////////////////////////////////////////////////
// Private member data
//////////////////////////////////////////////////////////
Box3DClass * m_pBox;
};
#endif //__BOX3D_H

View File

@@ -0,0 +1,626 @@
/*
** Command & Conquer Renegade(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 : LevelEdit *
* *
* $Archive:: /Commando/Code/Tools/LevelEdit/BuildingNode.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 9/13/01 9:44a $*
* *
* $Revision:: 7 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "stdafx.h"
#include "buildingnode.h"
#include "buildingchildnode.h"
#include "sceneeditor.h"
#include "filemgr.h"
#include "_assetmgr.h"
#include "editorassetmgr.h"
#include "w3d_file.h"
#include "cameramgr.h"
#include "collisiongroups.h"
#include "persistfactory.h"
#include "preset.h"
#include "editorchunkids.h"
#include "modelutils.h"
#include "vehiclefactorygameobj.h"
#include "refinerygameobj.h"
#include "nodemgr.h"
//////////////////////////////////////////////////////////////////////////////
// Persist factory
//////////////////////////////////////////////////////////////////////////////
SimplePersistFactoryClass<BuildingNodeClass, CHUNKID_NODE_BUILDING> _BuildingNodePersistFactory;
enum
{
CHUNKID_VARIABLES = 0x09071125,
CHUNKID_BASE_CLASS,
};
enum
{
VARID_VISOBJECTID = 0x01,
VARID_VISSECTORID,
VARID_CHILD_NODE
};
//////////////////////////////////////////////////////////////////////////////
//
// BuildingNodeClass
//
//////////////////////////////////////////////////////////////////////////////
BuildingNodeClass::BuildingNodeClass (PresetClass *preset)
: m_PhysObj (NULL),
ObjectNodeClass (preset)
{
return ;
}
//////////////////////////////////////////////////////////////////////////////
//
// BuildingNodeClass
//
//////////////////////////////////////////////////////////////////////////////
BuildingNodeClass::BuildingNodeClass (const BuildingNodeClass &src)
: m_PhysObj (NULL),
ObjectNodeClass (NULL)
{
(*this) = src;
return ;
}
//////////////////////////////////////////////////////////////////////////////
//
// ~BuildingNodeClass
//
//////////////////////////////////////////////////////////////////////////////
BuildingNodeClass::~BuildingNodeClass (void)
{
Free_Child_Nodes ();
Remove_From_Scene ();
MEMBER_RELEASE (m_PhysObj);
return ;
}
//////////////////////////////////////////////////////////////////////////////
//
// Initialize
//
// Note: This may be called more than once. It is used as an 'initialize'
// and a 're-initialize'.
//
//////////////////////////////////////////////////////////////////////////////
void
BuildingNodeClass::Initialize (void)
{
MEMBER_RELEASE (m_PhysObj);
//
// Load the model we want to use to identify the building controller
//
RenderObjClass *render_obj = ::Create_Render_Obj ("BUILDINGICON");
if (render_obj != NULL) {
//
// Create the new physics object
//
m_PhysObj = new DecorationPhysClass;
m_PhysObj->Set_Model (render_obj);
m_PhysObj->Set_Collision_Group (EDITOR_COLLISION_GROUP);
m_PhysObj->Peek_Model ()->Set_User_Data ((PVOID)&m_HitTestInfo, FALSE);
m_PhysObj->Set_Transform (m_Transform);
::Set_Model_Collision_Type (m_PhysObj->Peek_Model (), COLLISION_TYPE_0);
render_obj->Release_Ref ();
}
ObjectNodeClass::Initialize ();
return ;
}
////////////////////////////////////////////////////////////////
//
// Get_Factory
//
////////////////////////////////////////////////////////////////
const PersistFactoryClass &
BuildingNodeClass::Get_Factory (void) const
{
return _BuildingNodePersistFactory;
}
/////////////////////////////////////////////////////////////////
//
// operator=
//
/////////////////////////////////////////////////////////////////
const BuildingNodeClass &
BuildingNodeClass::operator= (const BuildingNodeClass &src)
{
//
// Start fresh
//
Free_Child_Nodes ();
//
// Copy the child node list
//
for (int index = 0; index < src.m_ChildNodes.Count (); index ++) {
NodeClass *child_node = src.m_ChildNodes[index];
if (child_node != NULL) {
Add_Child_Node (child_node->Get_Transform ());
}
}
NodeClass::operator= (src);
return *this;
}
/////////////////////////////////////////////////////////////////
//
// Save
//
/////////////////////////////////////////////////////////////////
bool
BuildingNodeClass::Save (ChunkSaveClass &csave)
{
csave.Begin_Chunk (CHUNKID_BASE_CLASS);
ObjectNodeClass::Save (csave);
csave.End_Chunk ();
csave.Begin_Chunk (CHUNKID_VARIABLES);
//
// Save the list of child node transforms
//
for (int index = 0; index < m_ChildNodes.Count (); index ++) {
NodeClass *child_node = m_ChildNodes[index];
if (child_node != NULL) {
Matrix3D tm = child_node->Get_Transform ();
WRITE_MICRO_CHUNK (csave, VARID_CHILD_NODE, tm);
}
}
csave.End_Chunk ();
return true;
}
/////////////////////////////////////////////////////////////////
//
// Load
//
/////////////////////////////////////////////////////////////////
bool
BuildingNodeClass::Load (ChunkLoadClass &cload)
{
while (cload.Open_Chunk ()) {
switch (cload.Cur_Chunk_ID ()) {
case CHUNKID_BASE_CLASS:
ObjectNodeClass::Load (cload);
break;
case CHUNKID_VARIABLES:
Load_Variables (cload);
break;
}
cload.Close_Chunk ();
}
return true;
}
/////////////////////////////////////////////////////////////////
//
// Load_Variables
//
/////////////////////////////////////////////////////////////////
bool
BuildingNodeClass::Load_Variables (ChunkLoadClass &cload)
{
while (cload.Open_Micro_Chunk ()) {
switch (cload.Cur_Micro_Chunk_ID ()) {
case VARID_CHILD_NODE:
{
//
// Read the child node's transfrom from the chunk
//
Matrix3D tm;
cload.Read (&tm, sizeof (tm));
//
// Add a new child node at this location
//
Add_Child_Node (tm);
}
break;
}
cload.Close_Micro_Chunk ();
}
return true;
}
//////////////////////////////////////////////////////////////////////
//
// Pre_Export
//
//////////////////////////////////////////////////////////////////////
void
BuildingNodeClass::Pre_Export (void)
{
Add_Ref ();
if (m_PhysObj != NULL && m_IsInScene) {
::Get_Scene_Editor ()->Remove_Object (m_PhysObj);
//
// Configure the building object (if necessary)
//
BuildingGameObj *building = Get_Building ();
if (building != NULL) {
//
// What type of building is this?
//
if (building->As_VehicleFactoryGameObj () != NULL) {
VehicleFactoryGameObj *airstrip = building->As_VehicleFactoryGameObj ();
//
// Configure the factory's creation transform
//
if (m_ChildNodes.Count () > 0) {
airstrip->Set_Creation_TM (m_ChildNodes[0]->Get_Transform ());
}
} else if (building->As_RefineryGameObj () != NULL) {
RefineryGameObj *refinery = building->As_RefineryGameObj ();
//
// Configure the refinery's docking transform
//
if (m_ChildNodes.Count () > 0) {
refinery->Set_Dock_TM (m_ChildNodes[0]->Get_Transform ());
}
}
}
//
// Pass the Pre_Export call onto any child nodes as well
//
for (int index = 0; index < m_ChildNodes.Count (); index ++) {
NodeClass *child_node = m_ChildNodes[index];
EditorLineClass *line = m_ChildLines[index];
//
// Remove the line from the scene
//
::Get_Scene_Editor ()->Remove_Object (line);
}
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Post_Export
//
//////////////////////////////////////////////////////////////////////
void
BuildingNodeClass::Post_Export (void)
{
if (m_PhysObj != NULL && m_IsInScene) {
::Get_Scene_Editor ()->Add_Dynamic_Object (m_PhysObj);
//
// Pass the Post_Export call onto any child nodes as well
//
for (int index = 0; index < m_ChildNodes.Count (); index ++) {
NodeClass *child_node = m_ChildNodes[index];
EditorLineClass *line = m_ChildLines[index];
//
// Add the line back into the world
//
::Get_Scene_Editor ()->Add_Dynamic_Object (line);
}
}
Release_Ref ();
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Add_Child_Node
//
//////////////////////////////////////////////////////////////////////
NodeClass *
BuildingNodeClass::Add_Child_Node (const Matrix3D &tm)
{
BuildingChildNodeClass *child_node = new BuildingChildNodeClass;
child_node->Initialize ();
child_node->Set_Transform (tm);
child_node->Set_Building (this);
NodeMgrClass::Setup_Node_Identity (*child_node);
m_ChildNodes.Add (child_node);
//
// Create and add the line from the building to the child node
//
EditorLineClass *line = new EditorLineClass;
line->Reset (m_Transform.Get_Translation (), tm.Get_Translation ());
m_ChildLines.Add (line);
//
// Add the objects to the scene if necessary
//
if (m_IsInScene) {
child_node->Add_To_Scene ();
::Get_Scene_Editor ()->Add_Dynamic_Object (line);
}
return child_node;
}
//////////////////////////////////////////////////////////////////////
//
// Can_Add_Child_Nodes
//
//////////////////////////////////////////////////////////////////////
bool
BuildingNodeClass::Can_Add_Child_Nodes (void) const
{
bool retval = false;
BuildingGameObj *building = Get_Building ();
if (building != NULL) {
//
// Is this one of the types of buildings which need
// child nodes?
//
if (building->As_VehicleFactoryGameObj () != NULL) {
//
// This type of building can only have one child node
//
if (m_ChildNodes.Count () == 0) {
retval = true;
}
} else if (building->As_RefineryGameObj () != NULL) {
//
// This type of building can only have one child node
//
if (m_ChildNodes.Count () == 0) {
retval = true;
}
}
}
return retval;
}
//////////////////////////////////////////////////////////////////////
//
// Remove_Child_Node
//
//////////////////////////////////////////////////////////////////////
void
BuildingNodeClass::Remove_Child_Node (NodeClass *child_node)
{
//
// Try to find the child node
//
for (int index = 0; index < m_ChildNodes.Count (); index ++) {
if (child_node == m_ChildNodes[index]) {
//
// Free the child node
//
MEMBER_RELEASE (child_node);
m_ChildNodes.Delete (index);
//
// Remove and free the line to the child node
//
::Get_Scene_Editor ()->Remove_Object (m_ChildLines[index]);
m_ChildLines[index]->Release_Ref ();
m_ChildLines.Delete (index);
break;
}
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Free_Child_Nodes
//
//////////////////////////////////////////////////////////////////////
void
BuildingNodeClass::Free_Child_Nodes (void)
{
SceneEditorClass *scene = ::Get_Scene_Editor ();
//
// Release our hold on each child node
//
for (int index = 0; index < m_ChildNodes.Count (); index ++) {
NodeClass *child_node = m_ChildNodes[index];
EditorLineClass *line = m_ChildLines[index];
scene->Remove_Object (line);
child_node->Remove_From_Scene ();
MEMBER_RELEASE (child_node);
MEMBER_RELEASE (line);
}
//
// Remove all the child nodes from the list
//
m_ChildNodes.Delete_All ();
m_ChildLines.Delete_All ();
return ;
}
//////////////////////////////////////////////////////////////////////////////
//
// Add_To_Scene
//
//////////////////////////////////////////////////////////////////////////////
void
BuildingNodeClass::Add_To_Scene (void)
{
SceneEditorClass *scene = ::Get_Scene_Editor ();
//
// Add all the waypoints to the scene
//
for (int index = 0; index < m_ChildNodes.Count (); index ++) {
NodeClass *child_node = m_ChildNodes[index];
EditorLineClass *line = m_ChildLines[index];
child_node->Add_To_Scene ();
scene->Add_Dynamic_Object (line);
}
NodeClass::Add_To_Scene ();
return ;
}
//////////////////////////////////////////////////////////////////////////////
//
// Remove_From_Scene
//
//////////////////////////////////////////////////////////////////////////////
void
BuildingNodeClass::Remove_From_Scene (void)
{
SceneEditorClass *scene = ::Get_Scene_Editor ();
if (scene != NULL && m_IsInScene) {
//
// Remove all the waypoints from the scene
//
for (int index = 0; index < m_ChildNodes.Count (); index ++) {
NodeClass *child_node = m_ChildNodes[index];
EditorLineClass *line = m_ChildLines[index];
child_node->Remove_From_Scene ();
scene->Remove_Object (line);
}
}
NodeClass::Remove_From_Scene ();
return ;
}
//////////////////////////////////////////////////////////////////////////////
//
// Update_Lines
//
//////////////////////////////////////////////////////////////////////////////
void
BuildingNodeClass::Update_Lines (void)
{
for (int index = 0; index < m_ChildNodes.Count (); index ++) {
NodeClass *child_node = m_ChildNodes[index];
EditorLineClass *line = m_ChildLines[index];
//
// Update the line between the node and its child
//
line->Reset (Get_Transform ().Get_Translation (), child_node->Get_Position ());
}
return ;
}
//////////////////////////////////////////////////////////////////////////////
//
// Hide
//
//////////////////////////////////////////////////////////////////////////////
void
BuildingNodeClass::Hide (bool hide)
{
//
// Apply the same operation to all the child nodes and lines
//
for (int index = 0; index < m_ChildNodes.Count (); index ++) {
NodeClass *child_node = m_ChildNodes[index];
EditorLineClass *line = m_ChildLines[index];
child_node->Hide (hide);
line->Hide (hide);
}
NodeClass::Hide (hide);
return ;
}
//////////////////////////////////////////////////////////////////////////////
//
// Get_Sub_Node
//
//////////////////////////////////////////////////////////////////////////////
NodeClass *
BuildingNodeClass::Get_Sub_Node (int index)
{
return m_ChildNodes[index];
}

View File

@@ -0,0 +1,241 @@
/*
** Command & Conquer Renegade(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 : LevelEdit *
* *
* $Archive:: /Commando/Code/Tools/LevelEdit/BuildingNode.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 5/11/01 9:04a $*
* *
* $Revision:: 6 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __BUILDING_NODE_H
#define __BUILDING_NODE_H
#include "objectnode.h"
#include "vector.h"
#include "icons.h"
#include "decophys.h"
#include "building.h"
#include "editorline.h"
////////////////////////////////////////////////////////////////////////////
// Forward declarations
////////////////////////////////////////////////////////////////////////////
class PresetClass;
class BuildingChildNodeClass;
////////////////////////////////////////////////////////////////////////////
//
// BuildingNodeClass
//
////////////////////////////////////////////////////////////////////////////
class BuildingNodeClass : public ObjectNodeClass
{
public:
//////////////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////////////
BuildingNodeClass (PresetClass *preset = NULL);
BuildingNodeClass (const BuildingNodeClass &src);
~BuildingNodeClass (void);
//////////////////////////////////////////////////////////////
// Public operators
//////////////////////////////////////////////////////////////
const BuildingNodeClass &operator= (const BuildingNodeClass &src);
//////////////////////////////////////////////////////////////////
// Public methods
//////////////////////////////////////////////////////////////////
// From PersistClass
virtual const PersistFactoryClass & Get_Factory (void) const;
// From NodeClass
void Initialize (void);
NodeClass * Clone (void) { return new BuildingNodeClass (*this); }
NODE_TYPE Get_Type (void) const { return NODE_TYPE_BUILDING; }
int Get_Icon_Index (void) const { return BUILDING_ICON; }
PhysClass * Peek_Physics_Obj (void) const { return m_PhysObj; }
bool Is_Static (void) const { return false; }
bool Can_Be_Rotated_Freely (void) const { return true; }
void On_Rotate (void);
void On_Translate (void);
void On_Transform (void);
void Add_To_Scene (void);
void Remove_From_Scene (void);
void Hide (bool hide);
NodeClass * Add_Child_Node (const Matrix3D &tm);
bool Can_Add_Child_Nodes (void) const;
int Get_Sub_Node_Count (void) const { return m_ChildNodes.Count (); }
NodeClass * Get_Sub_Node (int index);
//
// Export methods
//
void Pre_Export (void);
void Post_Export (void);
//
// From PersistClass
//
bool Save (ChunkSaveClass &csave);
bool Load (ChunkLoadClass &cload);
//
// Building specific
//
void Enable_Power (bool onoff);
bool Is_Power_Enabled (void) const;
void Set_Normalized_Health (float health);
void Remove_Child_Node (NodeClass *child_node);
void Update_Lines (void);
protected:
//////////////////////////////////////////////////////////////////
// Protected methods
//////////////////////////////////////////////////////////////////
bool Load_Variables (ChunkLoadClass &cload);
void Free_Child_Nodes (void);
BuildingGameObj * Get_Building (void) const { return reinterpret_cast<BuildingGameObj *> (m_GameObj); }
//////////////////////////////////////////////////////////////////
// Protected member data
//////////////////////////////////////////////////////////////////
DecorationPhysClass * m_PhysObj;
DynamicVectorClass<BuildingChildNodeClass *> m_ChildNodes;
DynamicVectorClass<EditorLineClass *> m_ChildLines;
};
//////////////////////////////////////////////////////////////////
// On_Rotate
//////////////////////////////////////////////////////////////////
inline void
BuildingNodeClass::On_Rotate (void)
{
if (m_GameObj != NULL) {
((BuildingGameObj *)m_GameObj)->Set_Position (m_Transform.Get_Translation ());
}
Update_Lines ();
NodeClass::On_Rotate ();
return ;
}
//////////////////////////////////////////////////////////////////
// On_Translate
//////////////////////////////////////////////////////////////////
inline void
BuildingNodeClass::On_Translate (void)
{
if (m_GameObj != NULL) {
((BuildingGameObj *)m_GameObj)->Set_Position (m_Transform.Get_Translation ());
}
Update_Lines ();
NodeClass::On_Translate ();
return ;
}
//////////////////////////////////////////////////////////////////
// On_Transform
//////////////////////////////////////////////////////////////////
inline void
BuildingNodeClass::On_Transform (void)
{
if (m_GameObj != NULL) {
((BuildingGameObj *)m_GameObj)->Set_Position (m_Transform.Get_Translation ());
}
Update_Lines ();
NodeClass::On_Transform ();
return ;
}
//////////////////////////////////////////////////////////////////
// Enable_Power
//////////////////////////////////////////////////////////////////
inline void
BuildingNodeClass::Enable_Power (bool onoff)
{
if (m_GameObj != NULL) {
((BuildingGameObj *)m_GameObj)->Enable_Power (onoff);
}
return ;
}
//////////////////////////////////////////////////////////////////
// Is_Power_Enabled
//////////////////////////////////////////////////////////////////
inline bool
BuildingNodeClass::Is_Power_Enabled (void) const
{
bool retval = false;
if (m_GameObj != NULL) {
retval = ((BuildingGameObj *)m_GameObj)->Is_Power_Enabled ();
}
return retval;
}
//////////////////////////////////////////////////////////////////
// Set_Normalized_Health
//////////////////////////////////////////////////////////////////
inline void
BuildingNodeClass::Set_Normalized_Health (float health)
{
if (m_GameObj != NULL) {
((BuildingGameObj *)m_GameObj)->Set_Normalized_Health (health);
}
return ;
}
#endif //__BUILDING_NODE_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,220 @@
/*
** Command & Conquer Renegade(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 : LevelEdit *
* *
* $Archive:: /Commando/Code/Tools/LevelEdit/CameraMgr.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 11/02/00 5:57p $*
* *
* $Revision:: 11 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __CAMERAMGR_H
#define __CAMERAMGR_H
#include "refcount.h"
#include "utils.h"
#include "rendobj.h"
#include "assetmgr.h"
#include "camera.h"
#include "physcontrol.h"
#include "hermitespline.h"
// Forward declarations
class NodeClass;
class SoldierGameObj;
class SoldierGameObjDef;
/*class CamaraCharPhys : public CharPhysClass
{
public:
CamaraCharPhys (void);
virtual ~CamaraCharPhys (void);
protected:
RenderObjClass * m_pRenderObj;
};*/
///////////////////////////////////////////////////////////////
//
// CameraMgr
//
///////////////////////////////////////////////////////////////
class CameraMgr
{
public:
///////////////////////////////////////////////////
// Public constructors/destructors
///////////////////////////////////////////////////
CameraMgr (void);
virtual ~CameraMgr (void);
///////////////////////////////////////////////////
// Public data types
///////////////////////////////////////////////////
typedef enum
{
MODE_MOVE_PLANE = 0,
MODE_MOVE_UPDOWN = 1,
MODE_FLY_THROUGH = 2,
MODE_WALK_THROUGH = 3,
MODE_ROTATE_FREE = 4,
MODE_ROTATE_X = 5,
MODE_ROTATE_Y = 6,
MODE_ROTATE_Z = 7,
MODE_ORBIT = 8,
MODE_FLYTO = 9,
MODE_COUNT
} CAMERA_MODE;
typedef enum
{
CAMERA_FRONT = 1,
CAMERA_BACK,
CAMERA_TOP,
CAMERA_BOTTOM,
CAMERA_LEFT,
CAMERA_RIGHT,
CAMERA_COUNT
} CAMERA_POS;
///////////////////////////////////////////////////
// Public methods
///////////////////////////////////////////////////
CameraMgr::CAMERA_MODE Get_Camera_Mode (void) const { return m_CameraMode; }
void Set_Camera_Mode (CAMERA_MODE new_mode);
void Update_Camera (float deltax, float deltay);
void Update_Camera_Animation (void);
void On_Frame (void);
Matrix3D Get_Character_TM (void);
//
// Position methods
//
void Set_Camera_Pos (CAMERA_POS position);
void Set_Transform (const Matrix3D &transform);
void Set_Position (const Vector3 &position);
void Move_Fwd (void) {}
void Move_Bkwd (void) {}
void Turn_Left (void) {}
void Turn_Right (void) {}
void Look_Up (void) {}
void Look_Dn (void) {}
void Look_Center (void) {}
void Increase_Speed (void);
void Decrease_Speed (void);
void Level_Camera (void);
void Goto_Node (NodeClass *node);
void Goto_Group (GroupMgrClass *pgroup);
void Fly_To_Transform (const Matrix3D &transform);
//
// Inline accessors
//
CameraClass * Get_Camera (void) const { return m_pCamera; }
//CamaraCharPhys * Get_Walkthru_Character (void) const { return m_pWalkThroughPhys; }
float Get_Speed_Modifier (void) const { return m_SpeedModifier; }
protected:
///////////////////////////////////////////////////
// Friends
///////////////////////////////////////////////////
friend LRESULT CALLBACK fnCameraKeyboardHook (int code, WPARAM wParam, LPARAM lParam);
friend class CLevelEditView;
///////////////////////////////////////////////////
// Protected methods
///////////////////////////////////////////////////
void Init_Camera (void);
void Auto_Level (void);
void Update_Fly_To (void);
static void Update_Camera_MOVE_ZOOM (CameraClass &camera, float deltax, float deltay);
static void Update_Camera_MOVE_PLANE (CameraClass &camera, float deltax, float deltay);
static void Update_Camera_FLY_THROUGH (CameraClass &camera, float deltax, float deltay);
static void Update_Camera_WALK_THROUGH (CameraClass &camera, float deltax, float deltay);
static void Update_Camera_ROTATE_FREE (CameraClass &camera, float deltax, float deltay);
static void Update_Camera_ROTATE_X (CameraClass &camera, float deltax, float deltay);
static void Update_Camera_ROTATE_Y (CameraClass &camera, float deltax, float deltay);
static void Update_Camera_ROTATE_Z (CameraClass &camera, float deltax, float deltay);
static void Update_Camera_ORBIT (CameraClass &camera, float deltax, float deltay);
static void Update_Camera_FLY_TO (CameraClass &camera, float deltax, float deltay);
///////////////////////////////////////////////////
// Protected data types
///////////////////////////////////////////////////
typedef void (*UPDATE_CAMERA_FN) (CameraClass &camera, float deltax, float deltay);
///////////////////////////////////////////////////
// Static member data
///////////////////////////////////////////////////
static bool _pKeyboardState[256];
static UPDATE_CAMERA_FN _pfnUpdateMethods[CAMERA_MODE::MODE_COUNT];
static HHOOK _hHook;
private:
///////////////////////////////////////////////////
// Private member data
///////////////////////////////////////////////////
bool m_bAutoLevel;
CameraClass * m_pCamera;
CAMERA_MODE m_CameraMode;
Matrix3D m_AutoLevelInitalMatrix;
Matrix3D m_AutoLevelEndMatrix;
double m_AutoLevelPercent;
//CamaraCharPhys * m_pWalkThroughPhys;
PhysControllerClass m_VJoystick;
float m_SpeedModifier;
HermiteSpline3DClass m_FlyToSpline;
Matrix3D m_FlyToStartTransform;
Matrix3D m_FlyToEndTransform;
DWORD m_FlyToStartTime;
SoldierGameObj * m_WalkThruObj;
SoldierGameObjDef * m_WalkThruDef;
};
#endif //__CAMERAMGR_H

View File

@@ -0,0 +1,241 @@
/*
** Command & Conquer Renegade(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/>.
*/
// ameraSettingsFormClass.cpp : implementation file
//
#include "StdAfx.h"
#include "leveledit.h"
#include "CameraSettingsForm.H"
#include "Utils.H"
#include "CameraMgr.H"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
//
// CameraSettingsFormClass
//
CameraSettingsFormClass::CameraSettingsFormClass (void)
: DockableFormClass(CameraSettingsFormClass::IDD)
{
//{{AFX_DATA_INIT(CameraSettingsFormClass)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
return ;
}
/////////////////////////////////////////////////////////////////////////////
//
// ~CameraSettingsFormClass
//
CameraSettingsFormClass::~CameraSettingsFormClass (void)
{
return ;
}
/////////////////////////////////////////////////////////////////////////////
//
// DoDataExchange
//
void
CameraSettingsFormClass::DoDataExchange (CDataExchange* pDX)
{
DockableFormClass::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CameraSettingsFormClass)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
return ;
}
BEGIN_MESSAGE_MAP(CameraSettingsFormClass, DockableFormClass)
//{{AFX_MSG_MAP(CameraSettingsFormClass)
ON_NOTIFY(UDN_DELTAPOS, IDC_DEPTH_SPIN, OnDeltaPosDepthSpin)
ON_EN_UPDATE(IDC_DEPTH_EDIT, OnUpdateDepthEdit)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CameraSettingsFormClass diagnostics
#ifdef _DEBUG
void CameraSettingsFormClass::AssertValid() const
{
DockableFormClass::AssertValid();
}
void CameraSettingsFormClass::Dump(CDumpContext& dc) const
{
DockableFormClass::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
//
// HandleInitDialog
//
void
CameraSettingsFormClass::HandleInitDialog (void)
{
// Set the depth range
SendDlgItemMessage (IDC_DEPTH_SPIN, UDM_SETRANGE, 0, MAKELPARAM (4000, 20));
// Put the current camera information into the controls
Update_Controls ();
return ;
}
/////////////////////////////////////////////////////////////////////////////
//
// Update_Controls
//
void
CameraSettingsFormClass::Update_Controls (void)
{
CameraMgr *pcamera_mgr = ::Get_Camera_Mgr ();
if (pcamera_mgr != NULL) {
const Matrix3D &transform = pcamera_mgr->Get_Camera ()->Get_Transform ();
CString temp_string;
// Put the x position of the camera into the controls
temp_string.Format ("%.2f", transform.Get_X_Translation ());
SetDlgItemText (IDC_POSX_EDIT, temp_string);
// Put the y position of the camera into the controls
temp_string.Format ("%.2f", transform.Get_Y_Translation ());
SetDlgItemText (IDC_POSY_EDIT, temp_string);
// Put the z position of the camera into the controls
temp_string.Format ("%.2f", transform.Get_Z_Translation ());
SetDlgItemText (IDC_POSZ_EDIT, temp_string);
// Put the x rotation of the camera into the controls
temp_string.Format ("%.2f", (float)RAD_TO_DEG (transform.Get_X_Rotation ()));
SetDlgItemText (IDC_ROTATEX_EDIT, temp_string);
// Put the y rotation of the camera into the controls
temp_string.Format ("%.2f", (float)RAD_TO_DEG (transform.Get_Y_Rotation ()));
SetDlgItemText (IDC_ROTATEY_EDIT, temp_string);
// Put the z rotation of the camera into the controls
temp_string.Format ("%.2f", (float)RAD_TO_DEG (transform.Get_Z_Rotation ()));
SetDlgItemText (IDC_ROTATEZ_EDIT, temp_string);
// Put the current depth of the camera into its dialog control
float near_plane = 0;
float far_plane = 0;
pcamera_mgr->Get_Camera ()->Get_Clip_Planes (near_plane, far_plane);
SetDlgItemInt (IDC_DEPTH_EDIT, (int)far_plane);
SendDlgItemMessage (IDC_DEPTH_SPIN, 0, MAKELPARAM ((short)far_plane, 0));
}
return ;
}
/////////////////////////////////////////////////////////////////////////////
//
// OnDeltaPosDepthSpin
//
void
CameraSettingsFormClass::OnDeltaPosDepthSpin
(
NMHDR* pNMHDR,
LRESULT* pResult
)
{
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
if (pNMUpDown) {
Set_Depth (pNMUpDown->iPos);
}
*pResult = 0;
return ;
}
/////////////////////////////////////////////////////////////////////////////
//
// OnUpdateDepthEdit
//
void
CameraSettingsFormClass::OnUpdateDepthEdit (void)
{
Set_Depth (GetDlgItemInt (IDC_DEPTH_EDIT));
return ;
}
/////////////////////////////////////////////////////////////////////////////
//
// Set_Depth
//
void
CameraSettingsFormClass::Set_Depth (int new_depth)
{
CameraMgr *pcamera_mgr = ::Get_Camera_Mgr ();
if (pcamera_mgr != NULL) {
// Get the current 'near' clip plane
double near_plane = 0;
double far_plane = 0;
//pcamera_mgr->Get_Camera ()->Get_Clip_Planes (near_plane, far_plane);
// Set the new 'far' clip plane
//pcamera_mgr->Get_Camera ()->Set_Clip_Planes (near_plane, (double)new_depth);
}
return ;
}
////////////////////////////////////////////////////////////////////////////
//
// WindowProc
//
LRESULT
CameraSettingsFormClass::WindowProc
(
UINT message,
WPARAM wParam,
LPARAM lParam
)
{
// Is this the message we are expecting?
if ((message == WM_SHOWWINDOW) || (message == WM_ACTIVATE)) {
// Make sure the controls reflect the current state when we are
// shown
if ((BOOL)LOWORD (wParam)) {
Update_Controls ();
}
}
// Allow the base class to process this message
return DockableFormClass::WindowProc(message, wParam, lParam);
}

View File

@@ -0,0 +1,161 @@
/*
** Command & Conquer Renegade(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/>.
*/
// CheckinStyleDialog.cpp : implementation file
//
#include "stdafx.h"
#include "leveledit.h"
#include "CheckinStyleDialog.h"
#include "RegKeys.H"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
//
// Constants
//
const TCHAR * const REG_NOT_CACHED = TEXT ("NotCached");
const TCHAR * const REG_NOW = TEXT ("Now");
const TCHAR * const REG_LATER = TEXT ("Later");
/////////////////////////////////////////////////////////////////////////////
//
// CheckinStyleDialogClass
//
CheckinStyleDialogClass::CheckinStyleDialogClass(CWnd* pParent /*=NULL*/)
: CDialog(CheckinStyleDialogClass::IDD, pParent)
{
//{{AFX_DATA_INIT(CheckinStyleDialogClass)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void CheckinStyleDialogClass::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CheckinStyleDialogClass)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CheckinStyleDialogClass, CDialog)
//{{AFX_MSG_MAP(CheckinStyleDialogClass)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CheckinStyleDialogClass message handlers
/////////////////////////////////////////////////////////////////////////////
//
// OnOK
//
void
CheckinStyleDialogClass::OnOK (void)
{
UINT ret_code = IDC_UPDATE_NOW;
CString cache_value = REG_NOW;
if (SendDlgItemMessage (IDC_UPDATE_LATER, BM_GETCHECK) == 1) {
ret_code = IDC_UPDATE_LATER;
cache_value = REG_LATER;
}
// Cache the value in the registry if necessary
if (SendDlgItemMessage (IDC_DONT_ASK_ME_AGAIN, BM_GETCHECK) == 1) {
theApp.WriteProfileString (CONFIG_KEY, CHECKIN_STYLE_VALUE, cache_value);
}
// Close the dialog with the appropriate control ID
EndDialog (ret_code);
return ;
}
/////////////////////////////////////////////////////////////////////////////
//
// OnCommand
//
BOOL
CheckinStyleDialogClass::OnCommand
(
WPARAM wParam,
LPARAM lParam
)
{
// Don't allow the user to cancel out of this dialog
if (LOWORD (wParam) == IDCANCEL) {
return FALSE;
}
// Allow the base class to process this message
return CDialog::OnCommand (wParam, lParam);
}
/////////////////////////////////////////////////////////////////////////////
//
// DoModal
//
int
CheckinStyleDialogClass::DoModal (void)
{
UINT ret_code = IDC_UPDATE_NOW;
// Get the cached 'checkin' style if possible
CString checkin_style = theApp.GetProfileString (CONFIG_KEY, CHECKIN_STYLE_VALUE, REG_NOT_CACHED);
if (checkin_style.CompareNoCase (REG_NOT_CACHED) == 0) {
// Allow the base class to show the dialog
ret_code = CDialog::DoModal ();
} else {
if (checkin_style.CompareNoCase (REG_LATER) == 0) {
ret_code = IDC_UPDATE_LATER;
}
}
// Return the dialog control's ID
return ret_code;
}
/////////////////////////////////////////////////////////////////////////////
//
// OnInitDialog
//
BOOL
CheckinStyleDialogClass::OnInitDialog (void)
{
// Allow the base class to process this message
CDialog::OnInitDialog ();
// Check 'update now' by default
SendDlgItemMessage (IDC_UPDATE_NOW, BM_SETCHECK, (WPARAM)TRUE);
return TRUE;
}

View File

@@ -0,0 +1,68 @@
/*
** Command & Conquer Renegade(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/>.
*/
#if !defined(AFX_CHECKINSTYLEDIALOG_H__2057225F_9559_11D2_9FED_00104B791122__INCLUDED_)
#define AFX_CHECKINSTYLEDIALOG_H__2057225F_9559_11D2_9FED_00104B791122__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// CheckinStyleDialog.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CheckinStyleDialogClass dialog
class CheckinStyleDialogClass : public CDialog
{
// Construction
public:
CheckinStyleDialogClass(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CheckinStyleDialogClass)
enum { IDD = IDD_CHECKIN_STYLE };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CheckinStyleDialogClass)
public:
virtual int DoModal();
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CheckinStyleDialogClass)
virtual void OnOK();
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_CHECKINSTYLEDIALOG_H__2057225F_9559_11D2_9FED_00104B791122__INCLUDED_)

View File

@@ -0,0 +1,113 @@
/*
** Command & Conquer Renegade(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/>.
*/
// CheckingOutDialog.cpp : implementation file
//
#include "stdafx.h"
#include "leveledit.h"
#include "CheckingOutDialog.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CheckingOutDialogClass dialog
CheckingOutDialogClass::CheckingOutDialogClass(CWnd* pParent /*=NULL*/)
: CDialog(CheckingOutDialogClass::IDD, pParent)
{
//{{AFX_DATA_INIT(CheckingOutDialogClass)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void CheckingOutDialogClass::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CheckingOutDialogClass)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CheckingOutDialogClass, CDialog)
//{{AFX_MSG_MAP(CheckingOutDialogClass)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
//
// WindowProc
//
LRESULT
CheckingOutDialogClass::WindowProc
(
UINT message,
WPARAM wParam,
LPARAM lParam
)
{
if (message == WM_USER+101) {
EndDialog (1);
}
// Allow the base class to process this message
return CDialog::WindowProc(message, wParam, lParam);
}
/////////////////////////////////////////////////////////////////////////////
//
// OnCommand
//
BOOL
CheckingOutDialogClass::OnCommand
(
WPARAM wParam,
LPARAM lParam
)
{
// Don't let the dialog be closed by hitting enter or escape
if (LOWORD (wParam) == IDOK || LOWORD (wParam) == IDCANCEL) {
return FALSE;
}
// Allow the base class to process this message
return CDialog::OnCommand(wParam, lParam);
}
/////////////////////////////////////////////////////////////////////////////
//
// OnInitDialog
//
BOOL
CheckingOutDialogClass::OnInitDialog (void)
{
// Allow the base class to process this message
CDialog::OnInitDialog ();
return TRUE;
}

View File

@@ -0,0 +1,66 @@
/*
** Command & Conquer Renegade(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/>.
*/
#if !defined(AFX_CHECKINGOUTDIALOG_H__2057225E_9559_11D2_9FED_00104B791122__INCLUDED_)
#define AFX_CHECKINGOUTDIALOG_H__2057225E_9559_11D2_9FED_00104B791122__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// CheckingOutDialog.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CheckingOutDialogClass dialog
class CheckingOutDialogClass : public CDialog
{
// Construction
public:
CheckingOutDialogClass(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CheckingOutDialogClass)
enum { IDD = IDD_CHECKING_OUT };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CheckingOutDialogClass)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CheckingOutDialogClass)
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_CHECKINGOUTDIALOG_H__2057225E_9559_11D2_9FED_00104B791122__INCLUDED_)

View File

@@ -0,0 +1,218 @@
/*
** Command & Conquer Renegade(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/>.
*/
// ChooseModPackageDialog.cpp : implementation file
//
#include "stdafx.h"
#include "leveledit.h"
#include "choosemodpackagedialog.h"
#include "assetpackagemgr.h"
#include "newassetpackagedialog.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
//
// ChooseModPackageDialogClass
//
/////////////////////////////////////////////////////////////////////////////
ChooseModPackageDialogClass::ChooseModPackageDialogClass(CWnd* pParent /*=NULL*/)
: CDialog(ChooseModPackageDialogClass::IDD, pParent)
{
//{{AFX_DATA_INIT(ChooseModPackageDialogClass)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
return ;
}
/////////////////////////////////////////////////////////////////////////////
//
// DoDataExchange
//
/////////////////////////////////////////////////////////////////////////////
void
ChooseModPackageDialogClass::DoDataExchange (CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(ChooseModPackageDialogClass)
DDX_Control(pDX, IDC_MOD_LIST_CTRL, ListCtrl);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(ChooseModPackageDialogClass, CDialog)
//{{AFX_MSG_MAP(ChooseModPackageDialogClass)
ON_BN_CLICKED(IDC_NEW_BUTTON, OnNewButton)
ON_NOTIFY(NM_DBLCLK, IDC_MOD_LIST_CTRL, OnDblclkModListCtrl)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
//
// OnInitDialog
//
/////////////////////////////////////////////////////////////////////////////
BOOL
ChooseModPackageDialogClass::OnInitDialog (void)
{
CDialog::OnInitDialog ();
//
// Configure the columns
//
ListCtrl.InsertColumn (0, "");
ListCtrl.SetExtendedStyle (ListCtrl.GetExtendedStyle () | LVS_EX_FULLROWSELECT);
//
// Choose an appropriate size for the column
//
CRect rect;
ListCtrl.GetClientRect (&rect);
rect.right -= ::GetSystemMetrics (SM_CXVSCROLL) + 2;
ListCtrl.SetColumnWidth (0, rect.Width ());
//
// Build a list of all the packages that are currently available
//
STRING_LIST package_list;
AssetPackageMgrClass::Build_Package_List (package_list);
//
// Add an entry to the control for each package
//
bool found = false;
for (int index = 0; index < package_list.Count (); index ++) {
int item_index = ListCtrl.InsertItem (index, package_list[index]);
if (item_index >= 0) {
//
// Is this the default entry?
//
if (::lstrcmpi (AssetPackageMgrClass::Get_Current_Package (), package_list[index]) == 0) {
ListCtrl.SetItemState (item_index, LVIS_SELECTED, LVIS_SELECTED);
found = true;
}
}
}
//
// Select the first entry by default
//
if (package_list.Count () > 0 && found) {
ListCtrl.SetItemState (0, LVIS_SELECTED, LVIS_SELECTED);
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
//
// OnOK
//
/////////////////////////////////////////////////////////////////////////////
void
ChooseModPackageDialogClass::OnOK (void)
{
int curr_index = ListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED);
if (curr_index >= 0) {
//
// Set the current mod package
//
CString package_name = ListCtrl.GetItemText (curr_index, 0);
AssetPackageMgrClass::Set_Current_Package (package_name);
//
// Close the dialog
//
CDialog::OnOK ();
} else {
//
// Warn the user
//
MessageBox ("You must select (or create) a Mod Package before continuing.", "Invalid Selection", MB_ICONERROR | MB_OK);
}
return ;
}
/////////////////////////////////////////////////////////////////////////////
//
// OnNewButton
//
/////////////////////////////////////////////////////////////////////////////
void
ChooseModPackageDialogClass::OnNewButton (void)
{
//
// Display a dialog to the user allowing them to create a new mod package
//
NewAssetPackageDialogClass dialog (this);
if (dialog.DoModal () == IDOK) {
//
// Create the new asset package
//
AssetPackageMgrClass::Create_Package (dialog.Get_Package_Name ());
//
// Add this package to the list
//
int item_index = ListCtrl.InsertItem (0xFF, dialog.Get_Package_Name ());
if (item_index >= 0) {
//
// Select the new package
//
ListCtrl.SetItemState (item_index, LVIS_SELECTED, LVIS_SELECTED);
}
}
return ;
}
/////////////////////////////////////////////////////////////////////////////
//
// OnDblclkModListCtrl
//
/////////////////////////////////////////////////////////////////////////////
void
ChooseModPackageDialogClass::OnDblclkModListCtrl (NMHDR *pNMHDR, LRESULT *pResult)
{
(*pResult) = 0;
//
// Simulate pressing the OK button
//
SendMessage (WM_COMMAND, MAKELONG (IDOK, BN_CLICKED), 0);
return ;
}

View File

@@ -0,0 +1,75 @@
/*
** Command & Conquer Renegade(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/>.
*/
#if !defined(AFX_CHOOSEMODPACKAGEDIALOG_H__86FFB2F7_5103_422D_B327_5DCF8343713C__INCLUDED_)
#define AFX_CHOOSEMODPACKAGEDIALOG_H__86FFB2F7_5103_422D_B327_5DCF8343713C__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "resource.h"
/////////////////////////////////////////////////////////////////////////////
//
// ChooseModPackageDialogClass
//
/////////////////////////////////////////////////////////////////////////////
class ChooseModPackageDialogClass : public CDialog
{
// Construction
public:
ChooseModPackageDialogClass(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(ChooseModPackageDialogClass)
enum { IDD = IDD_CHOOSE_MOD_PACKAGE };
CListCtrl ListCtrl;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(ChooseModPackageDialogClass)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(ChooseModPackageDialogClass)
virtual BOOL OnInitDialog();
virtual void OnOK();
afx_msg void OnNewButton();
afx_msg void OnDblclkModListCtrl(NMHDR* pNMHDR, LRESULT* pResult);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
public:
private:
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_CHOOSEMODPACKAGEDIALOG_H__86FFB2F7_5103_422D_B327_5DCF8343713C__INCLUDED_)

View File

@@ -0,0 +1,57 @@
/*
** Command & Conquer Renegade(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 : LevelEdit *
* *
* $Archive:: /Commando/Code/Tools/LevelEdit/CollisionGroups.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 10/06/00 3:38p $*
* *
* $Revision:: 5 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __COLLISION_GROUPS_H
#define __COLLISION_GROUPS_H
typedef enum {
DEF_COLLISION_GROUP = 10, // collides with itself and mouse clicks
EDITOR_COLLISION_GROUP, // doesn't collide with anything (other than mouse clicks)
MOUSE_CLICK_COLLISION_GROUP, // collides with everything
GAME_COLLISION_GROUP, // collides with everything except for EDITOR_COLLISION_GROUP
STATIC_OBJ_COLLISION_GROUP // only collides with static objects (group 15)
} COLLISION_GROUPS;
#endif //__COLLISION_GROUPS_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,252 @@
/*
** Command & Conquer Renegade(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/>.
*/
#if !defined(AFX_COLORBAR_H__D1243F40_D4D2_11D2_8DDF_00104B6FD9E3__INCLUDED_)
#define AFX_COLORBAR_H__D1243F40_D4D2_11D2_8DDF_00104B6FD9E3__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
// ColorBar.h : header file
//
/////////////////////////////////////////////////////////////////////////////
//
// Constants
//
const int MAX_COLOR_POINTS = 15;
//
// Window styles
//
#define CBRS_SUNKEN 0x00000001
#define CBRS_RAISED 0x00000002
#define CBRS_FRAME 0x00000004
#define CBRS_FRAME_MASK CBRS_FRAME | CBRS_RAISED | CBRS_SUNKEN
#define CBRS_HORZ 0x00000008
#define CBRS_VERT 0x00000010
#define CBRS_HAS_SEL 0x00000020
#define CBRS_SHOW_FRAMES 0x00000040
#define CBRS_PAINT_GRAPH 0x00000080
//
// Window messages and notifications
//
#define CBRN_MOVED_POINT 0x0001
#define CBRN_MOVING_POINT 0x0002
#define CBRN_DBLCLK_POINT 0x0003
#define CBRN_SEL_CHANGED 0x0004
#define CBRN_DEL_POINT 0x0005
#define CBRN_DELETED_POINT 0x0006
#define CBRN_INSERTED_POINT 0x0007
#define CBRM_GETCOLOR (WM_USER+101)
#define CBRM_SETCOLOR ( WM_USER+102)
//
// Point styles
//
#define POINT_VISIBLE 0x00000001
#define POINT_CAN_MOVE 0x00000002
//
// Return values for WM_NOTIFY
//
#define STOP_EVENT 0x00000077
/////////////////////////////////////////////////////////////////////////////
//
// Structures
//
// Structure used to send notifications via WM_NOTIFY
typedef struct
{
NMHDR hdr;
int key_index;
float red;
float green;
float blue;
float position;
} CBR_NMHDR;
/////////////////////////////////////////////////////////////////////////////
//
// ColorBarClass
//
class ColorBarClass : public CWnd
{
// Construction
public:
ColorBarClass();
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(ColorBarClass)
public:
virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~ColorBarClass();
// Generated message map functions
protected:
//{{AFX_MSG(ColorBarClass)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnPaint();
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnKillFocus(CWnd* pNewWnd);
afx_msg void OnSetFocus(CWnd* pOldWnd);
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
friend LRESULT WINAPI fnColorBarProc (HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
public:
/////////////////////////////////////////////////////////////////////////
//
// Public methods
//
bool Insert_Point (int index, float position, float red, float green, float blue, DWORD flags = POINT_VISIBLE | POINT_CAN_MOVE);
bool Insert_Point (CPoint point, DWORD flags = POINT_VISIBLE | POINT_CAN_MOVE);
bool Modify_Point (int index, float position, float red, float green, float blue, DWORD flags = POINT_VISIBLE | POINT_CAN_MOVE);
bool Set_User_Data (int index, DWORD data);
DWORD Get_User_Data (int index);
bool Set_Graph_Percent (int index, float percent);
float Get_Graph_Percent (int index);
bool Delete_Point (int index);
void Clear_Points (void);
int Get_Point_Count (void) const { return m_iColorPoints; }
bool Get_Point (int index, float *position, float *red, float *green, float *blue);
int Marker_From_Point (CPoint point);
void Set_Selection_Pos (float pos);
float Get_Selection_Pos (void) const { return m_SelectionPos; }
void Get_Color (float position, float *red, float *green, float *blue);
void Get_Range (float &min, float &max) const { min = m_MinPos; max = m_MaxPos; }
void Set_Range (float min, float max);
void Set_Redraw (bool redraw = true);
LRESULT Send_Notification (int code, int key);
//////////////////////////////////////////////////////////////////////////
// Static members
//////////////////////////////////////////////////////////////////////////
static ColorBarClass *Get_Color_Bar (HWND window_handle) { return (ColorBarClass *)::GetProp (window_handle, "CLASSPOINTER"); }
protected:
/////////////////////////////////////////////////////////////////////////
//
// Protected data types
//
typedef struct
{
float PosPercent;
int StartPos;
int EndPos;
float StartGraphPercent;
float GraphPercentInc;
float StartRed;
float StartGreen;
float StartBlue;
float RedInc;
float GreenInc;
float BlueInc;
DWORD user_data;
int flags;
} COLOR_POINT;
/////////////////////////////////////////////////////////////////////////
//
// Protected methods
//
void Paint_DIB (void);
void Create_Bitmap (void);
void Free_Bitmap (void);
void Free_Marker_Bitmap (void);
void Paint_Bar_Horz (int x_pos, int y_pos, int width, int height, UCHAR *pbits);
void Paint_Bar_Vert (int x_pos, int y_pos, int width, int height, UCHAR *pbits);
void Update_Point_Info (void);
void Load_Key_Frame_BMP (void);
void Paint_Key_Frame (int x_pos, int y_pos);
void Paint_Screen (HDC hwnd_dc);
void Get_Selection_Rectangle (CRect &rect);
void Move_Selection (CPoint point, bool send_notify = true);
void Move_Selection (float new_pos, bool send_notify = true);
void Repaint (void);
private:
/////////////////////////////////////////////////////////////////////////
//
// Private member data
//
HBITMAP m_hBitmap;
HBITMAP m_KeyFrameDIB;
HDC m_hMemDC;
UCHAR * m_pBits;
UCHAR * m_pKeyFrameBits;
int m_iColorWidth;
int m_iColorHeight;
int m_iBMPWidth;
int m_iBMPHeight;
int m_iMarkerWidth;
int m_iMarkerHeight;
int m_iScanlineSize;
int m_iColorPoints;
float m_MinPos;
float m_MaxPos;
COLOR_POINT m_ColorPoints[MAX_COLOR_POINTS];
CRect m_ColorArea;
int m_iCurrentKey;
bool m_bMoving;
bool m_bMoved;
bool m_bRedraw;
float m_SelectionPos;
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_COLORBAR_H__D1243F40_D4D2_11D2_8DDF_00104B6FD9E3__INCLUDED_)

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