UTILS.C

Go to the documentation of this file.
00001 /* file UTILS.C */
00002 
00003 #define MODULE_UTILS 1
00004 
00005 #include "animate.h"
00006 
00007 void Nudge(int command){
00008  int sx,sy,step=1,grabbed=0;
00009  if(tool == GRABBER || tool == NOTOOL){
00010    GetWindowCoords(ActiveView,NpointerX,NpointerY,NpointerZ,&sx,&sy);
00011    if(tool == GRABBER)grabbed=StageGrabIdentify();
00012    if(GetAsyncKeyState(VK_SHIFT  ) & 0x8000)step=5;
00013    if(command == IDM_PAN_LEFT) sx -= step; /* use PAN commands as ID's */
00014    if(command == IDM_PAN_RIGHT)sx += step;
00015    if(command == IDM_PAN_UP)   sy -= step;
00016    if(command == IDM_PAN_DOWN) sy += step;
00017    Draw3dCursor();
00018    GetWorldCoords(ActiveView,&NpointerX,&NpointerY,&NpointerZ,sx,sy);
00019    Draw3dCursor();
00020    if(coords_visible)UpdateRuler(0);
00021    if(tool == GRABBER && grabbed == 1)StageGrab(2,1); /* do it in the bitmap */
00022  }
00023  if(tool == ROTATOR){
00024    BOOL do_it=FALSE;
00025    if(command == IDM_PAN_LEFT){
00026      do_it=TRUE;
00027      if     (ActiveView == TRIRIGHT)command=IDM_PAN_UP;
00028      else if(ActiveView == TRIFRONT)command=IDM_ZOOM_OUT;
00029      else                           command=IDM_PAN_RIGHT;
00030    }
00031    else if(command == IDM_PAN_RIGHT){
00032      do_it=TRUE;
00033      if     (ActiveView == TRIRIGHT)command=IDM_PAN_DOWN;
00034      else if(ActiveView == TRIFRONT)command=IDM_ZOOM_IN;
00035      else                           command=IDM_PAN_LEFT;
00036    }
00037    if(do_it)StageStepRotate(command);
00038  }
00039 }
00040 
00041 void ReleaseNurbs(nurbs *n){
00042  long i;
00043  if(n->kvU != NULL)X__Free(n->kvU);
00044  n->kvU = NULL;
00045  if(n->kvV != NULL)X__Free(n->kvV);
00046  n->kvV = NULL;
00047  if(n->points == NULL)return;
00048  for(i=0;i < n->numV;i++)X__Free(n->points[i]);
00049  X__Free(n->points);
00050  n->points=NULL;
00051  return;
00052 }
00053 
00054 BOOL AllocNurbs(nurbs *n, double *ukv, double *vkv){
00055  long i;
00056  if(ukv == NULL){
00057  if((n->kvU = (double *)X__Malloc((n->numU + n->orderU) * sizeof(double)))
00058    == NULL)return FALSE;
00059  }
00060  else n->kvU = ukv;
00061  if(vkv == NULL){
00062  if((n->kvV = (double *)X__Malloc((n->numV + n->orderV) * sizeof(double)))
00063    == NULL)return FALSE;
00064  }
00065  else n->kvV = vkv;
00066  if((n->points = (vector4 **)X__Malloc((long)n->numV
00067        * (long)sizeof(vector4 *))) == NULL)return FALSE;
00068  for (i = 0; i < n->numV; i++){
00069    if((n->points[i] = (vector4 *)X__Malloc((long)n->numU
00070        * (long)sizeof(vector4))) == NULL)return FALSE;
00071  }
00072  return TRUE;
00073 }
00074 
00075 void FreeNurbs(long n, nurbs *Np){
00076  long i;
00077  if(n == 0 || Np == NULL)return;
00078  for(i=0;i<n;i++){
00079    ReleaseNurbs((Np+i));
00080  }
00081  X__Free(Np);
00082  return;
00083 }
00084 
00085 pathpoint *AppendPathPoint(pathpoint *Ppp){
00086 /* only used to load path from script or path file and during copy
00087    no need to ammend the number of pathpoints */
00088  pathpoint *tp;
00089  EDIT_ACTION=YES;
00090  if((tp = (pathpoint *)X__Malloc(sizeof(pathpoint))) == NULL){
00091    SendPrgmQuery(IDQ_NOMEM1,0);
00092    return NULL;
00093  }
00094  if(Ppp != NULL)Ppp->next=tp;
00095  tp->last=Ppp;
00096  tp->next=NULL;
00097  return tp;
00098 }
00099 
00100 PATHEDITCONTROL *CreatePathEditControlPoint(int *nPec,
00101                  PATHEDITCONTROL **Pec,
00102                  PATHEDITCONTROL *last,
00103                  PATHEDITCONTROL *next,
00104                  int frame, double distance){
00105  PATHEDITCONTROL *temp,*pe,*pe1;
00106  if((temp=(PATHEDITCONTROL *)X__Malloc(sizeof(PATHEDITCONTROL))) == NULL){
00107    if((*Pec) != NULL){ /* free up all path */
00108      if((pe = *Pec) != NULL)while(pe != NULL){
00109        pe1=pe; pe=pe->next; X__Free(pe1);
00110      }
00111    }
00112    *nPec=0;
00113    *Pec=NULL;
00114    return NULL;
00115  }
00116  if(*Pec == NULL)*Pec=temp;  /* The first in the sequence */
00117  temp->last=last; if(last != NULL)last->next=temp;
00118  temp->next=next; if(next != NULL)next->last=temp;
00119  temp->frame=frame;
00120  temp->distance=distance;
00121  temp->x=0; temp->y=0;
00122  *nPec = (*nPec)+1;
00123  return temp;
00124 }
00125 
00126 void DeletePathEditControlPoint(int *nPec,
00127                  PATHEDITCONTROL **Pec,
00128                  PATHEDITCONTROL *here){
00129  if(here->last != NULL)here->last->next=here->next;
00130  if(here->next != NULL)here->next->last=here->last;
00131  if(here == *Pec){
00132    *Pec=here->next;  /* which may be NULL */
00133  }
00134  X__Free(here);
00135  *nPec = (*nPec)-1;
00136  return;
00137 }
00138 
00139 void CreatePathPoint(void){
00140  int j;
00141  pathpoint *sp,*tp;
00142  EDIT_ACTION=YES;
00143  if(SelectedNode == NULL){
00144    SendPrgmQuery(IDQ_NOPATH,0);
00145    return;
00146  }
00147  if(SelectedPath == NULL || (sp=SelectedPathPoint) == NULL){
00148    ; //SendPrgmQuery(IDQ_PATH3,0);
00149    return;
00150  }
00151  DrawInvertNode(ghdc_triview_Bitmap,SelectedNode,EDITING);
00152  if(sp->next == NULL){
00153    SendPrgmQuery(IDQ_PATH4,0);
00154  }
00155  else if((tp = (pathpoint *)X__Malloc(sizeof(pathpoint))) == NULL){
00156    SendPrgmQuery(IDQ_NOMEM1,0);
00157  }
00158  else{
00159    tp->last=sp;
00160    tp->next=sp->next;
00161    sp->next->last=tp;
00162    sp->next=tp;
00163    for(j=0;j<3;j++){
00164      tp->p[j]=(sp->p[j] + tp->next->p[j])/2;
00165    }
00166    tp->ptheta = (sp->ptheta + tp->next->ptheta)/2.0;
00167    tp->pfi    = (sp->pfi    + tp->next->pfi   )/2.0;
00168    tp->distance=sp->distance+1.0;
00169    tp->tension_n=sp->tension_p;
00170    tp->tension_p=sp->tension_n;
00171    tp->status=sp->status;
00172    SelectedPath->npathpoints++;
00173  }
00174  SelectedPathPoint=NULL;
00175  DrawInvertNode(ghdc_triview_Bitmap,SelectedNode,EDITING);
00176 }
00177 
00178 void DeletePathPoint(void){
00179  pathpoint *tp;
00180  EDIT_ACTION=YES;
00181  if(SelectedNode == NULL){
00182    SendPrgmQuery(IDQ_NOPATH,0);
00183    return;
00184  }
00185  else if(SelectedPath == NULL)return;
00186  DrawInvertNode(ghdc_triview_Bitmap,SelectedNode,EDITING);
00187  if(SelectedPath->pathtype == CLOSED && SelectedPath->npathpoints < 4){
00188    SendPrgmQuery(IDQ_PATH5,0);
00189  }
00190  else if((tp=SelectedPathPoint) == NULL){
00191   ; // SendPrgmQuery(IDQ_PATH3,0);
00192  }
00193  else if(tp->next == NULL || tp->last == NULL){
00194    SendPrgmQuery(IDQ_PATH6,0);
00195  }
00196  else{
00197    tp->next->last = tp->last;
00198    tp->last->next = tp->next;
00199    X__Free(tp);
00200    SelectedPath->npathpoints--;
00201  }
00202  SelectedPathPoint=NULL;
00203  DrawInvertNode(ghdc_triview_Bitmap,SelectedNode,EDITING);
00204 }
00205 
00206 pathpoint *CreateIPointPath(short type, node *Np, short firstframe,
00207                             short *pathtype, short *npathpoints){
00208  pathpoint *temp1,*temp2,*temp3,*tp,*sp;
00209  object *Op;
00210  long lpx,lpy,lpz,fpx,fpy,fpz;
00211  HWND hwnd;
00212  EDIT_ACTION=YES;
00213  if((hwnd=GetFocus()) != ghwnd_main)hwnd=ghwndTimeline;
00214  if     (type == LOADED){
00215    return LoadPath(pathtype,npathpoints,hwnd);
00216  }
00217  else if(type == COPIED)
00218    return CopyPath(pathtype,npathpoints,Np,firstframe,hwnd);
00219  *pathtype=type;
00220  if((temp1 = (pathpoint *)X__Malloc(sizeof(pathpoint))) == NULL){
00221    SendPrgmQuery(IDQ_NOMEM1,0);
00222    return NULL;
00223  }
00224  if((temp2 = (pathpoint *)X__Malloc(sizeof(pathpoint))) == NULL){
00225    SendPrgmQuery(IDQ_NOMEM1,0);
00226    X__Free(temp1); return NULL;
00227  }
00228  if(type == CLOSED){
00229    if((temp3 = (pathpoint *)X__Malloc(sizeof(pathpoint))) == NULL){
00230      SendPrgmQuery(IDQ_NOMEM1,0);
00231      X__Free(temp1); X__Free(temp2); return NULL;
00232    }
00233  }
00234  fpx=NpointerX; fpy=NpointerY;        fpz=NpointerZ;
00235  lpx=NpointerX; lpy=NpointerY+TVsizeY; lpz=NpointerZ;
00236  if((Op=Np->fobj) != NULL)while(Op != NULL){ /* if not the first path for */
00237    if(Op->lastframe >= firstframe){          /* this object then put first*/
00238      if(Op->last != NULL){                   /* point at end of last and  */
00239        if(Op->last->pathtype == CLOSED)sp=Op->last->firstpathpoint;
00240        else{                                 /* last at cursor. Unless    */
00241          sp=NULL;                            /* closed then start at first*/
00242          if((tp=Op->last->firstpathpoint) != NULL)while(tp!=NULL){
00243            sp=tp;                            /* if first path then start  */
00244            tp=tp->next;                      /* at cursor                 */
00245          }
00246        }
00247        if(sp!=NULL){
00248          fpx=sp->p[0];  fpy=sp->p[1];  fpz=sp->p[2];
00249          lpx=NpointerX; lpy=NpointerY; lpz=NpointerZ;
00250        }
00251      }
00252      break;   /* break out of while loop */
00253    }
00254    Op=Op->next;
00255  }
00256  if(type == OPEN){
00257   temp1->last=NULL;
00258   temp1->next=temp2;
00259   temp2->last=temp1;
00260   temp2->next=NULL;
00261   temp1->ptheta=0; temp1->pfi=0;
00262   temp2->ptheta=0; temp2->pfi=0;
00263   temp1->p[0]=fpx; temp1->p[1]=fpy; temp1->p[2]=fpz;
00264   temp2->p[0]=lpx; temp2->p[1]=lpy; temp2->p[2]=lpz;
00265   temp1->distance=0.0; /* set by calculating path length */
00266   temp2->distance=0.0;
00267   temp1->status=temp2->status=0;
00268   temp1->tension_n=temp2->tension_n=0.5;
00269   temp1->tension_p=temp2->tension_p=0.5;
00270   *npathpoints=2;
00271  }
00272  else if(type ==CLOSED){
00273   temp1->last=NULL;
00274   temp1->next=temp2;
00275   temp2->last=temp1;
00276   temp2->next=temp3;
00277   temp3->last=temp2;
00278   temp3->next=NULL;
00279   temp1->ptheta=0; temp1->pfi=0;
00280   temp2->ptheta=0; temp2->pfi=0;
00281   temp3->ptheta=0; temp3->pfi=0;
00282   temp1->p[0]=fpx;        temp1->p[1]=fpy;         temp1->p[2]=fpz;
00283   temp2->p[0]=fpx+TVsizeX; temp2->p[1]=fpy+TVsizeY;  temp2->p[2]=fpz;
00284   temp3->p[0]=fpx-TVsizeX; temp3->p[1]=fpy+TVsizeY;  temp3->p[2]=fpz;
00285   temp1->distance=0.0;temp2->distance=0.0; temp3->distance=0.0;
00286   temp1->tension_n=temp2->tension_n=temp3->tension_n=0.5;
00287   temp1->tension_p=temp2->tension_p=temp3->tension_p=0.5;
00288   temp1->status=temp2->status=temp3->status=0;
00289   *npathpoints=3;
00290  }
00291  return temp1;
00292 }
00293 
00294 void DeleteCostume(node *Np, long frame){
00295  object *temp;
00296  pathpoint *pp,*pp1;
00297  PATHEDITCONTROL *pe,*pe1;
00298  temp=Np->fobj;
00299  while(temp != NULL){
00300   if((temp->firstframe <= frame) && (temp->lastframe >= frame)){
00301     EDIT_ACTION=YES;
00302     if(temp->fileID >= 0)DeleteRamFile(temp->fileID, temp);
00303     if((pp=temp->firstpathpoint) != NULL){
00304       if(SelectedPath == temp){
00305         SelectedPath=NULL;
00306         SelectedPathPoint=NULL;
00307       }
00308       while(pp != NULL){
00309         pp1=pp; pp=pp->next; X__Free(pp1);
00310       }
00311     }
00312     if(temp->v != NULL)X__Free(temp->v);   /* for paths this is velocity */
00313     if((pe=temp->pec) != NULL)while(pe != NULL){
00314         pe1=pe; pe=pe->next; X__Free(pe1);}
00315     DeleteEffect(temp);
00316     if(temp->xip == NULL)X__Free(temp->xip);  temp->xip=NULL;
00317     UnloadRamImage(&(temp->image));
00318     if(temp->next != NULL)temp->next->last = temp->last;
00319     if(temp->last != NULL)temp->last->next = temp->next;
00320     else Np->fobj=temp->next;
00321     X__Free(temp);
00322     return;
00323   }
00324  temp=temp->next;}
00325 }
00326 
00327 object *CreateCostume(node *Np, long firstframe, long lastframe){
00328  object *temp,*p,*q;
00329  short ff,lf;
00330  EDIT_ACTION=YES;
00331  ff=min(firstframe,lastframe);
00332  lf=max(firstframe,lastframe);
00333  if((temp = (object *)X__Malloc(sizeof(object))) == NULL){
00334    SendPrgmQuery(IDQ_NOMEM1,0);
00335    fail_op=YES; return NULL;
00336  }
00337  p=Np->fobj; q=NULL;
00338  LOOP:
00339  if(p != NULL){
00340    if(((lf >= p->firstframe) && (lf <= p->lastframe))
00341     ||((ff >= p->firstframe) && (ff <= p->lastframe))
00342     ||((ff <= p->firstframe) && (lf >= p->lastframe))){
00343       if((ff < p->firstframe) && (lf > p->lastframe))fail_op=YES;
00344       X__Free(temp); return NULL;}
00345    else if(lf < p->firstframe){/* item is before p */
00346       temp->next=p;
00347       if(p->last == NULL)Np->fobj = temp; /* before first item */
00348       else p->last->next=temp;
00349       temp->last = p->last;
00350       p->last=temp;
00351       goto END;
00352    }
00353    q=p; p=p->next;
00354    goto LOOP;
00355  }
00356  else{/* item is either only one or is last */
00357   if(q == NULL)Np->fobj=temp; /* item is only one */
00358   else q->next=temp;
00359   temp->last=q;
00360   temp->next=NULL;
00361   goto END;
00362  }
00363  goto LOOP;
00364 END:
00365  temp->name[0]='\0';
00366  temp->firstframe = ff;
00367  temp->lastframe = lf;
00368  temp->type = Np->type;
00369  temp->quick_only=0;
00370  temp->fileID = -1;
00371  temp->npathpoints=0;
00372  temp->origin[0]=0; temp->origin[1]=0; temp->origin[2]=0;
00373  temp->offset[0]=0; temp->offset[1]=0; temp->offset[2]=0;
00374  temp->colour[0]=0;
00375  temp->colour[1]=255;
00376  temp->colour[2]=0;
00377  temp->acolour[0]=0;
00378  temp->acolour[1]=128;
00379  temp->acolour[2]=0;
00380  temp->morph=NO;
00381  temp->morphNo=0;
00382  temp->xip=NULL;
00383  temp->effect=NULL;
00384  temp->edges=NULL;
00385  temp->points=NULL;
00386  temp->skeleton=NULL;
00387  temp->w_frame.Np=temp->w_frame.Ne=0;
00388  temp->w_frame.e=NULL; temp->w_frame.p=NULL;
00389  temp->skid=NULL;
00390  temp->npoints=0;
00391  temp->nskeleton=0;
00392  temp->nedges=0;
00393  temp->in_ram=0;
00394  temp->bWireframe=0;
00395  temp->pathtype = -1;
00396  temp->groundtype=0;
00397  temp->lighttype =0;
00398  temp->light_intensity=1.0;
00399  temp->depth_cue=0;
00400  temp->depth_cue_c=1.0;
00401  temp->depth_cue_l=1.0;
00402  temp->depth_cue_q=0.0;
00403  temp->self_shadow=1;
00404  temp->cast_shadow=1;
00405  temp->show_shadow=1;
00406  temp->firstpathpoint = NULL;
00407  temp->pec=NULL;
00408  temp->npec=0;
00409  temp->v=NULL;
00410  temp->pathlength=0.0;
00411  temp->gspec=temp->gtran=temp->grefl=temp->gbump=0.0;
00412  temp->hEffect=NULL;
00413  temp->effectname[0]=0;
00414  temp->Nurbs=NULL;
00415  temp->nNurbs=0;
00416  temp->bIKchain=FALSE;
00417  InitialiseRamImage(&(temp->image));
00418  memset(&(temp->particles),0,sizeof(ParticleSystem));
00419  InitialiseParticleSystem(&(temp->particles));
00420 // temp->particles.NumP=100;
00421 // strcpy(temp->particles.ImageName,"cloud");
00422 // temp->particles.colour_start[0]=temp->particles.colour_start[1]=temp->particles.colour_start[2]=255;
00423 // temp->particles.colour_end[0]=temp->particles.colour_end[1]=temp->particles.colour_end[2]=128;
00424 // temp->particles.alpha_start=temp->particles.alpha_end=500;  // scale 0 - 999
00425  return temp;
00426 }
00427 
00428 void DeleteSize(node *Np, long frame){
00429  size *temp;
00430  EDIT_ACTION=YES;
00431  temp=Np->fsiz;
00432  while(temp != NULL){
00433   if((temp->firstframe <= frame) && (temp->lastframe >= frame)){
00434     if(temp->next != NULL)temp->next->last = temp->last;
00435     if(temp->last != NULL)temp->last->next = temp->next;
00436     else Np->fsiz=temp->next;
00437     X__Free(temp);
00438     return;
00439   }
00440   temp=temp->next;
00441  }
00442 }
00443 
00444 static void SetDefaultCameraParams(cameraparam *c){
00445   c->f_number = 4;
00446   c->focal_length = 10;
00447   c->focus_distance = 10;
00448   c->polarn_angle = 0;
00449   c->polar_type  = 0;
00450   c->stereo_separation = 0.1;
00451   c->parallax_distance = 100.0;
00452 }
00453 
00454 size *CreateSize(node *Np, long firstframe, long lastframe){
00455  size *temp,*p,*q;
00456  short ff,lf;
00457  EDIT_ACTION=YES;
00458  ff=min(firstframe,lastframe);
00459  lf=max(firstframe,lastframe);
00460  if((temp = (size *)X__Malloc(sizeof(size))) == NULL){
00461    SendPrgmQuery(IDQ_NOMEM1,0);
00462    fail_op=YES; return NULL;
00463  }
00464  p=Np->fsiz; q=NULL;
00465  LOOP:
00466  if(p != NULL){
00467    if(((lf >= p->firstframe) && (lf <= p->lastframe))
00468     ||((ff >= p->firstframe) && (ff <= p->lastframe))
00469     ||((ff <= p->firstframe) && (lf >= p->lastframe))){
00470       if((ff < p->firstframe) && (lf > p->lastframe))fail_op=YES;
00471       X__Free(temp); return NULL;}
00472    else if(lf < p->firstframe){/* item is before p */
00473       temp->next=p;
00474       if(p->last == NULL)Np->fsiz = temp; /* before first item */
00475       else p->last->next=temp;
00476       temp->last = p->last;
00477       p->last=temp;
00478       goto END;
00479    }
00480    q=p; p=p->next;
00481    goto LOOP;
00482  }
00483  else{/* item is either only one or is last */
00484   if(q == NULL)Np->fsiz=temp; /* item is only one */
00485   else q->next=temp;
00486   temp->last=q;
00487   temp->next=NULL;
00488   goto END;
00489  }
00490  goto LOOP;
00491 END:
00492  temp->firstframe=ff;
00493  temp->lastframe=lf;
00494  temp->tweentype=0;
00495  temp->tension_s=0.5;
00496  temp->tension_e=0.5;
00497  temp->easin=1.0;
00498  temp->easout=1.0;
00499  if(temp->last == NULL){
00500    if(Np->type == LIGHT){
00501      temp->Sx=15; temp->Sy=5; temp->Sz=1; /* light cone angles sz not used */
00502    }
00503    else{
00504      temp->Sx=1;  temp->Sy=1; temp->Sz=1;
00505    }
00506    if(Np->type == CAMERA)SetDefaultCameraParams(&(temp->camera_params));
00507  }
00508  else{
00509    temp->Sx=temp->last->Sx;
00510    temp->Sy=temp->last->Sy;
00511    temp->Sz=temp->last->Sz;
00512    if(Np->type == CAMERA)memcpy(&(temp->camera_params),&(temp->last->camera_params),sizeof(cameraparam));
00513  }
00514  return temp;
00515 }
00516 
00517 void DeleteAlign(node *Np, long frame){
00518  align *temp;
00519  EDIT_ACTION=YES;
00520  temp=Np->fali;
00521  while(temp != NULL){
00522   if((temp->firstframe <= frame) && (temp->lastframe >= frame)){
00523     if(temp->next != NULL)temp->next->last = temp->last;
00524     if(temp->last != NULL)temp->last->next = temp->next;
00525     else Np->fali=temp->next;
00526     X__Free(temp);
00527     return;
00528   }
00529  temp=temp->next;}
00530 }
00531 
00532 align *CreateAlign(node *Np, long firstframe, long lastframe){
00533  align *temp,*p,*q;
00534  short ff,lf;
00535  EDIT_ACTION=YES;
00536  ff=min(firstframe,lastframe);
00537  lf=max(firstframe,lastframe);
00538  if((temp = (align *)X__Malloc(sizeof(align))) == NULL){
00539    SendPrgmQuery(IDQ_NOMEM1,0);
00540    fail_op=YES; return NULL;
00541  }
00542  p=Np->fali; q=NULL;
00543  LOOP:
00544  if(p != NULL){
00545    if(((lf >= p->firstframe) && (lf <= p->lastframe))
00546     ||((ff >= p->firstframe) && (ff <= p->lastframe))
00547     ||((ff <= p->firstframe) && (lf >= p->lastframe))){
00548       if((ff < p->firstframe) && (lf > p->lastframe))fail_op=YES;
00549       X__Free(temp); return NULL;}
00550    else if(lf < p->firstframe){/* item is before p */
00551       temp->next=p;
00552       if(p->last == NULL)Np->fali = temp; /* before first item */
00553       else p->last->next=temp;
00554       temp->last = p->last;
00555       p->last=temp;
00556       goto END;
00557    }
00558    q=p; p=p->next;
00559    goto LOOP;
00560  }
00561  else{/* item is either only one or is last */
00562   if(q == NULL)Np->fali=temp; /* item is only one */
00563   else q->next=temp;
00564   temp->last=q;
00565   temp->next=NULL;
00566   goto END;
00567  }
00568  goto LOOP;
00569 END:
00570  temp->type=TWEEN;
00571  temp->firstframe=ff;
00572  temp->lastframe=lf;
00573  temp->topath=NULL;
00574  temp->tension_s=0.5;
00575  temp->tension_e=0.5;
00576  temp->easin=1.0;
00577  temp->easout=1.0;
00578  if(temp->last == NULL){
00579   temp->theta=0;
00580   temp->phi=0;
00581   temp->alpha=0;
00582   temp->im=0;
00583   temp->ima= -1.0;
00584  }
00585  else{
00586   temp->theta=temp->last->theta;
00587   temp->phi=temp->last->phi;
00588   temp->alpha=temp->last->alpha;
00589   temp->im=temp->last->im;
00590   temp->ima=temp->last->ima;
00591  }
00592  return temp;
00593 }
00594 
00595 void DeletePosition(node *Np, long frame){
00596  position *temp;
00597  EDIT_ACTION=YES;
00598  temp=Np->fpos;
00599  while(temp != NULL){
00600   if((temp->firstframe <= frame) && (temp->lastframe >= frame)){
00601     if(temp->next != NULL)temp->next->last = temp->last;
00602     if(temp->last != NULL)temp->last->next = temp->next;
00603     else Np->fpos=temp->next;
00604     X__Free(temp);
00605     return;
00606   }
00607  temp=temp->next;}
00608 }
00609 
00610 void DeletePositionIn(node *Np, long first_frame, long last_frame){ // all positions!
00611   int i;
00612   for(i=first_frame;i<=last_frame;i++)DeletePosition(Np,i);
00613 }
00614 
00615 position *CreatePosition(node *Np, long firstframe, long lastframe){
00616  position *temp,*p,*q;
00617  short ff,lf;
00618  EDIT_ACTION=YES;
00619  ff=min(firstframe,lastframe);
00620  lf=max(firstframe,lastframe);
00621  if((temp = (position *)X__Malloc(sizeof(position))) == NULL){
00622    SendPrgmQuery(IDQ_NOMEM1,0);
00623    fail_op=YES; return NULL;
00624  }
00625  p=Np->fpos; q=NULL;
00626  LOOP:
00627  if(p != NULL){
00628    if(((lf >= p->firstframe) && (lf <= p->lastframe))
00629     ||((ff >= p->firstframe) && (ff <= p->lastframe))
00630     ||((ff <= p->firstframe) && (lf >= p->lastframe))){
00631       if((ff < p->firstframe) && (lf > p->lastframe))fail_op=YES;
00632       X__Free(temp); return NULL;}
00633    else if(lf < p->firstframe){/* item is before p */
00634       temp->next=p;
00635       if(p->last == NULL)Np->fpos = temp; /* before first item */
00636       else p->last->next=temp;
00637       temp->last = p->last;
00638       p->last=temp;
00639       goto END;
00640    }
00641    q=p; p=p->next;
00642    goto LOOP;
00643  }
00644  else{/* item is either only one or is last */
00645   if(q == NULL)Np->fpos=temp; /* item is only one */
00646   else q->next=temp;
00647   temp->last=q;
00648   temp->next=NULL;
00649   goto END;
00650  }
00651  goto LOOP;
00652 END:
00653  temp->type=TWEEN;
00654  temp->firstframe=ff;
00655  temp->lastframe=lf;
00656  temp->onpath=NULL;
00657  temp->tension_s=0.5;
00658  temp->tension_e=0.5;
00659  temp->easin=1.0;
00660  temp->easout=1.0;
00661  temp->fx=0; temp->fy=0; temp->fz=0;
00662  if(Np->type == TARGET){   /* if target add at the current cursor position*/
00663    temp->finish[0]=NpointerX;
00664    temp->finish[1]=NpointerY;
00665    temp->finish[2]=NpointerZ;
00666  }
00667  else if(temp->last == NULL){
00668    temp->finish[0]=0;
00669    temp->finish[1]=0;
00670    temp->finish[2]=0;
00671  }
00672  else{  /* put at same place as last */
00673    temp->finish[0]=temp->last->finish[0];
00674    temp->finish[1]=temp->last->finish[1];
00675    temp->finish[2]=temp->last->finish[2];
00676  }
00677  return temp;
00678 }
00679 
00680 void DeleteSky(node *Np, long frame){
00681  sky *temp;
00682  EDIT_ACTION=YES;
00683  temp=Np->fsky;
00684  while(temp != NULL){
00685   if((temp->firstframe <= frame) && (temp->lastframe >= frame)){
00686     if(temp->next != NULL)temp->next->last = temp->last;
00687     if(temp->last != NULL)temp->last->next = temp->next;
00688     else Np->fsky=temp->next;
00689     UnloadRamImage(&(temp->image));
00690     X__Free(temp);
00691     return;
00692   }
00693  temp=temp->next;}
00694 }
00695 
00696 sky *CreateSky(node *Np, long firstframe, long lastframe){
00697  int i;
00698  sky *temp,*p,*q;
00699  short ff,lf;
00700  EDIT_ACTION=YES;
00701  ff=min(firstframe,lastframe);
00702  lf=max(firstframe,lastframe);
00703  if((temp = (sky *)X__Malloc(sizeof(sky))) == NULL){
00704    SendPrgmQuery(IDQ_NOMEM1,0);
00705    fail_op=YES; return NULL;
00706  }
00707  p=Np->fsky; q=NULL;
00708  LOOP:
00709  if(p != NULL){
00710    if(((lf >= p->firstframe) && (lf <= p->lastframe))
00711     ||((ff >= p->firstframe) && (ff <= p->lastframe))
00712     ||((ff <= p->firstframe) && (lf >= p->lastframe))){
00713       if((ff < p->firstframe) && (lf > p->lastframe))fail_op=YES;
00714       X__Free(temp); return NULL;}
00715    else if(lf < p->firstframe){/* item is before p */
00716       temp->next=p;
00717       if(p->last == NULL)Np->fsky = temp; /* before first item */
00718       else p->last->next=temp;
00719       temp->last = p->last;
00720       p->last=temp;
00721       goto END;
00722    }
00723    q=p; p=p->next;
00724    goto LOOP;
00725  }
00726  else{/* item is either only one or is last */
00727   if(q == NULL)Np->fsky=temp; /* item is only one */
00728   else q->next=temp;
00729   temp->last=q;
00730   temp->next=NULL;
00731   goto END;
00732  }
00733  goto LOOP;
00734 END:
00735  temp->firstframe=ff;
00736  temp->lastframe=lf;
00737  temp->colour[0]=128;
00738  temp->colour[1]=60;
00739  temp->colour[2]=60;
00740  temp->zcolour[0]=0;
00741  temp->zcolour[1]=128;
00742  temp->zcolour[2]=255;
00743  temp->type=0;
00744  temp->gamb=0.08; temp->oamb=0.1;
00745  temp->gamb_colour[0]=temp->gamb_colour[1]=temp->gamb_colour[2]=0.08;
00746  temp->oamb_colour[0]=temp->oamb_colour[1]=temp->oamb_colour[2]=0.08;
00747  temp->aff=1; temp->alf=9999; temp->ast=1;
00748  for(i=0;i<32;i++)temp->sky_params[i]=0.0;
00749  temp->sky_params[0]=15.0;
00750  temp->sky_params[1]=50.0;
00751  strcpy(temp->sky_params_file,"<none>");
00752  InitialiseRamImage(&(temp->image));
00753  return temp;
00754 }
00755 
00756 void DeleteDirector(node *Np, long frame){
00757  director *temp;
00758  EDIT_ACTION=YES;
00759  temp=Np->fdirector;
00760  while(temp != NULL){
00761   if((temp->firstframe <= frame) && (temp->lastframe >= frame)){
00762     if(temp->next != NULL)temp->next->last = temp->last;
00763     if(temp->last != NULL)temp->last->next = temp->next;
00764     else Np->fdirector=temp->next;
00765     X__Free(temp);
00766     return;
00767   }
00768  temp=temp->next;}
00769 }
00770 
00771 director *CreateDirector(node *Np, long firstframe, long lastframe){
00772  director *temp,*p,*q;
00773  short ff,lf;
00774  EDIT_ACTION=YES;
00775  ff=min(firstframe,lastframe);
00776  lf=max(firstframe,lastframe);
00777  if((temp = (director *)X__Malloc(sizeof(sky))) == NULL){
00778    SendPrgmQuery(IDQ_NOMEM1,0);
00779    fail_op=YES; return NULL;
00780  }
00781  p=Np->fdirector; q=NULL;
00782  LOOP:
00783  if(p != NULL){
00784    if(((lf >= p->firstframe) && (lf <= p->lastframe))
00785     ||((ff >= p->firstframe) && (ff <= p->lastframe))
00786     ||((ff <= p->firstframe) && (lf >= p->lastframe))){
00787       if((ff < p->firstframe) && (lf > p->lastframe))fail_op=YES;
00788       X__Free(temp); return NULL;}
00789    else if(lf < p->firstframe){/* item is before p */
00790       temp->next=p;
00791       if(p->last == NULL)Np->fdirector = temp; /* before first item */
00792       else p->last->next=temp;
00793       temp->last = p->last;
00794       p->last=temp;
00795       goto END;
00796    }
00797    q=p; p=p->next;
00798    goto LOOP;
00799  }
00800  else{/* item is either only one or is last */
00801   if(q == NULL)Np->fdirector=temp; /* item is only one */
00802   else q->next=temp;
00803   temp->last=q;
00804   temp->next=NULL;
00805   goto END;
00806  }
00807  goto LOOP;
00808 END:
00809  temp->firstframe=ff;
00810  temp->lastframe=lf;
00811  temp->type=0;
00812  temp->ActiveCamera=FirstNp;
00813  return temp;
00814 }
00815 
00816 void DeleteNode(node *Np){
00817  sky       *Sp,*tSp;
00818  object    *Op,*tOp;
00819  position  *Pp,*tPp;
00820  director  *Dp,*tDp;
00821  align     *Ap,*tAp;
00822  size      *Zp,*tZp;
00823  node      *oldNp;
00824  if(Np == NULL)return;
00825  EDIT_ACTION=YES;
00826  oldNp=Np;
00827  if((Sp = Np->fsky) != NULL)while(Sp != NULL){
00828    DeleteSky(Np,Sp->lastframe);
00829    Sp=Np->fsky;
00830  //   tSp=Sp->next; X__Free(Sp); Sp=tSp;
00831  }
00832  if((Dp = Np->fdirector) != NULL)while(Dp != NULL){
00833     tDp=Dp->next; X__Free(Dp); Dp=tDp;}
00834  if((Op = Np->fobj) != NULL)while(Op != NULL){
00835    DeleteCostume(Np,Op->lastframe);
00836    Op=Np->fobj;
00837  }
00838  if((Pp = Np->fpos) != NULL)while(Pp != NULL){
00839    tPp=Pp->next; X__Free(Pp); Pp=tPp;}
00840  if((Ap = Np->fali) != NULL)while(Ap != NULL){
00841    tAp=Ap->next; X__Free(Ap); Ap=tAp;}
00842  if((Zp = Np->fsiz) != NULL)while(Zp != NULL){
00843    tZp=Zp->next; X__Free(Zp); Zp=tZp;}
00844  if(Np->last != NULL)Np->last->next=Np->next;
00845  if(Np->next != NULL)Np->next->last=Np->last;
00846  if(Np == MainNp )MainNp  = Np->last;
00847  if(Np == FirstNp)FirstNp = Np->next;
00848  Nnodes--;
00849  X__Free(Np);
00850  /* now look at all dependencies remaining to see if they depend on this
00851     node, if they do then remove the dependencies by conversion to
00852     the simplest type
00853  */
00854  if((Np=FirstNp) != NULL)while(Np != NULL){
00855    if((Pp=Np->fpos) != NULL)while(Pp != NULL){
00856      if(Pp->onpath == oldNp){Pp->onpath=NULL; Pp->type = TWEEN;}
00857      Pp=Pp->next;
00858    }
00859    if((Ap=Np->fali) != NULL)while(Ap != NULL){
00860      if(Ap->topath == oldNp){Ap->topath=NULL; Ap->type = TWEEN;}
00861      Ap=Ap->next;
00862    }
00863    /* if it's a director then check to see if it was pointing at a
00864       camera that has been deleted, if so point to first camera */
00865    if(Np->type == DIRECTOR){
00866      if((Dp=Np->fdirector) != NULL)while(Dp != NULL){
00867        if(Dp->ActiveCamera == oldNp)Dp->ActiveCamera=FirstNp;
00868        Dp=Dp->next;
00869      }
00870    }
00871    Np=Np->next;
00872  }
00873 }
00874 
00875 node *CreateNode(void){
00876  node *temp;
00877  if((temp = (node *)X__Malloc(sizeof(node))) == NULL){
00878    SendPrgmQuery(IDQ_NOMEM1,0);
00879    return NULL;
00880  }
00881  EDIT_ACTION=YES;
00882  if(MainNp == NULL)FirstNp=temp;
00883  else              MainNp->next=temp;
00884  temp->last=MainNp;
00885  temp->next=NULL;
00886  temp->fsky=NULL;
00887  temp->fdirector=NULL;
00888  temp->fobj=NULL;
00889  temp->fpos=NULL;
00890  temp->fali=NULL;
00891  temp->fsiz=NULL;
00892  temp->type=-1;
00893  temp->ID=MaxNodeID++;
00894  MainNp = temp;
00895  Nnodes++;
00896  return temp;
00897 }
00898 
00899 pathpoint *CopyPath(short *pathtype, short *npathpoints, node *Nc,
00900                     short firstframe, HWND parent){
00901  pathpoint *Ppp=NULL,*Fpp=NULL,*Lpp=NULL,*Cpp=NULL;
00902  char tempname[32];
00903  node *Np;
00904  object *Op;
00905  long i;
00906  if((Np=SelectNode(tempname,NO,parent)) == NULL || Np->type != PATH)return NULL;
00907  if((Op=Np->fobj) != NULL)while(Op != NULL){
00908    if(firstframe >= Op->firstframe && firstframe <= Op->lastframe){
00909      if(Op->npathpoints > 0 && (Cpp=Op->firstpathpoint) != NULL){
00910        for(i=0;i<Op->npathpoints;i++){
00911          if((Ppp=AppendPathPoint(Ppp)) == NULL)goto MEMFAIL;
00912          CopyPoint(Cpp->p,Ppp->p);
00913          Ppp->tension_n=Cpp->tension_n;
00914          Ppp->tension_p=Cpp->tension_p;
00915          Ppp->ptheta=0;Ppp->pfi=0;
00916          Ppp->distance=0.0; /* set by path length calculation */
00917          Lpp=Ppp;
00918          if(i == 0)Fpp=Ppp;
00919          Cpp=Cpp->next;
00920        }
00921        *npathpoints = Op->npathpoints;
00922        *pathtype = Op->pathtype;
00923        return Fpp;
00924      }
00925    }
00926    Op=Op->next;
00927  }
00928  return NULL;
00929  MEMFAIL:
00930  if(Lpp != NULL)while(Lpp!=NULL){Ppp=Lpp->last; X__Free(Lpp); Lpp=Ppp;}
00931  return NULL;
00932 }
00933 
00934 void CheckRecursiveFollow(node *Np, short ff, short lf){
00935  position *Pp;
00936  align    *Ap;
00937  char mess[256];
00938  object   *Op;
00939  double   alpha,theta,phi,sx,sy,sz,ima;
00940  short    im;
00941  point    Offset,TrackedOffset;
00942  long     tframe;
00943  tframe=CurrentFrame;
00944  AGAIN:
00945  if(setjmp(r_buf) != 0){
00946    SendPrgmQuery(IDQ_SELFFOLLOW1,0);
00947    sprintf(mess,"Actor %s reset to TWEEN", Np->actorname);
00948    MessageBox (NULL,mess,"NOTE",
00949     MB_OK | MB_ICONINFORMATION | MB_TASKMODAL);
00950    if((Pp=Np->fpos) != NULL)while(Pp != NULL){
00951      if((CurrentFrame >= Pp->firstframe) && (CurrentFrame <= Pp->lastframe)){
00952        Pp->type=TWEEN;  Pp->onpath=NULL; Pp->pnodename[0]='\0';
00953      }
00954      Pp=Pp->next;
00955    }
00956    if((Ap=Np->fali) != NULL)while(Ap != NULL){
00957      if((CurrentFrame >= Ap->firstframe) && (CurrentFrame <= Ap->lastframe)){
00958        Ap->type=TWEEN;  Ap->topath=NULL; Ap->anodename[0]='\0';
00959      }
00960      Ap=Ap->next;
00961    }
00962    goto AGAIN;
00963  }
00964  for(CurrentFrame=ff; CurrentFrame <= lf; CurrentFrame++){
00965    if((Op=Np->fobj) != NULL)while(Op != NULL){
00966      if(CurrentFrame >= Op->firstframe && CurrentFrame <= Op->lastframe){
00967        GetTransform(0,CurrentFrame,1.0,Np,Op,Offset,TrackedOffset,
00968                     &phi,&theta,&alpha,&sx,&sy,&sz,&im,&ima);
00969      }
00970      Op=Op->next;
00971    }
00972  }
00973  CurrentFrame=tframe;
00974 }
00975 
00976 void ScrapEverything(void){
00977  XIP  *Ip,*tIp;
00978  node *Np,*tNp;
00979  long i;
00980  char WorkfileName[64];
00981  if((Np=MainNp) != NULL)while(Np != NULL){
00982    tNp=Np->last;
00983    DeleteNode(Np);
00984    Np=tNp;
00985  }
00986  MainNp=NULL;
00987  FirstNp=NULL;
00988  SelectedNode=NULL;
00989  SelectedPath=NULL;
00990  SelectedPathPoint=NULL;
00991  SelectedCamera=NULL;
00992  Ncameras=0;
00993  Nnodes=0;
00994  Nground=0;
00995  Nrobots=0;
00996  Nskys=0;
00997  Ndirectors=0;
00998  MaxNodeID=0;
00999  if((Ip=MainIp) != NULL)while(Ip != NULL){
01000    tIp=Ip->last;
01001    DeleteImageProcess(Ip);
01002    Ip=tIp;
01003  }
01004  MainIp=NULL;
01005  FirstIp=NULL;
01006  NimageProcesses=0;
01007  fileID=0;
01008  Nframes=1;
01009  EnableMenuItem(GetMenu(ghwnd_main),IDM_FRAME_RENDERNOW,MF_GRAYED);
01010  CurrentFrame=1;
01011  FirstTimeRender=1;
01012  SelectedPathPhi=0.0;
01013  SelectedPathTheta=0.0;
01014  SelectedPathAlpha=0.0;
01015  SelectedPathOffset[0]=0;
01016  SelectedPathOffset[1]=0;
01017  SelectedPathOffset[2]=0;
01018  sprintf(WorkfileName,"%sW_$.SCR",TempPath);
01019  remove(WorkfileName);
01020  sprintf(WorkfileName,"%sX_$.SCR",TempPath);
01021  remove(WorkfileName);
01022  sprintf(WorkfileName,"%sY_$.SCR",TempPath);
01023  remove(WorkfileName);
01024  sprintf(WorkfileName,"%sW_$001.GIF",TempPath);
01025  remove(WorkfileName);
01026  sprintf(WorkfileName,"%sWIRE_$$$.APF",TempPath);
01027  remove(WorkfileName);
01028  FreePreview();
01029  EraseTempImageFiles();
01030  EDIT_ACTION=NO;
01031 }
01032 
01033 long SelectNodeID(HWND parent){
01034  node *Np;
01035  char temp[256];
01036  temp[0]=0;
01037  if((Np=SelectNode(temp,NO,parent)) == NULL)return -1;
01038  return (long)(Np->ID);
01039 }
01040 
01041 node *GetSelectedCamera(long cf, node *Sc){
01042  director *dp;
01043  node     *np;
01044  if(Ndirectors < 1 || use_director == 0)return Sc;
01045  np=FirstNp; while (np != NULL){
01046    if(np->type == DIRECTOR){
01047      dp=np->fdirector;
01048      while(dp != NULL){
01049        if(cf >= dp->firstframe && cf <= dp->lastframe){
01050          Sc=dp->ActiveCamera;
01051          return Sc;
01052        }
01053        dp=dp->next;
01054      }
01055      return Sc;
01056    }
01057    np=np->next;
01058  }
01059  return Sc;
01060 }
01061 
01062 typedef struct tagSELECTDLGLIST {
01063   int n;
01064   int maxlen;
01065   char *title;
01066   char **list;
01067   node **NpList;
01068 } SELECTDLGLIST;
01069 
01070 static BOOL CALLBACK ActorListDlgProc(HWND hwnd, UINT msg,
01071                                       WPARAM wparam, LPARAM lparam ){
01072  static SELECTDLGLIST *dp;
01073  static HBITMAP hbmpPicture,hbmpOld;
01074  static HBITMAP hbmpImages[N_OBJECTTYPELIST];
01075  HWND hctl;
01076  TCHAR tchBuf[MAX_PATH];
01077  TEXTMETRIC tm;
01078  int i,y,nItem;
01079  int tc;
01080  HDC hdcMem;
01081  LPMEASUREITEMSTRUCT lpmis;
01082  LPDRAWITEMSTRUCT lpdis;
01083  RECT rcBitmap;
01084  switch( msg ) {
01085    case WM_INITDIALOG:{
01086        dp=(SELECTDLGLIST *)lparam;
01087        for(i=0;i<N_OBJECTTYPELIST;i++){
01088          hbmpImages[i]=LoadBitmap(ghinst_main,
01089            MAKEINTRESOURCE(ObjectSmallBitmapIdList[i]));
01090        }
01091        hctl=GetDlgItem(hwnd,DLG_SELECT_LIST);
01092        for(i=0;i<dp->n;i++){
01093          nItem=SendMessage(hctl,LB_ADDSTRING,0,(LPARAM)dp->list[i]);
01094          if(dp->NpList != NULL){
01095            node *Np;
01096            Np=dp->NpList[i];
01097            if(Np != NULL){
01098              hbmpPicture=hbmpImages[0];
01099              if(Np->type == PATH)hbmpPicture=hbmpImages[1];
01100              if(Np->type == TARGET)hbmpPicture=hbmpImages[2];
01101              if(Np->type == GROUND)hbmpPicture=hbmpImages[3];
01102              if(Np->type == LIGHT)hbmpPicture=hbmpImages[4];
01103              if(Np->type == ANIMOBJ)hbmpPicture=hbmpImages[5];
01104              if(Np->type == PARTICLE)hbmpPicture=hbmpImages[6];
01105              if(Np->type == SKY)hbmpPicture=hbmpImages[7];
01106              if(Np->type == ROBOT)hbmpPicture=hbmpImages[8];
01107              if(Np->type == CAMERA)hbmpPicture=hbmpImages[9];
01108              if(Np->type == IMAGEP)hbmpPicture=hbmpImages[10];
01109              if(Np->type == DIRECTOR)hbmpPicture=hbmpImages[11];
01110              SendMessage(hctl,LB_SETITEMDATA,nItem,(LPARAM)hbmpPicture);
01111            }
01112          }
01113        }
01114        SendMessage(hctl,LB_SETCURSEL,0,0);
01115        SendMessage(hctl,LB_SETCOLUMNWIDTH,(WPARAM)(dp->maxlen+1)*6+22,0);
01116        SendMessage(hwnd,WM_SETTEXT,0,(LPARAM)dp->title);
01117        CentreDialogOnScreen(hwnd);
01118      }
01119      return (TRUE);
01120    case WM_MEASUREITEM:
01121      lpmis=(LPMEASUREITEMSTRUCT)lparam;
01122      lpmis->itemHeight=16;
01123      return TRUE;
01124    case WM_DRAWITEM:
01125      lpdis=(LPDRAWITEMSTRUCT)lparam;
01126      if(lpdis->itemID == -1)break;
01127      switch(lpdis->itemAction){
01128        case ODA_SELECT:
01129        case ODA_DRAWENTIRE:
01130          hbmpPicture=(HBITMAP)SendMessage(lpdis->hwndItem,LB_GETITEMDATA,
01131           lpdis->itemID,(LPARAM)0);
01132          hdcMem=CreateCompatibleDC(lpdis->hDC);
01133          hbmpOld=SelectObject(hdcMem,hbmpPicture);
01134          SendMessage(lpdis->hwndItem,LB_GETTEXT,lpdis->itemID,(LPARAM)tchBuf);
01135          GetTextMetrics(lpdis->hDC,&tm);
01136          y=(lpdis->rcItem.bottom+lpdis->rcItem.top-tm.tmHeight)/2;
01137          ExtTextOut(lpdis->hDC,
01138                     lpdis->rcItem.left+16+6,y,
01139                     ETO_OPAQUE | ETO_CLIPPED,
01140                     &lpdis->rcItem,
01141                     tchBuf,strlen(tchBuf),
01142                     NULL);
01143          BitBlt(lpdis->hDC,lpdis->rcItem.left,lpdis->rcItem.top,
01144                 lpdis->rcItem.right-lpdis->rcItem.left,
01145                 lpdis->rcItem.bottom-lpdis->rcItem.top,
01146                 hdcMem,0,0,SRCCOPY);
01147          SelectObject(hdcMem,hbmpOld);
01148          DeleteDC(hdcMem);
01149          if(lpdis->itemState & ODS_SELECTED){
01150            rcBitmap.left=lpdis->rcItem.left;
01151            rcBitmap.top=lpdis->rcItem.top;
01152            rcBitmap.right=lpdis->rcItem.left+
01153                           16+6+strlen(tchBuf)*tm.tmAveCharWidth;
01154            rcBitmap.bottom=lpdis->rcItem.top+16;
01155 //           InvertRect(lpdis->hDC,&rcBitmap);
01156            InvertRect(lpdis->hDC,&lpdis->rcItem);
01157          }
01158          break;
01159        case ODA_FOCUS:
01160          break;
01161      }
01162      return TRUE;
01163    case WM_COMMAND:
01164       switch(LOWORD(wparam)){
01165         case DLG_SELECT_LIST:
01166           switch(HIWORD(wparam)){
01167             case LBN_SELCHANGE:
01168               hctl=GetDlgItem(hwnd,DLG_SELECT_LIST);
01169               i=SendMessage(hctl,LB_GETCURSEL,0,0);
01170               if(dp->NpList != NULL){
01171                 node *Np;
01172                 Np=dp->NpList[i];
01173                 if(Np != NULL){
01174                   if(Np->type == NORMAL ||
01175                      Np->type == ROBOT  ||
01176                      Np->type == ANIMOBJ){
01177                     object *Op;
01178                     Op=GetObjectAtFrame(Np,CurrentFrame);
01179                     if(Op == NULL)
01180                       SetDlgItemText(hwnd,DLG_SELECT_INFO,Np->actorname);
01181                     else
01182                       SetDlgItemText(hwnd,DLG_SELECT_INFO,Op->name);
01183                   }
01184                   else
01185                     SetDlgItemText(hwnd,DLG_SELECT_INFO," ");
01186                 }
01187 
01188               }
01189               break;
01190             case LBN_DBLCLK:
01191             SendMessage(hwnd,WM_COMMAND,MAKEWPARAM(IDOK,0),0);
01192               break;
01193             default:
01194               break;
01195           }
01196           break;
01197         case IDCANCEL:
01198           EndDialog(hwnd, -1);
01199           return (TRUE);
01200         case IDOK:
01201           hctl=GetDlgItem(hwnd,DLG_SELECT_LIST);
01202           i=SendMessage(hctl,LB_GETCURSEL,0,0);
01203           EndDialog(hwnd,i);
01204           return(TRUE);
01205         default:
01206           break;
01207       }
01208       break;
01209    case WM_DESTROY:
01210      for(i=0;i<N_OBJECTTYPELIST;i++)DeleteObject(hbmpImages[i]);
01211      return TRUE;
01212  }
01213  return(FALSE);
01214 }
01215 
01216 node *SelectNode(char *NodeName, short with_sky, HWND parent){
01217  SELECTDLGLIST SelectDlgList;
01218  node *Np,**NpList;
01219  int maxlen=0;
01220  short id,i,j;
01221  char **ItemList;
01222  char title[256];
01223  if((ItemList = (char **)X__Malloc(sizeof(char *)*Nnodes)) == NULL)
01224      return NULL;
01225  for(i=0;i<Nnodes;i++){
01226    if((ItemList[i] = (char *)X__Malloc(128)) == NULL){
01227      if(i > 0)for(j=0;j<i;j++)X__Free(ItemList[j]);
01228      X__Free(ItemList);
01229      return NULL;
01230    }
01231  }
01232  if((NpList = (node **)X__Malloc(sizeof(node *)*Nnodes)) == NULL){
01233    for(i=0;i<Nnodes;i++)X__Free(ItemList[i]);
01234    X__Free(ItemList);
01235    return NULL;
01236  }
01237  i=0; Np=FirstNp; while(Np != NULL){ /* get list of node names */
01238    strcpy(ItemList[i]," ");
01239    strcat(ItemList[i],Np->actorname);
01240    NpList[i]=Np;
01241    maxlen=max(maxlen,strlen(ItemList[i]));
01242    i++; Np=Np->next;
01243  }
01244  TRYAGAIN:
01245  LoadString(ghinst_main,IDX_MISC_ACTOR,title,63);
01246  SelectDlgList.n=Nnodes;
01247  SelectDlgList.list=ItemList;
01248  SelectDlgList.title=title;
01249  SelectDlgList.maxlen=maxlen;
01250  SelectDlgList.NpList=NpList;
01251  id=DialogBoxParam(ghinst_main,MAKEINTRESOURCE(DLG_SELECT),parent,
01252                    (DLGPROC)ActorListDlgProc,(LPARAM)&SelectDlgList);
01253 // id=SelectScrolledItemList(Nnodes,ItemList,title,FALSE,parent);
01254  if(id != FAIL && with_sky == NO && NpList[id]->type == SKY){
01255    MessageBeep(MB_OK);
01256    goto TRYAGAIN;
01257  }
01258  if(id == FAIL || (with_sky == NO && NpList[id]->type == SKY)){
01259    for(i=0;i<Nnodes;i++)X__Free(ItemList[i]);
01260    X__Free(ItemList);
01261    X__Free(NpList);
01262    return NULL;
01263  }
01264  strcpy(NodeName,ItemList[id]);
01265  Np=NpList[id];
01266  for(i=0;i<Nnodes;i++)X__Free(ItemList[i]);
01267  X__Free(ItemList);
01268  X__Free(NpList);
01269  return Np;
01270 }
01271 
01272 void CentreDialogOnCursor(HWND hwnd){
01273  RECT rcDlg;
01274  POINT p;
01275  GetCursorPos(&p);
01276  GetWindowRect(hwnd,&rcDlg);
01277  OffsetRect(&rcDlg,-rcDlg.left,-rcDlg.top);
01278  OffsetRect(&rcDlg,p.x-rcDlg.right/2,p.y-rcDlg.bottom/2);
01279  if(rcDlg.left < 0)OffsetRect(&rcDlg,-rcDlg.left,0);
01280  if(rcDlg.top  < 0)OffsetRect(&rcDlg,0,-rcDlg.top);
01281  if(rcDlg.right  > Xres)OffsetRect(&rcDlg,Xres-rcDlg.right,0);
01282  if(rcDlg.bottom > Yres)OffsetRect(&rcDlg,0,Yres-rcDlg.bottom);
01283  SetWindowPos(hwnd,HWND_TOP,rcDlg.left,rcDlg.top,0,0,SWP_NOSIZE);
01284  return;
01285 }
01286 
01287 void CentreDialogOnScreen(HWND hWnd){
01288  RECT rc;
01289  GetWindowRect(hWnd, &rc);
01290  SetWindowPos(hWnd, NULL,
01291     (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left)) / 2,
01292     (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top)) / 2,
01293     0, 0, SWP_NOSIZE | SWP_NOZORDER);
01294 }
01295 
01296 void AppendFileExtension(char *filename, char *ext){
01297  if(strrchr(filename,'.') == NULL){
01298    strcat(filename,ext);
01299  }
01300 }
01301 
01302 char *short_form(char *filename){
01303  char *sps,*spc;
01304  sps=spc=filename;
01305  while((spc=strchr(spc,'\\')) != NULL){spc++; sps=spc;}
01306  return sps;
01307 }
01308 
01309 char *truncate_path(char *name, int n){
01310  static char compressed_path[256],newname[256];
01311  char *lp;
01312  int i,l;
01313  strcpy(newname,name);
01314  *short_form(newname) = '\0';
01315  if((l=strlen(newname)) == 0)return newname;
01316  if(strlen(newname) > n){
01317    strnset(compressed_path,'\0',255);
01318    strncpy(compressed_path,newname,3);
01319    strcat(compressed_path,"...");
01320    lp=strrchr(newname,'\\');
01321    if(lp != NULL)strcat(compressed_path,lp);
01322  }
01323  else strcpy(compressed_path,newname);
01324  AnsiLower(compressed_path);
01325  return compressed_path;
01326 }
01327 
01328 
Generated on Tue Jan 28 06:18:27 2014 for OpenFX by  doxygen 1.6.3