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                 else {
01253                   int iic; 
01254                   Op->groundTemperature = 0.0;
01255                   for(iic=0; iic< 8;iic++)Op->other_params[iic]=0.0;
01256                 }  
01257               }
01258             }
01259             if(failed_to_load == YES)DeleteCostume(Np,lastframe);
01260           }
01261         }
01262         Np=Np->next;
01263       }
01264       goto SUCCESS;
01265       FAILED:
01266       SendPrgmQuery(IDQ_STAGELOADFAIL,0);
01267       SUCCESS:
01268       X__Free(NNp);
01269       if(!(GetAsyncKeyState(VK_CONTROL) & 0x8000)){ /* don't recentre */
01270         get_centre_stage(TVC,TVP,TVclipMax,TVclipMin);
01271         TVsizeX=2*(TVC[0]-TVP[0]);
01272         TVsizeY=2*(TVC[1]-TVP[1]);
01273         TVsizeZ=2*(TVC[2]-TVP[2]);
01274         TVpointX=TVP[0]-TVsizeX/10;
01275         TVpointY=TVP[1]-TVsizeY/10;
01276         TVpointZ=TVP[2]-TVsizeZ/10;
01277         TVsizeX += TVsizeX/5; TVsizeY += TVsizeY/5; TVsizeZ += TVsizeZ/5;
01278         TVcentreX=NpointerX=TVC[0];
01279         TVcentreY=NpointerY=TVC[1];
01280         TVcentreZ=NpointerZ=TVC[2];
01281         GetTriview(FALSE);  /* this will adjust the TV size */
01282       }
01283       if(failed_to_find){
01284         SendPrgmQuery(IDQ_NOTALLLOADED,0);
01285       }
01286     }
01287     else{
01288       SendPrgmQuery(IDQ_NOTSTAGEFILE,0);
01289     }
01290     if(version > 3){ // Read any additional chunks
01291       loop:
01292       if(fread(str,1,4,fr) != 4)goto NOLOAD;
01293       //MessageBox(NULL,str,"Reading V4 chunk",MB_OK);
01294       if(!getlon_s(&chunk_size,fr))goto NOLOAD;
01295       if((strcmp(str,"EOFF")) == 0)goto NOLOAD;  // End of animation file
01296       else if((strcmp(str,"EMAP")) == 0 && bEmbedImageMaps)
01297         LoadEmbeddedImageMaps(chunk_size,fr);
01298       else getchunk_F(chunk_size,fr);
01299       goto loop;
01300     }
01301     NOLOAD:
01302     fclose(fr);
01303     if(Error != 0){
01304       SendPrgmQuery(IDQ_READERROR,0);
01305     }
01306   }
01307   else{
01308    SendPrgmQuery(IDQ_FILEOPENFAIL,0);
01309   }
01310  }
01311  EDIT_ACTION=NO;
01312  if(discarded_file_list != NULL && n_discarded > 0){
01313    for(i=0;i<n_discarded;i++){
01314      if(discarded_file_list[i].old != NULL)X__Free(discarded_file_list[i].old);
01315      if(discarded_file_list[i].new != NULL)X__Free(discarded_file_list[i].new);
01316    }
01317    X__Free(discarded_file_list);
01318    discarded_file_list=NULL;
01319    n_discarded=0;
01320  }
01321  return OK;
01322 }
01323 
01324 short SaveAnimationFile(char *filename, BOOL backup){
01325  unsigned char zeroname[16];
01326  node         *Np,**NNp;
01327  object       *Op;
01328  sky          *Sp;
01329  director     *Dp;
01330  position     *Pp;
01331  align        *Ap;
01332  size         *Xp;
01333  pathpoint    *Ppp;
01334  XIP          *Ip;
01335  short        One,Zero,Error,Nobj,Nsky,Ndirector,Npos,Nali,Nsiz,
01336               tt,tg,endcode = OK;
01337  long         i,j,k,kk,Minus1,head_chunks,version=6;  // latest 
01338  int id;
01339 #if __DEMO__
01340  // MessageBeep(MB_OK);
01341 #else
01342  memset(zeroname,0,16);
01343  zeroname[0] = zeroname[4] = 255;
01344  zeroname[1] = zeroname[5] = 254;
01345  zeroname[2] = zeroname[6] = 253;
01346  zeroname[3] = zeroname[7] = 252;
01347  Zero=0; One=1; Error=0; Minus1 = -1;
01348  if(filename != NULL){
01349   if(!backup && ((fo=fopen(filename,"r")) != NULL)){ /* check for old file */
01350    fclose(fo);
01351    id=SendPrgmQuery(IDQ_OVERWRITE,1);
01352    if(id != IDYES)return -1;
01353   }
01354   if((fo=fopen(filename,"wb")) != NULL){
01355     sprintf(str,"OFXA"); fwrite(str,1,4,fo);
01356     head_chunks=2;
01357     outlng_s(head_chunks,fo);
01358     outlng_s((long)ruler,fo);
01359     fwrite(ruler_name,1,8,fo);
01360     outlng_s(lrulerx,fo); outlng_s(lrulery,fo); outlng_s(lrulerz,fo);
01361     outlng_s(rulerx,fo);  outlng_s(rulery,fo);  outlng_s(rulerz,fo);
01362     outlng_s(grid_size,fo);
01363     outlng_s(version,fo);
01364     if(NimageProcesses > 0){
01365       sprintf(str,"XIMP"); fwrite(str,1,4,fo);
01366       outlng_s((long)NimageProcesses,fo);
01367       Ip=FirstIp;
01368       for(i=0,Ip=FirstIp;i<NimageProcesses;i++,Ip=Ip->next){
01369         k=strlen(Ip->p);
01370         outlng_s(k,fo);
01371         fwrite(Ip->p,1,k,fo);
01372       }
01373     }
01374 /* addition to pos rota and size structures */
01375 
01376     sprintf(str,"STAG"); fwrite(str,1,4,fo);
01377     fwrite(&Nframes,sizeof(long),1,fo);
01378     fwrite(&Nnodes,sizeof(short),1,fo);
01379     fwrite(&Nground,sizeof(short),1,fo);
01380     NNp=(node **)X__Malloc(Nnodes*sizeof(node *));
01381     if(NNp != NULL){
01382       for(i=0,Np=FirstNp;i<Nnodes;i++){
01383         fwrite(zeroname,1,16,fo);
01384         fwrite(Np->actorname,1,128,fo);
01385         fwrite(&(Np->type),sizeof(short),1,fo);
01386         fwrite(&(Np->ID),sizeof(short),1,fo);   // added
01387         if(i > 0 && Np->type == CAMERA){ /* first camera does not have flag */
01388           if(Np == SelectedCamera)fwrite(&One, 1,sizeof(short),fo);
01389           else                    fwrite(&Zero,1,sizeof(short),fo);
01390         }
01391         NNp[i]=Np;
01392         Np=Np->next;
01393       }
01394       for(i=0,Np=FirstNp;i<Nnodes;i++){
01395         fwrite(&(Np->type),sizeof(short),1,fo);
01396         fwrite(zeroname,1,16,fo);
01397         fwrite(Np->actorname,1,128,fo);
01398         Nsky=0;
01399         if((Sp=Np->fsky) != NULL){
01400           while(Sp != NULL){Nsky++; Sp=Sp->next;}
01401           fwrite(&Nsky,sizeof(short),1,fo);
01402           for(j=0,Sp=Np->fsky;j<Nsky;j++){
01403             fwrite(&(Sp->firstframe),sizeof(short),1,fo);
01404             fwrite(&(Sp->lastframe),sizeof(short),1,fo);
01405             fwrite(Sp->colour,1,3,fo);
01406             fwrite(Sp->zcolour,1,3,fo);
01407             id=Sp->type+8;   /* encode the type identifier */
01408             fwrite(&id,sizeof(short),1,fo);
01409             fwrite(&(Sp->gamb),sizeof(double),1,fo);
01410             fwrite(&(Sp->oamb),sizeof(double),1,fo);
01411             fwrite(Sp->gamb_colour,sizeof(double),3,fo);
01412             fwrite(Sp->oamb_colour,sizeof(double),3,fo);
01413             fwrite(Sp->name,1,128,fo);
01414             if(Sp->type == SKYANIMATED){
01415               fwrite(&(Sp->aff),sizeof(long),1,fo);
01416               fwrite(&(Sp->alf),sizeof(long),1,fo);
01417               fwrite(&(Sp->ast),sizeof(long),1,fo);
01418             }
01419             fwrite(&(Sp->sky_params),32*sizeof(double),1,fo); // version 5
01420             fwrite(&(Sp->sky_params_file),256,1,fo);          // version 5
01421             Sp=Sp->next;
01422           }
01423         }
01424         else fwrite(&Nsky,sizeof(short),1,fo);
01425 
01426         if(Np->type == DIRECTOR){
01427           Ndirector=0;
01428           Dp=Np->fdirector;
01429           while(Dp != NULL){Ndirector++; Dp=Dp->next;}
01430           fwrite(&Ndirector,sizeof(short),1,fo);
01431           if(Ndirector > 0)for(j=0,Dp=Np->fdirector;j<Ndirector;j++){
01432             fwrite(&(Dp->firstframe),sizeof(short),1,fo);
01433             fwrite(&(Dp->lastframe),sizeof(short),1,fo);
01434             kk=Dp->type;
01435             fwrite(&kk,sizeof(long),1,fo);
01436             if(Dp->ActiveCamera != NULL){
01437               for(k=0;k<Nnodes;k++)if(Dp->ActiveCamera == NNp[k])goto DPOS;
01438               k=Minus1;
01439               DPOS:
01440               fwrite(&k,sizeof(long),1,fo);
01441             }
01442             Dp=Dp->next;
01443           }
01444         }
01445         // else nothing to write
01446         Npos=0;
01447         if((Pp=Np->fpos) != NULL){
01448           while(Pp != NULL){Npos++; Pp=Pp->next;}
01449           fwrite(&Npos,sizeof(short),1,fo);
01450           for(j=0,Pp=Np->fpos;j<Npos;j++){
01451             fwrite(&(Pp->firstframe),sizeof(short),1,fo);
01452             fwrite(&(Pp->lastframe),sizeof(short),1,fo);
01453             fwrite(&(Pp->type),sizeof(short),1,fo);
01454             if(Pp->type == FOLLOWAT){
01455               fwrite(&(Pp->fx),sizeof(short),1,fo);
01456               fwrite(&(Pp->fy),sizeof(short),1,fo);
01457               fwrite(&(Pp->fz),sizeof(short),1,fo);
01458             }
01459             fwrite(Pp->finish,sizeof(point),1,fo);
01460             if(Pp->onpath != NULL){
01461               for(k=0;k<Nnodes;k++)if(Pp->onpath == NNp[k])goto EPOS;
01462               k=Minus1;
01463               EPOS:
01464               fwrite(&k,sizeof(long),1,fo);
01465             }
01466             else fwrite(&Minus1,sizeof(long),1,fo);
01467             fwrite(zeroname,1,16,fo);
01468             fwrite(Pp->pnodename,1,128,fo);
01469             Pp=Pp->next;
01470           }
01471         }
01472         else fwrite(&Npos,sizeof(short),1,fo);
01473         Nali=0;
01474         if((Ap=Np->fali) != NULL){
01475           while(Ap != NULL){Nali++; Ap=Ap->next;}
01476           fwrite(&Nali,sizeof(short),1,fo);
01477           for(j=0,Ap=Np->fali;j<Nali;j++){
01478             fwrite(&(Ap->firstframe),sizeof(short),1,fo);
01479             fwrite(&(Ap->lastframe),sizeof(short),1,fo);
01480             if(Ap->im > 0){     /* write out any internal motion */
01481               tt=Ap->type | 0x0008;
01482               fwrite(&tt,sizeof(short),1,fo);
01483               fwrite(&(Ap->im),sizeof(short),1,fo);
01484               fwrite(&(Ap->ima),sizeof(double),1,fo);
01485             }
01486             else fwrite(&(Ap->type),sizeof(short),1,fo);
01487             fwrite(&(Ap->theta),sizeof(double),1,fo);
01488             fwrite(&(Ap->phi),sizeof(double),1,fo);
01489             fwrite(&(Ap->alpha),sizeof(double),1,fo);
01490             if(Ap->topath != NULL){
01491               for(k=0;k<Nnodes;k++)if(Ap->topath == NNp[k])goto EALI;
01492               k=Minus1;
01493               EALI:
01494               fwrite(&k,sizeof(long),1,fo);
01495             }
01496             else fwrite(&Minus1,sizeof(long),1,fo);
01497             fwrite(zeroname,1,16,fo);
01498             fwrite(Ap->anodename,1,128,fo);
01499             Ap=Ap->next;
01500           }
01501         }
01502         else fwrite(&Nali,sizeof(short),1,fo);
01503         Nsiz=0;
01504         if((Xp=Np->fsiz) != NULL){
01505           while(Xp != NULL){Nsiz++; Xp=Xp->next;}
01506           fwrite(&Nsiz,sizeof(short),1,fo);
01507           for(j=0,Xp=Np->fsiz;j<Nsiz;j++){
01508             fwrite(&(Xp->firstframe),sizeof(short),1,fo);
01509             fwrite(&(Xp->lastframe),sizeof(short),1,fo);
01510             fwrite(&(Xp->Sx),sizeof(double),1,fo);
01511             fwrite(&(Xp->Sy),sizeof(double),1,fo);
01512             fwrite(&(Xp->Sz),sizeof(double),1,fo);
01513             fwrite(&(Xp->camera_params),20*sizeof(double),1,fo);  // only 3 used 17 left for expansion  // VERSION 5
01514             Xp=Xp->next;
01515           }
01516         }
01517         else fwrite(&Nsiz,sizeof(short),1,fo);
01518         Nobj=0;
01519         if((Op=Np->fobj) != NULL){ 
01520           while(Op != NULL){Nobj++; Op=Op->next;}
01521           fwrite(&Nobj,sizeof(short),1,fo);
01522           for(j=0,Op=Np->fobj;j<Nobj;j++){
01523             fwrite(&(Op->firstframe),sizeof(short),1,fo);
01524             fwrite(&(Op->lastframe),sizeof(short),1,fo);
01525             fwrite(Op->name,1,128,fo);  // need to make longer 
01526             fwrite(&(Op->type),sizeof(short),1,fo);
01527             if(Op->type == IMAGEP){
01528               if(Op->xip == NULL)tt=0;
01529               else               tt=1;
01530               fwrite(&tt,sizeof(short),1,fo);
01531               if(Op->xip != NULL){
01532                 tt = strlen(Op->xip);
01533                 fwrite(&tt,sizeof(short),1,fo);
01534                 fwrite(Op->xip,1,tt,fo);
01535               }
01536             }
01537             if(Op->effect != NULL){
01538               tt = Op->morph | (127 << 4); /* combine morphing */
01539               fwrite(&tt,sizeof(short),1,fo);      /* with effect      */
01540               tt = strlen(Op->effect);
01541               fwrite(&tt,sizeof(short),1,fo);      /* size of effect   */
01542               fwrite(Op->effect,1,tt,fo);          /* effect           */
01543             }
01544             else{
01545               tt = Op->morph;
01546               fwrite(&tt,sizeof(short),1,fo);      /* no effect        */
01547             }
01548             fwrite(&(Op->morphNo),sizeof(short),1,fo);
01549             fwrite(&(Op->fileID),sizeof(short),1,fo);
01550             fwrite(Op->origin,sizeof(point),1,fo);
01551             fwrite(Op->outline,sizeof(point),8,fo);
01552             if(Op->type == PARTICLE){
01553               kk=sizeof(ParticleSystem);
01554               fwrite(&kk,sizeof(long),1,fo); 
01555               fwrite(&(Op->particles),kk,1,fo);
01556             } 
01557             if(Op->type == ROBOT){/* skeleton structure if robot */
01558               fwrite(&(Op->nskeleton),sizeof(long),1,fo);
01559               if(Op->nskeleton > 0)for(k=0;k<Op->nskeleton;k++){
01560                 fwrite(Op->skeleton[k].R,sizeof(double),16,fo);
01561               }
01562             }
01563             tg=Op->groundtype+256;
01564             fwrite(&tg,sizeof(short),1,fo);
01565             fwrite(&(Op->lighttype),sizeof(short),1,fo);
01566             fwrite(Op->colour,1,3,fo);
01567             fwrite(&(Op->gspec),sizeof(double),1,fo);
01568             fwrite(&(Op->gtran),sizeof(double),1,fo);
01569             fwrite(&(Op->grefl),sizeof(double),1,fo);
01570             fwrite(&(Op->gbump),sizeof(double),1,fo);
01571             if(Op->groundtype > 127){
01572               fwrite(Op->acolour,1,3,fo);
01573             }
01574             fwrite(&(Op->pathtype),sizeof(short),1,fo);
01575             fwrite(&(Op->npathpoints),sizeof(short),1,fo);
01576             fwrite(&(Op->pathlength),sizeof(double),1,fo);
01577             if(Op->npathpoints > 0)
01578             for(k=0,Ppp=Op->firstpathpoint;k<Op->npathpoints;k++){
01579               fwrite(&(Ppp->status),sizeof(short),1,fo);
01580               fwrite(Ppp->p,sizeof(point),1,fo);
01581               fwrite(&(Ppp->distance),sizeof(double),1,fo);
01582               fwrite(&(Ppp->ptheta),sizeof(double),1,fo);
01583               fwrite(&(Ppp->pfi),sizeof(double),1,fo);
01584               Ppp=Ppp->next;
01585             }
01586             if(Op->type == PATH){/*out path velocities if path */
01587               PATHEDITCONTROL *pe1;
01588               if(Op->v == NULL){
01589                 SendPrgmQuery(IDQ_MANGLEDPATH,0);
01590               }
01591               else for(k=0;k<(Op->lastframe - Op->firstframe + 1);k++)
01592                 fwrite(&(Op->v[k]),sizeof(double),1,fo);
01593               if(Op->npathpoints > 0){
01594                 for(k=0,Ppp=Op->firstpathpoint;k<Op->npathpoints;k++){
01595                   fwrite(&(Ppp->tension_p),sizeof(double),1,fo);
01596                   fwrite(&(Ppp->tension_n),sizeof(double),1,fo);
01597                   Ppp=Ppp->next;
01598                 }
01599               }
01600               kk=Op->npec;
01601               fwrite(&kk,sizeof(long),1,fo);  /* PathEdit Controls */
01602               if(Op->npec > 0)for(k=0,pe1=Op->pec;k<Op->npec;k++){
01603                 kk=pe1->frame; fwrite(&kk,sizeof(long),1,fo);
01604                 fwrite(&(pe1->distance),sizeof(double),1,fo);
01605                 pe1=pe1->next;
01606               }
01607             }
01608             if(version > 1){ // put additions here
01609               kk=(long)Op->bWireframe; fwrite(&kk,sizeof(long),1,fo);
01610               if(version > 2){
01611                 kk=(long)Op->self_shadow; fwrite(&kk,sizeof(long),1,fo);
01612                 kk=(long)Op->cast_shadow; fwrite(&kk,sizeof(long),1,fo);
01613                 kk=(long)Op->show_shadow; fwrite(&kk,sizeof(long),1,fo);
01614                 kk=(long)Op->depth_cue; fwrite(&kk,sizeof(long),1,fo);
01615                 fwrite(&(Op->depth_cue_c),sizeof(double),1,fo);
01616                 fwrite(&(Op->depth_cue_l),sizeof(double),1,fo);
01617                 fwrite(&(Op->depth_cue_q),sizeof(double),1,fo);
01618                 if(version > 5){  // version 6   
01619                   fwrite(&(Op->groundTemperature),sizeof(double),1,fo);
01620                   fwrite(&(Op->other_params),sizeof(double),8,fo);
01621                 } 
01622               }
01623             }
01624             Op=Op->next;
01625           }
01626         }
01627         else fwrite(&Nobj,sizeof(short),1,fo);
01628         Np=Np->next;
01629       }
01630       X__Free(NNp);
01631     }
01632     else{
01633       endcode = FAIL;
01634       SendPrgmQuery(IDQ_NOMEM1,0);
01635     }
01636     if(endcode != FAIL){
01637       long posIs = -1, posIe = -1;
01638       fprintf(fo,"EMAP"); posIs=ftell(fo); outlng_s(0,fo);
01639       WriteEmbeddedImageMaps(fo);
01640       posIe=ftell(fo);
01641       fprintf(fo,"EOFF"); outlng_s(0,fo);  // zero length chunk to end 
01642       if(posIs > 0){fseek(fo,posIs,0); outlng_s(posIe-posIs-4,fo);} // enbedded images
01643     }
01644     fclose(fo);
01645     if(Error != 0){
01646       endcode = FAIL;
01647       SendPrgmQuery(IDQ_SAVINGERROR,0);
01648     }
01649   }
01650   else{
01651    endcode = FAIL;
01652    SendPrgmQuery(IDQ_FILEOPENFAIL,0);
01653   }
01654  }
01655  else endcode = FAIL;
01656 #endif
01657  return endcode;
01658 }
01659 
01660 static void LoadEmbeddedImageMaps(long chunk_size, FILE *fr){
01661  node    *Np;
01662  object  *Op;
01663  sky     *Sp;
01664  long    i,st; 
01665  for(i=0,Np=FirstNp;i<Nnodes;i++){
01666    if((Sp=Np->fsky) != NULL){
01667      while(Sp != NULL){
01668        st=Sp->type;
01669        if(st == SKYMAPPED   ||
01670           st == SKYANIMATED ||
01671           st == SKYCUBE     ||
01672           st == BACKDROP){
01673           //MessageBox(NULL,Sp->name,"Reading Sky for",MB_OK);
01674           ReadRamImage(&(Sp->image),fr);
01675         }
01676         Sp=Sp->next;
01677      }
01678    }
01679    if((Op=Np->fobj) != NULL){
01680      while(Op != NULL){
01681        if(Op->type == GROUND){
01682          if(Op->groundtype == BRUM || Op->groundtype == TBRUM ||
01683             Op->groundtype == MBRUM){
01684            //MessageBox(NULL,Op->name,"Reading Ground for",MB_OK);
01685            ReadRamImage(&(Op->image),fr);
01686          }
01687        }
01688        Op=Op->next;
01689      }
01690    }
01691    Np=Np->next;
01692  }
01693 }
01694 
01695 static void WriteEmbeddedImageMaps(FILE *fr){
01696  node    *Np;
01697  object  *Op;
01698  sky     *Sp;
01699  long    i,st; 
01700  for(i=0,Np=FirstNp;i<Nnodes;i++){
01701    if((Sp=Np->fsky) != NULL){
01702      while(Sp != NULL){
01703        st=Sp->type;
01704        if(st == SKYMAPPED   ||
01705           st == SKYANIMATED ||
01706           st == SKYCUBE     ||
01707           st == BACKDROP){
01708           WriteRamImage(&(Sp->image),fr);
01709         }
01710         Sp=Sp->next;
01711      }
01712    }
01713    if((Op=Np->fobj) != NULL){
01714      while(Op != NULL){
01715        if(Op->type == GROUND){
01716          if(Op->groundtype == BRUM || Op->groundtype == TBRUM ||
01717             Op->groundtype == MBRUM){
01718            WriteRamImage(&(Op->image),fr);
01719          }
01720        }
01721        Op=Op->next;
01722      }
01723    }
01724    Np=Np->next;
01725  }
01726 }
01727 
01728 // end save/load OFX file  //////////////////////////////
01729 
01730 
01731 pathpoint *LoadPath(short *pathtype, short *npathpoints, HWND parent){
01732  FILE *fpp;
01733  pathpoint *Ppp=NULL,*Fpp=NULL,*Lpp=NULL;
01734  short  fail,points,x,y,z,i;
01735  long xx,yy,zz;
01736  unsigned char closed,magic;
01737  long   packer;
01738  EnableToolPannels(ALL_PANNELS,FALSE);
01739  if(SelectSfxFileName(0,gszPTHfile,gszPTHdir,IDX_MISC_OPENPATH,
01740    "(*.PTH)|*.pth|",parent) == TRUE){
01741    EnableToolPannels(ALL_PANNELS,TRUE);
01742    if((fpp=fopen(gszPTHfile,"rb")) == NULL){
01743      SendPrgmQuery(IDQ_FILEOPENFAIL,0);
01744      return NULL;
01745    }
01746    if(fread(&points,2,1,fpp) != 1)goto NOREAD;
01747    if(fread(&packer,4,1,fpp) != 1)goto NOREAD;
01748    if(fread(&closed,1,1,fpp) != 1)goto NOREAD;
01749    if(fread(&magic,1,1 ,fpp)  != 1 || magic != 0x88)goto NOREAD;
01750    if(points == 0)goto NOREAD;
01751    for(i=0; i< points; i++){
01752      if(fread(&xx,4,1,fpp) != 1)goto NOREAD;
01753      if(fread(&yy,4,1,fpp) != 1)goto NOREAD;
01754      if(fread(&zz,4,1,fpp) != 1)goto NOREAD;
01755      if((Ppp=AppendPathPoint(Ppp)) == NULL)goto NOREAD;
01756      Ppp->p[0]=xx; Ppp->p[1]=yy; Ppp->p[2]=zz;
01757      Ppp->ptheta=0;Ppp->pfi=0;
01758      Ppp->tension_p=Ppp->tension_n=0.5;
01759      Ppp->distance=0.0; /* set by path length calculation */
01760      Lpp=Ppp;
01761      if(i == 0)Fpp=Ppp;
01762    }
01763    *npathpoints = points;
01764    if(closed == 1) *pathtype = CLOSED;
01765    else            *pathtype = OPEN;
01766    goto READOK;
01767    NOREAD:
01768    SendPrgmQuery(IDQ_MANGLEDPATH,0);
01769    fclose(fpp);
01770    if(Lpp != NULL)while(Lpp!=NULL){Ppp=Lpp->last; X__Free(Lpp); Lpp=Ppp;}
01771    return NULL;
01772    READOK:
01773    fclose(fpp);
01774    return Fpp;   /* return pointer to first point on path */
01775  }
01776  EnableToolPannels(ALL_PANNELS,TRUE);
01777  return NULL;
01778 }
01779 
01780 void SaveAnimFile(node *Np){
01781   FILE *fani;
01782   object *Op;
01783   char objectname[256];
01784   short count,tf;
01785  if(Np->type != NORMAL && Np->type != ANIMOBJ){
01786    SendPrgmQuery(IDQ_OLD2,0);
01787    return;
01788  }
01789  if(SelectSfxFileName(1,gszANIfile,gszANIdir,IDX_MISC_WRITEMODELSET,
01790    "(*.ANI)|*.ani|",ghwndTimeline) == TRUE){
01791     AppendFileExtension(gszANIfile,".ani");
01792     if( (fani=fopen(gszANIfile,"w")) == NULL){
01793       SendPrgmQuery(IDQ_FILEOPENFAIL,0);
01794       return;
01795     }
01796     count=0; tf=0;
01797     if((Op=Np->fobj) != NULL)while(Op!=NULL){
01798       count++; tf=Op->lastframe; Op=Op->next;
01799     }
01800     fprintf(fani,"%d %d\n",count,tf);
01801     if((Op=Np->fobj) != NULL)while(Op!=NULL){
01802       strcpy(objectname,Op->name);
01803       HideWhiteSpaces(objectname);
01804       fprintf(fani,"%s %d %d\n",objectname,Op->firstframe,Op->lastframe);
01805       Op=Op->next;
01806     }
01807     fclose(fani);
01808   }
01809   return;
01810 }
01811 
01812 void LoadAnimObject(node *Np, short firstframe, short lastframe, HWND parent){
01813  FILE *fani;
01814  long count,cyclelength,Ncycles,dt,elementstart,elementend,elementlength;
01815  short ff,lf,llf,failed_to_load;
01816  char  string[16],objectfile[128];
01817  long  fpos,i,j;
01818  double scale;
01819  object *tempobj,*firstobj;
01820  if(lastframe < firstframe)return;
01821  EDIT_ACTION=YES;
01822  failed_to_load=NO;
01823  dt=lastframe-firstframe+1;
01824  if(SelectSfxFileName(0,gszANIfile,gszANIdir,IDX_MISC_OPENMODELSET,
01825    "(*.ANI)|*.ani|",parent) == TRUE){
01826    if( (fani=fopen(gszANIfile,"r")) == NULL){
01827      SendPrgmQuery(IDQ_FILEOPENFAIL,0);
01828      return;
01829    }
01830    Ncycles=RequestNumEntry(1,1,99,"No. Cycles"," Cycles");
01831    if(Ncycles < 0){
01832     fclose(fani);
01833     return;
01834    }
01835    if(fscanf(fani,"%ld %ld\n",&count,&cyclelength) != 2){
01836      SendPrgmQuery(IDQ_READERROR,0);
01837      fclose(fani);
01838      return;
01839    }
01840    if((count-1)*Ncycles + 1 > dt){ /* at least one frame for each element */
01841      SendPrgmQuery(IDQ_ANIOBJ1,0);
01842      fclose(fani);
01843      return;
01844    }
01845    if(fscanf(fani,"%s %ld %ld\n",objectfile
01846                  ,&elementstart,&elementend) != 3){
01847      SendPrgmQuery(IDQ_READERROR,0);
01848      fclose(fani);
01849      return;
01850    }
01851    RestoreWhiteSpaces(objectfile);
01852    elementlength = elementend-elementstart+1;
01853    if(elementlength != 1){
01854      SendPrgmQuery(IDQ_ANIOBJ2,0);
01855      fclose(fani);
01856      return;
01857    }
01858    ff=firstframe; lf=ff;  /* the first element is always 1 frame no morph */
01859    firstobj=NULL;
01860    tempobj=CreateCostume(Np,ff,lf);
01861    if(tempobj == NULL || fail_op == YES){
01862      if(tempobj != NULL)DeleteCostume(Np,ff);
01863      SendPrgmQuery(IDQ_ANIOBJ3,0);
01864      fclose(fani);
01865      return;
01866    }
01867    tempobj->type=Np->type;
01868    strcpy(tempobj->name,objectfile);
01869    tempobj->morph=NO;
01870    if(LoadMeshObject(objectfile,tempobj,NO,YES,NO) == FAIL){
01871      DeleteCostume(Np,ff);
01872      failed_to_load=YES;
01873    }
01874    else firstobj=tempobj;
01875    fpos=ftell(fani);
01876    cyclelength -= 1; /* excluding the first frame which is 1 frame */
01877    scale = (double)(dt-1)/(double)(Ncycles*cyclelength);
01878    llf=lf+1;
01879    for(j=0;j<Ncycles;j++){
01880      for(i=0;i<count-1;i++){
01881        if(fscanf(fani,"%s %ld %ld\n",objectfile
01882                      ,&elementstart,&elementend) != 3){
01883          SendPrgmQuery(IDQ_READERROR,0);
01884          fclose(fani);
01885          return;
01886        }
01887        RestoreWhiteSpaces(objectfile);
01888        ff=firstframe + (short)(( cyclelength*j + elementstart - 1 )*scale);
01889        if(ff < llf)ff=llf;
01890        lf=firstframe + (short)(( cyclelength*j + elementend   - 1 )*scale);
01891        if(lf < llf)lf =llf;
01892        llf=lf+1;  /* insist on at least one frame for each element */
01893        tempobj=CreateCostume(Np,ff,lf);
01894        if(tempobj == NULL || fail_op == YES){
01895          if(tempobj != NULL)DeleteCostume(Np,ff);
01896          SendPrgmQuery(IDQ_ANIOBJ3,0);
01897          fclose(fani);
01898          return;
01899        }
01900        tempobj->type=Np->type;
01901        strcpy(tempobj->name,objectfile);
01902        tempobj->morph = YES; /* possible new data */
01903        if(LoadMeshObject(objectfile,tempobj,NO,YES,NO) == FAIL){
01904          failed_to_load=YES;
01905          DeleteCostume(Np,ff);
01906          tempobj=NULL;
01907        }
01908      }
01909      fseek(fani,fpos,SEEK_SET);
01910    }
01911    if(lf < lastframe && tempobj != NULL)tempobj->lastframe = lastframe;
01912    fclose(fani);
01913    if(firstobj != NULL)if((firstobj=firstobj->next) != NULL)
01914    while(firstobj != NULL){ /* fix up object end points */
01915      firstobj->firstframe = firstobj->last->lastframe+1;
01916      firstobj=firstobj->next;
01917    }
01918  }
01919  if(failed_to_load){
01920    SendPrgmQuery(IDQ_ANIOBJ4,0);
01921  }
01922 }
01923 
01925 
01926 struct done_list {char fn[256],fm[256];};
01927 
01928 static struct done_list *pdone;
01929 static int ndone;
01930 
01931 static BOOL in_done_list(char *name){
01932  int i;
01933  if(ndone > 0){
01934    for(i=0;i<ndone;i++){
01935      if(strcmp(pdone[i].fn,name) == 0)return TRUE;
01936    } 
01937  }
01938  if(ndone == 0)pdone=(struct done_line *)X__Malloc(sizeof(struct done_list));
01939  else          pdone=(struct done_line *)X__Realloc(pdone,sizeof(struct done_list)*(ndone+1));
01940  if(pdone != NULL){
01941    //fprintf(debug,"Adding [%s] to done list item %ld\n",name,ndone);
01942    strcpy(pdone[ndone].fn,name);
01943    ndone++;
01944  }
01945  return FALSE;
01946 }
01947 
01948 static BOOL in_comp_list(char *name, char *newname){
01949  if(ndone == 0)pdone=(struct done_line *)X__Malloc(sizeof(struct done_list));
01950  else          pdone=(struct done_line *)X__Realloc(pdone,sizeof(struct done_list)*(ndone+1));
01951  if(pdone != NULL){
01952    strcpy(pdone[ndone].fn,name);
01953    strcpy(pdone[ndone].fm,newname);
01954    ndone++;
01955  }
01956  return FALSE;
01957 }
01958 
01959 
01960 static void copy_file_to_pack(FILE *pk, char *f){
01961  FILE *fi;
01962  char c;
01963  int bc=0,cc;
01964  if((fi=fopen(f,"rb")) != NULL){
01965    while(!feof(fi)){
01966      cc=fread(&c,1,1,fi); 
01967      if(ferror(fi)){MessageBox(NULL," ",NULL,MB_OK); break;}
01968      if(cc > 0)fwrite(&c,1,1,pk); bc += cc;
01969    } 
01970    fclose(fi);
01971  }  
01972  //if(debug != NULL)fprintf(debug,"%ld bytes copied from file [%s]\n",bc,f);
01973 }
01974 
01975 static void copy_file_from_pack(FILE *pk, char *f, int l){
01976  FILE *fo;
01977  char c;
01978  int bc=0,cc;
01979  if((fo=fopen(f,"wb")) != NULL){
01980    for(bc=0;bc<l;bc++){
01981      cc=fread(&c,1,1,pk); 
01982      if(ferror(pk)){MessageBox(NULL," ",NULL,MB_OK); break;}
01983      if(cc > 0)fwrite(&c,1,1,fo);
01984    } 
01985    fclose(fo);
01986  }  
01987  //if(debug != NULL)fprintf(debug,"%ld bytes written to file [%s]\n",l,f);
01988 }
01989 
01990 
01991 void PackAnimationFile(void){
01992  struct done_list *pdone=NULL;
01993  FILE *foo;
01994  char tempstor[512];
01995  node *Np;
01996  object *Op;
01997  int i,j,Nobj;
01998  long pos1,pos1e,pos2,pos2e,pos3,pos3e;
01999  if(SelectSfxFileName(1,gszPAKfile,gszPAKdir,  // 1=>Save
02000     IDX_MISC_PACK,"(*.OFXP)|*.ofxp|",ghwnd_main) == TRUE){
02001    AppendFileExtension(gszPAKfile,".ofxp");
02002    ghcurSave=SetCursor(ghcurWait);
02003    strcpy(tempstor,TempPath);
02004    strcat(tempstor,"build_$.ofx");
02005    SaveAnimationFile(tempstor,TRUE);
02006    if((foo=fopen(gszPAKfile,"wb")) != NULL){
02007      fprintf(foo,"FORM");
02008      pos1=ftell(foo); outlng_s(0,foo);
02009      fprintf(foo,"OFXP");
02010      fprintf(foo,"ANIM"); pos2=ftell(foo);  outlng_s(0,foo); 
02011      copy_file_to_pack(foo,tempstor);
02012      pos2e=ftell(foo);
02013      ndone=0; pdone=NULL;
02014      //if(debug != NULL)fprintf(debug,"Pak [%s] Anim [%s]\n",gszPAKfile,tempstor);
02015      for(i=0,Np=FirstNp;i<Nnodes;i++){
02016        if((Op=Np->fobj) != NULL){ 
02017          Nobj=0; while(Op != NULL){Nobj++; Op=Op->next;}
02018          for(j=0,Op=Np->fobj;j<Nobj;j++){
02019            if(Op->fileID >= 0){
02020 //           if(Op->type == NORMAL || Op->type == ANIMOBJ || Op->type == ROBOT){ // This should be same as ...
02021              if(!in_done_list(Op->name)){
02022                fprintf(foo,"MODL"); pos3=ftell(foo);  outlng_s(0,foo); 
02023                //if(debug != NULL)fprintf(debug,"Copying File [%s], type %ld\n",Op->name,Op->type);
02024                outlng_s(255,foo); fwrite(Op->name,1,255,foo);
02025                copy_file_to_pack(foo,Op->name);
02026                pos3e=ftell(foo);
02027                fseek(foo,pos3,0);  outlng_s(pos3e-pos3-4,foo);
02028                //if(debug != NULL)fprintf(debug,"Model file %ld bytes\n",pos3e-pos3-4);
02029                fseek(foo,pos3e,0); 
02030              }
02031            }
02032            Op=Op->next;
02033          }
02034        }
02035        Np=Np->next;
02036      }
02037      fprintf(foo,"ENDP"); outlng_s(0,foo); 
02038      if(pdone != NULL)X__Free(pdone);
02039      pos1e=ftell(foo);
02040      fseek(foo,pos1,0);  outlng_s(pos1e-pos1-4,foo); // overall form   
02041      fseek(foo,pos2,0);  outlng_s(pos2e-pos2-4,foo); // animation file
02042      fclose(foo);
02043    }
02044    else  SendPrgmQuery(IDQ_FILEOPENFAIL,0);
02045    remove(tempstor);
02046    SetCursor(ghcurSave);
02047  }
02048 }
02049 
02050 void UnpackAnimationFile(void){
02051  FILE *fii;
02052  char *pj,chunk[5],animation_file[256],model_file[256],new_name[256];
02053  long ns,chunksize;
02054  chunk[4]='\0';
02055  if(SelectSfxFileName(0,gszPAKfile,gszPAKdir,IDX_MISC_UNPACK,
02056       "(*.OFXP)|*.ofxp|",ghwnd_main) == TRUE){
02057 
02058    strcpy(animation_file,gszPAKfile); 
02059    animation_file[strlen(gszPAKfile)-1] = '\0';
02060    ndone=0; pdone=NULL;
02061    if((fii=fopen(gszPAKfile,"rb")) != NULL){
02062      fread(chunk,1,4,fii);
02063      if(strncmp(chunk,"FORM",4) != 0)goto ERROR_READ;  // not a pack file  
02064      getlon_s(&chunksize,fii);
02065      fread(chunk,1,4,fii);
02066      if(strncmp(chunk,"OFXP",4) != 0)goto ERROR_READ;  // not a pack file  
02067      fread(chunk,1,4,fii);
02068      if(strncmp(chunk,"ANIM",4) != 0)goto ERROR_READ;  // not an animation file 
02069      getlon_s(&chunksize,fii);
02070      //if(debug != NULL)fprintf(debug,"Writing animation file [%s] length %ld\n",animation_file,chunksize);
02071      copy_file_from_pack(fii,animation_file,chunksize);
02072      while(1){  // process the models
02073        fread(chunk,1,4,fii);
02074        if(ferror(fii))goto ERROR_READ;
02075        getlon_s(&chunksize,fii);
02076        //if(debug != NULL)fprintf(debug,"Reading Chunk [%s] length %ld\n",chunk,chunksize);
02077        if(strncmp(chunk,"ENDP",4) == 0)break; // end of models
02078        else if(strncmp(chunk,"MODL",4) == 0){
02079          getlon_s(&ns,fii); fread(model_file,1,255,fii);
02080          // make up the new name
02081          strcpy(new_name,animation_file); pj=strrchr(new_name,'\\');
02082          if(pj != NULL){pj += 1; *pj=0;}
02083          strcat(new_name,short_form(model_file));
02084          in_comp_list(model_file,new_name);
02085          //if(debug != NULL)fprintf(debug,"model [%s] size %ld new_name [%s]\n",model_file,chunksize-259,new_name);
02086          //getchunk_F(chunksize-259,fii); // testing instead of next line
02087          copy_file_from_pack(fii,new_name,chunksize-259);
02088        }
02089        else getchunk_F(chunksize,fii);
02090        if(feof(fii))goto ERROR_READ;
02091      }
02092      fclose(fii);
02093      // Load the animation and re-vector all the names
02094      LoadAnimationFile(animation_file,TRUE);
02095      // now resave the animation
02096      SaveAnimationFile(animation_file,TRUE);
02097      ReDrawStageDisplay(TRUE);
02098      if(ghwndOpenGLview == NULL)PerspectiveView(0,1);
02099      else UpdateGLview(TRUE);
02100      if(coords_visible)UpdateRuler(0);
02101      UPDATETIMELINES(IDC_TIMEL_UPDATE)
02102      goto END_UNPACK;
02103      ERROR_READ:
02104      MessageBox(NULL," ",NULL,MB_OK);
02105      fclose(fii);
02106      END_UNPACK:   
02107      if(pdone != NULL)X__Free(pdone); pdone=NULL; ndone=0;
02108    }
02109  }
02110 }
02111 
02112 static void UnpackName(char *name){
02113  int i;
02114  if(ndone > 0){
02115    for(i=0;i<ndone;i++){
02116      if(strcmp(pdone[i].fn,name) == 0){ // found the name - substitute replacement
02117        strcpy(name,pdone[i].fm);
02118        return;
02119      }
02120    } 
02121  }
02122 }
02123 
02125 
02126 static long undo_frame;
02127 
02128 void Save_UndoA(void){
02129  if(UNDO_ACTIVE == NO)return;
02130 //MessageBeep(MB_OK);
02131  undo_frame=CurrentFrame;
02132  SaveAnimationFile(gszUndoFile,TRUE);
02133  EnableMenuItem(GetMenu(ghwnd_main),IDM_ACTOR_TOOL_UNDO,MF_ENABLED);
02134 }
02135 
02136 void Restore_UndoA(void){
02137  if(UNDO_ACTIVE == NO)return;
02138  SetCursor(ghcurSave);
02139  LoadAnimationFile(gszUndoFile,FALSE);
02140  CurrentFrame=undo_frame;
02141 // SetScrollRange(ghwnd_xscl,SB_CTL,1,(int)Nframes,FALSE);
02142 // SetScrollPos(ghwnd_xscl,SB_CTL,(int)CurrentFrame,TRUE);
02143  SendMessage(ghwnd_xscl,TBM_SETRANGE,(WPARAM)TRUE,(LPARAM)MAKELONG(1,Nframes));
02144  SendMessage(ghwnd_xscl,TBM_SETPOS,TRUE,(LPARAM)CurrentFrame);
02145  ReDrawStageDisplay(TRUE);
02146  if(ghwndOpenGLview == NULL)PerspectiveView(0,1);
02147  else UpdateGLview(TRUE);
02148  if(coords_visible)UpdateRuler(0);
02149  UPDATETIMELINES(IDC_TIMEL_UPDATE)
02150  SetCursor(ghcurSave);
02151 }
02152 
02153 
02154 
02155 

Generated on Sun Apr 27 14:20:09 2014 for OpenFX by  doxygen 1.5.6