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_)