LOADER.C

Go to the documentation of this file.
00001 /* file loader.c    */
00002 
00003 #define MODULE_LOADER 1
00004 
00005 #include "animate.h"
00006 #include "callall.h"
00007 
00008 static char WIN32_environment[512];
00009 
00010 char *R_GetEnv(char const *aa){
00011  if(GetEnvironmentVariable((LPTSTR)aa,(LPTSTR)WIN32_environment,256) == 0)
00012    return NULL;
00013 //MessageBox(NULL,WIN32_environment,aa,MB_OK);
00014  return WIN32_environment;
00015 }
00016 
00017 typedef struct {
00018  char *old,*new;
00019  object *Op;
00020 } discarded_file;
00021 
00022 
00023 static FILE *fo,*fr;
00024 static long newface,newedge,newvert,newnurbs,n_discarded=0,
00025             minX,minY,minZ,maxX,maxY,maxZ;
00026 static char str[8]={0,0,0,0,0,0,0,0},RAMfilename[256];
00027 static discarded_file *discarded_file_list=NULL;
00028 
00029 static short TryAgainToLoad(char *filename, object *Op);
00030 static void StageReadSkeleton(long clen, object *Op, short version, HANDLE);
00031 static void StageReadAxis(long clen, object *Op, HANDLE);
00032 static short StageReadEdges(long clen, object *Op, BOOL short_form, HANDLE);
00033 static void StageReadVertices(long clen, object *Op, HANDLE);
00034 static void StageReadWireframe(long clen, object *Op, HANDLE);
00035 static void StageReadNurbs(long clen, object *Op, HANDLE);
00036 static HANDLE SearchForFile(char *, char *);
00037 static void LoadEmbeddedImageMaps(long chunk_size, FILE *fr);
00038 static void WriteEmbeddedImageMaps(FILE *fr);
00039 static void UnpackName(char *name);
00040 
00041 #include "wspaces.c"
00042 
00044 
00045 static short TryAgainToLoad(char *filename, object *Op){
00046  long i;
00047  discarded_file *temp;
00048  char title[256];
00049  if(GetAsyncKeyState(VK_CONTROL) & 0x8000)return NO;
00050  i=max(0,((long)strlen(filename)-25));
00051  if(i > 0)sprintf(title,"Rep: ...%s",(filename+i));
00052  else     sprintf(title,"Replace %s",filename);
00053  if(SelectFileName(0,gszSCEfile,gszSCEdir,title,"(*.MFX)|*.mfx|",ghwnd_main)
00054           == TRUE){
00055    temp=(discarded_file*)X__Realloc(discarded_file_list,
00056       sizeof(discarded_file)*(n_discarded+1));
00057    if(temp != NULL){  /* make a list so that any other objects of the same */
00058      discarded_file_list=temp; /* file are also redirected */
00059      discarded_file_list[n_discarded].old=strdup(filename);
00060      discarded_file_list[n_discarded].new=strdup(gszSCEfile);
00061      discarded_file_list[n_discarded].Op=Op;
00062      n_discarded++;
00063    }
00064    strcpy(filename,gszSCEfile);
00065    return YES;
00066  }
00067  return NO;
00068 }
00069 
00070 void ReplaceOneObjectFile(node *Np, object *Lop, char *NewName){
00071  short robot;
00072  long ff,lf;
00073  skel *S,*Scopy;
00074  long i,nSkelO;
00075  lf=Lop->lastframe;
00076  ff=Lop->firstframe;
00077  Scopy=NULL;
00078  if(Lop->type == ROBOT){ // make copy of skeleton
00079    S=Lop->skeleton;
00080    nSkelO=Lop->nskeleton;
00081    if(nSkelO > 0 && S != NULL){
00082      Scopy=(skel *)X__Malloc(nSkelO*sizeof(skel));
00083      if(Scopy != NULL)memcpy(Scopy,S,nSkelO*sizeof(skel));
00084    }
00085  }
00086  DeleteCostume(Np,Lop->lastframe);
00087  Lop=CreateCostume(Np,ff,lf);
00088  if(fail_op == YES){;}
00089  else if(Lop == NULL){;}
00090  else{
00091    Lop->type=Np->type;
00092    strcpy(Lop->name,NewName);
00093    if(Lop->type == ROBOT)robot=YES;
00094    else                  robot=NO;
00095    if(LoadMeshObject(NewName,Lop,YES,YES,robot) == FAIL){
00096      DeleteCostume(Np,lf);
00097    }
00098    else{
00099      if(Lop->type == ROBOT){
00100        if(Lop->nskeleton == nSkelO && Lop->skeleton != NULL && Scopy != NULL){ // copy back the robot pose
00101          memcpy(Lop->skeleton,Scopy,nSkelO*sizeof(skel)); 
00102        } 
00103      }
00104    }
00105  }
00106  if(Scopy != NULL)X__Free(Scopy);
00107  return;
00108 }
00109 
00110 void ReplaceObjectFile(object *Lop, char *NewName){
00111  node   *Np;
00112  object *Op;
00113  point  *P,*Pw,origin,offset;
00114  Sedge  *E,*Ew;
00115  long   *Skid;
00116  skel   *S;
00117  nurbs  *Nn;
00118  short fileid,inram,robot;
00119  long i,j,nNurbs,nSkelO;
00120  char Oldname[256];
00121  P=Lop->points;
00122  E=Lop->edges;
00123  S=Lop->skeleton;
00124  nSkelO=Lop->nskeleton;
00125  Pw=Lop->w_frame.p;
00126  Ew=Lop->w_frame.e;
00127  nNurbs=Lop->nNurbs;
00128  Nn=Lop->Nurbs;
00129  Skid=Lop->skid;
00130  fileid = Lop->fileID;
00131  inram=Lop->in_ram;
00132  CopyPoint(Lop->origin,origin);
00133  CopyPoint(Lop->offset,offset);
00134  if(Lop->type == ROBOT)robot=YES;
00135  else                  robot=NO;
00136  if(LoadMeshObject(NewName,Lop,YES,NO,robot) == FAIL){
00137    SendPrgmQuery(IDQ_OLD3,0);  /* put back anything that might have changed */
00138    Lop->in_ram=inram;
00139    CopyPoint(origin,Lop->origin);
00140    CopyPoint(offset,Lop->origin);
00141  }
00142  else{
00143    sprintf(RAMfilename,"%s%d.$$$",TempPath,fileid);
00144 //   remove(RAMfilename);
00145    strcpy(Oldname,Lop->name);
00146    strcpy(Lop->name,NewName);
00147    if(P != NULL)X__Free(P);
00148    if(E != NULL)X__Free(E);
00149    if(robot && S != NULL  && Lop->nskeleton == nSkelO){ // can copy the old skeleton pose to the new one
00150      for(i=0;i<nSkelO;i++){
00151        memcpy(&(Lop->skeleton[i]),&(S[i]),sizeof(skel));
00152      }
00153    }
00154    if(S != NULL)X__Free(S);
00155    if(Pw != NULL)X__Free(Pw);
00156    if(Ew != NULL)X__Free(Ew);
00157    if(Skid != NULL)X__Free(Skid);
00158    if(Nn != NULL)FreeNurbs(nNurbs,Nn);
00159    if((Np=FirstNp) != NULL)while(Np != NULL){ /* update any other same model */
00160      if((Op=Np->fobj) != NULL)while(Op != NULL){
00161        if(strcmp(Oldname,Op->name) == 0 && Op != Lop){
00162          for(j=0;j<3;j++){
00163            Op->origin[j] = Lop->origin[j];
00164            Op->offset[j] = Lop->offset[j];
00165            for(i=0;i<8;i++){
00166              Op->outline[i][j]  = Lop->outline[i][j];
00167            }
00168          }
00169          strcpy(Op->name,Lop->name);
00170          Op->npoints   = Lop->npoints;
00171          Op->nedges    = Lop->nedges;
00172          Op->points    = Lop->points;
00173          Op->edges     = Lop->edges;
00174          Op->in_ram    = Lop->in_ram;
00175          Op->fileID    = Lop->fileID;
00176          Op->skid      = Lop->skid;
00177          Op->nNurbs    = Lop->nNurbs;
00178          Op->Nurbs     = Lop->Nurbs;
00179          Op->bIKchain  = Lop->bIKchain;
00180          if(Op->nskeleton != Lop->nskeleton){/* skeketons incompatible */
00181            SendPrgmQuery(IDQ_SKELINCOMPAT,0);
00182          }
00183          Op->nskeleton = Lop->nskeleton;
00184          Op->w_frame.Np= Lop->w_frame.Np;
00185          Op->w_frame.Ne= Lop->w_frame.Ne;
00186          Op->w_frame.e = Lop->w_frame.e;
00187          Op->w_frame.p = Lop->w_frame.p;
00188        }
00189        Op=Op->next;
00190      }
00191      Np=Np->next;
00192    }
00193  }
00194 }
00195 
00196 void DeleteRamFile(short id, object *op){
00197  /* remove only if single object present  - delete from ram if INRAM */
00198  node   *Np;
00199  object *Op;
00200  int idcount;
00201  idcount=0;
00202  if((Np=FirstNp) != NULL)while(Np != NULL){
00203   if((Op=Np->fobj) != NULL)while(Op != NULL){
00204     if(id == Op->fileID)idcount++;
00205     Op=Op->next;
00206   }
00207   Np=Np->next;
00208  }
00209  op->nskeleton=0;
00210  if(op->skeleton != NULL)X__Free(op->skeleton);
00211  op->skeleton=NULL;
00212  if(idcount > 1)return; /* if this is needed by another actor */
00213  if(op->points != NULL){X__Free(op->points); op->points = NULL;}
00214  if(op->edges != NULL){X__Free(op->edges); op->edges = NULL;}
00215  op->npoints=0;    op->nedges=0;
00216  if(op->skid != NULL){X__Free(op->skid); op->skid=NULL;}
00217  if(op->w_frame.e != NULL){X__Free(op->w_frame.e); op->w_frame.e = NULL;}
00218  if(op->w_frame.p != NULL){X__Free(op->w_frame.p); op->w_frame.p = NULL;}
00219  op->w_frame.Ne=0; op->w_frame.Np=0;
00220  op->in_ram=0;
00221  op->bIKchain=FALSE;
00222  if(op->Nurbs != NULL){
00223    FreeNurbs(op->nNurbs,op->Nurbs);
00224    op->nNurbs=0; op->Nurbs=NULL;
00225  }
00226  sprintf(RAMfilename,"%s%d.$$$",TempPath,id);
00227 // if(remove(RAMfilename) != 0){
00228 //; /*   Failed to delete Work file */
00229 // }
00230 }
00231 
00232 object *ObjectExists(char *FileName, object *Oop, long *fileID){
00233  node   *Np;
00234  object *Op;
00235  long i;
00236  /* first check if this is in the discarded list - if it is and the new
00237     entry exists then return that */
00238   if(n_discarded > 0 && discarded_file_list != NULL){
00239     for(i=0;i<n_discarded;i++){
00240       if(discarded_file_list[i].old != NULL &&
00241          discarded_file_list[i].new != NULL &&
00242          discarded_file_list[i].Op  != NULL){
00243         if(strcmp(FileName,discarded_file_list[i].old) == 0){
00244           Op=discarded_file_list[i].Op;
00245           *fileID=Op->fileID;
00246           strcpy(FileName,discarded_file_list[i].new);
00247           return Op;
00248         }
00249       }
00250     }
00251   }
00252  /* now check all the other actors + costumes to see it this one is in
00253     use */
00254  if((Np=FirstNp) != NULL)while(Np != NULL){
00255   if((Op=Np->fobj) != NULL)while(Op != NULL){
00256     if(strcmp(FileName,Op->name) == 0 && Op != Oop){
00257       *fileID = Op->fileID;
00258       return Op;
00259     }
00260     Op=Op->next;
00261   }
00262   Np=Np->next;
00263  }
00264  return NULL;
00265 }
00266 
00268 
00269 void outlng_s(long lng, FILE *foo){
00270  fputc((char)(lng >> 24),foo);
00271  fputc((char)(lng >> 16),foo);
00272  fputc((char)(lng >>  8),foo);
00273  fputc((char)(lng      ),foo);
00274 }
00275 
00276 unsigned char getlon_s(long * val, FILE *f){
00277  *val  = ((long)getc(f))<<24;
00278  *val |= ((long)getc(f))<<16;
00279  *val |= ((long)getc(f))<<8;
00280  *val |= ((long)getc(f));
00281  return(1);
00282 }
00283 
00284 static unsigned char getush_s(FILE *f, long * val){
00285  *val  = ((long)getc(f))<<8;
00286  *val |= ((long)getc(f));
00287  return(1);
00288 }
00289 
00290 unsigned char getsht_s(FILE *f, short * val){
00291  *val  = ((short)getc(f))<<8;
00292  *val |= ((short)getc(f));
00293  return(1);
00294 }
00295 
00296 // load the OFX file
00297 
00298 unsigned char getlon_H(HANDLE f, long * val){
00299  DWORD dwRead;
00300  long l,l0,l1,l2,l3;
00301  ReadFile(f,&l,sizeof(long),&dwRead,NULL);
00302  l0 = (l >> 24) & 0x000000ff;
00303  l1 = (l >> 16) & 0x000000ff;
00304  l2 = (l >>  8) & 0x000000ff;
00305  l3 = (l      ) & 0x000000ff;
00306  *val = (l3 << 24) | (l2 << 16) | (l1 <<  8) | l0;
00307  return(1);
00308 }
00309 
00310 static unsigned char getush_H(HANDLE f, long * val){
00311  DWORD dwRead;
00312  unsigned short s,s0,s1;
00313  ReadFile(f,&s,sizeof(short),&dwRead,NULL);
00314  s0 = (s >>  8) & 0x00ff;
00315  s1 = (s      ) & 0x00ff;
00316  *val = (s1 <<  8) | s0;
00317  return(1);
00318 }
00319 
00320 unsigned char getsht_H(HANDLE f, short * val){
00321  DWORD dwRead;
00322  short s,s0,s1;
00323  ReadFile(f,&s,sizeof(short),&dwRead,NULL);
00324  s0 = (s >>  8) & 0x00ff;
00325  s1 = (s      ) & 0x00ff;
00326  *val = (s1 <<  8) | s0;
00327  return(1);
00328 }
00329 
00330 static unsigned short GetUshortFromBuffer(unsigned char *b){
00331  return ((unsigned short)(*b) <<  8) | (unsigned short)(*(b+1));
00332 }
00333 
00334 static short GetShortFromBuffer(unsigned char *b){
00335  return ((short)(*b) <<  8) | (short)(*(b+1));
00336 }
00337 
00338 static long GetLongFromBuffer(unsigned char *b){
00339  return ((long)(*b) << 24) | ((long)(*(b+1)) << 16) |
00340         ((long)(*(b+2)) <<  8) | (long)(*(b+3));
00341 }
00342 
00343 static void getchunk_H(long clen, HANDLE f){
00344  SetFilePointer(f,clen,NULL,FILE_CURRENT);
00345 }
00346 
00347 static void getchunk_F(long clen, FILE *f){
00348  fseek(f,clen,SEEK_CUR); 
00349 }
00350 
00351 static void StageReadSkeleton(long clen, object *Op, short version,HANDLE fp){
00352  unsigned char *buffer=NULL,*b;
00353  DWORD dwRead;
00354  short loadit=1;
00355  long s;
00356  long n,i,j,k,l,l0,l1,l2,*jj;
00357  char name[32]={"None"};
00358  skel *sp;
00359  buffer=(unsigned char *)X__Malloc(clen);
00360  if(buffer == NULL)return;  b=buffer;
00361  if(!ReadFile(fp,buffer,clen,&dwRead,NULL) || dwRead != clen){
00362    X__Free(buffer);
00363    return;
00364  }
00365  n=(long)GetLongFromBuffer(b); b+= 4;
00366  if((Op->skeleton=(skel *)X__Malloc(n*(long)sizeof(skel))) == NULL)loadit=0;
00367  else Op->nskeleton=n;
00368  sp=Op->skeleton;
00369  for(i=0;i<n;i++){
00370   l0=(long)GetLongFromBuffer(b); b+= 4;
00371   l1=(long)GetLongFromBuffer(b); b+= 4;
00372   l2=(long)GetLongFromBuffer(b); b+= 4;
00373   if(version < 3){s=(long)GetShortFromBuffer(b); b+= 2;}
00374   else           {s=(long)GetLongFromBuffer(b); b+= 4;}
00375   if(version > 0){
00376     memcpy(name,b,16); b+= 16;
00377     if(version > 3){
00378       l=(long)GetLongFromBuffer(b); b+= 4;
00379       sp->weight=(double)l/1000.0;
00380       l=(long)GetLongFromBuffer(b); b+= 4;
00381       sp->wrange=(double)l/1000.0;
00382       l=(long)GetLongFromBuffer(b); b+= 4;
00383       sp->wzone=(double)l/1000.0;
00384     }
00385     else sp->weight=1.0;
00386   }
00387   strcpy(sp->name,name);
00388   if(version > 1){
00389     for(j=0;j<3;j++){
00390       l=(long)GetLongFromBuffer(b); b+= 4;
00391       sp->u[j] = ((double)l)*1.0e-8;
00392     }
00393     for(j=0;j<3;j++){
00394       l=(long)GetLongFromBuffer(b); b+= 4;
00395       sp->v[j] = ((double)l)*1.0e-8;
00396     }
00397     for(j=0;j<3;j++){
00398       l=(long)GetLongFromBuffer(b); b+= 4;
00399       sp->w[j] = ((double)l)*1.0e-8;
00400     }
00401     for(j=0;j<8;j++)for(k=0;k<3;k++){
00402       sp->bx[j][k]=(long)GetLongFromBuffer(b); b+= 4;
00403       sp->bx[j][k] -= Op->origin[k];
00404     }
00405   }
00406   if(loadit){
00407     sp->id=s;
00408     sp->pp[0]=sp->p[0] = l0 - Op->origin[0];
00409     sp->pp[1]=sp->p[1] = l1 - Op->origin[1];
00410     sp->pp[2]=sp->p[2] = l2 - Op->origin[2];
00411     for(j=0;j<3;j++){
00412       sp->pt[j]=0;
00413       sp->uu[j]=sp->u[j];
00414       sp->vv[j]=sp->v[j];
00415       sp->ww[j]=sp->w[j];
00416     }
00417     null_transform(sp->R);
00418     null_transform(sp->Q);
00419     null_transform(sp->T);
00420     sp->IKlock=FALSE;
00421     sp->uIKlock=FALSE;
00422     sp->vIKlock=FALSE;
00423     sp->wIKlock=FALSE;
00424     sp->uIKmin=0.0; sp->vIKmin=0.0; sp->wIKmin=0.0;
00425     sp->uIKmax=360.0; sp->vIKmax=360.0; sp->wIKmax=360.0;
00426     sp++;
00427   }
00428  }
00429  n=(long)GetLongFromBuffer(b); b+= 4;
00430  if(n > 0){
00431    if(loadit){
00432      if((Op->skid=(long *)X__Malloc(n*(long)sizeof(long))) == NULL){
00433        loadit=0;
00434        X__Free(Op->skeleton); Op->skeleton=NULL; Op->nskeleton=0;
00435      }
00436      else jj=Op->skid;
00437    }
00438    for(i=0;i<n;i++){
00439      if(version < 3){s=(long)GetShortFromBuffer(b); b+= 2;}
00440      else           {s=(long)GetLongFromBuffer(b); b+= 4;}
00441      if(loadit)*jj++ = (long)s;
00442    }
00443  }
00444  X__Free(buffer);
00445  return;
00446 }
00447 
00448 static void StageReadWireframe(long clen, object *Op, HANDLE fp){
00449  long i,np,ne,readit=1,size,x,y;
00450  point p;
00451  getlon_H(fp,&np);
00452  getlon_H(fp,&ne);
00453  size=np*(long)sizeof(point);
00454  if((Op->w_frame.p = (point *)X__Malloc(size)) == NULL)readit=0;
00455  size=ne*(long)sizeof(Sedge);
00456  if((Op->w_frame.e = (Sedge *)X__Malloc(size)) == NULL){
00457    readit=0;
00458    if(Op->w_frame.p != NULL){X__Free(Op->w_frame.p); Op->w_frame.p=NULL;}
00459  }
00460  for(i=0;i<np;i++){
00461    getlon_H(fp,&p[0]); getlon_H(fp,&p[1]); getlon_H(fp,&p[2]);
00462    p[0] -= Op->origin[0];
00463    p[1] -= Op->origin[1];
00464    p[2] -= Op->origin[2];
00465    if(readit)CopyPoint(p,Op->w_frame.p[i]);
00466  }
00467  for(i=0;i<ne;i++){
00468    getlon_H(fp,&x); getlon_H(fp,&y);
00469    if(readit){Op->w_frame.e[i][0]=x; Op->w_frame.e[i][1]=y;}
00470  }
00471  if(readit){
00472    Op->w_frame.Np=np; Op->w_frame.Ne=ne;
00473  }
00474 }
00475 
00476 static void StageReadNurbs(long clen, object *Op, HANDLE fp){
00477  DWORD dwRead;
00478  BOOL readit=TRUE;
00479  long i,j,k,N;
00480  nurbs *n,*Np;
00481  vector4 *p;
00482  double w;
00483  ReadFile(fp,&N,sizeof(long),&dwRead,NULL);
00484  if(N == 0)return;
00485  newnurbs=N;
00486  if((Np=(nurbs *)X__Malloc(N*sizeof(nurbs))) == NULL)return;
00487  for(k=0;k<N;k++){
00488    n=(Np+k);
00489    ReadFile(fp,&(n->properties),sizeof(NurbsProperties),&dwRead,NULL);
00490    ReadFile(fp,&(n->numU),sizeof(long),&dwRead,NULL);
00491    ReadFile(fp,&(n->numV),sizeof(long),&dwRead,NULL);
00492    ReadFile(fp,&(n->orderU),sizeof(long),&dwRead,NULL);
00493    ReadFile(fp,&(n->orderV),sizeof(long),&dwRead,NULL);
00494    AllocNurbs(n,NULL,NULL);
00495    for(i=0;i<n->numU + n->orderU; i++)
00496      ReadFile(fp,&(n->kvU[i]),sizeof(double),&dwRead,NULL);
00497    for(i=0;i<n->numV + n->orderV; i++)
00498      ReadFile(fp,&(n->kvV[i]),sizeof(double),&dwRead,NULL);
00499    for(i=0;i<n->numV; i++)
00500    for(j=0;j<n->numU; j++){
00501      p=&(n->points[i][j]);
00502      ReadFile(fp,p,sizeof(vector4),&dwRead,NULL);
00503      w=p->w;
00504      p->x=(p->x)/w;
00505      p->y=(p->y)/w;
00506      p->z=(p->z)/w;
00507      minX=min(p->x,minX);     maxX=max(p->x,maxX);
00508      minY=min(p->y,minY);     maxY=max(p->y,maxY);
00509      minZ=min(p->z,minZ);     maxZ=max(p->z,maxZ);
00510      p->x = (p->x - (long)Op->origin[0])*w;
00511      p->y = (p->y - (long)Op->origin[1])*w;
00512      p->z = (p->z - (long)Op->origin[2])*w;
00513    }
00514  }
00515  if(readit){
00516    Op->nNurbs=N;
00517    Op->Nurbs=Np;
00518  }
00519  return;
00520 }
00521 
00522 static void StageReadAxis(long clen, object *Op,HANDLE fp){
00523  long i,notrequired;
00524  getlon_H(fp,&Op->origin[0]);
00525  getlon_H(fp,&Op->origin[1]);
00526  getlon_H(fp,&Op->origin[2]);
00527  for(i=0;i<9;i++)getlon_H(fp,&notrequired);
00528 }
00529 
00530 static short StageReadEdges(long clen, object *Op, BOOL short_form, HANDLE fp){
00531   DWORD dwRead;
00532   long i,size;
00533   unsigned char *buffer=NULL,*b;
00534   if(short_form)newedge=clen/4;
00535   else          newedge=clen/8;
00536   size=newedge*(long)sizeof(Sedge);
00537   if(Op->in_ram){
00538     if(size > 0){
00539       if((Op->edges = (Sedge *)X__Malloc(size)) == NULL)return FAIL;
00540     }
00541     else Op->edges=NULL;
00542     Op->nedges=newedge;
00543   }
00544   if(newedge == 0)return OK;
00545   buffer=(unsigned char *)X__Malloc(clen);
00546   if(buffer == NULL)return FAIL;  b=buffer;
00547   if(!ReadFile(fp,buffer,clen,&dwRead,NULL) || dwRead != clen){
00548     X__Free(buffer);
00549     return FAIL;
00550   }
00551   for(i=0;i<newedge;i++){
00552     if(short_form){
00553       Op->edges[i][0]=(long)GetUshortFromBuffer(b); b+= 2;
00554       Op->edges[i][1]=(long)GetUshortFromBuffer(b); b+= 2;
00555     }
00556     else {
00557       Op->edges[i][0]=(long)GetLongFromBuffer(b); b+= 4;
00558       Op->edges[i][1]=(long)GetLongFromBuffer(b); b+= 4;
00559     }
00560   }
00561   X__Free(buffer);
00562   return OK;
00563 }
00564 
00565 static void StageReadVertices(long clen, object *Op, HANDLE fp){
00566   DWORD dwRead;
00567   unsigned char *buffer=NULL,*b;
00568   char c;
00569   long i,szz,xyz[3],size;
00570   newvert=clen/12;
00571   size=newvert*(long)sizeof(point);
00572   if(Op->in_ram){
00573     if((Op->points = (point *)X__Malloc(size)) == NULL)Op->in_ram=0;
00574     else Op->npoints=newvert;
00575   }
00576   if(newvert == 0)return;
00577   buffer=(unsigned char *)X__Malloc(clen);
00578   if(buffer == NULL)return;  b=buffer;
00579   if(!ReadFile(fp,buffer,clen,&dwRead,NULL) || dwRead != clen){
00580     X__Free(buffer);
00581     return;
00582   }
00583   for(i=0;i<newvert;i++){
00584      xyz[0]=(long)GetLongFromBuffer(b); b+= 4;
00585      xyz[1]=(long)GetLongFromBuffer(b); b+= 4;
00586      xyz[2]=(long)GetLongFromBuffer(b); b+= 4;
00587      minX=min(xyz[0],minX);     maxX=max(xyz[0],maxX);
00588      minY=min(xyz[1],minY);     maxY=max(xyz[1],maxY);
00589      minZ=min(xyz[2],minZ);     maxZ=max(xyz[2],maxZ);
00590      if(Op->in_ram)CopyPoint(xyz,Op->points[i]);
00591   }
00592   X__Free(buffer);
00593   return;
00594 }
00595 
00596 static HANDLE SearchForFile(char *input, char *output){
00597  HANDLE fp;
00598  char *fs;
00599  long l;
00600  char pref[32];
00601  char replace[1024],path[1024];
00602  // first try to see if the model is on the same drive as OFX
00603  strcpy(output,input);
00604 //MessageBox(NULL,output,"Replace file",NULL);
00605  output[0]=gszHomeDir[0]; // get drive from root
00606  fp=CreateFile(output,GENERIC_READ,
00607                  FILE_SHARE_READ,NULL,OPEN_EXISTING,
00608                  FILE_ATTRIBUTE_READONLY,(HANDLE)NULL);
00609  if(fp != INVALID_HANDLE_VALUE)return fp;
00610  // Now check the preferences paths 
00611  fs=short_form(input);
00612  // try to see if in same path as animation file
00613  strcpy(replace,gszSTGfile);
00614  if(FileInPath(replace) != NULL) *FileInPath(replace)='\0';
00615  strcat(replace,fs);
00616 //#if 0
00617 //MessageBox(NULL,replace,"Trying In same directory as animation file",NULL);
00618  fp=CreateFile(replace,GENERIC_READ,
00619                FILE_SHARE_READ,NULL,OPEN_EXISTING,
00620                FILE_ATTRIBUTE_READONLY,(HANDLE)NULL);
00621  if(fp != INVALID_HANDLE_VALUE){
00622   strcpy(output,replace);
00623   return fp;
00624  }
00625 //#endif
00626  for(l=1;l<=128;l++){ 
00627    sprintf(pref,"MODEL-PATH%ld",l);
00628    GetPrivateProfileString(IniRenderSection,pref,"$$$",
00629                            output,255,IniFilename);
00630    if(strncmp(output,"$$$",3) == 0)break;   // no more info in INI file
00631    if(output[1] != ':')continue;            // try next one (invalid entry)
00632    if(output[strlen(output)-1] != '\\')strcat(output,"\\");
00633    strcat(output,fs);
00634 //MessageBox(NULL,output,"Trying preference path with",NULL);
00635    fp=CreateFile(output,GENERIC_READ,
00636                  FILE_SHARE_READ,NULL,OPEN_EXISTING,
00637                  FILE_ATTRIBUTE_READONLY,(HANDLE)NULL);
00638    if(fp != INVALID_HANDLE_VALUE)return fp;
00639  }
00640  // now try to see if derived from "openfx" folder in different location
00641  strlwr(input); 
00642  if((fs=strstr(input,"openfx\\")) != NULL){
00643    fs+=7;
00644    strcpy(output,gszHomeDir); strcat(output,fs);
00645 //MessageBox(NULL,output,"Trying new root for model",NULL);
00646    fp=CreateFile(output,GENERIC_READ,
00647                  FILE_SHARE_READ,NULL,OPEN_EXISTING,
00648                  FILE_ATTRIBUTE_READONLY,(HANDLE)NULL);
00649    if(fp != INVALID_HANDLE_VALUE)return fp;
00650  }
00651  // try putting whole path in OpenFX folder
00652  if(input[2] == '\\'){
00653    strcpy(output,gszHomeDir); strcat(output,(input+3));
00654 //MessageBox(NULL,output,"Trying whole path in OFX home folder",NULL);
00655    fp=CreateFile(output,GENERIC_READ,
00656                  FILE_SHARE_READ,NULL,OPEN_EXISTING,
00657                  FILE_ATTRIBUTE_READONLY,(HANDLE)NULL);
00658    if(fp != INVALID_HANDLE_VALUE)return fp;
00659  }
00660  // else replace one of a number of partial paths with a default partial path
00661  GetPrivateProfileString(IniRenderSection,"MODEL-ROOT","$$$",
00662                          path,512,IniFilename);
00663  if(strncmp(path,"$$$",3) != 0){
00664    if(path[strlen(path)-1] != '\\')strcat(path,"\\");
00665    strlwr(path);
00666    for(l=1;l<=128;l++){ 
00667      sprintf(pref,"MODEL-ROOT%ld",l);
00668      GetPrivateProfileString(IniRenderSection,pref,"$$$",
00669                              replace,255,IniFilename);
00670      if(strncmp(replace,"$$$",3) == 0)break;   // no info in INI file
00671      if(replace[1] != ':')continue;            // try next one (invalid entry)
00672      if(replace[strlen(replace)-1] != '\\')strcat(replace,"\\");
00673      strlwr(replace);
00674 //MessageBox(NULL,replace,"looking for",NULL);
00675 //MessageBox(NULL,input,"in",NULL);
00676      if((fs=strstr(input,replace)) != NULL){   // found string
00677        fs += strlen(replace);
00678        strcpy(output,path);
00679        strcat(output,fs);
00680 //MessageBox(NULL,output,"Trying substitute path",NULL);
00681        fp=CreateFile(output,GENERIC_READ,
00682                    FILE_SHARE_READ,NULL,OPEN_EXISTING,
00683                    FILE_ATTRIBUTE_READONLY,(HANDLE)NULL);
00684        if(fp != INVALID_HANDLE_VALUE)return fp;
00685      }
00686    }   
00687  }
00688  return INVALID_HANDLE_VALUE;
00689 }
00690 
00691 short LoadMeshObject(char *FileName, object *Op, short report,
00692                       short check, short robot){
00693  DWORD dwRead;
00694  HANDLE fp;
00695  object *Lop;
00696  long CHUNKsize,FORMsize,i,j,OldfileID,notrequired;
00697  short status=1;
00698  skel *sp;
00699  Op->in_ram = 1;  /* don't support disk base any more */
00700  maxX = maxY = maxZ = -MAXUNIT;
00701  minX = minY = minZ =  MAXUNIT;
00702  Op->origin[0]=0; Op->origin[1]=0; Op->origin[2]=0;
00703  Op->offset[0]=0; Op->offset[1]=0; Op->offset[2]=0;
00704  Op->w_frame.Np=Op->w_frame.Ne=0;
00705  Op->w_frame.e=NULL; Op->w_frame.p=NULL;
00706  Op->skid=NULL;
00707  Op->npoints=0; Op->nedges=0;
00708  Op->nskeleton=0;
00709  Op->nNurbs=0; Op->Nurbs=NULL;
00710  Op->bIKchain=FALSE;
00711  InitialiseRamImage(&(Op->image));
00712  if((check == 0) || ((Lop=ObjectExists(FileName,Op,&OldfileID)) == NULL)){
00713    sprintf(RAMfilename,"%s%d.$$$",TempPath,fileID);
00714    Op->fileID=fileID;
00715    fileID++;
00716  }
00717  else{
00718    for(j=0;j<3;j++){
00719      Op->origin[j] = Lop->origin[j];
00720      Op->offset[j] = Lop->offset[j];
00721      for(i=0;i<8;i++){
00722        Op->outline[i][j]  = Lop->outline[i][j];
00723      }
00724    }
00725    Op->npoints   = Lop->npoints;
00726    Op->nedges    = Lop->nedges;
00727    Op->points    = Lop->points;
00728    Op->edges     = Lop->edges;
00729    Op->nNurbs    = Lop->nNurbs;
00730    Op->Nurbs     = Lop->Nurbs;
00731    Op->w_frame.Np= Lop->w_frame.Np;
00732    Op->w_frame.Ne= Lop->w_frame.Ne;
00733    Op->w_frame.e = Lop->w_frame.e;
00734    Op->w_frame.p = Lop->w_frame.p;
00735    /* make copy of the skeleton */
00736    Op->in_ram    = Lop->in_ram;
00737    Op->fileID=OldfileID;
00738    if(Lop->nskeleton > 0){
00739      j=(long)(Lop->nskeleton)*(long)sizeof(skel);
00740      if((Op->skeleton=(skel *)X__Malloc(j)) != NULL){
00741        Op->nskeleton = Lop->nskeleton;
00742        memcpy(Op->skeleton,Lop->skeleton,j);
00743        sp=Op->skeleton;               /* Copy will be same as */
00744        for(j=0;j<Op->nskeleton;j++){  /* original             */
00745          null_transform(sp->R);
00746          null_transform(sp->Q);
00747          null_transform(sp->T);
00748          sp++;
00749        }
00750      }
00751      else{
00752        Op->nskeleton=0;
00753      }
00754    }
00755    else Op->nskeleton=0;
00756    Op->skid      = Lop->skid;
00757    return OK;
00758  }
00759  fp=CreateFile(FileName,GENERIC_READ,
00760                FILE_SHARE_READ,NULL,OPEN_EXISTING,
00761                FILE_ATTRIBUTE_READONLY,(HANDLE)NULL);
00762  if(fp == INVALID_HANDLE_VALUE){
00763    if((fp=SearchForFile(FileName,RAMfilename)) != INVALID_HANDLE_VALUE)goto UPDATED;
00764    DeleteRamFile(Op->fileID,Op);
00765    if(report){
00766      SendPrgmQuery(IDQ_FILEOPENFAIL,0);
00767    }
00768    return FAIL;
00769    UPDATED:
00770 //MessageBox(NULL,RAMfilename,FileName,MB_OK);
00771    strcpy(FileName,RAMfilename);
00772    // and relpace the object name with the one found
00773    strcpy(Op->name,RAMfilename);
00774  }
00775  newedge=0; newvert=0; newnurbs=0;
00776  fail_op=NO;
00777  ReadFile(fp,str,4,&dwRead,NULL);
00778  if (dwRead != 4 || strcmp(str,"FORM") != 0){
00779    goto FAILURE1;
00780  }
00781  if(!ReadFile(fp,&FORMsize,sizeof(long),&dwRead,NULL))goto end;
00782  if(!ReadFile(fp,str,4,&dwRead,NULL))goto FAILURE1;
00783  if (dwRead != 4 || (strcmp(str,"OFXM") != 0 && strcmp(str,"AAPO") != 0)){
00784    goto FAILURE1;
00785  }
00786 loop:
00787  if(!ReadFile(fp,str,4,&dwRead,NULL))goto end;
00788  if(dwRead != 4)goto end;
00789  if (getlon_H(fp,&CHUNKsize) != 1) goto end;
00790  if     (strcmp(str,"VERT") == 0)StageReadVertices(CHUNKsize,Op,fp);
00791  else if(strcmp(str,"EDGE") == 0 ||
00792          strcmp(str,"edge") == 0){
00793   BOOL short_form;
00794   if(strcmp(str,"edge") == 0)short_form=TRUE; else short_form=FALSE;
00795   if(StageReadEdges(CHUNKsize,Op,short_form,fp) == FAIL){
00796     if(Op->in_ram){ /* try to load again to back up device */
00797       X__Free(Op->points);
00798       Op->npoints=0;
00799       fail_op=YES;  goto FAILURE2;
00800     }
00801   }
00802  }
00803  else if(strcmp(str,"AXIS") == 0)StageReadAxis(CHUNKsize,Op,fp);
00804  else if(strcmp(str,"OFFS") == 0){
00805    getlon_H(fp,&notrequired);    /* is 3 for 3 long integers to follow */
00806    getlon_H(fp,&Op->offset[0]);
00807    getlon_H(fp,&Op->offset[1]);
00808    getlon_H(fp,&Op->offset[2]);
00809  }
00810  else if((strcmp(str,"SK04")) == 0 && robot == YES){
00811    StageReadSkeleton(CHUNKsize,Op,4,fp);
00812  }
00813  else if((strcmp(str,"SK03")) == 0 && robot == YES){
00814    StageReadSkeleton(CHUNKsize,Op,3,fp);
00815  }
00816  else if((strcmp(str,"SK02")) == 0 && robot == YES){
00817    StageReadSkeleton(CHUNKsize,Op,2,fp);
00818  }
00819  else if((strcmp(str,"SK01")) == 0 && robot == YES){
00820    StageReadSkeleton(CHUNKsize,Op,1,fp);
00821  }
00822  else if((strcmp(str,"SKEL")) == 0 && robot == YES){
00823    StageReadSkeleton(CHUNKsize,Op,0,fp);
00824  }
00825  else if((strcmp(str,"WFRM")) == 0)StageReadWireframe(CHUNKsize,Op,fp);
00826  else if((strcmp(str,"NURB")) == 0)StageReadNurbs(CHUNKsize,Op,fp);
00827  else getchunk_H(CHUNKsize,fp);
00828  if(fail_op == YES)goto FAILURE2;
00829  goto loop;
00830 end:
00831  CloseHandle(fp);
00832  if(newvert == 0 && newnurbs == 0)return FAIL;  /* no object in file */
00833  Op->outline[0][0]=minX; Op->outline[0][1]=minY; Op->outline[0][2]=maxZ;
00834  Op->outline[1][0]=maxX; Op->outline[1][1]=minY; Op->outline[1][2]=maxZ;
00835  Op->outline[2][0]=maxX; Op->outline[2][1]=maxY; Op->outline[2][2]=maxZ;
00836  Op->outline[3][0]=minX; Op->outline[3][1]=maxY; Op->outline[3][2]=maxZ;
00837  Op->outline[4][0]=minX; Op->outline[4][1]=minY; Op->outline[4][2]=minZ;
00838  Op->outline[5][0]=maxX; Op->outline[5][1]=minY; Op->outline[5][2]=minZ;
00839  Op->outline[6][0]=maxX; Op->outline[6][1]=maxY; Op->outline[6][2]=minZ;
00840  Op->outline[7][0]=minX; Op->outline[7][1]=maxY; Op->outline[7][2]=minZ;
00841  for(i=0;i<8;i++){
00842    Op->outline[i][0] -= Op->origin[0];
00843    Op->outline[i][1] -= Op->origin[1];
00844    Op->outline[i][2] -= Op->origin[2];
00845  }
00846  Op->offset[0] -= Op->origin[0];
00847  Op->offset[1] -= Op->origin[1];
00848  Op->offset[2] -= Op->origin[2];
00849  return fileID;
00850 FAILURE1:
00851  CloseHandle(fp);
00852  SendPrgmQuery(IDQ_NOTAMODEL,0);
00853  return FAIL;
00854 FAILURE2:
00855  CloseHandle(fp);
00856  SendPrgmQuery(IDQ_TFWE,0);
00857  fail_op=NO;
00858  return FAIL;
00859 }
00860 
00862 
00863 short LoadAnimationFile(char *filename, BOOL bUnpack){  // max version = 6
00864  unsigned char zeroname[16];
00865  BOOL          skip;
00866  node          *Np,**NNp;
00867  object        *Op;
00868  sky           *Sp;
00869  director      *Dp;
00870  position      *Pp;
00871  align         *Ap;
00872  size          *Xp;
00873  pathpoint     *Ppp;
00874  point         TVC,TVP,TVclipMax,TVclipMin;
00875  short         Zero,Error,Nobj,Nsky,Npos,Ndirector,Nali,Nsiz,tt
00876               ,firstframe,lastframe,N,Nf
00877               ,failed_to_find
00878               ,failed_to_load
00879               ,robot;
00880  long          i,j,k,kk,Minus1,dummylong,head_chunks,version=0,
00881                chunk_size;
00882  double        dummydouble,x,y,z;
00883  point         Outline[8];
00884  Zero=0; Error=0; Minus1 = -1; failed_to_find=0;
00885  n_discarded=0; discarded_file_list=NULL;
00886 
00887  if(filename != NULL){
00888   if((fr=fopen(filename,"rb")) != NULL){
00889     ScrapEverything();    /* get rid of everything */
00890     UpdateSelectedActor(FALSE);
00891     NEXTSEGMENT:
00892     if(fread(str,1,4,fr) != 4){Error=1; goto NOLOAD;}
00893     if(strcmp(str,"OFXA") == 0  || strcmp(str,"ANIH") == 0){
00894       getlon_s(&head_chunks,fr);
00895       getlon_s(&i,fr);   ruler = (double)i;
00896       if(fread(ruler_name,1,8,fr) != 8){Error=1; goto NOLOAD;}
00897       getlon_s(&lrulerx,fr); getlon_s(&lrulery,fr);   getlon_s(&lrulerz,fr);
00898       rulerx = lrulerx; rulery = lrulery; rulerz = lrulerz;
00899       getlon_s(&i,fr);       getlon_s(&i,fr);         getlon_s(&i,fr);
00900       getlon_s(&grid_size,fr);
00901       if(head_chunks > 1){
00902         getlon_s(&version,fr);
00903       }
00904       goto NEXTSEGMENT;
00905     }
00906     if(strcmp(str,"XIMP") == 0){
00907       getlon_s(&head_chunks,fr);
00908       for(i=0;i<head_chunks;i++){
00909         skip=FALSE;
00910         if(CreateImageProcess(NULL) == NULL)skip=TRUE;
00911         getlon_s(&kk,fr);
00912         if(!skip){
00913           MainIp->p=(char *)X__Malloc(kk+1);
00914           if(MainIp->p == NULL)skip=TRUE;
00915           if(!skip)memset(MainIp->p,0,kk+1);
00916           if(!skip)fread(MainIp->p,1,kk,fr);
00917           else for(j=0;j<kk;j++)fread(&dummylong,1,1,fr);
00918         }
00919       }
00920       goto NEXTSEGMENT;
00921     }
00922     if(strcmp(str,"STAG") == 0){
00923       fread(&Nf,sizeof(long),1,fr);
00924       fread(&N,sizeof(short),1,fr);
00925       NNp=(node **)X__Malloc(N*sizeof(node *));
00926       if(NNp == NULL){Error=1; goto NOLOAD;}
00927       /* this used to be the location of scrap-everything moved XIMP !! */
00928       Nframes=Nf;
00929       fread(&Nground,sizeof(short),1,fr);
00930       for(i=0;i<N;i++){
00931         Np=CreateNode();
00932         NNp[i]=Np;
00933         fread(zeroname,1,16,fr);
00934         if(zeroname[0] == 255 && zeroname[1] == 254 &&
00935            zeroname[2] == 253 && zeroname[3] == 252 &&
00936            zeroname[4] == 255 && zeroname[5] == 254 &&
00937            zeroname[6] == 253 && zeroname[7] == 252){
00938           fread(Np->actorname,1,128,fr);
00939         }
00940         else{
00941           strcpy(Np->actorname,(char *)zeroname);
00942         }
00943         fread(&(Np->type),sizeof(short),1,fr);
00944         if(version > 0){
00945           fread(&(Np->ID),sizeof(short),1,fr);
00946           if(Np->ID >= MaxNodeID)MaxNodeID=Np->ID + 1;
00947         }
00948         if(Np->type == ROBOT)Nrobots++;
00949         if(Np->type == SKY)Nskys=1;
00950         if(Np->type == DIRECTOR)Ndirectors=1;
00951         else if(Np->type == CAMERA){
00952           Ncameras++;
00953           if(Ncameras == 1)SelectedCamera=Np;
00954           else if(Ncameras > 1){  /* additional camera has flag => in use */
00955             fread(&tt,1,sizeof(short),fr);
00956             if(tt)SelectedCamera=Np;
00957           }
00958         }
00959       }
00960       for(i=0,Np=FirstNp;i<Nnodes;i++){
00961         fread(&(Np->type),sizeof(short),1,fr);
00962         fread(zeroname,1,16,fr);
00963         if(zeroname[0] == 255 && zeroname[1] == 254 &&
00964            zeroname[2] == 253 && zeroname[3] == 252 &&
00965            zeroname[4] == 255 && zeroname[5] == 254 &&
00966            zeroname[6] == 253 && zeroname[7] == 252){
00967           fread(Np->actorname,1,128,fr);
00968         }
00969         else{
00970           strcpy(Np->actorname,(char *)zeroname);
00971         }
00972         fread(&Nsky,sizeof(short),1,fr);
00973         if(Nsky > 0){
00974           for(j=0;j<Nsky;j++){
00975             fread(&firstframe,sizeof(short),1,fr);
00976             fread(&lastframe,sizeof(short),1,fr);
00977             Sp=CreateSky(Np,firstframe,lastframe);
00978             fread(Sp->colour,1,3,fr);
00979             fread(Sp->zcolour,1,3,fr);
00980             fread(&Sp->type,sizeof(short),1,fr);
00981             if(Sp->type > 7){ /* ambient is specified         */
00982               Sp->type -= 8;   /* extract the type identifier */
00983               fread(&Sp->gamb,sizeof(double),1,fr);
00984               fread(&Sp->oamb,sizeof(double),1,fr);
00985               fread(Sp->gamb_colour,sizeof(double),3,fr);
00986               fread(Sp->oamb_colour,sizeof(double),3,fr);
00987             }
00988             fread(Sp->name,1,128,fr);
00989             if(Sp->type == SKYANIMATED){
00990               fread(&Sp->aff,sizeof(long),1,fr);
00991               fread(&Sp->alf,sizeof(long),1,fr);
00992               fread(&Sp->ast,sizeof(long),1,fr);
00993             }
00994             if(version > 4){
00995               fread(&Sp->sky_params,32*sizeof(double),1,fr);
00996               fread(&Sp->sky_params_file,256,1,fr); 
00997             }
00998           }
00999         }
01000         if(Np->type == DIRECTOR){
01001           fread(&Ndirector,sizeof(short),1,fr);
01002           if(Ndirector > 0)for(j=0;j<Ndirector;j++){
01003             fread(&firstframe,sizeof(short),1,fr);
01004             fread(&lastframe,sizeof(short),1,fr);
01005             Dp=CreateDirector(Np,firstframe,lastframe);
01006             fread(&Dp->type,sizeof(long),1,fr);
01007             fread(&k,sizeof(long),1,fr);
01008             if(k >= 0)Dp->ActiveCamera=NNp[k];
01009           }
01010         }
01011         fread(&Npos,sizeof(short),1,fr);
01012         if(Npos > 0){
01013           for(j=0;j<Npos;j++){
01014             fread(&firstframe,sizeof(short),1,fr);
01015             fread(&lastframe,sizeof(short),1,fr);
01016             Pp=CreatePosition(Np,firstframe,lastframe);
01017             fread(&(Pp->type),sizeof(short),1,fr);
01018             if(Pp->type == FOLLOWAT){
01019               fread(&(Pp->fx),sizeof(short),1,fr);
01020               fread(&(Pp->fy),sizeof(short),1,fr);
01021               fread(&(Pp->fz),sizeof(short),1,fr);
01022             }
01023             fread(Pp->finish,sizeof(point),1,fr);
01024             fread(&k,sizeof(long),1,fr);
01025             if(k >= 0)Pp->onpath=NNp[k];
01026             fread(zeroname,1,16,fr);
01027             if(zeroname[0] == 255 && zeroname[1] == 254 &&
01028                zeroname[2] == 253 && zeroname[3] == 252 &&
01029                zeroname[4] == 255 && zeroname[5] == 254 &&
01030                zeroname[6] == 253 && zeroname[7] == 252){
01031               fread(Pp->pnodename,1,128,fr);
01032             }
01033             else{
01034               strcpy(Pp->pnodename,(char *)zeroname);
01035             }
01036           }
01037         }
01038         fread(&Nali,sizeof(short),1,fr);
01039         if(Nali > 0){
01040           for(j=0;j<Nali;j++){
01041             fread(&firstframe,sizeof(short),1,fr);
01042             fread(&lastframe,sizeof(short),1,fr);
01043             Ap=CreateAlign(Np,firstframe,lastframe);
01044             fread(&(Ap->type),sizeof(short),1,fr);
01045             if(Ap->type > 7){  /* if internal motion present read it in */
01046               Ap->type = (Ap->type & 0x0007);
01047               fread(&(Ap->im),sizeof(short),1,fr);
01048               fread(&(Ap->ima),sizeof(double),1,fr);
01049             }
01050             else{Ap->im=0; Ap->ima=0.0;} /* no internal motion */
01051             fread(&(Ap->theta),sizeof(double),1,fr);
01052             fread(&(Ap->phi),sizeof(double),1,fr);
01053             fread(&(Ap->alpha),sizeof(double),1,fr);
01054             fread(&k,sizeof(long),1,fr);
01055             if(k >= 0)Ap->topath=NNp[k];
01056             fread(zeroname,1,16,fr);
01057             if(zeroname[0] == 255 && zeroname[1] == 254 &&
01058                zeroname[2] == 253 && zeroname[3] == 252 &&
01059                zeroname[4] == 255 && zeroname[5] == 254 &&
01060                zeroname[6] == 253 && zeroname[7] == 252){
01061               fread(Ap->anodename,1,128,fr);
01062             }
01063             else{
01064               strcpy(Ap->anodename,(char *)zeroname);
01065             }
01066           }
01067         }
01068         fread(&Nsiz,sizeof(short),1,fr);
01069         if(Nsiz > 0){
01070           for(j=0;j<Nsiz;j++){
01071             fread(&firstframe,sizeof(short),1,fr);
01072             fread(&lastframe,sizeof(short),1,fr);
01073             Xp=CreateSize(Np,firstframe,lastframe);
01074             fread(&(Xp->Sx),sizeof(double),1,fr);
01075             fread(&(Xp->Sy),sizeof(double),1,fr);
01076             fread(&(Xp->Sz),sizeof(double),1,fr);
01077             if(version > 4){
01078               fread(&(Xp->camera_params),20*sizeof(double),1,fr);
01079             }
01080           }
01081         }
01082         fread(&Nobj,sizeof(short),1,fr);
01083         if(Nobj > 0){
01084           for(j=0;j<Nobj;j++){
01085             if((fread(&firstframe,sizeof(short),1,fr)) != 1)goto FAILED;
01086             if((fread(&lastframe,sizeof(short),1,fr)) != 1)goto FAILED;
01087             Op=CreateCostume(Np,firstframe,lastframe);
01088             if(Op == NULL)goto FAILED;
01089             fread(Op->name,1,128,fr);   // RSFX  need to make longer
01090             if((fread(&(Op->type),sizeof(short),1,fr)) != 1)goto FAILED;
01091             if(Op->type == IMAGEP){
01092               if(fread(&tt,sizeof(short),1,fr) != 1)goto FAILED;
01093               if(tt > 0){
01094                 if(fread(&tt,sizeof(short),1,fr) != 1)goto FAILED;
01095                 if(tt > 0){
01096                   Op->xip=(char *)X__Malloc(tt+1);
01097                   if(Op->xip == NULL)goto FAILED;
01098                   memset(Op->xip,0,tt+1);
01099                   fread(Op->xip,1,tt,fr);
01100                 }
01101               }
01102             }
01103             fread(&(Op->morph),sizeof(short),1,fr);
01104             tt = Op->morph >> 4;  /* high bits of morph flag for effect*/
01105             Op->morph &= 0x000f;  /* must be 0 or 1 or 2 or 3*/
01106             if(tt == 127){ /* read the rest of the effects structure */
01107               fread(&tt,sizeof(short),1,fr);
01108               Op->effect=(char *)X__Malloc(tt+1);
01109               memset(Op->effect,0,tt+1);
01110               fread(Op->effect,1,tt,fr);
01111             }
01112             else Op->effect=NULL;
01113             if(Op->effect != NULL){
01114               char effectname[255];
01115               sscanf(Op->effect,"%s",effectname);
01116               if(strlen(effectname) == 1){
01117                 int idd;
01118                 idd=atoi(effectname);
01119                 sprintf(effectname,"%seffects\\%s",gszHomeDir,
01120                          internal_effect_list[idd-1]);
01121               }
01122               LoadEffectLibrary(effectname,Op); /* hidden white spaces */
01123             }
01124             fread(&(Op->morphNo),sizeof(short),1,fr); Op->morphNo=0; /* NB temp */
01125             fread(&(Op->fileID),sizeof(short),1,fr);
01126             if((fread(Op->origin,sizeof(point),1,fr)) != 1)goto FAILED;
01127             if((fread(Outline,sizeof(point),8,fr)) != 8)goto FAILED;
01128             if(Op->type == PARTICLE){ 
01129               for(k=0;k<8;k++)CopyPoint(Outline[k],Op->outline[k]);
01130             }
01131             Op->offset[0]=Op->origin[0]; /* will be set in LoadObject */
01132             Op->offset[1]=Op->origin[1]; /* as will Op->origin and outline */
01133             Op->offset[2]=Op->origin[2];
01134             failed_to_load=NO;  
01135             if(Op->type == ROBOT)robot=YES; 
01136             else                 robot=NO;
01137             TRYAGAINLOAD:
01138             if(Op->fileID >= 0){
01139               if(bUnpack)UnpackName(Op->name);
01140               if(LoadMeshObject(Op->name,Op,NO,YES,robot)
01141                                    == FAIL){
01142                 if(TryAgainToLoad(Op->name,Op))goto TRYAGAINLOAD;
01143                 failed_to_find=YES;
01144                 failed_to_load=YES;
01145               }
01146             }
01147             if(Op->type == PARTICLE){ 
01148               fread(&dummylong,sizeof(long),1,fr);
01149               fread(&(Op->particles),dummylong,1,fr);   
01150             }
01151             if(Op->type == ROBOT){/* skeleton structure if robot */
01152               fread(&dummylong,sizeof(long),1,fr);
01153               if(failed_to_find == YES || failed_to_load == YES ||
01154                                           dummylong != Op->nskeleton){
01155                 SendPrgmQuery(IDQ_SKELINCOMPAT,0);
01156                 if(dummylong > 0)for(k=0;k<dummylong;k++){
01157                   for(kk=0;kk<16;kk++)fread(&dummydouble,sizeof(double),1,fr);
01158                 }
01159               }
01160               else{
01161                 Op->nskeleton=dummylong;
01162                 if(Op->nskeleton > 0)for(k=0;k<Op->nskeleton;k++){
01163                   fread(Op->skeleton[k].R,sizeof(double),16,fr);
01164                   c4to4(Op->skeleton[k].R,Op->skeleton[k].Q);
01165                 }
01166               }
01167             }
01168             fread(&(Op->groundtype),sizeof(short),1,fr);
01169             fread(&(Op->lighttype),sizeof(short),1,fr);
01170             fread(Op->colour,1,3,fr);
01171             if(Op->groundtype >= 255){  /* for compatibility  with old */
01172               Op->groundtype -= 256;
01173               fread(&(Op->gspec),sizeof(double),1,fr);
01174               fread(&(Op->gtran),sizeof(double),1,fr);
01175               fread(&(Op->grefl),sizeof(double),1,fr);
01176               fread(&(Op->gbump),sizeof(double),1,fr);
01177             }
01178             if(Op->groundtype > 127){
01179               fread(Op->acolour,1,3,fr);
01180             }
01181             fread(&(Op->pathtype),sizeof(short),1,fr);
01182             fread(&(Op->npathpoints),sizeof(short),1,fr);
01183             fread(&(Op->pathlength),sizeof(double),1,fr);
01184             if(Op->npathpoints > 0){
01185               for(k=0,Ppp=NULL;k<Op->npathpoints;k++){
01186                  if((Ppp=AppendPathPoint(Ppp)) == NULL){
01187                    DeleteCostume(Np,lastframe);
01188                    goto FAILED;
01189                  }
01190                  if(k == 0)Op->firstpathpoint=Ppp;
01191                  fread(&(Ppp->status),sizeof(short),1,fr);
01192                  fread(Ppp->p,sizeof(point),1,fr);
01193                  fread(&(Ppp->distance),sizeof(double),1,fr);
01194                  fread(&(Ppp->ptheta),sizeof(double),1,fr);
01195                  fread(&(Ppp->pfi),sizeof(double),1,fr);
01196                  Ppp->tension_p=Ppp->tension_n=0.5;
01197               }
01198             }
01199             if(Op->type == PATH){ /* read the path velocities + new items */
01200               if((Op->v=ReTweenVelocity(Op,NULL,
01201                       (int)(lastframe-firstframe+1),
01202                       (int)(lastframe-firstframe+1),
01203                       Op->pathlength,0)) != NULL){
01204                 if(strncmp(Op->name,"PATH1991",8) == 0 ||
01205                    strncmp(Op->name,"PATH1995",8) == 0){
01206                   for(k=0;k<(lastframe-firstframe+1);k++)
01207                   if(fread(&(Op->v[k]),sizeof(double),1,fr) != 1)goto FAILED;
01208                 }
01209                 else strcpy(Op->name,"PATH1995"); /* make old paths new */
01210               }
01211               else goto FAILED;
01212               if(strncmp(Op->name,"PATH1995",8) == 0){ /* read tensions */
01213                 PATHEDITCONTROL *pe1;
01214                 if(Op->npathpoints > 0){
01215                   for(k=0,Ppp=Op->firstpathpoint;k<Op->npathpoints;k++){
01216                     fread(&(Ppp->tension_p),sizeof(double),1,fr);
01217                     fread(&(Ppp->tension_n),sizeof(double),1,fr);
01218                     Ppp=Ppp->next;
01219                   }
01220                 }
01221                 fread(&kk,sizeof(long),1,fr);  /* PathEdit Controls */
01222                 Op->npec=0; Op->pec=NULL; pe1=NULL;
01223                 if(kk > 0)for(k=0;k<kk;k++){
01224                   fread(&dummylong,sizeof(long),1,fr);
01225                   fread(&dummydouble,sizeof(double),1,fr);
01226                   pe1=CreatePathEditControlPoint(&(Op->npec),&(Op->pec),pe1,
01227                                                  NULL,dummylong,dummydouble);
01228                   if(Op->pec == NULL)goto FAILED;
01229                 }
01230               }
01231               else strcpy(Op->name,"PATH1995"); /* make old paths new */
01232             }
01233             if(version > 1){ // for versions > 1
01234               fread(&(dummylong),sizeof(long),1,fr);
01235               Op->bWireframe=(short)dummylong;
01236               if(version > 2){
01237                 fread(&(dummylong),sizeof(long),1,fr);
01238                 Op->self_shadow=(short)dummylong;
01239                 fread(&(dummylong),sizeof(long),1,fr);
01240                 Op->cast_shadow=(short)dummylong;
01241                 fread(&(dummylong),sizeof(long),1,fr);
01242                 Op->show_shadow=(short)dummylong;
01243                 fread(&(dummylong),sizeof(long),1,fr);
01244                 Op->depth_cue=(short)dummylong;
01245                 fread(&(Op->depth_cue_c),sizeof(double),1,fr);
01246                 fread(&(Op->depth_cue_l),sizeof(double),1,fr);
01247                 fread(&(Op->depth_cue_q),sizeof(double),1,fr);
01248                 if(version > 5){  // version 6   
01249                   fread(&(Op->groundTemperature),sizeof(double),1,fr);
01250                   fread(&(Op->other_params),sizeof(double),8,fr);
01251                 } 
01252               }
01253             }
01254             if(failed_to_load == YES)DeleteCostume(Np,lastframe);
01255           }
01256         }
01257         Np=Np->next;
01258       }
01259       goto SUCCESS;
01260       FAILED:
01261       SendPrgmQuery(IDQ_STAGELOADFAIL,0);
01262       SUCCESS:
01263       X__Free(NNp);
01264       if(!(GetAsyncKeyState(VK_CONTROL) & 0x8000)){ /* don't recentre */
01265         get_centre_stage(TVC,TVP,TVclipMax,TVclipMin);
01266         TVsizeX=2*(TVC[0]-TVP[0]);
01267         TVsizeY=2*(TVC[1]-TVP[1]);
01268         TVsizeZ=2*(TVC[2]-TVP[2]);
01269         TVpointX=TVP[0]-TVsizeX/10;
01270         TVpointY=TVP[1]-TVsizeY/10;
01271         TVpointZ=TVP[2]-TVsizeZ/10;
01272         TVsizeX += TVsizeX/5; TVsizeY += TVsizeY/5; TVsizeZ += TVsizeZ/5;
01273         TVcentreX=NpointerX=TVC[0];
01274         TVcentreY=NpointerY=TVC[1];
01275         TVcentreZ=NpointerZ=TVC[2];
01276         GetTriview(FALSE);  /* this will adjust the TV size */
01277       }
01278       if(failed_to_find){
01279         SendPrgmQuery(IDQ_NOTALLLOADED,0);
01280       }
01281     }
01282     else{
01283       SendPrgmQuery(IDQ_NOTSTAGEFILE,0);
01284     }
01285     if(version > 3){ // Read any additional chunks
01286       loop:
01287       if(fread(str,1,4,fr) != 4)goto NOLOAD;
01288       //MessageBox(NULL,str,"Reading V4 chunk",MB_OK);
01289       if(!getlon_s(&chunk_size,fr))goto NOLOAD;
01290       if((strcmp(str,"EOFF")) == 0)goto NOLOAD;  // End of animation file
01291       else if((strcmp(str,"EMAP")) == 0 && bEmbedImageMaps)
01292         LoadEmbeddedImageMaps(chunk_size,fr);
01293       else getchunk_F(chunk_size,fr);
01294       goto loop;
01295     }
01296     NOLOAD:
01297     fclose(fr);
01298     if(Error != 0){
01299       SendPrgmQuery(IDQ_READERROR,0);
01300     }
01301   }
01302   else{
01303    SendPrgmQuery(IDQ_FILEOPENFAIL,0);
01304   }
01305  }
01306  EDIT_ACTION=NO;
01307  if(discarded_file_list != NULL && n_discarded > 0){
01308    for(i=0;i<n_discarded;i++){
01309      if(discarded_file_list[i].old != NULL)X__Free(discarded_file_list[i].old);
01310      if(discarded_file_list[i].new != NULL)X__Free(discarded_file_list[i].new);
01311    }
01312    X__Free(discarded_file_list);
01313    discarded_file_list=NULL;
01314    n_discarded=0;
01315  }
01316  return OK;
01317 }
01318 
01319 short SaveAnimationFile(char *filename, BOOL backup){
01320  unsigned char zeroname[16];
01321  node         *Np,**NNp;
01322  object       *Op;
01323  sky          *Sp;
01324  director     *Dp;
01325  position     *Pp;
01326  align        *Ap;
01327  size         *Xp;
01328  pathpoint    *Ppp;
01329  XIP          *Ip;
01330  short        One,Zero,Error,Nobj,Nsky,Ndirector,Npos,Nali,Nsiz,
01331               tt,tg,endcode = OK;
01332  long         i,j,k,kk,Minus1,head_chunks,version=6;  // latest 
01333  int id;
01334 #if __DEMO__
01335  // MessageBeep(MB_OK);
01336 #else
01337  memset(zeroname,0,16);
01338  zeroname[0] = zeroname[4] = 255;
01339  zeroname[1] = zeroname[5] = 254;
01340  zeroname[2] = zeroname[6] = 253;
01341  zeroname[3] = zeroname[7] = 252;
01342  Zero=0; One=1; Error=0; Minus1 = -1;
01343  if(filename != NULL){
01344   if(!backup && ((fo=fopen(filename,"r")) != NULL)){ /* check for old file */
01345    fclose(fo);
01346    id=SendPrgmQuery(IDQ_OVERWRITE,1);
01347    if(id != IDYES)return -1;
01348   }
01349   if((fo=fopen(filename,"wb")) != NULL){
01350     sprintf(str,"OFXA"); fwrite(str,1,4,fo);
01351     head_chunks=2;
01352     outlng_s(head_chunks,fo);
01353     outlng_s((long)ruler,fo);
01354     fwrite(ruler_name,1,8,fo);
01355     outlng_s(lrulerx,fo); outlng_s(lrulery,fo); outlng_s(lrulerz,fo);
01356     outlng_s(rulerx,fo);  outlng_s(rulery,fo);  outlng_s(rulerz,fo);
01357     outlng_s(grid_size,fo);
01358     outlng_s(version,fo);
01359     if(NimageProcesses > 0){
01360       sprintf(str,"XIMP"); fwrite(str,1,4,fo);
01361       outlng_s((long)NimageProcesses,fo);
01362       Ip=FirstIp;
01363       for(i=0,Ip=FirstIp;i<NimageProcesses;i++,Ip=Ip->next){
01364         k=strlen(Ip->p);
01365         outlng_s(k,fo);
01366         fwrite(Ip->p,1,k,fo);
01367       }
01368     }
01369 /* addition to pos rota and size structures */
01370 
01371     sprintf(str,"STAG"); fwrite(str,1,4,fo);
01372     fwrite(&Nframes,sizeof(long),1,fo);
01373     fwrite(&Nnodes,sizeof(short),1,fo);
01374     fwrite(&Nground,sizeof(short),1,fo);
01375     NNp=(node **)X__Malloc(Nnodes*sizeof(node *));
01376     if(NNp != NULL){
01377       for(i=0,Np=FirstNp;i<Nnodes;i++){
01378         fwrite(zeroname,1,16,fo);
01379         fwrite(Np->actorname,1,128,fo);
01380         fwrite(&(Np->type),sizeof(short),1,fo);
01381         fwrite(&(Np->ID),sizeof(short),1,fo);   // added
01382         if(i > 0 && Np->type == CAMERA){ /* first camera does not have flag */
01383           if(Np == SelectedCamera)fwrite(&One, 1,sizeof(short),fo);
01384           else                    fwrite(&Zero,1,sizeof(short),fo);
01385         }
01386         NNp[i]=Np;
01387         Np=Np->next;
01388       }
01389       for(i=0,Np=FirstNp;i<Nnodes;i++){
01390         fwrite(&(Np->type),sizeof(short),1,fo);
01391         fwrite(zeroname,1,16,fo);
01392         fwrite(Np->actorname,1,128,fo);
01393         Nsky=0;
01394         if((Sp=Np->fsky) != NULL){
01395           while(Sp != NULL){Nsky++; Sp=Sp->next;}
01396           fwrite(&Nsky,sizeof(short),1,fo);
01397           for(j=0,Sp=Np->fsky;j<Nsky;j++){
01398             fwrite(&(Sp->firstframe),sizeof(short),1,fo);
01399             fwrite(&(Sp->lastframe),sizeof(short),1,fo);
01400             fwrite(Sp->colour,1,3,fo);
01401             fwrite(Sp->zcolour,1,3,fo);
01402             id=Sp->type+8;   /* encode the type identifier */
01403             fwrite(&id,sizeof(short),1,fo);
01404             fwrite(&(Sp->gamb),sizeof(double),1,fo);
01405             fwrite(&(Sp->oamb),sizeof(double),1,fo);
01406             fwrite(Sp->gamb_colour,sizeof(double),3,fo);
01407             fwrite(Sp->oamb_colour,sizeof(double),3,fo);
01408             fwrite(Sp->name,1,128,fo);
01409             if(Sp->type == SKYANIMATED){
01410               fwrite(&(Sp->aff),sizeof(long),1,fo);
01411               fwrite(&(Sp->alf),sizeof(long),1,fo);
01412               fwrite(&(Sp->ast),sizeof(long),1,fo);
01413             }
01414             fwrite(&(Sp->sky_params),32*sizeof(double),1,fo); // version 5
01415             fwrite(&(Sp->sky_params_file),256,1,fo);          // version 5
01416             Sp=Sp->next;
01417           }
01418         }
01419         else fwrite(&Nsky,sizeof(short),1,fo);
01420 
01421         if(Np->type == DIRECTOR){
01422           Ndirector=0;
01423           Dp=Np->fdirector;
01424           while(Dp != NULL){Ndirector++; Dp=Dp->next;}
01425           fwrite(&Ndirector,sizeof(short),1,fo);
01426           if(Ndirector > 0)for(j=0,Dp=Np->fdirector;j<Ndirector;j++){
01427             fwrite(&(Dp->firstframe),sizeof(short),1,fo);
01428             fwrite(&(Dp->lastframe),sizeof(short),1,fo);
01429             kk=Dp->type;
01430             fwrite(&kk,sizeof(long),1,fo);
01431             if(Dp->ActiveCamera != NULL){
01432               for(k=0;k<Nnodes;k++)if(Dp->ActiveCamera == NNp[k])goto DPOS;
01433               k=Minus1;
01434               DPOS:
01435               fwrite(&k,sizeof(long),1,fo);
01436             }
01437             Dp=Dp->next;
01438           }
01439         }
01440         // else nothing to write
01441         Npos=0;
01442         if((Pp=Np->fpos) != NULL){
01443           while(Pp != NULL){Npos++; Pp=Pp->next;}
01444           fwrite(&Npos,sizeof(short),1,fo);
01445           for(j=0,Pp=Np->fpos;j<Npos;j++){
01446             fwrite(&(Pp->firstframe),sizeof(short),1,fo);
01447             fwrite(&(Pp->lastframe),sizeof(short),1,fo);
01448             fwrite(&(Pp->type),sizeof(short),1,fo);
01449             if(Pp->type == FOLLOWAT){
01450               fwrite(&(Pp->fx),sizeof(short),1,fo);
01451               fwrite(&(Pp->fy),sizeof(short),1,fo);
01452               fwrite(&(Pp->fz),sizeof(short),1,fo);
01453             }
01454             fwrite(Pp->finish,sizeof(point),1,fo);
01455             if(Pp->onpath != NULL){
01456               for(k=0;k<Nnodes;k++)if(Pp->onpath == NNp[k])goto EPOS;
01457               k=Minus1;
01458               EPOS:
01459               fwrite(&k,sizeof(long),1,fo);
01460             }
01461             else fwrite(&Minus1,sizeof(long),1,fo);
01462             fwrite(zeroname,1,16,fo);
01463             fwrite(Pp->pnodename,1,128,fo);
01464             Pp=Pp->next;
01465           }
01466         }
01467         else fwrite(&Npos,sizeof(short),1,fo);
01468         Nali=0;
01469         if((Ap=Np->fali) != NULL){
01470           while(Ap != NULL){Nali++; Ap=Ap->next;}
01471           fwrite(&Nali,sizeof(short),1,fo);
01472           for(j=0,Ap=Np->fali;j<Nali;j++){
01473             fwrite(&(Ap->firstframe),sizeof(short),1,fo);
01474             fwrite(&(Ap->lastframe),sizeof(short),1,fo);
01475             if(Ap->im > 0){     /* write out any internal motion */
01476               tt=Ap->type | 0x0008;
01477               fwrite(&tt,sizeof(short),1,fo);
01478               fwrite(&(Ap->im),sizeof(short),1,fo);
01479               fwrite(&(Ap->ima),sizeof(double),1,fo);
01480             }
01481             else fwrite(&(Ap->type),sizeof(short),1,fo);
01482             fwrite(&(Ap->theta),sizeof(double),1,fo);
01483             fwrite(&(Ap->phi),sizeof(double),1,fo);
01484             fwrite(&(Ap->alpha),sizeof(double),1,fo);
01485             if(Ap->topath != NULL){
01486               for(k=0;k<Nnodes;k++)if(Ap->topath == NNp[k])goto EALI;
01487               k=Minus1;
01488               EALI:
01489               fwrite(&k,sizeof(long),1,fo);
01490             }
01491             else fwrite(&Minus1,sizeof(long),1,fo);
01492             fwrite(zeroname,1,16,fo);
01493             fwrite(Ap->anodename,1,128,fo);
01494             Ap=Ap->next;
01495           }
01496         }
01497         else fwrite(&Nali,sizeof(short),1,fo);
01498         Nsiz=0;
01499         if((Xp=Np->fsiz) != NULL){
01500           while(Xp != NULL){Nsiz++; Xp=Xp->next;}
01501           fwrite(&Nsiz,sizeof(short),1,fo);
01502           for(j=0,Xp=Np->fsiz;j<Nsiz;j++){
01503             fwrite(&(Xp->firstframe),sizeof(short),1,fo);
01504             fwrite(&(Xp->lastframe),sizeof(short),1,fo);
01505             fwrite(&(Xp->Sx),sizeof(double),1,fo);
01506             fwrite(&(Xp->Sy),sizeof(double),1,fo);
01507             fwrite(&(Xp->Sz),sizeof(double),1,fo);
01508             fwrite(&(Xp->camera_params),20*sizeof(double),1,fo);  // only 3 used 17 left for expansion  // VERSION 5
01509             Xp=Xp->next;
01510           }
01511         }
01512         else fwrite(&Nsiz,sizeof(short),1,fo);
01513         Nobj=0;
01514         if((Op=Np->fobj) != NULL){ 
01515           while(Op != NULL){Nobj++; Op=Op->next;}
01516           fwrite(&Nobj,sizeof(short),1,fo);
01517           for(j=0,Op=Np->fobj;j<Nobj;j++){
01518             fwrite(&(Op->firstframe),sizeof(short),1,fo);
01519             fwrite(&(Op->lastframe),sizeof(short),1,fo);
01520             fwrite(Op->name,1,128,fo);  // need to make longer 
01521             fwrite(&(Op->type),sizeof(short),1,fo);
01522             if(Op->type == IMAGEP){
01523               if(Op->xip == NULL)tt=0;
01524               else               tt=1;
01525               fwrite(&tt,sizeof(short),1,fo);
01526               if(Op->xip != NULL){
01527                 tt = strlen(Op->xip);
01528                 fwrite(&tt,sizeof(short),1,fo);
01529                 fwrite(Op->xip,1,tt,fo);
01530               }
01531             }
01532             if(Op->effect != NULL){
01533               tt = Op->morph | (127 << 4); /* combine morphing */
01534               fwrite(&tt,sizeof(short),1,fo);      /* with effect      */
01535               tt = strlen(Op->effect);
01536               fwrite(&tt,sizeof(short),1,fo);      /* size of effect   */
01537               fwrite(Op->effect,1,tt,fo);          /* effect           */
01538             }
01539             else{
01540               tt = Op->morph;
01541               fwrite(&tt,sizeof(short),1,fo);      /* no effect        */
01542             }
01543             fwrite(&(Op->morphNo),sizeof(short),1,fo);
01544             fwrite(&(Op->fileID),sizeof(short),1,fo);
01545             fwrite(Op->origin,sizeof(point),1,fo);
01546             fwrite(Op->outline,sizeof(point),8,fo);
01547             if(Op->type == PARTICLE){
01548               kk=sizeof(ParticleSystem);
01549               fwrite(&kk,sizeof(long),1,fo); 
01550               fwrite(&(Op->particles),kk,1,fo);
01551             } 
01552             if(Op->type == ROBOT){/* skeleton structure if robot */
01553               fwrite(&(Op->nskeleton),sizeof(long),1,fo);
01554               if(Op->nskeleton > 0)for(k=0;k<Op->nskeleton;k++){
01555                 fwrite(Op->skeleton[k].R,sizeof(double),16,fo);
01556               }
01557             }
01558             tg=Op->groundtype+256;
01559             fwrite(&tg,sizeof(short),1,fo);
01560             fwrite(&(Op->lighttype),sizeof(short),1,fo);
01561             fwrite(Op->colour,1,3,fo);
01562             fwrite(&(Op->gspec),sizeof(double),1,fo);
01563             fwrite(&(Op->gtran),sizeof(double),1,fo);
01564             fwrite(&(Op->grefl),sizeof(double),1,fo);
01565             fwrite(&(Op->gbump),sizeof(double),1,fo);
01566             if(Op->groundtype > 127){
01567               fwrite(Op->acolour,1,3,fo);
01568             }
01569             fwrite(&(Op->pathtype),sizeof(short),1,fo);
01570             fwrite(&(Op->npathpoints),sizeof(short),1,fo);
01571             fwrite(&(Op->pathlength),sizeof(double),1,fo);
01572             if(Op->npathpoints > 0)
01573             for(k=0,Ppp=Op->firstpathpoint;k<Op->npathpoints;k++){
01574               fwrite(&(Ppp->status),sizeof(short),1,fo);
01575               fwrite(Ppp->p,sizeof(point),1,fo);
01576               fwrite(&(Ppp->distance),sizeof(double),1,fo);
01577               fwrite(&(Ppp->ptheta),sizeof(double),1,fo);
01578               fwrite(&(Ppp->pfi),sizeof(double),1,fo);
01579               Ppp=Ppp->next;
01580             }
01581             if(Op->type == PATH){/*out path velocities if path */
01582               PATHEDITCONTROL *pe1;
01583               if(Op->v == NULL){
01584                 SendPrgmQuery(IDQ_MANGLEDPATH,0);
01585               }
01586               else for(k=0;k<(Op->lastframe - Op->firstframe + 1);k++)
01587                 fwrite(&(Op->v[k]),sizeof(double),1,fo);
01588               if(Op->npathpoints > 0){
01589                 for(k=0,Ppp=Op->firstpathpoint;k<Op->npathpoints;k++){
01590                   fwrite(&(Ppp->tension_p),sizeof(double),1,fo);
01591                   fwrite(&(Ppp->tension_n),sizeof(double),1,fo);
01592                   Ppp=Ppp->next;
01593                 }
01594               }
01595               kk=Op->npec;
01596               fwrite(&kk,sizeof(long),1,fo);  /* PathEdit Controls */
01597               if(Op->npec > 0)for(k=0,pe1=Op->pec;k<Op->npec;k++){
01598                 kk=pe1->frame; fwrite(&kk,sizeof(long),1,fo);
01599                 fwrite(&(pe1->distance),sizeof(double),1,fo);
01600                 pe1=pe1->next;
01601               }
01602             }
01603             if(version > 1){ // put additions here
01604               kk=(long)Op->bWireframe; fwrite(&kk,sizeof(long),1,fo);
01605               if(version > 2){
01606                 kk=(long)Op->self_shadow; fwrite(&kk,sizeof(long),1,fo);
01607                 kk=(long)Op->cast_shadow; fwrite(&kk,sizeof(long),1,fo);
01608                 kk=(long)Op->show_shadow; fwrite(&kk,sizeof(long),1,fo);
01609                 kk=(long)Op->depth_cue; fwrite(&kk,sizeof(long),1,fo);
01610                 fwrite(&(Op->depth_cue_c),sizeof(double),1,fo);
01611                 fwrite(&(Op->depth_cue_l),sizeof(double),1,fo);
01612                 fwrite(&(Op->depth_cue_q),sizeof(double),1,fo);
01613                 if(version > 5){  // version 6   
01614                   fwrite(&(Op->groundTemperature),sizeof(double),1,fo);
01615                   fwrite(&(Op->other_params),sizeof(double),8,fo);
01616                 } 
01617               }
01618             }
01619             Op=Op->next;
01620           }
01621         }
01622         else fwrite(&Nobj,sizeof(short),1,fo);
01623         Np=Np->next;
01624       }
01625       X__Free(NNp);
01626     }
01627     else{
01628       endcode = FAIL;
01629       SendPrgmQuery(IDQ_NOMEM1,0);
01630     }
01631     if(endcode != FAIL){
01632       long posIs = -1, posIe = -1;
01633       fprintf(fo,"EMAP"); posIs=ftell(fo); outlng_s(0,fo);
01634       WriteEmbeddedImageMaps(fo);
01635       posIe=ftell(fo);
01636       fprintf(fo,"EOFF"); outlng_s(0,fo);  // zero length chunk to end 
01637       if(posIs > 0){fseek(fo,posIs,0); outlng_s(posIe-posIs-4,fo);} // enbedded images
01638     }
01639     fclose(fo);
01640     if(Error != 0){
01641       endcode = FAIL;
01642       SendPrgmQuery(IDQ_SAVINGERROR,0);
01643     }
01644   }
01645   else{
01646    endcode = FAIL;
01647    SendPrgmQuery(IDQ_FILEOPENFAIL,0);
01648   }
01649  }
01650  else endcode = FAIL;
01651 #endif
01652  return endcode;
01653 }
01654 
01655 static void LoadEmbeddedImageMaps(long chunk_size, FILE *fr){
01656  node    *Np;
01657  object  *Op;
01658  sky     *Sp;
01659  long    i,st; 
01660  for(i=0,Np=FirstNp;i<Nnodes;i++){
01661    if((Sp=Np->fsky) != NULL){
01662      while(Sp != NULL){
01663        st=Sp->type;
01664        if(st == SKYMAPPED   ||
01665           st == SKYANIMATED ||
01666           st == SKYCUBE     ||
01667           st == BACKDROP){
01668           //MessageBox(NULL,Sp->name,"Reading Sky for",MB_OK);
01669           ReadRamImage(&(Sp->image),fr);
01670         }
01671         Sp=Sp->next;
01672      }
01673    }
01674    if((Op=Np->fobj) != NULL){
01675      while(Op != NULL){
01676        if(Op->type == GROUND){
01677          if(Op->groundtype == BRUM || Op->groundtype == TBRUM ||
01678             Op->groundtype == MBRUM){
01679            //MessageBox(NULL,Op->name,"Reading Ground for",MB_OK);
01680            ReadRamImage(&(Op->image),fr);
01681          }
01682        }
01683        Op=Op->next;
01684      }
01685    }
01686    Np=Np->next;
01687  }
01688 }
01689 
01690 static void WriteEmbeddedImageMaps(FILE *fr){
01691  node    *Np;
01692  object  *Op;
01693  sky     *Sp;
01694  long    i,st; 
01695  for(i=0,Np=FirstNp;i<Nnodes;i++){
01696    if((Sp=Np->fsky) != NULL){
01697      while(Sp != NULL){
01698        st=Sp->type;
01699        if(st == SKYMAPPED   ||
01700           st == SKYANIMATED ||
01701           st == SKYCUBE     ||
01702           st == BACKDROP){
01703           WriteRamImage(&(Sp->image),fr);
01704         }
01705         Sp=Sp->next;
01706      }
01707    }
01708    if((Op=Np->fobj) != NULL){
01709      while(Op != NULL){
01710        if(Op->type == GROUND){
01711          if(Op->groundtype == BRUM || Op->groundtype == TBRUM ||
01712             Op->groundtype == MBRUM){
01713            WriteRamImage(&(Op->image),fr);
01714          }
01715        }
01716        Op=Op->next;
01717      }
01718    }
01719    Np=Np->next;
01720  }
01721 }
01722 
01723 // end save/load OFX file  //////////////////////////////
01724 
01725 
01726 pathpoint *LoadPath(short *pathtype, short *npathpoints, HWND parent){
01727  FILE *fpp;
01728  pathpoint *Ppp=NULL,*Fpp=NULL,*Lpp=NULL;
01729  short  fail,points,x,y,z,i;
01730  long xx,yy,zz;
01731  unsigned char closed,magic;
01732  long   packer;
01733  EnableToolPannels(ALL_PANNELS,FALSE);
01734  if(SelectSfxFileName(0,gszPTHfile,gszPTHdir,IDX_MISC_OPENPATH,
01735    "(*.PTH)|*.pth|",parent) == TRUE){
01736    EnableToolPannels(ALL_PANNELS,TRUE);
01737    if((fpp=fopen(gszPTHfile,"rb")) == NULL){
01738      SendPrgmQuery(IDQ_FILEOPENFAIL,0);
01739      return NULL;
01740    }
01741    if(fread(&points,2,1,fpp) != 1)goto NOREAD;
01742    if(fread(&packer,4,1,fpp) != 1)goto NOREAD;
01743    if(fread(&closed,1,1,fpp) != 1)goto NOREAD;
01744    if(fread(&magic,1,1 ,fpp)  != 1 || magic != 0x88)goto NOREAD;
01745    if(points == 0)goto NOREAD;
01746    for(i=0; i< points; i++){
01747      if(fread(&xx,4,1,fpp) != 1)goto NOREAD;
01748      if(fread(&yy,4,1,fpp) != 1)goto NOREAD;
01749      if(fread(&zz,4,1,fpp) != 1)goto NOREAD;
01750      if((Ppp=AppendPathPoint(Ppp)) == NULL)goto NOREAD;
01751      Ppp->p[0]=xx; Ppp->p[1]=yy; Ppp->p[2]=zz;
01752      Ppp->ptheta=0;Ppp->pfi=0;
01753      Ppp->tension_p=Ppp->tension_n=0.5;
01754      Ppp->distance=0.0; /* set by path length calculation */
01755      Lpp=Ppp;
01756      if(i == 0)Fpp=Ppp;
01757    }
01758    *npathpoints = points;
01759    if(closed == 1) *pathtype = CLOSED;
01760    else            *pathtype = OPEN;
01761    goto READOK;
01762    NOREAD:
01763    SendPrgmQuery(IDQ_MANGLEDPATH,0);
01764    fclose(fpp);
01765    if(Lpp != NULL)while(Lpp!=NULL){Ppp=Lpp->last; X__Free(Lpp); Lpp=Ppp;}
01766    return NULL;
01767    READOK:
01768    fclose(fpp);
01769    return Fpp;   /* return pointer to first point on path */
01770  }
01771  EnableToolPannels(ALL_PANNELS,TRUE);
01772  return NULL;
01773 }
01774 
01775 void SaveAnimFile(node *Np){
01776   FILE *fani;
01777   object *Op;
01778   char objectname[256];
01779   short count,tf;
01780  if(Np->type != NORMAL && Np->type != ANIMOBJ){
01781    SendPrgmQuery(IDQ_OLD2,0);
01782    return;
01783  }
01784  if(SelectSfxFileName(1,gszANIfile,gszANIdir,IDX_MISC_WRITEMODELSET,
01785    "(*.ANI)|*.ani|",ghwndTimeline) == TRUE){
01786     AppendFileExtension(gszANIfile,".ani");
01787     if( (fani=fopen(gszANIfile,"w")) == NULL){
01788       SendPrgmQuery(IDQ_FILEOPENFAIL,0);
01789       return;
01790     }
01791     count=0; tf=0;
01792     if((Op=Np->fobj) != NULL)while(Op!=NULL){
01793       count++; tf=Op->lastframe; Op=Op->next;
01794     }
01795     fprintf(fani,"%d %d\n",count,tf);
01796     if((Op=Np->fobj) != NULL)while(Op!=NULL){
01797       strcpy(objectname,Op->name);
01798       HideWhiteSpaces(objectname);
01799       fprintf(fani,"%s %d %d\n",objectname,Op->firstframe,Op->lastframe);
01800       Op=Op->next;
01801     }
01802     fclose(fani);
01803   }
01804   return;
01805 }
01806 
01807 void LoadAnimObject(node *Np, short firstframe, short lastframe, HWND parent){
01808  FILE *fani;
01809  long count,cyclelength,Ncycles,dt,elementstart,elementend,elementlength;
01810  short ff,lf,llf,failed_to_load;
01811  char  string[16],objectfile[128];
01812  long  fpos,i,j;
01813  double scale;
01814  object *tempobj,*firstobj;
01815  if(lastframe < firstframe)return;
01816  EDIT_ACTION=YES;
01817  failed_to_load=NO;
01818  dt=lastframe-firstframe+1;
01819  if(SelectSfxFileName(0,gszANIfile,gszANIdir,IDX_MISC_OPENMODELSET,
01820    "(*.ANI)|*.ani|",parent) == TRUE){
01821    if( (fani=fopen(gszANIfile,"r")) == NULL){
01822      SendPrgmQuery(IDQ_FILEOPENFAIL,0);
01823      return;
01824    }
01825    Ncycles=RequestNumEntry(1,1,99,"No. Cycles"," Cycles");
01826    if(Ncycles < 0){
01827     fclose(fani);
01828     return;
01829    }
01830    if(fscanf(fani,"%ld %ld\n",&count,&cyclelength) != 2){
01831      SendPrgmQuery(IDQ_READERROR,0);
01832      fclose(fani);
01833      return;
01834    }
01835    if((count-1)*Ncycles + 1 > dt){ /* at least one frame for each element */
01836      SendPrgmQuery(IDQ_ANIOBJ1,0);
01837      fclose(fani);
01838      return;
01839    }
01840    if(fscanf(fani,"%s %ld %ld\n",objectfile
01841                  ,&elementstart,&elementend) != 3){
01842      SendPrgmQuery(IDQ_READERROR,0);
01843      fclose(fani);
01844      return;
01845    }
01846    RestoreWhiteSpaces(objectfile);
01847    elementlength = elementend-elementstart+1;
01848    if(elementlength != 1){
01849      SendPrgmQuery(IDQ_ANIOBJ2,0);
01850      fclose(fani);
01851      return;
01852    }
01853    ff=firstframe; lf=ff;  /* the first element is always 1 frame no morph */
01854    firstobj=NULL;
01855    tempobj=CreateCostume(Np,ff,lf);
01856    if(tempobj == NULL || fail_op == YES){
01857      if(tempobj != NULL)DeleteCostume(Np,ff);
01858      SendPrgmQuery(IDQ_ANIOBJ3,0);
01859      fclose(fani);
01860      return;
01861    }
01862    tempobj->type=Np->type;
01863    strcpy(tempobj->name,objectfile);
01864    tempobj->morph=NO;
01865    if(LoadMeshObject(objectfile,tempobj,NO,YES,NO) == FAIL){
01866      DeleteCostume(Np,ff);
01867      failed_to_load=YES;
01868    }
01869    else firstobj=tempobj;
01870    fpos=ftell(fani);
01871    cyclelength -= 1; /* excluding the first frame which is 1 frame */
01872    scale = (double)(dt-1)/(double)(Ncycles*cyclelength);
01873    llf=lf+1;
01874    for(j=0;j<Ncycles;j++){
01875      for(i=0;i<count-1;i++){
01876        if(fscanf(fani,"%s %ld %ld\n",objectfile
01877                      ,&elementstart,&elementend) != 3){
01878          SendPrgmQuery(IDQ_READERROR,0);
01879          fclose(fani);
01880          return;
01881        }
01882        RestoreWhiteSpaces(objectfile);
01883        ff=firstframe + (short)(( cyclelength*j + elementstart - 1 )*scale);
01884        if(ff < llf)ff=llf;
01885        lf=firstframe + (short)(( cyclelength*j + elementend   - 1 )*scale);
01886        if(lf < llf)lf =llf;
01887        llf=lf+1;  /* insist on at least one frame for each element */
01888        tempobj=CreateCostume(Np,ff,lf);
01889        if(tempobj == NULL || fail_op == YES){
01890          if(tempobj != NULL)DeleteCostume(Np,ff);
01891          SendPrgmQuery(IDQ_ANIOBJ3,0);
01892          fclose(fani);
01893          return;
01894        }
01895        tempobj->type=Np->type;
01896        strcpy(tempobj->name,objectfile);
01897        tempobj->morph = YES; /* possible new data */
01898        if(LoadMeshObject(objectfile,tempobj,NO,YES,NO) == FAIL){
01899          failed_to_load=YES;
01900          DeleteCostume(Np,ff);
01901          tempobj=NULL;
01902        }
01903      }
01904      fseek(fani,fpos,SEEK_SET);
01905    }
01906    if(lf < lastframe && tempobj != NULL)tempobj->lastframe = lastframe;
01907    fclose(fani);
01908    if(firstobj != NULL)if((firstobj=firstobj->next) != NULL)
01909    while(firstobj != NULL){ /* fix up object end points */
01910      firstobj->firstframe = firstobj->last->lastframe+1;
01911      firstobj=firstobj->next;
01912    }
01913  }
01914  if(failed_to_load){
01915    SendPrgmQuery(IDQ_ANIOBJ4,0);
01916  }
01917 }
01918 
01920 
01921 struct done_list {char fn[256],fm[256];};
01922 
01923 static struct done_list *pdone;
01924 static int ndone;
01925 
01926 static BOOL in_done_list(char *name){
01927  int i;
01928  if(ndone > 0){
01929    for(i=0;i<ndone;i++){
01930      if(strcmp(pdone[i].fn,name) == 0)return TRUE;
01931    } 
01932  }
01933  if(ndone == 0)pdone=(struct done_line *)X__Malloc(sizeof(struct done_list));
01934  else          pdone=(struct done_line *)X__Realloc(pdone,sizeof(struct done_list)*(ndone+1));
01935  if(pdone != NULL){
01936    //fprintf(debug,"Adding [%s] to done list item %ld\n",name,ndone);
01937    strcpy(pdone[ndone].fn,name);
01938    ndone++;
01939  }
01940  return FALSE;
01941 }
01942 
01943 static BOOL in_comp_list(char *name, char *newname){
01944  if(ndone == 0)pdone=(struct done_line *)X__Malloc(sizeof(struct done_list));
01945  else          pdone=(struct done_line *)X__Realloc(pdone,sizeof(struct done_list)*(ndone+1));
01946  if(pdone != NULL){
01947    strcpy(pdone[ndone].fn,name);
01948    strcpy(pdone[ndone].fm,newname);
01949    ndone++;
01950  }
01951  return FALSE;
01952 }
01953 
01954 
01955 static void copy_file_to_pack(FILE *pk, char *f){
01956  FILE *fi;
01957  char c;
01958  int bc=0,cc;
01959  if((fi=fopen(f,"rb")) != NULL){
01960    while(!feof(fi)){
01961      cc=fread(&c,1,1,fi); 
01962      if(ferror(fi)){MessageBox(NULL," ",NULL,MB_OK); break;}
01963      if(cc > 0)fwrite(&c,1,1,pk); bc += cc;
01964    } 
01965    fclose(fi);
01966  }  
01967  //if(debug != NULL)fprintf(debug,"%ld bytes copied from file [%s]\n",bc,f);
01968 }
01969 
01970 static void copy_file_from_pack(FILE *pk, char *f, int l){
01971  FILE *fo;
01972  char c;
01973  int bc=0,cc;
01974  if((fo=fopen(f,"wb")) != NULL){
01975    for(bc=0;bc<l;bc++){
01976      cc=fread(&c,1,1,pk); 
01977      if(ferror(pk)){MessageBox(NULL," ",NULL,MB_OK); break;}
01978      if(cc > 0)fwrite(&c,1,1,fo);
01979    } 
01980    fclose(fo);
01981  }  
01982  //if(debug != NULL)fprintf(debug,"%ld bytes written to file [%s]\n",l,f);
01983 }
01984 
01985 
01986 void PackAnimationFile(void){
01987  struct done_list *pdone=NULL;
01988  FILE *foo;
01989  char tempstor[512];
01990  node *Np;
01991  object *Op;
01992  int i,j,Nobj;
01993  long pos1,pos1e,pos2,pos2e,pos3,pos3e;
01994  if(SelectSfxFileName(1,gszPAKfile,gszPAKdir,  // 1=>Save
01995     IDX_MISC_PACK,"(*.OFXP)|*.ofxp|",ghwnd_main) == TRUE){
01996    AppendFileExtension(gszPAKfile,".ofxp");
01997    ghcurSave=SetCursor(ghcurWait);
01998    strcpy(tempstor,TempPath);
01999    strcat(tempstor,"build_$.ofx");
02000    SaveAnimationFile(tempstor,TRUE);
02001    if((foo=fopen(gszPAKfile,"wb")) != NULL){
02002      fprintf(foo,"FORM");
02003      pos1=ftell(foo); outlng_s(0,foo);
02004      fprintf(foo,"OFXP");
02005      fprintf(foo,"ANIM"); pos2=ftell(foo);  outlng_s(0,foo); 
02006      copy_file_to_pack(foo,tempstor);
02007      pos2e=ftell(foo);
02008      ndone=0; pdone=NULL;
02009      //if(debug != NULL)fprintf(debug,"Pak [%s] Anim [%s]\n",gszPAKfile,tempstor);
02010      for(i=0,Np=FirstNp;i<Nnodes;i++){
02011        if((Op=Np->fobj) != NULL){ 
02012          Nobj=0; while(Op != NULL){Nobj++; Op=Op->next;}
02013          for(j=0,Op=Np->fobj;j<Nobj;j++){
02014            if(Op->fileID >= 0){
02015 //           if(Op->type == NORMAL || Op->type == ANIMOBJ || Op->type == ROBOT){ // This should be same as ...
02016              if(!in_done_list(Op->name)){
02017                fprintf(foo,"MODL"); pos3=ftell(foo);  outlng_s(0,foo); 
02018                //if(debug != NULL)fprintf(debug,"Copying File [%s], type %ld\n",Op->name,Op->type);
02019                outlng_s(255,foo); fwrite(Op->name,1,255,foo);
02020                copy_file_to_pack(foo,Op->name);
02021                pos3e=ftell(foo);
02022                fseek(foo,pos3,0);  outlng_s(pos3e-pos3-4,foo);
02023                //if(debug != NULL)fprintf(debug,"Model file %ld bytes\n",pos3e-pos3-4);
02024                fseek(foo,pos3e,0); 
02025              }
02026            }
02027            Op=Op->next;
02028          }
02029        }
02030        Np=Np->next;
02031      }
02032      fprintf(foo,"ENDP"); outlng_s(0,foo); 
02033      if(pdone != NULL)X__Free(pdone);
02034      pos1e=ftell(foo);
02035      fseek(foo,pos1,0);  outlng_s(pos1e-pos1-4,foo); // overall form   
02036      fseek(foo,pos2,0);  outlng_s(pos2e-pos2-4,foo); // animation file
02037      fclose(foo);
02038    }
02039    else  SendPrgmQuery(IDQ_FILEOPENFAIL,0);
02040    remove(tempstor);
02041    SetCursor(ghcurSave);
02042  }
02043 }
02044 
02045 void UnpackAnimationFile(void){
02046  FILE *fii;
02047  char *pj,chunk[5],animation_file[256],model_file[256],new_name[256];
02048  long ns,chunksize;
02049  chunk[4]='\0';
02050  if(SelectSfxFileName(0,gszPAKfile,gszPAKdir,IDX_MISC_UNPACK,
02051       "(*.OFXP)|*.ofxp|",ghwnd_main) == TRUE){
02052 
02053    strcpy(animation_file,gszPAKfile); 
02054    animation_file[strlen(gszPAKfile)-1] = '\0';
02055    ndone=0; pdone=NULL;
02056    if((fii=fopen(gszPAKfile,"rb")) != NULL){
02057      fread(chunk,1,4,fii);
02058      if(strncmp(chunk,"FORM",4) != 0)goto ERROR_READ;  // not a pack file  
02059      getlon_s(&chunksize,fii);
02060      fread(chunk,1,4,fii);
02061      if(strncmp(chunk,"OFXP",4) != 0)goto ERROR_READ;  // not a pack file  
02062      fread(chunk,1,4,fii);
02063      if(strncmp(chunk,"ANIM",4) != 0)goto ERROR_READ;  // not an animation file 
02064      getlon_s(&chunksize,fii);
02065      //if(debug != NULL)fprintf(debug,"Writing animation file [%s] length %ld\n",animation_file,chunksize);
02066      copy_file_from_pack(fii,animation_file,chunksize);
02067      while(1){  // process the models
02068        fread(chunk,1,4,fii);
02069        if(ferror(fii))goto ERROR_READ;
02070        getlon_s(&chunksize,fii);
02071        //if(debug != NULL)fprintf(debug,"Reading Chunk [%s] length %ld\n",chunk,chunksize);
02072        if(strncmp(chunk,"ENDP",4) == 0)break; // end of models
02073        else if(strncmp(chunk,"MODL",4) == 0){
02074          getlon_s(&ns,fii); fread(model_file,1,255,fii);
02075          // make up the new name
02076          strcpy(new_name,animation_file); pj=strrchr(new_name,'\\');
02077          if(pj != NULL){pj += 1; *pj=0;}
02078          strcat(new_name,short_form(model_file));
02079          in_comp_list(model_file,new_name);
02080          //if(debug != NULL)fprintf(debug,"model [%s] size %ld new_name [%s]\n",model_file,chunksize-259,new_name);
02081          //getchunk_F(chunksize-259,fii); // testing instead of next line
02082          copy_file_from_pack(fii,new_name,chunksize-259);
02083        }
02084        else getchunk_F(chunksize,fii);
02085        if(feof(fii))goto ERROR_READ;
02086      }
02087      fclose(fii);
02088      // Load the animation and re-vector all the names
02089      LoadAnimationFile(animation_file,TRUE);
02090      // now resave the animation
02091      SaveAnimationFile(animation_file,TRUE);
02092      ReDrawStageDisplay(TRUE);
02093      if(ghwndOpenGLview == NULL)PerspectiveView(0,1);
02094      else UpdateGLview(TRUE);
02095      if(coords_visible)UpdateRuler(0);
02096      UPDATETIMELINES(IDC_TIMEL_UPDATE)
02097      goto END_UNPACK;
02098      ERROR_READ:
02099      MessageBox(NULL," ",NULL,MB_OK);
02100      fclose(fii);
02101      END_UNPACK:   
02102      if(pdone != NULL)X__Free(pdone); pdone=NULL; ndone=0;
02103    }
02104  }
02105 }
02106 
02107 static void UnpackName(char *name){
02108  int i;
02109  if(ndone > 0){
02110    for(i=0;i<ndone;i++){
02111      if(strcmp(pdone[i].fn,name) == 0){ // found the name - substitute replacement
02112        strcpy(name,pdone[i].fm);
02113        return;
02114      }
02115    } 
02116  }
02117 }
02118 
02120 
02121 static long undo_frame;
02122 
02123 void Save_UndoA(void){
02124  if(UNDO_ACTIVE == NO)return;
02125 //MessageBeep(MB_OK);
02126  undo_frame=CurrentFrame;
02127  SaveAnimationFile(gszUndoFile,TRUE);
02128  EnableMenuItem(GetMenu(ghwnd_main),IDM_ACTOR_TOOL_UNDO,MF_ENABLED);
02129 }
02130 
02131 void Restore_UndoA(void){
02132  if(UNDO_ACTIVE == NO)return;
02133  SetCursor(ghcurSave);
02134  LoadAnimationFile(gszUndoFile,FALSE);
02135  CurrentFrame=undo_frame;
02136 // SetScrollRange(ghwnd_xscl,SB_CTL,1,(int)Nframes,FALSE);
02137 // SetScrollPos(ghwnd_xscl,SB_CTL,(int)CurrentFrame,TRUE);
02138  SendMessage(ghwnd_xscl,TBM_SETRANGE,(WPARAM)TRUE,(LPARAM)MAKELONG(1,Nframes));
02139  SendMessage(ghwnd_xscl,TBM_SETPOS,TRUE,(LPARAM)CurrentFrame);
02140  ReDrawStageDisplay(TRUE);
02141  if(ghwndOpenGLview == NULL)PerspectiveView(0,1);
02142  else UpdateGLview(TRUE);
02143  if(coords_visible)UpdateRuler(0);
02144  UPDATETIMELINES(IDC_TIMEL_UPDATE)
02145  SetCursor(ghcurSave);
02146 }
02147 
02148 
02149 
02150 
Generated on Tue Jan 28 06:18:26 2014 for OpenFX by  doxygen 1.6.3