reman3/Rayman_X/cpa/Appli/CvrtA3DtoA3i/Src/makeanim.cpp

565 lines
17 KiB
C++

// **********************************************************************************
// * "makeanim.c" *
// * Written by : Sébastien Rubens *
// * Tabulations : 4 char *
// **********************************************************************************
#define MAKEANIM_C
// **********************************************************************************
// Suivi des versions
// 1.01 : 17/07/98
// Sort channel by channel number
// Hierarchy now contains channel number (no more index in array of element)
// 1.02 : 21/07/98
// Bug correction in Hierarchy optimisation (when channel is supressed)
// 1.03 : 23/07/98
// Correction in Hierarchy optimisation : kill couple when channel number is undefined
// Remove Empty Error File
// 1.04 : 30/07/98
// Use a second Dir(found in Version.ini) to find Anim and generate A3i
// 1.05 : 17/08/98
// Generalized use of N Dir found in Version.ini separate by a DIR_SEPARATOR
// Treat CameraAngle Key in General Section of A3D
// 1.05b : 25/08/98
// Raise stack of event
// 1.06 : 25/08/98
// Generate All anim in a specific dir (first dir in version.ini)
// To Generate All anim use option -a
// 1.07 : 27/08/98
// Change Morph structure (like N64)
// Treat Morphing Entry in Key Section
// 1.08 : 28/08/98
// Accelerated Interpollation - Type 1
// Put Version in A3i File
// 1.09 : 11/09/98
// Correction of overwrite bug with anim with 0 channel
// Transparency in animation is now possible (transparency isn't interpolated)
// 1.09a : 16/09/98
// Correction Add the good number of Alignement bytes before events
// 1.09b : 24/09/98
// Correction of overwrite bug with anim with 0 channel (previous correction was lost)
// 1.09c : 25/09/98
// Merging end + correction from Seb Rubens
// 1.10 : 29/09/98
// Ajout du numero de canal dans les events et tri complet des events
// (correction bug tir et arret des sons)
// 1.10a : 29/09/98
// Bug correction : when last key is a simple key and wasn't on the last frame channel
// don't move after the last key
// 1.11 : 09/10/98
// Correction for scale computing
// 14/10/98
// New Option -z : to compact TBL (save original in a TBO file)
// All families in the file MakeAnim.in are not compacted
// MakeAnim.ini format:
// FamilyName1<CR>
// ...
// FamilyNameN<CR>
// 1.11a : 14/10/98
// Correction of transparence bug (in NTTO optimisation)
// 1.11b : 16/10/98
// Bug correction for object number > 255
// Bug correction, now deleting unused event
// 1.12 : 19/10/98
// Integration of the last change from Seb
// 1.13 : 22/10/98 FBF
// Integration modif from N64 version
// 1.13a : 26/10/98
// Bug correction when having V5 Anim (respect anim indexing)
// Add precision parameter
// Correction for emptyobject optimization
// Correction for Generate Channel object
// 1.13b : 27/10/98
// Correction for quaternion interpolation
// 1.13c : 28/10/98
// Correction with bad A3D file or Empty file (respect anim indexing)
// 1.13d : 30/10/98
// Sort of Warnings and Errors
// 1.13e : ???
// maybe structure modification for N64 version
// 1.13f : 7/12/98
// Correction of bug that add Key frame
// : 11/01/99
// Ajout de l'option "d'optimisation" -o
// 1.13g : 01/02/99
// Correction for Extra Key frames optimization
// 1.13h : 16/03/99
// Correction for vector optimization (fn_v_DiscretizeScal)
// 1.14 : 25/03/99
// Change treatment of Entry ObjectType in A3D file
// Check CHL and TBL presence before analysing
// return 0 if no problem
// no wait for keystroke in batch mode
// 1.14a : 30/03/99
// Correction of event sort
// 1.15 : 16/04/99
// change the format of ini file to set specific precision
// 1.15a : 16/06/99
// Correction for deleting hierarchy couple
// 1.16 : 24/06/99
// Correction precision option bug
// check STA file with compact option to suppress unused object
// 1.16a : 28/06/99
// Correction bug analyse STA & unvalidate unused anim
// : 05/07/99
// Modif event sort --> use qsort
// Create Anims dir if not exist
// 1.17 : 20/07/99
// Modif in quaternion compacting method
// **********************************************************************************
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <sys/stat.h>
#include <direct.h>
#include "afx.h"
#include "SCR.h"
#include "specif\\a3x_pref.h"
#include "a3x_glob.h"
#include "makeanim.h"
#include "a3x_int.h"
#include "a3x_intb.h"
#include "l_global_v6.h"
#include "l_a3d_v6.h"
#include "l_chl_v6.h"
#include "l_Tbl_v6.h"
#include "l_Sta_v6.h"
#include "l_optim_v6.h"
#include "inifile.h"
#define FAMILY_NAME_LENGTH 32
#define NO_PROBLEMO 0
#define ERR_WRONG_PARAMETERS 1
#define ERR_NO_CHL_FILE 2
#define ERR_NO_TBL_FILE 3
#define ERR_NO_STA_FILE 4
// **********************************************************************************
// Files & Dir Defines
#define VERSION_OPTIONS_FILE "Version.ini"
#define DIR_SEPARATOR ","
// OPTION command
#define BATCH_ARG "b" // no interaction
#define BATCH_HELP "\t-b : Batch mode, no interaction\n"
#define ALL_ARG "a" // treat all anim found and save in the same dir
#define ALL_HELP "\t-a : Treat all anim found and convert in the corresponding Dir\n"
#define COMPAC_ARG "z" // compact Tbl
#define COMPAC_HELP "\t-z : Save Tbl in Tbo(Original Table) file and compact it\n"
#define EPSIL_ARG "p" // set precision
#define EPSIL_HELP "\t-p Epsilon : Set the precision for optimisation\n"
#define OPTIM_ARG "o" // pseudo-optimization of non-optim anim
#define OPTIM_HELP "\t-o KeyFreq : Set the keyFrequence of non-optimized animation(Default=1)\n"
unsigned short uwNumOfBank= 1;
unsigned short uwAnalysedAnim;
tdstAnimInfo stAnims[NombreDanimationsParDirectory];
unsigned short g_uwTotalNumOfAnim=0;
char LongActorName[5][500];
char LongChannelName[500];
char LongFileName[500],LongFileName2[500];
char AnimationName[500];
char szFamilyName[FAMILY_NAME_LENGTH];
int bCompactTbl=FALSE;
// parametrable variables
SEB_xReal xDefaultEps = (SEB_xReal) 0.0001;
extern int iKeyFreq;
unsigned char bBatch=FALSE;
// ***************************************************************************** Main
// MAIN
//
// Modif 30/07/98 : Second anim Dir treatment - Carlos Torres
// Modif 17/08/98 : Generalized use of N Dir - Carlos Torres
// Modif 25/08/98 : Add option -a, Let script module found Chl and Tbl File
// Save file in First dir of version.ini File
// Modif 08/01/99 : Add optim option
// **********************************************************************************
int main(int argc,char * argv[] ) {
FILE * fdTest;
int iCurArg = 1,iFamilyName = -1;
int bTreatAll=FALSE;
unsigned short uwNumOfAnim[5];
unsigned char ucNbDir = 1;
unsigned short uwNbAnims;
int i;
printf("MakeAnim.exe by Sebastien Rubens (Ubi R&D, Montreuil)\nVersion %d.%02d%c\n\n",
(A3i_Version&0xF000)>>12,(A3i_Version&0x0FF0)>>4,(A3i_Version&0x000F)?'a'+(A3i_Version&0x000F)-1:' ');
// ------------------------------------------------------------------------------
// Parameter Treatment
// ------------------------------------------------------------------------------
for(iCurArg=1;iCurArg<argc;iCurArg++) {
// options
if (*argv[iCurArg]=='-') {
// batch Option
if (!stricmp(&argv[iCurArg][1],BATCH_ARG)) {
bBatch = TRUE;
}
// All Option
else if (!stricmp(&argv[iCurArg][1],ALL_ARG)) {
bTreatAll = TRUE;
}
// Compact Option
else if (!stricmp(&argv[iCurArg][1],COMPAC_ARG)) {
bCompactTbl = TRUE;
}
// Set precision
else if (!stricmp(&argv[iCurArg][1],EPSIL_ARG)) {
if (++iCurArg < argc) {
sscanf(argv[iCurArg],"%f",&xDefaultEps);
if ((xDefaultEps < 0) || (xDefaultEps > 0.1)) {
printf("Bad epsilon specify %f\n",xDefaultEps);
WaitKeyStroke();
exit(ERR_WRONG_PARAMETERS);
}
}
else {
printf("No epsilon specify\n");
WaitKeyStroke();
exit(ERR_WRONG_PARAMETERS);
}
}
// Set Key Freq
else if (!stricmp(&argv[iCurArg][1],OPTIM_ARG)) {
if (++iCurArg < argc) {
sscanf(argv[iCurArg],"%d",&iKeyFreq);
if (iKeyFreq <= 0) {
printf("Bad KeyFreq specify %d\n",iKeyFreq);
WaitKeyStroke();
exit(ERR_WRONG_PARAMETERS);
}
}
else {
printf("No KeyFreq specify\n");
WaitKeyStroke();
exit(ERR_WRONG_PARAMETERS);
}
}
else {
printf("Option %s Unknown\n",argv[iCurArg]);
WaitKeyStroke();
exit(ERR_WRONG_PARAMETERS);
}
}
// Family name Option
else if (iFamilyName == -1) {
strcpy(szFamilyName,argv[iCurArg]);
iFamilyName=iCurArg;
}
// Argument unknown
else {
printf("Argument %s Unknowm\n",argv[iCurArg]);
WaitKeyStroke();
exit(ERR_WRONG_PARAMETERS);
}
}
// read parameter - just the name of character Family
if (iFamilyName == -1) {
printf("Family not specify\n");
printf("Command format is : MakeAnim [Options] <Family_Name>\n");
printf("\tGenerate Anim in A3i format in a specific dir(without option -a)\n");
printf("\tSpecific Dir is the first dir in the %s File\n",VERSION_OPTIONS_FILE);
printf("Incompatible with the version 1.06 and previous version\n");
printf("\nOptions :\n");
printf(BATCH_HELP);
printf(ALL_HELP);
printf(COMPAC_HELP);
printf(OPTIM_HELP);
WaitKeyStroke();
exit(ERR_WRONG_PARAMETERS);
}
// ------------------------------------------------------------------------------
// INIT
// ------------------------------------------------------------------------------
// init a table with sinus value
fn_v_InitSinTab();
// init others modules (ERM MMG SCR)
fn_v_InitMemV6i();
fn_v_InitSaveAnimationV6i();
fn_v_StartA3dV6i();
// Set channel&CHL path
sprintf(LongChannelName,"%s\\%s",DIR_FAMILIES,szFamilyName);
// Set Anims path
sprintf(LongActorName[0],"%s\\%s\\%s",DIR_DATA,DIR_ANIMS,szFamilyName);
// ------------------------------------------------------------------------------
// Get second Data Dir
fdTest = fopen(VERSION_OPTIONS_FILE,"rb");
if (fdTest) {
char szSecondDataDir[50];
char szAnimDir[50];
char * szToken;
struct _stat stBuf;
fgets(szSecondDataDir,50,fdTest);
// suppress last char (EOL)
szSecondDataDir[(i=strlen(szSecondDataDir))-2] = NULL;
fclose(fdTest);
// Look for a third Dir
szToken = strtok(szSecondDataDir,DIR_SEPARATOR);
// check Anims dir for specif gamedata
sprintf(szAnimDir,"%s\\%s",szToken,DIR_ANIMS,szFamilyName);
// check if Dir Exist & create it if necessary
if (_stat(szAnimDir,&stBuf))
_mkdir(szAnimDir);
// Get all dirs
while (szToken) {
// Set Anims path
sprintf(LongActorName[ucNbDir],"%s\\%s\\%s",szToken,DIR_ANIMS,szFamilyName);
// check if Dir Exist
if (!_stat(LongActorName[ucNbDir],&stBuf))
ucNbDir++;
// if not all option create Specific Dir
else if (!bTreatAll && (ucNbDir == 1)) {
// create Save Dir
_mkdir(LongActorName[ucNbDir]);
ucNbDir++;
}
szToken = strtok(NULL,DIR_SEPARATOR);
}
}
// Get anim number in each Directory for the family
for (i=0;i<ucNbDir;i++) {
uwNumOfAnim[i] = fn_uw_GetDirV6i(LongActorName[i],bTreatAll);
}
// ------------------------------------------------------------------------------
// LOAD MakeAnim.ini File
// ------------------------------------------------------------------------------
fn_v_IniFileInit(szFamilyName);
sprintf(LongFileName,"%s^%s",MAKEANIM_OPTIONS_FILE,szFamilyName);
// check if file exist
if (SCR_fn_c_RdL0_IsSectionExists(LongFileName)) {
SCR_fnp_st_RdL0_AnalyseSection( LongFileName, SCR_CDF_uw_Anl_NotSaveSection );
SCR_fn_v_RdL0_Close();
}
// ------------------------------------------------------------------------------
// LOAD CHL File
// ------------------------------------------------------------------------------
fn_v_InitCHLV6i();
sprintf(LongFileName,"%s\\%s.CHL",LongChannelName,szFamilyName);
// check if file exist
if (SCR_fn_c_RdL0_IsSectionExists(LongFileName)) {
SCR_fnp_st_RdL0_AnalyseSection( LongFileName, SCR_CDF_uw_Anl_NotSaveSection );
SCR_fn_v_RdL0_Close();
}
else {
printf("File %s not found\n",LongFileName);
WaitKeyStroke();
return ERR_NO_CHL_FILE;
}
// ------------------------------------------------------------------------------
// Copy Originals Table in Tbl File or save original TBL
// ------------------------------------------------------------------------------
if (bCompactTbl) {
struct _finddata_t stFileInfo;
long lHandle;
// Find Tbl in data
for (i=0;i<ucNbDir;i++) {
strcpy(LongFileName,LongActorName[i]);
sprintf(strchr(LongFileName,'\\') + 1,"%s\\%s\\*.TBL",REL_DIR_FAMILY,szFamilyName);
lHandle = _findfirst(LongFileName,&stFileInfo);
// stop at first TBL found
if (lHandle != -1)
break;
}
// compact all family's tbl
if (lHandle != -1) {
do {
// Build File name
sprintf(strrchr(LongFileName,'\\')+1,"%s",stFileInfo.name);
strcpy(LongFileName2,LongFileName);
LongFileName2[strlen(LongFileName2)-1] = 'O';
// Get tbl original
if (!CopyFile(LongFileName2,LongFileName,NULL))
// save original tbl
CopyFile(LongFileName,LongFileName2,NULL);
} while (!_findnext(lHandle,&stFileInfo));
_findclose(lHandle);
}
}
// ------------------------------------------------------------------------------
// LOAD TBL File
// ------------------------------------------------------------------------------
fn_v_InitTBLV6i();
sprintf(LongFileName,"%s\\%s.TBL",LongChannelName,szFamilyName);
// check if file exist
if (SCR_fn_c_RdL0_IsSectionExists(LongFileName)) {
SCR_fnp_st_RdL0_AnalyseSection( LongFileName, SCR_CDF_uw_Anl_NotSaveSection );
SCR_fn_v_RdL0_Close();
}
else {
printf("File %s not found\n",LongFileName);
WaitKeyStroke();
return ERR_NO_TBL_FILE;
}
// ------------------------------------------------------------------------------
// Check State file
// ------------------------------------------------------------------------------
if (bCompactTbl) {
fn_v_InitSTAV6i();
sprintf(LongFileName,"%s\\%s.STA",LongChannelName,szFamilyName);
// check if file exist
if (SCR_fn_c_RdL0_IsSectionExists(LongFileName)) {
SCR_fnp_st_RdL0_AnalyseSection( LongFileName, SCR_CDF_uw_Anl_NotSaveSection );
SCR_fn_v_RdL0_Close();
}
else {
printf("File %s not found\n",LongFileName);
WaitKeyStroke();
return ERR_NO_STA_FILE;
}
}
// ------------------------------------------------------------------------------
// LOAD A3D Files (all Family's animation)
// ------------------------------------------------------------------------------
fn_v_InitA3dV6i();
for ( uwAnalysedAnim=0 ; uwAnalysedAnim<g_uwTotalNumOfAnim; uwAnalysedAnim++ ) {
if (!bValid(&stAnims[uwAnalysedAnim])) {
// Set AnimationName
sprintf(AnimationName,"%s\\%s",szFamilyName,szAnimName(&stAnims[uwAnalysedAnim]));
// search the good dir
for (i=0,uwNbAnims=uwNumOfAnim[0];i<ucNbDir;i++,uwNbAnims+=uwNumOfAnim[i])
if (uwAnalysedAnim < uwNbAnims)
break;
// Set LongFileName
sprintf(LongFileName,"%s\\%s",LongActorName[i],szAnimName(&stAnims[uwAnalysedAnim]));
SCR_fnp_st_RdL0_AnalyseSection( LongFileName, SCR_CDF_uw_Anl_NotSaveSection );
fn_v_KillMem();
}
else {
// always allocate A3D General in stack to respect indexing
fn_v_AllocateOnStack( eStackBinA3dGENERAL, 1 );
}
}
// ------------------------------------------------------------------------------
// BINARISE ANIM
// ------------------------------------------------------------------------------
fn_v_VerifyAnimationV6i(g_uwTotalNumOfAnim);
fn_v_OptimiseAnimationV6i(g_uwTotalNumOfAnim);
fn_v_OptimiseAnimation2V6i(g_uwTotalNumOfAnim);
// ------------------------------------------------------------------------------
// UPDATE TBL
// ------------------------------------------------------------------------------
if (bCompactTbl) {
struct _finddata_t stFileInfo;
long lHandle;
// Find Tbl in data
for (i=0;i<ucNbDir;i++) {
strcpy(LongFileName,LongActorName[i]);
sprintf(strchr(LongFileName,'\\') + 1,"%s\\%s\\*.TBL",REL_DIR_FAMILY,szFamilyName);
lHandle = _findfirst(LongFileName,&stFileInfo);
// stop at first TBL found
if (lHandle != -1)
break;
}
// compact all family's tbl
if (lHandle != -1) {
fn_vGenerateNewObjectNumber(TRUE);
do {
// Build File name
sprintf(strrchr(LongFileName,'\\')+1,"%s",stFileInfo.name);
// update TBL to compact it
fn_vCompactTBL(LongFileName);
} while (!_findnext(lHandle,&stFileInfo));
_findclose(lHandle);
}
}
// Keep tbl index for uncompactable TBL
else
fn_vGenerateNewObjectNumber(FALSE);
// ------------------------------------------------------------------------------
// SAVE ANIM
// ------------------------------------------------------------------------------
for (i=0,uwNbAnims=0;i<ucNbDir;i++) {
if (bTreatAll || (ucNbDir==1))
fn_v_SaveAnimationV6i(uwNbAnims,uwNumOfAnim[i],LongActorName[i]);
else
fn_v_SaveAnimationV6i(uwNbAnims,uwNumOfAnim[i],LongActorName[1]);
uwNbAnims += uwNumOfAnim[i];
}
//TagadaPouetPouet( uwNumOfAnim );
// ------------------------------------------------------------------------------
// END OF PROGRAM
// ------------------------------------------------------------------------------
// verify if stacks is enough big
fn_vCheckStacks();
fn_v_EndA3dV6i();
SCR_fn_v_RdL0_Close();
fn_v_EndSaveAnimationV6i();
printf( "\n\nFin de binarisation...\n" );
return 0;
}
// **********************************************************************************
#undef MAKEANIM_C