00001
00002
00003
00004
00005
00006
00007
00008 #define MODULE_SCRIPT 1
00009
00010 #include "animate.h"
00011 #include "spin_dll.h"
00012
00013 static short CreatePathObject(short action, node *Np, object *tempobj,
00014 long firstframe, long lastframe);
00015 static short SetupTimeLineEndPoints(short current, short *ff, short *lf,
00016 short *type,short line, HWND parent);
00017 static void SetFollowAtOptions(position *, HWND);
00018 static short EditEndPoints(short type, object *vp, position *pp, align *ap);
00019 static void ChangeSizeEndPoints(node *Np, short frame, short code);
00020 static void ChangeAlignEndPoints(node *, short, short, HWND, int);
00021 static void ChangePositionEndPoints(node *, short, short, HWND ,int);
00022 static short EditObjectTimeline(node *Np, short frame, short code,
00023 short in_script);
00024 static void CopyObject(node *Np, short firstframe, short lastframe);
00025 static void CutOutObject(node *Np, short frame);
00026 static void CutOutPosition(node *Np, short frame);
00027 static void CutOutAlign(node *Np, short frame);
00028 static node *LoadStandinModel(short *nmodels, char *title, char *command);
00029 static LRESULT CALLBACK TimelineEditorWndProc(HWND hwnd, UINT msg,
00030 WPARAM wparam, LPARAM lparam );
00031 static LRESULT CALLBACK TimelineChildWndProc(HWND hwnd, UINT msg,
00032 WPARAM wparam, LPARAM lparam );
00033 static LRESULT CALLBACK pTimeLineEditDlgProc(HWND hwnd, UINT msg,
00034 WPARAM wparam, LPARAM lparam);
00035 static LRESULT CALLBACK rTimeLineEditDlgProc(HWND hwnd, UINT msg,
00036 WPARAM wparam, LPARAM lparam);
00037 static LRESULT CALLBACK DlgCommandDlgProc(HWND hwnd, UINT msg,
00038 WPARAM wparam, LPARAM lparam);
00039 static LRESULT CALLBACK ReorderDlgProc(HWND hwnd, UINT msg,
00040 WPARAM wParam, LPARAM lParam);
00041 static int GetPresets(int nPresets);
00042 static BOOL BuildFromPreset(int action);
00043 static void FreePresets(void);
00044
00045 static point Cube[8]={ UNIT, UNIT,-UNIT,
00046 -UNIT, UNIT,-UNIT,
00047 -UNIT,-UNIT,-UNIT,
00048 UNIT,-UNIT,-UNIT,
00049 UNIT, UNIT, UNIT,
00050 -UNIT, UNIT, UNIT,
00051 -UNIT,-UNIT, UNIT,
00052 UNIT,-UNIT, UNIT};
00053 static point Disk[8]={ UNIT, UNIT,-UNIT/10,
00054 -UNIT, UNIT,-UNIT/10,
00055 -UNIT,-UNIT,-UNIT/10,
00056 UNIT,-UNIT,-UNIT/10,
00057 UNIT, UNIT, UNIT/10,
00058 -UNIT, UNIT, UNIT/10,
00059 -UNIT,-UNIT, UNIT/10,
00060 UNIT,-UNIT, UNIT/10};
00061
00062
00063
00064 node *AddOnlyNewNode(HWND hWnd, long action){
00065 node *Np;
00066 object *Op;
00067 #if __DEMO__
00068 if(Nnodes >= 10){
00069 MessageBox(NULL,"Only 10 actors allowed in demo","Demo",MB_OK);
00070 return NULL;
00071 }
00072 #endif
00073 if((Np=CreateNode()) != NULL){
00074 if(action < 0){
00075 EnableToolPannels(ALL_PANNELS,FALSE);
00076 action=(long)DialogBoxParam(ghinst_main,MAKEINTRESOURCE(DLG_ADDACTOR),hWnd,
00077 (DLGPROC)SelectActorDlgProc,(LPARAM)Np);
00078 EnableToolPannels(ALL_PANNELS,TRUE);
00079 }
00080 if(action == FAIL)strcpy(Np->actorname,"FAIL");
00081 if((action == GROUND && Nground > 0) ||
00082 (action == 7 && Nskys > 0) ||
00083 (action == 11 && Ndirectors > 0)
00084 ){
00085 SendPrgmQuery(IDQ_ONLYONEALLOWED,0);
00086 action = FAIL;
00087 }
00088 if(action == GROUND)Nground=1;
00089 if(action == 8)Nrobots++;
00090 if(action == 7)Nskys=1;
00091 if(action == 11)Ndirectors=1;
00092 if(action < 0){
00093 DeleteNode(Np);
00094 Np=NULL;
00095 }
00096 else if(action == 6)Np->type = PARTICLE;
00097 else if(action == 7)Np->type = SKY;
00098 else if(action == 8)Np->type = ROBOT;
00099 else if(action == 9){
00100 Np->type = CAMERA;
00101 if((Op=CreateCostume(Np,1,(short)Nframes)) == NULL){
00102 DeleteNode(Np);
00103 Np=NULL;
00104 }
00105 else{
00106 Ncameras++;
00107 Op->type=Np->type;
00108 Np->fobj->morph=NO;
00109 }
00110 }
00111 else if(action == 10)Np->type = IMAGEP;
00112 else if(action == 11)Np->type = DIRECTOR;
00113 else Np->type = action;
00114 }
00115 return Np;
00116 }
00117
00118 void AddQuickActor(long command){
00119 long action;
00120 node *local_node;
00121 Save_UndoA();
00122 if(command < 0){
00123 local_node=AddOnlyNewNode(ghwnd_main,-1);
00124 }
00125 else{
00126 action=NORMAL;
00127 switch (command){
00128 case IDM_ACTOR_QADD_MOD: action=NORMAL; break;
00129 case IDM_ACTOR_QADD_MORPH: action=ANIMOBJ; break;
00130 case IDM_ACTOR_QADD_CAMERA: action=9; break;
00131 case IDM_ACTOR_QADD_TARGET: action=TARGET; break;
00132 case IDM_ACTOR_QADD_LIGHT: action=LIGHT; break;
00133 case IDM_ACTOR_QADD_PATH: action=PATH; break;
00134 case IDM_ACTOR_QADD_SKY: action=7; break;
00135 case IDM_ACTOR_QADD_GROUND: action=GROUND; break;
00136 case IDM_ACTOR_QADD_XIP: action=10; break;
00137 case IDM_ACTOR_QADD_ROBOT: action=8; break;
00138 case IDM_ACTOR_QADD_CSG: action=6; break;
00139 case IDM_ACTOR_QADD_DIRECTOR: action=11; break;
00140 }
00141 local_node=AddOnlyNewNode(ghwnd_main,action);
00142 if(local_node != NULL){
00143 char tchBuf[64];
00144 long i,tc;
00145 strcpy(local_node->actorname,"Actor");
00146 if (local_node->type == GROUND)
00147 sprintf(tchBuf,"%s",ObjectTypeList[3]);
00148 else if(local_node->type == SKY)
00149 sprintf(tchBuf,"%s",ObjectTypeList[7]);
00150 else if(local_node->type == DIRECTOR)
00151 sprintf(tchBuf,"%s",ObjectTypeList[11]);
00152 else{
00153 node *nnp;
00154 tc=1;
00155 nnp=FirstNp; while(nnp != NULL){
00156 if(local_node != nnp && local_node->type == nnp->type)tc++;
00157 nnp=nnp->next;
00158 }
00159 if (local_node->type == NORMAL)i=0;
00160 else if(local_node->type == PATH)i=1;
00161 else if(local_node->type == TARGET)i=2;
00162 else if(local_node->type == LIGHT)i=4;
00163 else if(local_node->type == ANIMOBJ)i=5;
00164 else if(local_node->type == PARTICLE)i=6;
00165 else if(local_node->type == ROBOT)i=8;
00166 else if(local_node->type == CAMERA)i=9;
00167 else if(local_node->type == IMAGEP)i=10;
00168 sprintf(tchBuf,"%s%d",ObjectTypeList[i],tc);
00169 }
00170 strcpy(local_node->actorname,tchBuf);
00171 }
00172 }
00173 if(local_node != NULL){
00174 position *localpp;
00175 if(local_node->type != SKY &&
00176 local_node->type != IMAGEP &&
00177 local_node->type != DIRECTOR &&
00178 (localpp=CreatePosition(local_node,1,Nframes)) != NULL){
00179 localpp->type=SPLINE;
00180 localpp->finish[0]=NpointerX;
00181 localpp->finish[1]=NpointerY;
00182 localpp->finish[2]=NpointerZ;
00183 if(local_node->type != TARGET){
00184 CreateAlign(local_node,1,Nframes);
00185 CreateSize(local_node,1,Nframes);
00186 }
00187 }
00188 if(local_node->type != CAMERA){
00189 if(AddCostumeTimeLine(local_node) == FAIL){
00190 if(local_node->type == GROUND)Nground=0;
00191 if(local_node->type == SKY)Nskys=0;
00192 if(local_node->type == DIRECTOR)Ndirectors=0;
00193 if(local_node->type == ROBOT)Nrobots--;
00194 DeleteNode(local_node);
00195 local_node=NULL;
00196 }
00197 }
00198 if( local_node != NULL &&
00199 (local_node->type == CAMERA || local_node->type == LIGHT)){
00200
00201 object *Op;
00202 CreateNode();
00203
00204 sprintf(MainNp->actorname,"Target(%s)",local_node->actorname);
00205 MainNp->type=TARGET;
00206 Op=CreateCostume(MainNp,1,(short)Nframes);
00207 Op->type=MainNp->type;
00208 local_node->fali->type=TRACK;
00209 local_node->fali->topath=MainNp;
00210 localpp=CreatePosition(MainNp,1,Nframes);
00211 MainNp->fpos->finish[0]=local_node->fpos->finish[0];
00212 MainNp->fpos->finish[1]=local_node->fpos->finish[1]+TVsizeY/4;
00213 MainNp->fpos->finish[2]=local_node->fpos->finish[2]-TVsizeZ/4;
00214 MainNp->fpos->type=SPLINE;
00215 }
00216 ReDrawStageDisplay(TRUE);
00217 if(ghwndOpenGLview == NULL)PerspectiveView(0,1);
00218 else UpdateGLview(TRUE);
00219 UPDATETIMELINES(IDC_TIMEL_UPDATE)
00220 }
00221 }
00222
00223
00224 short GetTimeGapAtFrame(node *Np, long frame,
00225 short *start_gap, short *end_gap){
00226 object *Op,*Op1=NULL;
00227 sky *Sp,*Sp1=NULL;
00228 director *Dp,*Dp1=NULL;
00229 if(Np == NULL)return FAIL;
00230 if(Np->type == SKY){
00231 if((Sp=Np->fsky) != NULL)while(Sp != NULL){
00232 if(frame < Sp->firstframe){
00233 *end_gap=Sp->firstframe-1;
00234 if(Sp->last != NULL)*start_gap=Sp->last->lastframe+1;
00235 else *start_gap=1;
00236 return OK;
00237 }
00238 Sp1=Sp;
00239 Sp=Sp->next;
00240 }
00241 *end_gap=Nframes;
00242 if(Sp1 != NULL)*start_gap=Sp1->lastframe+1;
00243 else *start_gap=1;
00244 return OK;
00245 }
00246 else if(Np->type == DIRECTOR){
00247 if((Dp=Np->fdirector) != NULL)while(Dp != NULL){
00248 if(frame < Dp->firstframe){
00249 *end_gap=Dp->firstframe-1;
00250 if(Dp->last != NULL)*start_gap=Dp->last->lastframe+1;
00251 else *start_gap=1;
00252 return OK;
00253 }
00254 Dp1=Dp;
00255 Dp=Dp->next;
00256 }
00257 *end_gap=Nframes;
00258 if(Dp1 != NULL)*start_gap=Dp1->lastframe+1;
00259 else *start_gap=1;
00260 return OK;
00261 }
00262 else{
00263 if((Op=Np->fobj) != NULL)while(Op != NULL){
00264 if(frame < Op->firstframe){
00265 *end_gap=Op->firstframe-1;
00266 if(Op->last != NULL)*start_gap=Op->last->lastframe+1;
00267 else *start_gap=1;
00268 return OK;
00269 }
00270 Op1=Op;
00271 Op=Op->next;
00272 }
00273 *end_gap=Nframes;
00274 if(Op1 != NULL)*start_gap=Op1->lastframe+1;
00275 else *start_gap=1;
00276 return OK;
00277 }
00278 return FAIL;
00279 }
00280
00281 object *GetObjectAtFrame(node *Np, long frame){
00282 object *Op;
00283 sky *Sp;
00284 director *Dp;
00285 if(Np != NULL){
00286 if(Np->type == SKY){
00287 if((Sp=Np->fsky) != NULL)while(Sp != NULL){
00288 if(frame >= Sp->firstframe && frame <= Sp->lastframe)
00289 return (object *)Sp;
00290 Sp=Sp->next;
00291 }
00292 }
00293 else if(Np->type == DIRECTOR){
00294 if((Dp=Np->fdirector) != NULL)while(Dp != NULL){
00295 if(frame >= Dp->firstframe && frame <= Dp->lastframe)
00296 return (object *)Dp;
00297 Dp=Dp->next;
00298 }
00299 }
00300 else{
00301 if((Op=Np->fobj) != NULL)while(Op != NULL){
00302 if(frame >= Op->firstframe && frame <= Op->lastframe)return Op;
00303 Op=Op->next;
00304 }
00305 }
00306 }
00307 return NULL;
00308 }
00309
00310 void GetTimelinesAtFrame(node *Np, long frame, object **o,
00311 position **p, align **a, size **s){
00312 object *Op;
00313 position *Pp;
00314 align *Ap;
00315 size *Sp;
00316 if(Np == NULL)return;
00317 if(Np->type == SKY)return;
00318 if((Op=Np->fobj) != NULL)while(Op != NULL){
00319 if(frame >= Op->firstframe && frame <= Op->lastframe){
00320 *o = Op; break;
00321 }
00322 Op=Op->next;
00323 }
00324 if((Pp=Np->fpos) != NULL)while(Pp != NULL){
00325 if(frame >= Pp->firstframe && frame <= Pp->lastframe){
00326 *p = Pp; break;
00327 }
00328 Pp=Pp->next;
00329 }
00330 if((Ap=Np->fali) != NULL)while(Ap != NULL){
00331 if(frame >= Ap->firstframe && frame <= Ap->lastframe){
00332 *a = Ap; break;
00333 }
00334 Ap=Ap->next;
00335 }
00336 if((Sp=Np->fsiz) != NULL)while(Sp != NULL){
00337 if(frame >= Sp->firstframe && frame <= Sp->lastframe){
00338 *s = Sp; break;
00339 }
00340 Sp=Sp->next;
00341 }
00342 return;
00343 }
00344
00345 short AddCostumeTimeLine(node *Np){
00346 short ff,lf,retval=FAIL;
00347 point TVC,TVP,TVclipMin,TVclipMax;
00348 if(Np != NULL){
00349 if(GetObjectAtFrame(Np,CurrentFrame) == NULL){
00350 if(GetTimeGapAtFrame(Np,CurrentFrame,&ff,&lf) == OK){
00351 retval=(short)EditObject(Np,ff,lf,NO,NO);
00352 if(Preferences.autocentre &&
00353 !(GetAsyncKeyState(VK_CONTROL) & 0x8000)){
00354 get_centre_stage(TVC,TVP,TVclipMin,TVclipMax);
00355 TVpointX=TVP[0]; TVpointY=TVP[1]; TVpointZ=TVP[2];
00356 TVsizeX=2*(TVC[0]-TVP[0]);
00357 TVsizeY=2*(TVC[1]-TVP[1]);
00358 TVsizeZ=2*(TVC[2]-TVP[2]);
00359 TVcentreX=NpointerX=TVC[0];
00360 TVcentreY=NpointerY=TVC[1];
00361 TVcentreZ=NpointerZ=TVC[2];
00362 GetTriview(FALSE);
00363 }
00364 if(retval == OK){
00365 ReDrawStageDisplay(TRUE);
00366 if(ghwndOpenGLview == NULL)PerspectiveView(0,1);
00367 else UpdateGLview(TRUE);
00368 }
00369 return retval;
00370 }
00371 else{
00372 SendPrgmQuery(IDQ_NOADDTIMELINE,0);
00373 }
00374 }
00375 else if(Np->type == SKY || Np->type == IMAGEP)
00376 retval=EditObject(Np,(short)CurrentFrame,(short)CurrentFrame,NO,NO);
00377 else {
00378 SendPrgmQuery(IDQ_COSTUMEEXISTS,0);
00379 }
00380 }
00381 return retval;
00382 }
00383
00384 short EditObject(node *Np, short firstframe, short lastframe,
00385 short in_script, short split){
00386
00387 sky *tempsky;
00388 director *tempdirector;
00389 object *tempobj;
00390 short action,type,i,n,retval=OK;
00391 HWND hwnd;
00392 struct NP {node *np; short ff,lf;} NP;
00393 struct NC {node *np; object *op,*tp; int d;} NC;
00394
00395 if(in_script)hwnd=ghwndTimeline; else hwnd=ghwnd_main;
00396
00397 if(Np->type == SKY){
00398 tempsky = CreateSky(Np,firstframe,lastframe);
00399 if((tempsky == NULL) && fail_op == NO){
00400 NP.np=Np; NP.ff=firstframe; NP.lf=lastframe;
00401 action=(short)DialogBoxParam(ghinst_main,
00402 MAKEINTRESOURCE(DLG_LINEOPT),hwnd,
00403 (DLGPROC)ObjectTimelineDlgProc,(LPARAM)&NP);
00404 if(action == 0)DeleteSky(Np,firstframe);
00405 else if(action == 1){
00406 if((tempsky=Np->fsky) != NULL)while(tempsky != NULL){
00407 if(firstframe >= tempsky->firstframe &&
00408 firstframe <= tempsky->lastframe){
00409 EditSkyDialog(tempsky,in_script);
00410 break;
00411 }
00412 tempsky=tempsky->next;
00413 }
00414 }
00415 }
00416 else if(tempsky != NULL){
00417 if(EditSkyDialog(tempsky,in_script) < 0){
00418 DeleteSky(Np,firstframe);
00419 retval=FAIL;
00420 }
00421 }
00422 fail_op=NO;
00423 }
00424
00425 else if(Np->type == DIRECTOR){
00426 tempdirector = CreateDirector(Np,firstframe,lastframe);
00427 if((tempdirector == NULL) && fail_op == NO){
00428 NP.np=Np; NP.ff=firstframe; NP.lf=lastframe;
00429 action=(short)DialogBoxParam(ghinst_main,
00430 MAKEINTRESOURCE(DLG_LINEOPT),hwnd,
00431 (DLGPROC)ObjectTimelineDlgProc,(LPARAM)&NP);
00432 if(action == 0)DeleteDirector(Np,firstframe);
00433 else if(action == 1){
00434 if((tempdirector=Np->fdirector) != NULL)while(tempdirector != NULL){
00435 if(firstframe >= tempdirector->firstframe &&
00436 firstframe <= tempdirector->lastframe){
00437 EditDirectorDialog(tempdirector,in_script);
00438 break;
00439 }
00440 tempdirector=tempdirector->next;
00441 }
00442 }
00443 }
00444 else if(tempdirector != NULL){
00445 if(EditDirectorDialog(tempdirector,in_script) < 0){
00446 DeleteDirector(Np,firstframe);
00447 retval=FAIL;
00448 }
00449 }
00450 fail_op=NO;
00451 }
00452
00453 else if(Np->type != CAMERA){
00454 tempobj=CreateCostume(Np,firstframe,lastframe);
00455 if(fail_op == YES)fail_op=NO;
00456 else if((tempobj == NULL) && (firstframe == lastframe)){
00457 NP.np=Np; NP.ff=firstframe; NP.lf=lastframe;
00458 if(Np->type == IMAGEP){
00459 action=EditObjectTimeline(Np,firstframe,0,in_script);
00460 }
00461 else
00462 action=(short)DialogBoxParam(ghinst_main,
00463 MAKEINTRESOURCE(DLG_LINEOPT),hwnd,
00464 (DLGPROC)ObjectTimelineDlgProc,(LPARAM)&NP);
00465 if (action == 0)DeleteCostume(Np,firstframe);
00466 else if(action == 1){
00467 EditObjectTimeline(Np,firstframe,0,in_script);
00468 }
00469 else if(action == 3)
00470 CutOutObject(Np,firstframe);
00471 else if(action == 4)
00472 CopyObject(Np,firstframe,lastframe);
00473 else if(action == 5)
00474 ExportRobotSequence(Np);
00475 else if(action == 6)
00476 SetRobotToWalkPath(Np);
00477 }
00478 else if(tempobj != NULL){
00479 tempobj->type=Np->type;
00480 CheckRecursiveFollow(Np,firstframe,lastframe);
00481 if(Np->type == NORMAL || (Np->type == ANIMOBJ && tempobj->next != NULL)){
00482 if((i=SelectMorphFileName(gszSCEfile,gszSCEdir,"Select Model",
00483 "(*.MFX)|*.mfx|",hwnd)) > 0){
00484 strcpy(tempobj->name,gszSCEfile);
00485 if(i > 3){
00486 i=1;
00487 }
00488 tempobj->morph=(short)(i-1);
00489 if(tempobj->morph < 0){
00490 DeleteCostume(Np,firstframe);
00491 retval=FAIL;
00492 }
00493 else if(LoadMeshObject(tempobj->name,tempobj,YES,YES,NO) == FAIL){
00494 DeleteCostume(Np,firstframe);
00495 retval=FAIL;
00496 }
00497 }
00498 else{
00499 DeleteCostume(Np,firstframe);
00500 retval=FAIL;
00501 }
00502 }
00503 else if(Np->type == ANIMOBJ){
00504 DeleteCostume(Np,firstframe);
00505 LoadAnimObject(Np,firstframe,lastframe,hwnd);
00506 }
00507 else if(Np->type == GROUND){
00508 if(EditGroundDialog(tempobj,in_script) < 0){
00509 DeleteCostume(Np,firstframe);
00510 retval=FAIL;
00511 }
00512 }
00513 else if(Np->type == LIGHT){
00514 tempobj->colour[0]=255; tempobj->colour[1]=255;
00515 tempobj->colour[2]=255; tempobj->lighttype=SPHERE;
00516 if(EditLightDialog(tempobj,(int)in_script) < 0){
00517 DeleteCostume(Np,firstframe);
00518 retval=FAIL;
00519 }
00520 }
00521 else if(Np->type == PATH){
00522 action=(short)DialogBox(ghinst_main,
00523 MAKEINTRESOURCE(DLG_PATHTYPE),
00524 hwnd,(DLGPROC)PathSetDlgProc);
00525 strcpy(tempobj->name,"PATH1995");
00526 if(action < OPEN){
00527 DeleteCostume(Np,firstframe);
00528 retval=FAIL;
00529 }
00530 else CreatePathObject(action,Np,tempobj,firstframe,lastframe);
00531 }
00532 else if(Np->type == PARTICLE){
00533 object temp_obj;
00534 tempobj->lighttype=0; tempobj->groundtype=0; tempobj->groundTemperature=10;
00535 tempobj->colour[0]=255; tempobj->colour[1]=255; tempobj->colour[2]=0;
00536 NC.op=tempobj; NC.tp=&temp_obj; NC.np=Np; NC.d=0;
00537 action=(short)DialogBoxParam(ghinst_main,
00538 MAKEINTRESOURCE(DLG_PARTICLE),
00539 hwnd,(DLGPROC)ParticleDlgProc,(LPARAM)&NC);
00540 if(action < 0 || action == 1){
00541 DeleteCostume(Np,firstframe);
00542 retval=FAIL;
00543 }
00544 else{
00545 for(i=0;i<8;i++){
00546 if(tempobj->lighttype==DISK)CopyPoint(Disk[i],tempobj->outline[i]);
00547 else CopyPoint(Cube[i],tempobj->outline[i]);
00548 }
00549 }
00550 }
00551 else if(Np->type == TARGET){ ; }
00552 else if(Np->type == IMAGEP){
00553 if(in_script)hwnd=ghwndTimeline; else hwnd=ghwnd_main;
00554 if((tempobj->xip=EditObjectImageProcess(hwnd,tempobj->xip)) == NULL){
00555 DeleteCostume(Np,firstframe);
00556 retval=FAIL;
00557 }
00558 tempobj->morph=1;
00559 }
00560 else if(Np->type == ROBOT){
00561 if(in_script)hwnd=ghwndTimeline; else hwnd=ghwnd_main;
00562 if(split && tempobj != NULL && tempobj->next != NULL){
00563 strcpy(gszSCEfile,tempobj->next->name);
00564 strcpy(gszSCEdir,tempobj->next->name);
00565 *FileInPath(gszSCEdir) = '\0';
00566 if(!(GetAsyncKeyState(VK_CONTROL) & 0x8000)){n=1; goto DONT_GET_NEW;}
00567 }
00568 n=1;
00569 if((split && (SelectSfxFileName(0,gszSCEfile,gszSCEdir,IDX_MISC_SELECTROBOT,
00570 "(*.MFX)|*.mfx|",hwnd) == TRUE)) ||
00571 (n=SelectRobotFileName(gszSCEfile,gszSCEdir,IDX_MISC_SELECTROBOT,
00572 "Skeleton or Sequences|*.mfx;*.rsq|"
00573 "(*.MFX)|*.mfx|"
00574 "(*.RSQ)|*.rsq|",hwnd)) != 0){
00575 DONT_GET_NEW:
00576 strcpy(tempobj->name,gszSCEfile);
00577 tempobj->morph=0;
00578
00579
00580
00581
00582
00583 {
00584 if(n < 0){
00585 i=ImportRobotSequence(n*(-1),Np,gszRSQfile,firstframe,lastframe);
00586 }
00587 else if(n < 2){
00588 i=LoadMeshObject(tempobj->name,tempobj,YES,YES,YES);
00589 }
00590 else {
00591 long dura,step,lastf;
00592
00593 dura=lastframe-firstframe+1;
00594 step=dura/n;
00595 if(step < 1)n=1;
00596 DeleteCostume(Np,firstframe);
00597 for(i=0;i<n;i++){
00598 if(i == n-1)lastf=lastframe;
00599 else lastf=firstframe+step-1;
00600 tempobj=CreateCostume(Np,firstframe,lastf);
00601 if(fail_op == YES){ i=OK; split=0; fail_op=NO; retval=FAIL; break;}
00602 strcpy(tempobj->name,gszSCEfile);
00603 tempobj->morph=0;
00604 if(LoadMeshObject(tempobj->name,tempobj,YES,YES,YES) == FAIL){
00605 DeleteCostume(Np,firstframe);
00606 i=OK; split=0; retval=FAIL;
00607 break;
00608 }
00609 firstframe=lastf+1;
00610 }
00611 }
00612 if(i == FAIL){
00613 DeleteCostume(Np,firstframe);
00614 retval=FAIL;
00615 }
00616 else if(split){
00617 object *Opl,*Opn;
00618 if(tempobj != NULL && (Opl=tempobj->last) != NULL
00619 && (Opn=tempobj->next) != NULL){
00620 double mr;
00621 mr=(double)(Opn->lastframe - firstframe+1);
00622 mr=(double)(lastframe - firstframe+1)/mr;
00623 if((n=tempobj->nskeleton) == Opn->nskeleton &&
00624 tempobj->skeleton != NULL && Opn->skeleton != NULL){
00625 InterpolateRobot(mr,Opn,Opl);
00626 for(i=0;i<n;i++){
00627 c4to4((Opn->skeleton+i)->Q,(tempobj->skeleton+i)->R);
00628 }
00629 }
00630 }
00631 }
00632 }
00633 }
00634 else{
00635 DeleteCostume(Np,firstframe);
00636 retval=FAIL;
00637 }
00638 }
00639 }
00640 }
00641 UpdateSelectedActor(FALSE);
00642 return retval;
00643 }
00644
00645 static short CreatePathObject(short action, node *Np, object *tempobj,
00646 long firstframe, long lastframe){
00647 int i;
00648 tempobj->firstpathpoint=CreateIPointPath(action,Np,(short)firstframe,
00649 &(tempobj->pathtype),&(tempobj->npathpoints));
00650 if(tempobj->firstpathpoint != NULL){
00651 tempobj->origin[0]=0;
00652 tempobj->origin[1]=0;
00653 tempobj->origin[2]=0;
00654 tempobj->pathlength=PathLength(tempobj->firstpathpoint
00655 ,tempobj->pathtype
00656 ,tempobj->npathpoints);
00657 i=tempobj->lastframe - tempobj->firstframe + 1;
00658 tempobj->v=ReTweenVelocity(tempobj,NULL,i,i,tempobj->pathlength,0);
00659 return 0;
00660 }
00661 DeleteCostume(Np,firstframe);
00662 return -1;
00663 }
00664
00665 void MakeKey(char com, long frame, node *np){
00666 position *Pp,*tempPp;
00667 align *Ap,*tempAp;
00668 size *Xp,*tempXp;
00669 double ratio,sx,sy,sz,ddp,phi,theta,alpha,kx[4],ky[4],kz[4];
00670 point Offset,dp,spl,spn;
00671 short ff;
00672 if(np == NULL){
00673 SendPrgmQuery(IDQ_OLD1,0);
00674 }
00675 else if(com == 'P'){
00676 if((Pp=np->fpos) != NULL)while(Pp != NULL){
00677 if(frame >= Pp->firstframe && frame < Pp->lastframe){
00678 if((Pp->last == NULL) || (Pp->firstframe == Pp->lastframe))
00679 CopyPoint(Pp->finish,Offset);
00680 else{
00681 ratio=(double)(frame+1 - Pp->firstframe)
00682 /(double)(Pp->lastframe+1 - Pp->firstframe);
00683 if(Pp->type == TWEEN || Pp->type == FOLLOWAT){
00684 SubPoints(Pp->finish,Pp->last->finish,dp);
00685 ScalePoint(ratio,ratio,ratio,dp,dp);
00686 AddPoints(Pp->last->finish,dp,Offset);
00687 }
00688 else{
00689 if(Pp->last->last != NULL)CopyPoint(Pp->last->last->finish,spl);
00690 else{
00691 SubPoints(Pp->finish,Pp->last->finish,dp);
00692 SubPoints(Pp->last->finish,dp,spl);
00693 }
00694 if(Pp->next != NULL)CopyPoint(Pp->next->finish,spn);
00695 else{
00696 SubPoints(Pp->finish,Pp->last->finish,dp);
00697 AddPoints(Pp->finish,dp,spn);
00698 }
00699 SplinesK(kx,spl[0],Pp->last->finish[0],Pp->finish[0],spn[0]);
00700 SplinesK(ky,spl[1],Pp->last->finish[1],Pp->finish[1],spn[1]);
00701 SplinesK(kz,spl[2],Pp->last->finish[2],Pp->finish[2],spn[2]);
00702 Offset[0] = SplinesP(kx,ratio);
00703 Offset[1] = SplinesP(ky,ratio);
00704 Offset[2] = SplinesP(kz,ratio);
00705 }
00706 }
00707 ff=Pp->firstframe;
00708 Pp->firstframe=frame+1;
00709 tempPp=CreatePosition(np,ff,(short)frame);
00710 if(tempPp == NULL){
00711 Pp->firstframe=ff;
00712 return;
00713 }
00714 tempPp->type = Pp->type;
00715 CopyPoint(Offset,tempPp->finish);
00716 tempPp->onpath=Pp->onpath;
00717 tempPp->tension_s=Pp->tension_s;
00718 tempPp->tension_e=Pp->tension_e;
00719 goto MADEKEY;
00720 }
00721 Pp=Pp->next;
00722 }
00723 SendPrgmQuery(IDQ_NOADDKEY,0);
00724 }
00725 else if(com == 'Z'){
00726 if((Xp=np->fsiz) != NULL)while(Xp != NULL){
00727 if(frame >= Xp->firstframe && frame < Xp->lastframe){
00728 if(Xp->last == NULL){
00729 sx=Xp->Sx; sy=Xp->Sy; sz=Xp->Sz;
00730 }
00731 else{
00732 ratio=(double)(frame+1 - Xp->firstframe)
00733 /(double)(Xp->lastframe+1 - Xp->firstframe);
00734 sx = (Xp->Sx - Xp->last->Sx)*ratio + Xp->last->Sx;
00735 sy = (Xp->Sy - Xp->last->Sy)*ratio + Xp->last->Sy;
00736 sz = (Xp->Sz - Xp->last->Sz)*ratio + Xp->last->Sz;
00737 }
00738 ff=Xp->firstframe;
00739 Xp->firstframe=frame+1;
00740 tempXp=CreateSize(np,ff,(short)frame);
00741 if(tempXp == NULL){
00742 Xp->firstframe=ff;
00743 return;
00744 }
00745 tempXp->Sx=sx;
00746 tempXp->Sy=sy;
00747 tempXp->Sz=sz;
00748 if(tempXp->last != NULL)memcpy(&tempXp->camera_params,&(tempXp->last->camera_params),sizeof(cameraparam));
00749 goto MADEKEY;
00750 }
00751 Xp=Xp->next;
00752 }
00753 SendPrgmQuery(IDQ_NOADDKEY,0);
00754 }
00755 else if(com == 'A'){
00756 if((Ap=np->fali) != NULL)while(Ap != NULL){
00757 if(frame >= Ap->firstframe && frame < Ap->lastframe){
00758 if((Ap->last == NULL) || (Ap->firstframe == Ap->lastframe)){
00759 phi=Ap->phi;
00760 theta=Ap->theta;
00761 alpha=Ap->alpha;
00762 }
00763 else{
00764 ratio=(double)(frame+1 - Ap->firstframe)
00765 /(double)(Ap->lastframe+1 - Ap->firstframe);
00766 ddp = Ap->phi - Ap->last->phi;
00767 if(ddp < -180.0)ddp += 360.0;
00768 if(ddp > 180.0)ddp -= 360.0;
00769 ddp *= ratio;
00770 ddp += Ap->last->phi;
00771 if(ddp < -180.0)ddp += 360.0;
00772 if(ddp > 180.0)ddp -= 360.0;
00773 phi = ddp;
00774 ddp = Ap->theta - Ap->last->theta;
00775 if(ddp < -180.0)ddp += 360.0;
00776 if(ddp > 180.0)ddp -= 360.0;
00777 ddp *= ratio;
00778 ddp += Ap->last->theta;
00779 if(ddp < -180.0)ddp += 360.0;
00780 if(ddp > 180.0)ddp -= 360.0;
00781 theta = ddp;
00782 ddp = Ap->alpha - Ap->last->alpha;
00783 if(ddp < -180.0)ddp += 360.0;
00784 if(ddp > 180.0)ddp -= 360.0;
00785 ddp *= ratio;
00786 ddp += Ap->last->alpha;
00787 if(ddp < -180.0)ddp += 360.0;
00788 if(ddp > 180.0)ddp -= 360.0;
00789 alpha = ddp;
00790 }
00791 ff=Ap->firstframe;
00792 Ap->firstframe=frame+1;
00793 tempAp=CreateAlign(np,ff,(short)frame);
00794 if(tempAp == NULL){
00795 Ap->firstframe=ff;
00796 return;
00797 }
00798 tempAp->type=Ap->type;
00799 tempAp->theta=theta;
00800 tempAp->phi=phi;
00801 tempAp->alpha=alpha;
00802 tempAp->im=Ap->im;
00803 tempAp->ima=Ap->ima;
00804 tempAp->topath=Ap->topath;
00805 tempAp->tension_s=Ap->tension_s;
00806 tempAp->tension_e=Ap->tension_e;
00807 goto MADEKEY;
00808 }
00809 Ap=Ap->next;
00810 }
00811 SendPrgmQuery(IDQ_NOADDKEY,0);
00812 }
00813 return;
00814 MADEKEY:
00815 UPDATETIMELINES(IDC_TIMEL_UPDATE)
00816 UpdateSelectedActor(FALSE);
00817 return;
00818 }
00819
00820 void NextKey(char com){
00821 object *Op;
00822 position *Pp;
00823 align *Ap;
00824 size *Xp;
00825 if(com == 'N'){
00826 if(SelectedNode == NULL)goto KEY_ERR;
00827 if(tool == NOTOOL || tool == NODETOOL || tool == SKELETOR){
00828 if((Op=SelectedNode->fobj) != NULL)while(Op != NULL){
00829 if(CurrentFrame < Op->lastframe){
00830 CurrentFrame=Op->lastframe;
00831 goto GOTIT;
00832 }
00833 Op=Op->next;
00834 }
00835 goto KEY_ERR;
00836 }
00837 else if(tool == GRABBER || (tool == TRACKER && subtool == SHIFTER)){
00838 if((Pp=SelectedNode->fpos) != NULL)while(Pp != NULL){
00839 if(CurrentFrame < Pp->lastframe){
00840 CurrentFrame=Pp->lastframe;
00841 goto GOTIT;
00842 }
00843 Pp=Pp->next;
00844 }
00845 goto KEY_ERR;
00846 }
00847 else if(tool == ROTATOR || (tool == TRACKER && subtool == ANGLER)){
00848 if((Ap=SelectedNode->fali) != NULL)while(Ap != NULL){
00849 if(CurrentFrame < Ap->lastframe){
00850 CurrentFrame=Ap->lastframe;
00851 goto GOTIT;
00852 }
00853 Ap=Ap->next;
00854 }
00855 goto KEY_ERR;
00856 }
00857 else if(tool == SIZER){
00858 if((Xp=SelectedNode->fsiz) != NULL)while(Xp != NULL){
00859 if(CurrentFrame < Xp->lastframe){
00860 CurrentFrame=Xp->lastframe;
00861 goto GOTIT;
00862 }
00863 Xp=Xp->next;
00864 }
00865 goto KEY_ERR;
00866 }
00867 else goto KEY_ERR;
00868 }
00869 else if(com == 'L'){
00870 if(SelectedNode == NULL)goto KEY_ERR;
00871 if(tool == NOTOOL || tool == NODETOOL || tool == SKELETOR){
00872 if((Op=SelectedNode->fobj) != NULL)while(Op != NULL){
00873 if(CurrentFrame <= Op->lastframe){
00874 if(Op->last == NULL)goto KEY_ERR;
00875 CurrentFrame=Op->last->lastframe;
00876 goto GOTIT;
00877 }
00878 Op=Op->next;
00879 }
00880 goto KEY_ERR;
00881 }
00882 else if(tool == GRABBER || (tool == TRACKER && subtool == SHIFTER)){
00883 if((Pp=SelectedNode->fpos) != NULL)while(Pp != NULL){
00884 if(CurrentFrame <= Pp->lastframe){
00885 if(Pp->last == NULL)goto KEY_ERR;
00886 CurrentFrame=Pp->last->lastframe;
00887 goto GOTIT;
00888 }
00889 Pp=Pp->next;
00890 }
00891 goto KEY_ERR;
00892 }
00893 else if(tool == ROTATOR || (tool == TRACKER && subtool == ANGLER)){
00894 if((Ap=SelectedNode->fali) != NULL)while(Ap != NULL){
00895 if(CurrentFrame <= Ap->lastframe){
00896 if(Ap->last == NULL)goto KEY_ERR;
00897 CurrentFrame=Ap->last->lastframe;
00898 goto GOTIT;
00899 }
00900 Ap=Ap->next;
00901 }
00902 goto KEY_ERR;
00903 }
00904 else if(tool == SIZER){
00905 if((Xp=SelectedNode->fsiz) != NULL)while(Xp != NULL){
00906 if(CurrentFrame <= Xp->lastframe){
00907 if(Xp->last == NULL)goto KEY_ERR;
00908 CurrentFrame=Xp->last->lastframe;
00909 goto GOTIT;
00910 }
00911 Xp=Xp->next;
00912 }
00913 goto KEY_ERR;
00914 }
00915 else goto KEY_ERR;
00916 }
00917 goto KEY_ERR;
00918 GOTIT:
00919 ReDrawStageDisplay(TRUE);
00920 UpdateSelectedActor(FALSE);
00921 if(ghwndOpenGLview == NULL)PerspectiveView(0,1);
00922 else UpdateGLview(TRUE);
00923
00924 SendMessage(ghwnd_xscl,TBM_SETPOS,TRUE,(LPARAM)CurrentFrame);
00925 return;
00926 KEY_ERR:
00927 MessageBeep(MB_OK);
00928
00929 return;
00930 }
00931
00932 short MakeControl(node *Np, char typ, HWND parent){
00933
00934 short code,nextf,lastf,type;
00935 position *Pp;
00936 align *Ap;
00937 size *Xp;
00938 nextf=Nframes;
00939 lastf=1;
00940 code=FAIL;
00941 if(typ == 'P'){
00942 if((Pp=Np->fpos) != NULL){
00943 if(Np->type == SKY || Np->type == IMAGEP)return OK;
00944 while(Pp != NULL){
00945 if(Pp->firstframe > CurrentFrame){
00946 nextf=Pp->firstframe-1;
00947 break;
00948 }
00949 lastf=Pp->lastframe+1;
00950 Pp=Pp->next;
00951 }
00952 }
00953 EditPosition(Np,lastf,nextf,0,parent); code=OK;
00954 }
00955 if(typ == 'A'){
00956 if(Np->type == PATH || Np->type == SKY || Np->type == TARGET ||
00957 Np->type == IMAGEP)return OK;
00958 if((Ap=Np->fali) != NULL){
00959 while(Ap != NULL){
00960 if(Ap->firstframe > CurrentFrame){
00961 nextf=Ap->firstframe-1;
00962 break;
00963 }
00964 lastf=Ap->lastframe+1;
00965 Ap=Ap->next;
00966 }
00967 }
00968 EditAlign(Np,lastf,nextf,0,parent); code=OK;
00969 }
00970 if(typ == 'Z'){
00971 if(Np->type == PATH || Np->type == SKY || Np->type == TARGET ||
00972 Np->type == IMAGEP)return OK;
00973 if((Xp=Np->fsiz) != NULL){
00974 while(Xp != NULL){
00975 if(Xp->firstframe > CurrentFrame){
00976 nextf=Xp->firstframe-1;
00977 break;
00978 }
00979 lastf=Xp->lastframe+1;
00980 Xp=Xp->next;
00981 }
00982 }
00983 EditSize(Np,lastf,nextf); code=OK;
00984 }
00985 if(code == FAIL){;}
00986 else{
00987 UPDATETIMELINES(IDC_TIMEL_UPDATE)
00988 }
00989 fail_op=NO;
00990 return code;
00991 }
00992
00993 short CheckForControl(node *Np, char typ){
00994 position *Pp;
00995 align *Ap;
00996 size *Xp;
00997 if(typ == 'P'){
00998 if((Pp=Np->fpos) != NULL){
00999 while(Pp != NULL){
01000 if(Pp->firstframe <= CurrentFrame && Pp->lastframe >= CurrentFrame){
01001 return YES;
01002 }
01003 Pp=Pp->next;
01004 }
01005 }
01006 }
01007 if(typ == 'A'){
01008 if((Ap=Np->fali) != NULL){
01009 while(Ap != NULL){
01010 if(Ap->firstframe <= CurrentFrame && Ap->lastframe >= CurrentFrame){
01011 return YES;
01012 }
01013 Ap=Ap->next;
01014 }
01015 }
01016 }
01017 if(typ == 'Z'){
01018 if((Xp=Np->fsiz) != NULL){
01019 while(Xp != NULL){
01020 if(Xp->firstframe <= CurrentFrame && Xp->lastframe >= CurrentFrame){
01021 return YES;
01022 }
01023 Xp=Xp->next;
01024 }
01025 }
01026 }
01027 return NO;
01028 }
01029
01030 void EditPosition(node *Np, short firstframe, short lastframe,
01031 short type, HWND parent){
01032 position *tempposition;
01033 short action;
01034 double x,y,z;
01035 if(Np->type == SKY || Np->type == IMAGEP)return;
01036 tempposition = CreatePosition(Np,firstframe,lastframe);
01037 if(fail_op == YES)fail_op=NO;
01038 else if(tempposition != NULL){
01039 tempposition->type=SPLINE;
01040 ChangePositionEndPoints(Np,firstframe,lastframe,parent,YES);
01041 }
01042 else if(firstframe == lastframe){
01043 ChangePositionEndPoints(Np,firstframe,firstframe,parent,NO);
01044 }
01045 UpdateSelectedActor(FALSE);
01046 return;
01047 }
01048
01049 void EditAlign(node *Np, short firstframe, short lastframe,
01050 short type, HWND parent){
01051 align *tempalign;
01052 short action,dumyi1;
01053 double dr1,dr2,dr3,dr4;
01054 point dumypoint,dp1;
01055 if((Np->type == SKY) || (Np->type == TARGET) ||
01056 (Np->type == PATH)|| (Np->type == IMAGEP))return;
01057 tempalign = CreateAlign(Np,firstframe,lastframe);
01058 if(fail_op == YES)fail_op=NO;
01059 else if(tempalign != NULL){
01060 ChangeAlignEndPoints(Np,firstframe,lastframe,parent,YES);
01061 }
01062 else if(firstframe == lastframe){
01063 ChangeAlignEndPoints(Np,firstframe,firstframe,parent,NO);
01064 }
01065 UpdateSelectedActor(FALSE);
01066 return;
01067 }
01068
01069 void EditSize(node *Np, short firstframe, short lastframe){
01070 size *tempsize;
01071 char string[32];
01072 short action;
01073 double sx,sy,sz;
01074 if( (Np->type == SKY) || (Np->type == TARGET)
01075 || (Np->type == PATH) || (Np->type == IMAGEP))return;
01076 tempsize = CreateSize(Np,firstframe,lastframe);
01077 if(fail_op == YES)fail_op=NO;
01078 else if((tempsize == NULL) && (firstframe == lastframe)){
01079 ChangeSizeEndPoints(Np,firstframe,0);
01080 }
01081 else if(tempsize != NULL){
01082 sx=tempsize->Sx; sy=tempsize->Sy; sz=tempsize->Sz;
01083 if(Np->type == LIGHT){
01084 if(RequestEditLightSize(&sx,&sy,&sz,tempsize,0) < 0){
01085 DeleteSize(Np,firstframe);
01086 return;
01087 }
01088 }
01089 else if(Np->type == CAMERA){
01090 if(EditCameraSize(&sx,&sy,&sz,tempsize,0) < 0){
01091 DeleteSize(Np,firstframe);
01092 return;
01093 }
01094 }
01095 else{
01096 if(RequestEditSize(&sx,&sy,&sz,tempsize,0) < 0){
01097 DeleteSize(Np,firstframe);
01098 return;
01099 }
01100 }
01101 tempsize->Sx=sx; tempsize->Sy=sy; tempsize->Sz=sz;
01102 }
01103 UpdateSelectedActor(FALSE);
01104 return;
01105 }
01106
01107
01108
01109 static node *LoadStandinModel(short *, char *, char *);
01110
01111 static void ChangeSizeEndPoints(node *Np, short frame, short code){
01112 size *tempsize;
01113 char string[24];
01114 short l,f,minf,maxf;
01115 double sx,sy,sz;
01116 int i;
01117 EDIT_ACTION=YES;
01118 if((tempsize = Np->fsiz) != NULL)while(tempsize != NULL){
01119 if(tempsize->firstframe <=frame && tempsize->lastframe >=frame){
01120 if(code == 0){
01121 sx=tempsize->Sx; sy=tempsize->Sy; sz=tempsize->Sz;
01122 if(Np->type == LIGHT){
01123 i=RequestEditLightSize(&sx,&sy,&sz,tempsize,1);
01124 if(i == OK){
01125 tempsize->Sx=sx; tempsize->Sy=sy; tempsize->Sz=sz;
01126 }
01127 else if(i == 2){
01128 DeleteSize(Np,frame);
01129 }
01130 }
01131 else if(Np->type == CAMERA){
01132 i=(int)EditCameraSize(&sx,&sy,&sz,tempsize,1);
01133 if(i == OK){
01134 tempsize->Sx=sx; tempsize->Sy=sy; tempsize->Sz=sz;
01135 }
01136 else if(i == 2){
01137 DeleteSize(Np,frame);
01138 }
01139 }
01140 else{
01141 i=(int)RequestEditSize(&sx,&sy,&sz,tempsize,1);
01142 if(i == OK){
01143 tempsize->Sx=sx; tempsize->Sy=sy; tempsize->Sz=sz;
01144 }
01145 else if(i == 2){
01146 DeleteSize(Np,frame);
01147 }
01148 }
01149 }
01150 break;
01151 }
01152 tempsize=tempsize->next;
01153 }
01154 else{
01155 SendPrgmQuery(IDQ_SYNTAXERROR,0);
01156 }
01157 }
01158
01159 static void ChangeAlignEndPoints(node *Np, short ff, short lf,
01160 HWND parent,int new){
01161 int i;
01162 align *Op,Align;
01163 struct NP {node *np; align *ap; int new;} NP;
01164 if((Op=Np->fali) != NULL)while(Op != NULL){
01165 if(Op->firstframe <= ff && Op->lastframe >= lf){
01166 memcpy(&Align,Op,sizeof(align));
01167 NP.np=Np; NP.ap= &Align; NP.new=new;
01168 if((i=(int)DialogBoxParam(ghinst_main,MAKEINTRESOURCE(DLG_TLER),parent,
01169 (DLGPROC)rTimeLineEditDlgProc,(LPARAM)&NP)) >= 0){
01170 EDIT_ACTION=YES;
01171 if(i == 1)DeleteAlign(Np,lf);
01172 else if(i == 2)CutOutAlign(Np,lf);
01173 else memcpy(Op,&Align,sizeof(align));
01174 }
01175 else if(new == YES){
01176 DeleteAlign(Np,lf);
01177 }
01178 CheckRecursiveFollow(Np,Op->firstframe,Op->lastframe);
01179 return;
01180 }
01181 Op=Op->next;
01182 }
01183 }
01184
01185 static void ChangePositionEndPoints(node *Np, short ff, short lf,
01186 HWND parent, int new){
01187 int i;
01188 position *Op,Position;
01189 struct NP {node *np; position *pp; int new;} NP;
01190 if((Op=Np->fpos) != NULL)while(Op != NULL){
01191 if(Op->firstframe <= ff && Op->lastframe >= lf){
01192 memcpy(&Position,Op,sizeof(position));
01193 NP.np=Np; NP.pp= &Position; NP.new=new;
01194 if((i=(int)DialogBoxParam(ghinst_main,MAKEINTRESOURCE(DLG_TLEP),parent,
01195 (DLGPROC)pTimeLineEditDlgProc,(LPARAM)&NP)) >= 0){
01196 EDIT_ACTION=YES;
01197 if(i == 1)DeletePosition(Np,lf);
01198 else if(i == 2)CutOutPosition(Np,lf);
01199 else memcpy(Op,&Position,sizeof(position));
01200 }
01201 else if(new == YES){
01202 DeletePosition(Np,lf);
01203 }
01204 CheckRecursiveFollow(Np,Op->firstframe,Op->lastframe);
01205 return;
01206 }
01207 Op=Op->next;
01208 }
01209 }
01210
01211 static short EditObjectTimeline(node *Np, short frame, short code,
01212 short in_script){
01213 object *Op;
01214 char string[10];
01215 short f,l,minf,maxf,oldff,oldlf,action=-1,action1;
01216 double ref;
01217 HWND hwnd;
01218 EDIT_ACTION=YES;
01219 if(in_script)hwnd=ghwndTimeline; else hwnd=ghwnd_main;
01220 if((Op=Np->fobj) != NULL)while(Op != NULL){
01221 if(Op->firstframe <= frame && Op->lastframe >= frame){
01222 oldff=Op->firstframe; oldlf=Op->lastframe;
01223 if(Op->type == NORMAL || Op->type == ANIMOBJ){
01224 action=(short)DialogBoxParam(ghinst_main,MAKEINTRESOURCE(DLG_COSTUME),
01225 hwnd,(DLGPROC)EditObjectDlgProc,(LPARAM)Op);
01226 }
01227 else if(Op->type == GROUND){
01228 if(EditGroundDialog(Op,YES) < 0){;}
01229 }
01230 else if(Op->type == LIGHT){
01231 if(EditLightDialog(Op,YES) < 0){;}
01232 }
01233 else if(Op->type == IMAGEP){
01234 action=(short)DialogBoxParam(ghinst_main,MAKEINTRESOURCE(DLG_COSTUMEXIP),
01235 hwnd,(DLGPROC)EditObjectXipDlgProc,(LPARAM)Op);
01236 }
01237 else if(Op->type == PARTICLE){
01238 struct NC {node *np; object *op,*tp; int d;} NC;
01239 object temp_obj;
01240 NC.op=Op; NC.tp=&temp_obj; NC.np=Np; NC.d=1;
01241 action=(short)DialogBoxParam(ghinst_main,
01242 MAKEINTRESOURCE(DLG_PARTICLE),
01243 hwnd,(DLGPROC)ParticleDlgProc,(LPARAM)&NC);
01244 if(action == 1){
01245 DeleteCostume(Np,frame);
01246 }
01247 }
01248
01249
01250 CheckRecursiveFollow(Np,Op->firstframe,Op->lastframe);
01251 return action;
01252 }
01253 Op=Op->next;
01254 }
01255 return action;
01256 }
01257
01258 static void CopyObject(node *Np, short firstframe, short lastframe){
01259 object *Op,*tempobj,*lastobj;
01260 pathpoint *Ppp,*Qpp;
01261 short endframe,newstart,newend,i;
01262 long sks;
01263 lastobj=NULL;
01264 EDIT_ACTION=YES;
01265 if((Op=Np->fobj) != NULL)while(Op != NULL){lastobj=Op; Op=Op->next; }
01266 if(lastobj == NULL || lastobj->lastframe >= Nframes){
01267 SendPrgmQuery(IDQ_NOCOPYSPACE,0);
01268 }
01269 else if((Op=Np->fobj) != NULL){
01270 endframe=lastobj->lastframe;
01271 while(Op != NULL && Op->firstframe <= lastframe){
01272 if(Op->lastframe >= firstframe){
01273 newstart= endframe+1;
01274 newend = newstart+(Op->lastframe-Op->firstframe);
01275 if(newend > Nframes)newend=Nframes;
01276 tempobj=CreateCostume(Np,newstart,newend);
01277 if(tempobj == NULL){
01278 SendPrgmQuery(IDQ_COPYFAIL,0);
01279 break;
01280 }
01281 strcpy(tempobj->name,Op->name);
01282 tempobj->morph=Op->morph;
01283 tempobj->morphNo=Op->morphNo;
01284 if(Op->effect != NULL){
01285 tempobj->effect=(char *)X__Malloc(strlen(Op->effect)+1);
01286 strncpy(tempobj->effect,Op->effect,strlen(Op->effect)+1);
01287 }
01288 if(Op->xip != NULL){
01289 tempobj->xip=(char *)X__Malloc(strlen(Op->xip)+1);
01290 strncpy(tempobj->xip,Op->xip,strlen(Op->xip)+1);
01291 }
01292 tempobj->hEffect=Op->hEffect;
01293 strcpy(tempobj->effectname,Op->effectname);
01294 tempobj->type=Op->type;
01295 tempobj->quick_only=Op->quick_only;
01296 tempobj->fileID=Op->fileID;
01297 tempobj->in_ram=Op->in_ram;
01298 tempobj->bWireframe=Op->bWireframe;
01299 tempobj->points=Op->points;
01300 tempobj->edges=Op->edges;
01301 tempobj->nedges=Op->nedges;
01302 tempobj->npoints=Op->npoints;
01303 tempobj->w_frame.Np=Op->w_frame.Np;
01304 tempobj->w_frame.Ne=Op->w_frame.Ne;
01305 tempobj->w_frame.p=Op->w_frame.p;
01306 tempobj->w_frame.e=Op->w_frame.e;
01307 tempobj->nNurbs=Op->nNurbs;
01308 tempobj->Nurbs=Op->Nurbs;
01309 tempobj->bIKchain=Op->bIKchain;
01310 if(Op->nskeleton > 0){
01311 sks=(long)(Op->nskeleton)*(long)sizeof(skel);
01312 if((tempobj->skeleton=(skel *)X__Malloc(sks)) != NULL){
01313 tempobj->nskeleton = Op->nskeleton;
01314 memcpy(tempobj->skeleton,Op->skeleton,sks);
01315 }
01316 else{
01317 tempobj->nskeleton=0;
01318 }
01319 }
01320 tempobj->skid=Op->skid;
01321 CopyPoint(Op->origin,tempobj->origin);
01322 CopyPoint(Op->offset,tempobj->offset);
01323 for(i=0;i<8;i++){
01324 CopyPoint(Op->outline[i],tempobj->outline[i]);
01325 }
01326 tempobj->groundtype=Op->groundtype;
01327 tempobj->groundTemperature=Op->groundTemperature;
01328 tempobj->lighttype=Op->lighttype;
01329 tempobj->light_intensity=Op->light_intensity;
01330 tempobj->depth_cue=Op->depth_cue;
01331 tempobj->depth_cue_c=Op->depth_cue_c;
01332 tempobj->depth_cue_l=Op->depth_cue_l;
01333 tempobj->depth_cue_q=Op->depth_cue_l;
01334 tempobj->self_shadow=Op->self_shadow;
01335 tempobj->cast_shadow=Op->cast_shadow;
01336 tempobj->show_shadow=Op->show_shadow;
01337 tempobj->colour[0]=Op->colour[0];
01338 tempobj->acolour[0]=Op->acolour[0];
01339 tempobj->colour[1]=Op->colour[1];
01340 tempobj->acolour[1]=Op->acolour[1];
01341 tempobj->colour[2]=Op->colour[2];
01342 tempobj->acolour[2]=Op->acolour[2];
01343 tempobj->pathtype=Op->pathtype;
01344 tempobj->npathpoints=Op->npathpoints;
01345 tempobj->pathlength=Op->pathlength;
01346 tempobj->gspec=Op->gspec;
01347 tempobj->gtran=Op->gtran;
01348 tempobj->grefl=Op->grefl;
01349 tempobj->gbump=Op->gbump;
01350 if(Op->npathpoints > 0)
01351 for(i=0,Ppp=NULL,Qpp=Op->firstpathpoint;i<Op->npathpoints;i++){
01352 if(((Ppp=AppendPathPoint(Ppp)) != NULL) && Qpp != NULL){
01353 if(i == 0)tempobj->firstpathpoint=Ppp;
01354 Ppp->status=Qpp->status;
01355 CopyPoint(Qpp->p,Ppp->p);
01356 Ppp->distance=Qpp->distance;
01357 Ppp->ptheta=Qpp->ptheta;
01358 Ppp->pfi=Qpp->pfi;
01359 Ppp->tension_n=Qpp->tension_n;
01360 Ppp->tension_p=Qpp->tension_p;
01361 Qpp=Qpp->next;
01362 }
01363 }
01364 tempobj->pec=NULL;
01365 tempobj->npec=0;
01366 if(Op->v != NULL){
01367 tempobj->v=ReTweenVelocity(Op,Op->v,
01368 (int)(Op->lastframe-Op->firstframe+1),
01369 (int)(tempobj->lastframe-tempobj->firstframe+1),
01370 Op->pathlength,1);
01371 }
01372 memcpy(&(tempobj->particles),&(Op->particles),sizeof(ParticleSystem));
01373 endframe=newend;
01374 CheckRecursiveFollow(Np,newstart,newend);
01375 if(newend == Nframes){
01376 SendPrgmQuery(IDQ_NOCOPYSPACE,0);
01377 break;
01378 }
01379 }
01380 Op=Op->next;
01381 }
01382 }
01383 }
01384
01385 static void CutOutObject(node *Np, short frame){
01386 object *Op,*Op1;
01387 short ff,lf,df;
01388 EDIT_ACTION=YES;
01389 if((Op=Np->fobj) != NULL)while(Op != NULL){
01390 if((ff=Op->firstframe) <= frame && (lf=Op->lastframe) >= frame){
01391 df=Op->lastframe - Op->firstframe+1;
01392 Op1=Op->next;
01393 DeleteCostume(Np,frame);
01394 while(Op1 != NULL){
01395 Op1->firstframe -= df;
01396 Op1->lastframe -= df;
01397 CheckRecursiveFollow(Np,Op1->firstframe,Op1->lastframe);
01398 Op1=Op1->next;
01399 }
01400 return;
01401 }
01402 Op=Op->next;
01403 }
01404 }
01405
01406 static void CutOutPosition(node *Np, short frame){
01407 position *Op,*Op1;
01408 short ff,lf,df;
01409 EDIT_ACTION=YES;
01410 if((Op=Np->fpos) != NULL)while(Op != NULL){
01411 if((ff=Op->firstframe) <= frame && (lf=Op->lastframe) >= frame){
01412 df=Op->lastframe - Op->firstframe+1;
01413 Op1=Op->next;
01414 DeletePosition(Np,frame);
01415 while(Op1 != NULL){
01416 Op1->firstframe -= df;
01417 Op1->lastframe -= df;
01418 CheckRecursiveFollow(Np,Op1->firstframe,Op1->lastframe);
01419 Op1=Op1->next;
01420 }
01421 return;
01422 }
01423 Op=Op->next;
01424 }
01425 }
01426
01427 static void CutOutAlign(node *Np, short frame){
01428 align *Op,*Op1;
01429 short ff,lf,df;
01430 EDIT_ACTION=YES;
01431 if((Op=Np->fali) != NULL)while(Op != NULL){
01432 if((ff=Op->firstframe) <= frame && (lf=Op->lastframe) >= frame){
01433 df=Op->lastframe - Op->firstframe+1;
01434 Op1=Op->next;
01435 DeleteAlign(Np,frame);
01436 while(Op1 != NULL){
01437 Op1->firstframe -= df;
01438 Op1->lastframe -= df;
01439 CheckRecursiveFollow(Np,Op1->firstframe,Op1->lastframe);
01440 Op1=Op1->next;
01441 }
01442 return;
01443 }
01444 Op=Op->next;
01445 }
01446 }
01447
01448 static node *LoadStandinModel(short *nmodels, char *title, char *command){
01449 object *Op;
01450 if(CreateNode() == NULL)return NULL;
01451 sprintf(MainNp->actorname,"Model%d",(*nmodels+1));
01452 MainNp->type=NORMAL;
01453 if((Op=CreateCostume(MainNp,1,(short)Nframes)) == NULL || fail_op)goto ERRORS;
01454 Op->type=MainNp->type;
01455 if(SelectFileName(0,gszSCEfile,gszSCEdir,title,
01456 "(*.MFX)|*.mfx|",ghwnd_main) == TRUE){
01457 strcpy(Op->name,gszSCEfile);
01458 Op->morph=NO;
01459 if(LoadMeshObject(gszSCEfile,Op,YES,YES,NO) == FAIL)
01460 DeleteCostume(MainNp,1);
01461 }
01462 else DeleteCostume(MainNp,1);
01463 (*nmodels)++;
01464 return MainNp;
01465 ERRORS:
01466 DeleteNode(MainNp);
01467 return NULL;
01468 }
01469
01470 static BOOL CALLBACK FollowAtOptionsDlgProc(HWND hwnd,UINT msg,
01471 WPARAM wparam,LPARAM lparam){
01472 char str[32];
01473 position *pp;
01474 BOOL err;
01475 int i;
01476 switch( msg ) {
01477 case WM_PAINT:
01478 PaintDialogBackground(hwnd,ghinst_main);
01479 break;
01480 case WM_INITDIALOG:{
01481 SetWindowLong(hwnd,GWL_USERDATA,lparam);
01482 pp=(position *)lparam;
01483 if(pp->fx)SendDlgItemMessage(hwnd,DLG_FOLLOWAT_LR,BM_SETCHECK,1,0);
01484 if(pp->fy)SendDlgItemMessage(hwnd,DLG_FOLLOWAT_FB,BM_SETCHECK,1,0);
01485 if(pp->fz)SendDlgItemMessage(hwnd,DLG_FOLLOWAT_UD,BM_SETCHECK,1,0);
01486 CentreDialogOnCursor(hwnd);
01487 }
01488 return (TRUE);
01489 case WM_COMMAND:
01490 pp=(position *)GetWindowLong(hwnd,GWL_USERDATA);
01491 switch(LOWORD(wparam)){
01492 case DLG_FOLLOWAT_CANCEL:
01493 EndDialog(hwnd,FAIL);
01494 return(TRUE);
01495 case DLG_FOLLOWAT_OK:
01496 if(SendDlgItemMessage(hwnd,DLG_FOLLOWAT_LR,BM_GETCHECK,0,0))
01497 pp->fx=1; else pp->fx=0;
01498 if(SendDlgItemMessage(hwnd,DLG_FOLLOWAT_FB,BM_GETCHECK,0,0))
01499 pp->fy=1; else pp->fy=0;
01500 if(SendDlgItemMessage(hwnd,DLG_FOLLOWAT_UD,BM_GETCHECK,0,0))
01501 pp->fz=1; else pp->fz=0;
01502 EndDialog(hwnd,OK);
01503 return(TRUE);
01504 default:
01505 break;
01506 }
01507 break;
01508 default: break;
01509 }
01510 return(FALSE);
01511 }
01512
01513 static void SetFollowAtOptions(position *Pp, HWND parent){
01514 int i;
01515 position pp;
01516 HWND original;
01517 memcpy(&pp,Pp,sizeof(position));
01518 original=GetActiveWindow();
01519 if((i=DialogBoxParam(ghinst_main,MAKEINTRESOURCE(DLG_FOLLOWAT),parent,
01520 (DLGPROC)FollowAtOptionsDlgProc,(LPARAM)&pp)) == OK){
01521 EDIT_ACTION=YES;
01522 memcpy(Pp,&pp,sizeof(position));
01523 }
01524 if(original != NULL)SetActiveWindow(original);
01525 return;
01526 }
01527
01528 static LRESULT CALLBACK pTimeLineEditDlgProc(HWND hwnd, UINT msg,
01529 WPARAM wparam, LPARAM lparam){
01530 static position *dp;
01531 static node *np;
01532 char title[128];
01533 struct NP {node *np; position *pp; int new;} *NP;
01534 node *OnPath;
01535 BOOL err,status;
01536 int i,TypeID[6]={DLG_TLEP_PT,DLG_TLEP_FOLLOW,DLG_TLEP_ST,
01537 DLG_TLEP_FOFF,DLG_TLEP_FON,DLG_TLEP_FAT};
01538 int ff,lf;
01539 double x,y,z;
01540 switch( msg ) {
01541 case WM_PAINT:
01542 PaintDialogBackground(hwnd,ghinst_main);
01543 break;
01544 case WM_INITDIALOG:{
01545 EnableToolPannels(ALL_PANNELS,FALSE);
01546 NP=(struct NP *)lparam;
01547 dp=NP->pp; np=NP->np;
01548 sprintf(title,"Movement Timeline for %s Actor",NP->np->actorname);
01549 SendMessage(hwnd,WM_SETTEXT,0,(LPARAM)title);
01550 if(NP->new == YES){
01551 EnableWindow(GetDlgItem(hwnd,DLG_TLEP_DELETE),FALSE);
01552 EnableWindow(GetDlgItem(hwnd,DLG_TLEP_CUT),FALSE);
01553 }
01554 SetDlgItemInt(hwnd,DLG_TLEP_F,dp->firstframe,FALSE);
01555 SetDlgItemInt(hwnd,DLG_TLEP_L,dp->lastframe,FALSE);
01556 if(dp->last != NULL)ff=dp->last->lastframe+1;
01557 else ff=1;
01558 if(dp->next != NULL)lf=dp->next->firstframe-1;
01559 else lf=Nframes;
01560 SendDlgItemMessage(hwnd,DLG_TLEP_FS,SPNM_SETRANGE,0,
01561 MAKELPARAM(ff,lf));
01562 SendDlgItemMessage(hwnd,DLG_TLEP_FS,SPNM_SETCRNTVALUE,
01563 (WPARAM)dp->firstframe,0);
01564 SendDlgItemMessage(hwnd,DLG_TLEP_FS,SPNM_SETEDITCTRL,0,
01565 (LPARAM)GetDlgItem(hwnd,DLG_TLEP_F));
01566 SendDlgItemMessage(hwnd,DLG_TLEP_LS,SPNM_SETRANGE,0,
01567 MAKELPARAM(ff,lf));
01568 SendDlgItemMessage(hwnd,DLG_TLEP_LS,SPNM_SETCRNTVALUE,
01569 (WPARAM)dp->lastframe,0);
01570 SendDlgItemMessage(hwnd,DLG_TLEP_LS,SPNM_SETEDITCTRL,0,
01571 (LPARAM)GetDlgItem(hwnd,DLG_TLEP_L));
01572 SendDlgItemMessage(hwnd,TypeID[dp->type],BM_SETCHECK,TRUE,0);
01573 x = (double)(dp->finish[0]-lrulerx); x /= ruler;
01574 y = (double)(dp->finish[1]-lrulery); y /= ruler;
01575 z = (double)(dp->finish[2]-lrulerz); z /= ruler;
01576 sprintf(title,"%.2lf",x); SetDlgItemText(hwnd,DLG_TLEP_X,title);
01577 sprintf(title,"%.2lf",y); SetDlgItemText(hwnd,DLG_TLEP_Y,title);
01578 sprintf(title,"%.2lf",z); SetDlgItemText(hwnd,DLG_TLEP_Z,title);
01579 OnPath=dp->onpath;
01580 if(OnPath != NULL){
01581 SetDlgItemText(hwnd,DLG_TLEP_FOLLOWED,OnPath->actorname);
01582 }
01583 else{
01584 SetDlgItemText(hwnd,DLG_TLEP_FOLLOWED,"<None>");
01585 }
01586 if(OnPath == NULL)status=FALSE; else status=TRUE;
01587 EnableWindow(GetDlgItem(hwnd,DLG_TLEP_FOLLOW),status);
01588 if(OnPath != NULL && OnPath->type == PATH)status=FALSE;
01589 EnableWindow(GetDlgItem(hwnd,DLG_TLEP_FOFF),status);
01590 EnableWindow(GetDlgItem(hwnd,DLG_TLEP_FON),status);
01591 EnableWindow(GetDlgItem(hwnd,DLG_TLEP_FAT),status);
01592 if(dp->type == TWEEN || dp->type == SPLINE)
01593 status=FALSE; else status=TRUE;
01594 EnableWindow(GetDlgItem(hwnd,DLG_TLEP_FOLLOWED),status);
01595 EnableWindow(GetDlgItem(hwnd,DLG_TLEP_X),!status);
01596 EnableWindow(GetDlgItem(hwnd,DLG_TLEP_Y),!status);
01597 EnableWindow(GetDlgItem(hwnd,DLG_TLEP_Z),!status);
01598 if(OnPath == NULL)status=TRUE;
01599 EnableWindow(GetDlgItem(hwnd,DLG_TLEP_SELECT),status);
01600 CentreDialogOnScreen(hwnd);
01601 }
01602 return (TRUE);
01603 case WM_DESTROY:
01604 EnableToolPannels(ALL_PANNELS,TRUE);
01605 break;
01606 case WM_COMMAND:
01607
01608 if(dp == NULL)break;
01609 switch(LOWORD(wparam)){
01610 case DLG_TLEP_PT: i=TWEEN; goto PT1;
01611 case DLG_TLEP_ST: i=SPLINE; goto PT1;
01612 case DLG_TLEP_FOLLOW: i=FOLLOW; goto PT1;
01613 case DLG_TLEP_FOFF: i=FOLLOWOFF; goto PT1;
01614 case DLG_TLEP_FON: i=FOLLOWON; goto PT1;
01615 case DLG_TLEP_FAT: i=FOLLOWAT;
01616 PT1:
01617 dp->type=i;
01618 OnPath=dp->onpath;
01619 if(OnPath == NULL)status=FALSE; else status=TRUE;
01620 EnableWindow(GetDlgItem(hwnd,DLG_TLEP_FOLLOW),status);
01621 if(OnPath != NULL && OnPath->type == PATH)status=FALSE;
01622 EnableWindow(GetDlgItem(hwnd,DLG_TLEP_FOFF),status);
01623 EnableWindow(GetDlgItem(hwnd,DLG_TLEP_FON),status);
01624 EnableWindow(GetDlgItem(hwnd,DLG_TLEP_FAT),status);
01625 if(OnPath != NULL)
01626 SetDlgItemText(hwnd,DLG_TLEP_FOLLOWED,OnPath->actorname);
01627 else
01628 SetDlgItemText(hwnd,DLG_TLEP_FOLLOWED,"<None>");
01629 if(dp->type == TWEEN || dp->type == SPLINE)
01630 status=FALSE; else status=TRUE;
01631 EnableWindow(GetDlgItem(hwnd,DLG_TLEP_FOLLOWED),status);
01632 EnableWindow(GetDlgItem(hwnd,DLG_TLEP_X),!status);
01633 EnableWindow(GetDlgItem(hwnd,DLG_TLEP_Y),!status);
01634 EnableWindow(GetDlgItem(hwnd,DLG_TLEP_Z),!status);
01635 if(OnPath == NULL)status=TRUE;
01636 EnableWindow(GetDlgItem(hwnd,DLG_TLEP_SELECT),status);
01637 break;
01638 case DLG_TLEP_SELECT:
01639 if((OnPath=SelectNode(dp->pnodename,NO,hwnd)) != NULL){
01640 if(OnPath == np){
01641 MessageBox(hwnd,"Actor Cannot Follow Itself",NULL,MB_OK);
01642 break;
01643 }
01644 dp->onpath=OnPath;
01645 strcpy(dp->pnodename,OnPath->actorname);
01646 }
01647 OnPath=dp->onpath;
01648 if(OnPath == NULL)status=FALSE; else status=TRUE;
01649 EnableWindow(GetDlgItem(hwnd,DLG_TLEP_FOLLOW),status);
01650 if(OnPath != NULL && OnPath->type == PATH)status=FALSE;
01651 EnableWindow(GetDlgItem(hwnd,DLG_TLEP_FOFF),status);
01652 EnableWindow(GetDlgItem(hwnd,DLG_TLEP_FON),status);
01653 EnableWindow(GetDlgItem(hwnd,DLG_TLEP_FAT),status);
01654 if(OnPath != NULL)
01655 SetDlgItemText(hwnd,DLG_TLEP_FOLLOWED,OnPath->actorname);
01656 else
01657 SetDlgItemText(hwnd,DLG_TLEP_FOLLOWED,"<None>");
01658 if(dp->type == TWEEN || dp->type == SPLINE)
01659 status=FALSE; else status=TRUE;
01660 EnableWindow(GetDlgItem(hwnd,DLG_TLEP_FOLLOWED),status);
01661 EnableWindow(GetDlgItem(hwnd,DLG_TLEP_X),!status);
01662 EnableWindow(GetDlgItem(hwnd,DLG_TLEP_Y),!status);
01663 EnableWindow(GetDlgItem(hwnd,DLG_TLEP_Z),!status);
01664 if(OnPath == NULL)status=TRUE;
01665 EnableWindow(GetDlgItem(hwnd,DLG_TLEP_SELECT),status);
01666 break;
01667 case DLG_TLEP_COPY:
01668 if(dp->last != NULL){
01669 x = (double)(dp->last->finish[0]-lrulerx); x /= ruler;
01670 y = (double)(dp->last->finish[1]-lrulery); y /= ruler;
01671 z = (double)(dp->last->finish[2]-lrulerz); z /= ruler;
01672 sprintf(title,"%.2lf",x); SetDlgItemText(hwnd,DLG_TLEP_X,title);
01673 sprintf(title,"%.2lf",y); SetDlgItemText(hwnd,DLG_TLEP_Y,title);
01674 sprintf(title,"%.2lf",z); SetDlgItemText(hwnd,DLG_TLEP_Z,title);
01675 }
01676 break;
01677 case IDCANCEL:
01678 case DLG_TLEP_CANCEL:
01679 EndDialog(hwnd,-1);
01680 return(TRUE);
01681 case DLG_TLEP_DELETE:
01682 EndDialog(hwnd,1);
01683 return(TRUE);
01684 case DLG_TLEP_CUT:
01685 EndDialog(hwnd,2);
01686 return(TRUE);
01687 case IDOK:
01688 case DLG_TLEP_OK:
01689 if(dp->type == TWEEN || dp->type == SPLINE){
01690 dp->onpath=NULL; dp->pnodename[0]='\0';
01691 }
01692 if(dp->type == FOLLOWAT)SetFollowAtOptions(dp,hwnd);
01693 i=GetDlgItemInt(hwnd,DLG_TLEP_F,&err,FALSE);
01694 if(err)dp->firstframe=(short)i;
01695 if(dp->last != NULL && dp->firstframe <= dp->last->lastframe)
01696 dp->firstframe=dp->last->lastframe+1;
01697 if(dp->firstframe < 1)dp->firstframe=1;
01698 i=GetDlgItemInt(hwnd,DLG_TLEP_L,&err,FALSE);
01699 if(err)dp->lastframe=(short)i;
01700 if(dp->next != NULL && dp->lastframe >= dp->next->firstframe)
01701 dp->lastframe=dp->next->firstframe-1;
01702 if(dp->lastframe > Nframes)dp->lastframe=Nframes;
01703 if(dp->lastframe < dp->firstframe)dp->lastframe=dp->firstframe;
01704 if(GetDlgItemText(hwnd,DLG_TLEP_X,title,10) != 0){
01705 x=atof(title); x *= ruler; dp->finish[0]=lrulerx+(long)x;
01706 }
01707 if(GetDlgItemText(hwnd,DLG_TLEP_Y,title,10) != 0){
01708 y=atof(title); y *= ruler; dp->finish[1]=lrulery+(long)y;
01709 }
01710 if(GetDlgItemText(hwnd,DLG_TLEP_Z,title,10) != 0){
01711 z=atof(title); z *= ruler; dp->finish[2]=lrulerz+(long)z;
01712 }
01713 EndDialog(hwnd,0);
01714 return(TRUE);
01715 default:
01716 break;
01717 }
01718 break;
01719 default: break;
01720 }
01721 return(FALSE);
01722 }
01723
01724 static LRESULT CALLBACK rTimeLineEditDlgProc(HWND hwnd, UINT msg,
01725 WPARAM wparam, LPARAM lparam){
01726 static align *dp;
01727 static node *np;
01728 node *OnPath;
01729 BOOL err,status;
01730 char title[128];
01731 struct NP {node *np; align *ap; int new;} *NP;
01732 int i,TypeID[5]={DLG_TLER_PT,DLG_TLER_TOPATH,DLG_TLER_LOOKAT,
01733 DLG_TLER_MIMIC,DLG_TLER_ST},
01734 InternalID[4]={DLG_TLER_NA,DLG_TLER_VA,DLG_TLER_SA,DLG_TLER_FA};
01735 int ff,lf;
01736 double a;
01737 switch( msg ) {
01738 case WM_PAINT:
01739 PaintDialogBackground(hwnd,ghinst_main);
01740 break;
01741 case WM_INITDIALOG:{
01742 dp=NULL;
01743 EnableToolPannels(ALL_PANNELS,FALSE);
01744 NP=(struct NP *)lparam;
01745 dp=NP->ap;
01746 np=NP->np;
01747 sprintf(title,"Rotation Timeline for %s Actor",NP->np->actorname);
01748 SendMessage(hwnd,WM_SETTEXT,0,(LPARAM)title);
01749 if(NP->new == YES){
01750 EnableWindow(GetDlgItem(hwnd,DLG_TLER_DELETE),FALSE);
01751 EnableWindow(GetDlgItem(hwnd,DLG_TLER_CUT),FALSE);
01752 }
01753 SetDlgItemInt(hwnd,DLG_TLER_F,dp->firstframe,FALSE);
01754 SetDlgItemInt(hwnd,DLG_TLER_L,dp->lastframe,FALSE);
01755 if(dp->last != NULL)ff=dp->last->lastframe+1;
01756 else ff=1;
01757 if(dp->next != NULL)lf=dp->next->firstframe-1;
01758 else lf=Nframes;
01759 SendDlgItemMessage(hwnd,DLG_TLER_FS,SPNM_SETRANGE,0,
01760 MAKELPARAM(ff,lf));
01761 SendDlgItemMessage(hwnd,DLG_TLER_FS,SPNM_SETCRNTVALUE,
01762 (WPARAM)dp->firstframe,0);
01763 SendDlgItemMessage(hwnd,DLG_TLER_FS,SPNM_SETEDITCTRL,0,
01764 (LPARAM)GetDlgItem(hwnd,DLG_TLER_F));
01765 SendDlgItemMessage(hwnd,DLG_TLER_LS,SPNM_SETRANGE,0,
01766 MAKELPARAM(ff,lf));
01767 SendDlgItemMessage(hwnd,DLG_TLER_LS,SPNM_SETCRNTVALUE,
01768 (WPARAM)dp->lastframe,0);
01769 SendDlgItemMessage(hwnd,DLG_TLER_LS,SPNM_SETEDITCTRL,0,
01770 (LPARAM)GetDlgItem(hwnd,DLG_TLER_L));
01771 SendDlgItemMessage(hwnd,TypeID[dp->type],BM_SETCHECK,TRUE,0);
01772 sprintf(title,"%.2lf",dp->theta);
01773 SetDlgItemText(hwnd,DLG_TLER_THETA,title);
01774 sprintf(title,"%.2lf",dp->alpha);
01775 SetDlgItemText(hwnd,DLG_TLER_ALPHA,title);
01776 sprintf(title,"%.2lf",dp->phi);
01777 SetDlgItemText(hwnd,DLG_TLER_PHI,title);
01778 OnPath=dp->topath;
01779 if(OnPath != NULL){
01780 SetDlgItemText(hwnd,DLG_TLER_FOLLOWED,OnPath->actorname);
01781 }
01782 else{
01783 SetDlgItemText(hwnd,DLG_TLER_FOLLOWED,"<None>");
01784 }
01785 if(OnPath == NULL)status=FALSE; else status=TRUE;
01786 EnableWindow(GetDlgItem(hwnd,DLG_TLER_LOOKAT),status);
01787 EnableWindow(GetDlgItem(hwnd,DLG_TLER_MIMIC),status);
01788 if(OnPath != NULL && OnPath->type != PATH)status=FALSE;
01789 EnableWindow(GetDlgItem(hwnd,DLG_TLER_TOPATH),status);
01790 if(dp->type == TWEEN || dp->type == SPLINEA)
01791 status=FALSE; else status=TRUE;
01792 EnableWindow(GetDlgItem(hwnd,DLG_TLER_FOLLOWED),status);
01793 EnableWindow(GetDlgItem(hwnd,DLG_TLER_THETA),!status);
01794 EnableWindow(GetDlgItem(hwnd,DLG_TLER_ALPHA),!status);
01795 EnableWindow(GetDlgItem(hwnd,DLG_TLER_PHI),!status);
01796 if(OnPath == NULL)status=TRUE;
01797 EnableWindow(GetDlgItem(hwnd,DLG_TLER_SELECT),status);
01798 if(NP->np->type == CAMERA || NP->np->type == GROUND){
01799 EnableWindow(GetDlgItem(hwnd,DLG_TLER_NA),FALSE);
01800 EnableWindow(GetDlgItem(hwnd,DLG_TLER_VA),FALSE);
01801 EnableWindow(GetDlgItem(hwnd,DLG_TLER_SA),FALSE);
01802 EnableWindow(GetDlgItem(hwnd,DLG_TLER_FA),FALSE);
01803 EnableWindow(GetDlgItem(hwnd,DLG_TLER_CLOCK),FALSE);
01804 EnableWindow(GetDlgItem(hwnd,DLG_TLER_ACLOCK),FALSE);
01805 }
01806 else{
01807 SendDlgItemMessage(hwnd,InternalID[dp->im],BM_SETCHECK,TRUE,0);
01808 if(dp->ima < 0.0)
01809 SendDlgItemMessage(hwnd,DLG_TLER_CLOCK,BM_SETCHECK,TRUE,0);
01810 else SendDlgItemMessage(hwnd,DLG_TLER_ACLOCK,BM_SETCHECK,TRUE,0);
01811 }
01812 CentreDialogOnScreen(hwnd);
01813 }
01814 return (TRUE);
01815 case WM_DESTROY:
01816 EnableToolPannels(ALL_PANNELS,TRUE);
01817 break;
01818 case WM_COMMAND:
01819 if(dp == NULL)break;
01820 switch(LOWORD(wparam)){
01821 case DLG_TLER_PT: i=TWEEN; goto PT1;
01822 case DLG_TLER_ST: i=SPLINEA; goto PT1;
01823 case DLG_TLER_TOPATH: i=TOPATH; goto PT1;
01824 case DLG_TLER_LOOKAT: i=TRACK; goto PT1;
01825 case DLG_TLER_MIMIC: i=COPY; goto PT1;
01826 PT1:
01827 dp->type=i;
01828 OnPath=dp->topath;
01829 if(OnPath == NULL)status=FALSE; else status=TRUE;
01830 EnableWindow(GetDlgItem(hwnd,DLG_TLER_LOOKAT),status);
01831 EnableWindow(GetDlgItem(hwnd,DLG_TLER_MIMIC),status);
01832 if(OnPath != NULL && OnPath->type != PATH)status=FALSE;
01833 EnableWindow(GetDlgItem(hwnd,DLG_TLER_TOPATH),status);
01834 if(OnPath != NULL)
01835 SetDlgItemText(hwnd,DLG_TLER_FOLLOWED,OnPath->actorname);
01836 else
01837 SetDlgItemText(hwnd,DLG_TLER_FOLLOWED,"<None>");
01838 if(dp->type == TWEEN || dp->type == SPLINEA)
01839 status=FALSE; else status=TRUE;
01840 EnableWindow(GetDlgItem(hwnd,DLG_TLER_FOLLOWED),status);
01841 EnableWindow(GetDlgItem(hwnd,DLG_TLER_THETA),!status);
01842 EnableWindow(GetDlgItem(hwnd,DLG_TLER_ALPHA),!status);
01843 EnableWindow(GetDlgItem(hwnd,DLG_TLER_PHI),!status);
01844 if(OnPath == NULL)status=TRUE;
01845 EnableWindow(GetDlgItem(hwnd,DLG_TLER_SELECT),status);
01846 break;
01847 case DLG_TLER_SELECT:
01848 if((OnPath=SelectNode(dp->anodename,NO,hwnd)) != NULL){
01849 if(OnPath == np){
01850 MessageBox(hwnd,"Actor Cannot Look at Itself",NULL,MB_OK);
01851 break;
01852 }
01853 dp->topath=OnPath;
01854 strcpy(dp->anodename,OnPath->actorname);
01855 }
01856 OnPath=dp->topath;
01857 if(OnPath == NULL)status=FALSE; else status=TRUE;
01858 EnableWindow(GetDlgItem(hwnd,DLG_TLER_LOOKAT),status);
01859 EnableWindow(GetDlgItem(hwnd,DLG_TLER_MIMIC),status);
01860 if(OnPath != NULL && OnPath->type != PATH)status=FALSE;
01861 EnableWindow(GetDlgItem(hwnd,DLG_TLER_TOPATH),status);
01862 if(OnPath != NULL)
01863 SetDlgItemText(hwnd,DLG_TLER_FOLLOWED,OnPath->actorname);
01864 else
01865 SetDlgItemText(hwnd,DLG_TLER_FOLLOWED,"<None>");
01866 if(dp->type == TWEEN || dp->type == SPLINEA)
01867 status=FALSE; else status=TRUE;
01868 EnableWindow(GetDlgItem(hwnd,DLG_TLER_FOLLOWED),status);
01869 EnableWindow(GetDlgItem(hwnd,DLG_TLER_THETA),!status);
01870 EnableWindow(GetDlgItem(hwnd,DLG_TLER_ALPHA),!status);
01871 EnableWindow(GetDlgItem(hwnd,DLG_TLER_PHI),!status);
01872 if(OnPath == NULL)status=TRUE;
01873 EnableWindow(GetDlgItem(hwnd,DLG_TLER_SELECT),status);
01874 break;
01875 case DLG_TLER_NA: dp->im=0; break;
01876 case DLG_TLER_VA: dp->im=1; break;
01877 case DLG_TLER_SA: dp->im=2; break;
01878 case DLG_TLER_FA: dp->im=3; break;
01879 case DLG_TLER_CLOCK:
01880 dp->ima = -1.0;
01881 break;
01882 case DLG_TLER_ACLOCK:
01883 dp->ima = 1.0;
01884 break;
01885 case DLG_TLER_COPY:
01886 if(dp->last != NULL){
01887 sprintf(title,"%.2lf",dp->last->theta);
01888 SetDlgItemText(hwnd,DLG_TLER_THETA,title);
01889 sprintf(title,"%.2lf",dp->last->alpha);
01890 SetDlgItemText(hwnd,DLG_TLER_ALPHA,title);
01891 sprintf(title,"%.2lf",dp->last->phi);
01892 SetDlgItemText(hwnd,DLG_TLER_PHI,title);
01893 }
01894 break;
01895 case IDCANCEL:
01896 case DLG_TLER_CANCEL:
01897 EndDialog(hwnd,-1);
01898 return(TRUE);
01899 case DLG_TLER_DELETE:
01900 EndDialog(hwnd,1);
01901 return(TRUE);
01902 case DLG_TLER_CUT:
01903 EndDialog(hwnd,2);
01904 return(TRUE);
01905 case IDOK:
01906 case DLG_TLER_OK:
01907 if(dp->type == TWEEN || dp->type == SPLINEA){
01908 dp->topath=NULL; dp->anodename[0]='\0';
01909 }
01910 i=GetDlgItemInt(hwnd,DLG_TLER_F,&err,FALSE);
01911 if(err)dp->firstframe=(short)i;
01912 if(dp->last != NULL && dp->firstframe <= dp->last->lastframe)
01913 dp->firstframe=dp->last->lastframe+1;
01914 if(dp->firstframe < 1)dp->firstframe=1;
01915 i=GetDlgItemInt(hwnd,DLG_TLER_L,&err,FALSE);
01916 if(err)dp->lastframe=(short)i;
01917 if(dp->next != NULL && dp->lastframe >= dp->next->firstframe)
01918 dp->lastframe=dp->next->firstframe-1;
01919 if(dp->lastframe > Nframes)dp->lastframe=Nframes;
01920 if(dp->lastframe < dp->firstframe)dp->lastframe=dp->firstframe;
01921 if(GetDlgItemText(hwnd,DLG_TLER_ALPHA,title,10) != 0){
01922 a=atof(title);
01923 if(a >= -360.0 && a <= 360.0)dp->alpha=a;
01924 }
01925 if(GetDlgItemText(hwnd,DLG_TLER_THETA,title,10) != 0){
01926 a=atof(title);
01927 if(a >= -360.0 && a <= 360.0)dp->theta=a;
01928 }
01929 if(GetDlgItemText(hwnd,DLG_TLER_PHI,title,10) != 0){
01930 a=atof(title);
01931 if(a >= -360.0 && a <= 360.0)dp->phi=a;
01932 }
01933 EndDialog(hwnd,0);
01934 return(TRUE);
01935 default:
01936 break;
01937 }
01938 break;
01939 default: break;
01940 }
01941 return(FALSE);
01942 }
01943
01944 static LRESULT CALLBACK DlgCommandDlgProc(HWND hwnd, UINT msg,
01945 WPARAM wparam, LPARAM lparam){
01946 node *np;
01947 char title[128];
01948 switch( msg ) {
01949 case WM_PAINT:
01950 PaintDialogBackground(hwnd,ghinst_main);
01951 break;
01952 case WM_INITDIALOG:
01953 np=(node *)lparam;
01954 sprintf(title,"Edit: %s",np->actorname);
01955 SendMessage(hwnd,WM_SETTEXT,0,(LPARAM)title);
01956 CentreDialogOnScreen(hwnd);
01957 return (TRUE);
01958 case WM_DESTROY:
01959 break;
01960 case WM_COMMAND:
01961 switch(LOWORD(wparam)){
01962 case IDCANCEL:
01963 EndDialog(hwnd,-1);
01964 return(TRUE);
01965 case DLG_KEYF_COMMAND_DELETE:
01966 EndDialog(hwnd,IDM_TIMELINE_ACTOR_DELETE);
01967 return(TRUE);
01968 case DLG_KEYF_COMMAND_RENAME:
01969 EndDialog(hwnd,IDM_TIMELINE_ACTOR_RENAME);
01970 return(TRUE);
01971 case DLG_KEYF_COMMAND_INFO:
01972 EndDialog(hwnd,IDM_TIMELINE_ACTOR_INFO);
01973 return(TRUE);
01974 case DLG_KEYF_COMMAND_SAVEANI:
01975 EndDialog(hwnd,IDM_TIMELINE_ACTOR_SAVEANIOBJ);
01976 return(TRUE);
01977 default:
01978 break;
01979 }
01980 break;
01981 default: break;
01982 }
01983 return(FALSE);
01984 }
01985
01986 #define CYORDERDLGLINE 18 // Height of a line.
01987 static HWND hwndOrderDlg;
01988 static HWND hwndOrderList;
01989 static WNDPROC lpfnOldLBWndProc;
01990 static BOOL cSelItems=FALSE;
01991
01992 static BOOL OrderDlgInsertHitTest(INT y,PINT piInsert){
01993 INT i;
01994 INT iPixel;
01995 INT iInsert;
01996 INT iLine;
01997 BOOL fInsertZone;
01998 if (!cSelItems) return FALSE;
01999 iPixel = y % CYORDERDLGLINE;
02000 if (iPixel < 3) {
02001 iLine = y / CYORDERDLGLINE;
02002 fInsertZone = TRUE;
02003 }
02004 else if (iPixel > CYORDERDLGLINE - 3) {
02005 iLine = (y / CYORDERDLGLINE) + 1;
02006 fInsertZone = TRUE;
02007 }
02008 else {
02009 fInsertZone = FALSE;
02010 }
02011 if (fInsertZone) {
02012 iInsert = iLine + (INT)SendMessage(hwndOrderList,
02013 LB_GETTOPINDEX, 0, 0L);
02014 if (iInsert > Nnodes)fInsertZone = FALSE;
02015 else *piInsert = iInsert;
02016 }
02017 return fInsertZone;
02018 }
02019
02020 static LRESULT CALLBACK OrderDlgLBWndProc(HWND hwnd,UINT msg,WPARAM wParam,
02021 LPARAM lParam){
02022 INT iInsert;
02023 int item;
02024 switch (msg) {
02025 case WM_SETCURSOR:
02026 if (LOWORD(lParam) == HTCLIENT)return TRUE;
02027 break;
02028 case WM_MOUSEMOVE:
02029 if (!(GetKeyState(VK_LBUTTON) & 0x8000) &&
02030 OrderDlgInsertHitTest(HIWORD(lParam), &iInsert))
02031 SetCursor(ghcurInsert);
02032 else
02033 SetCursor(ghcurArrow);
02034 break;
02035 case WM_LBUTTONDOWN:
02036 if(OrderDlgInsertHitTest(HIWORD(lParam), &iInsert)) {
02037 item=SendMessage(hwndOrderList,LB_GETCURSEL,0,0);
02038 if(item == 0 || iInsert == 0){
02039 SendPrgmQuery(IDQ_CAMERANOREORDER,0);
02040 SetFocus(hwnd);
02041 }
02042 else if(item != LB_ERR){
02043 char temp[64];
02044 cSelItems=FALSE;
02045 SendMessage(hwndOrderList,LB_GETTEXT,item,(LPARAM)temp);
02046 if(item > iInsert){
02047 SendMessage(hwndOrderList,LB_DELETESTRING,(WPARAM)item,0);
02048 SendMessage(hwndOrderList,LB_INSERTSTRING,(WPARAM)iInsert,(LPARAM)temp);
02049 }
02050 else if(item < iInsert){
02051 SendMessage(hwndOrderList,LB_INSERTSTRING,(WPARAM)iInsert,(LPARAM)temp);
02052 SendMessage(hwndOrderList,LB_DELETESTRING,(WPARAM)item,0);
02053 }
02054 if(iInsert != item){
02055 node *n_out=NULL,*n_in=NULL,*Np,*Lp;
02056 int i;
02057 Np=FirstNp; i=0; while(Np != NULL){
02058 if(i == item) n_out=Np;
02059 if(i == iInsert)n_in=Np;
02060 Lp=Np;
02061 i++; Np=Np->next;
02062 }
02063 if(n_out != NULL){
02064 if(n_out->next != NULL)n_out->next->last = n_out->last;
02065 if(n_out->last != NULL)n_out->last->next = n_out->next;
02066 if(n_out == FirstNp)FirstNp=n_out->next;
02067 if(n_out == MainNp)MainNp=n_out->last;
02068 if(n_in != NULL){
02069 n_out->last=n_in->last;
02070 if(n_in->last != NULL)n_in->last->next=n_out;
02071 n_in->last=n_out;
02072 n_out->next=n_in;
02073 if(n_in == FirstNp)FirstNp=n_out;
02074 }
02075 else{
02076 if(Lp != MainNp)MessageBeep(MB_OK);
02077 n_out->next=NULL;
02078 n_out->last=Lp;
02079 Lp->next=n_out;
02080 MainNp=n_out;
02081 }
02082 }
02083 }
02084 }
02085 return FALSE;
02086 }
02087 break;
02088 }
02089 return CallWindowProc((WNDPROC)lpfnOldLBWndProc,hwnd,msg,wParam,lParam);
02090 }
02091
02092 static void OrderDlgInit(HWND hwnd){
02093 int nItem;
02094 node *Np;
02095 hwndOrderDlg = hwnd;
02096 hwndOrderList = GetDlgItem(hwnd,DLG_REORDER_LIST);
02097 cSelItems=FALSE;
02098 Np=FirstNp; while(Np != NULL){
02099 nItem=SendMessage(hwndOrderList,LB_ADDSTRING,0,(LPARAM)Np->actorname);
02100 Np=Np->next;
02101 }
02102 lpfnOldLBWndProc = (WNDPROC)SetWindowLong(hwndOrderList,
02103 GWL_WNDPROC, (DWORD)OrderDlgLBWndProc);
02104 CentreDialogOnScreen(hwnd);
02105 }
02106
02107 static LRESULT CALLBACK ReorderDlgProc(HWND hwnd, UINT msg,
02108 WPARAM wParam, LPARAM lParam){
02109 switch (msg) {
02110 case WM_PAINT:
02111 PaintDialogBackground(hwnd,ghinst_main);
02112 break;
02113 case WM_INITDIALOG:
02114 OrderDlgInit(hwnd);
02115 return TRUE;
02116 case WM_MEASUREITEM:
02117 ((LPMEASUREITEMSTRUCT)lParam)->itemHeight = CYORDERDLGLINE;
02118 return TRUE;
02119 case WM_DRAWITEM:{
02120 LPDRAWITEMSTRUCT lpdis=(LPDRAWITEMSTRUCT)lParam;
02121 TCHAR szItem[MAX_PATH];
02122 TEXTMETRIC tm;
02123 int y;
02124 if(lpdis->itemState & ODS_SELECTED) {
02125 SetBkColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT));
02126 SetTextColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
02127 }
02128 else {
02129 SetBkColor(lpdis->hDC, GetSysColor(COLOR_WINDOW));
02130 SetTextColor(lpdis->hDC, GetSysColor(COLOR_WINDOWTEXT));
02131 }
02132 switch(lpdis->itemAction){
02133 case ODA_SELECT:
02134 case ODA_DRAWENTIRE:
02135 SendMessage(lpdis->hwndItem,LB_GETTEXT,lpdis->itemID,(LPARAM)szItem);
02136 GetTextMetrics(lpdis->hDC,&tm);
02137 y=(lpdis->rcItem.bottom+lpdis->rcItem.top-tm.tmHeight)/2;
02138 ExtTextOut(lpdis->hDC,6,y,
02139 ETO_OPAQUE | ETO_CLIPPED, &lpdis->rcItem,
02140 szItem, lstrlen(szItem), NULL);
02141 default:
02142 break;
02143 }
02144 if(lpdis->itemState & ODS_FOCUS)
02145 DrawFocusRect(lpdis->hDC, &lpdis->rcItem);
02146 }
02147 return TRUE;
02148 case WM_COMMAND:
02149 switch (LOWORD(wParam)) {
02150 case DLG_REORDER_LIST:
02151 switch (HIWORD(wParam)) {
02152 case LBN_SELCHANGE:
02153 cSelItems=TRUE;
02154 break;
02155 }
02156 break;
02157 case IDCANCEL:
02158 case IDOK:
02159 EndDialog(hwnd, LOWORD(wParam));
02160 break;
02161 }
02162 return TRUE;
02163 default:
02164 return FALSE;
02165 }
02166 return FALSE;
02167 }
02168
02169
02170 #define UPDATETRIVIEW(x) \
02171 if(ghwndTimeline != NULL){ \
02172 if(!IsZoomed(ghwndTimeline)){ \
02173 ReDrawStageDisplay(TRUE); \
02174 if(ghwndOpenGLview == NULL) \
02175 PerspectiveView(0,1); \
02176 else UpdateGLview(TRUE); \
02177 } \
02178 }
02179
02180 #define BOUND(x,min,max) ((x) < (min) ? (min) : ((x) > (max) ? (max) : (x)))
02181 #define A_H 60
02182 #define F_W 10
02183 #define L_H 10
02184 #define WM_KEYFRAMEUPDATE (WM_USER+1)
02185
02186 static void DoKeyFramerCommand(WPARAM wparam, int local_actor);
02187
02188 static char szTimelineChildClass[]="OFX:TimelineChildClass";
02189 static char szTimelineClass[]="OFX:TimelineClass";
02190 static int TimelineStatusPartsList[3]={110,220,-1};
02191 static int FirstTime=TRUE,IndicatorVisible = NO,IndicatorActive=NO,
02192 IndicatedActor= -1, IndicatedFrame= -1, IndicatedLine= -1,
02193 ScrollingTimeLine=0,TimeLineUpdateFlag=0,TimeLineVisibleFlag=0,
02194 IndicatorsChanged=NO;
02195 static HBITMAP hTimelineBitmap=NULL;
02196 static HWND hwndTimelineInfo=NULL;
02197 static node *IndicatedNode=NULL;
02198 static sky *IndicatedSky=NULL;
02199 static director *IndicatedDirector=NULL;
02200 static object *IndicatedObject=NULL;
02201 static position *IndicatedPosition=NULL;
02202 static align *IndicatedAlign=NULL;
02203 static size *IndicatedSize=NULL;
02204 static DWORD fdwStyleP = WS_POPUP | WS_CLIPSIBLINGS | WS_CAPTION |
02205 WS_SYSMENU | WS_THICKFRAME |
02206 WS_MAXIMIZEBOX | WS_MINIMIZEBOX |
02207 !WS_VSCROLL | !WS_HSCROLL;
02208 static DWORD fdwStyleD = WS_CHILD | WS_CLIPSIBLINGS | !WS_CAPTION |
02209 !WS_SYSMENU | !WS_THICKFRAME | !WS_MAXIMIZEBOX |
02210 !WS_VSCROLL | !WS_HSCROLL | !WS_BORDER;
02211 static DWORD fdwStyleC = WS_CHILD | WS_VSCROLL | WS_HSCROLL | WS_VISIBLE;
02212 static int xScreen,yScreen,nXBorder,nXTitle,nYTitle;
02213 static POINT ptSize;
02214 static long NoldFrames= -1, NoldNodes = -1;
02215 static char *linetype[5]={NULL,NULL,NULL,NULL,NULL};
02216
02217 static int ChangeIndicatedKeys(BOOL bEditKeyStart){
02218 int dn,fn,update=0;
02219
02220 if(IndicatedObject != NULL){
02221 if(bEditKeyStart){
02222 if(IndicatedObject->last == NULL)dn=1;
02223 else dn=IndicatedObject->last->firstframe+1;
02224 if(IndicatedFrame >= dn){
02225 if(IndicatedObject->next == NULL)dn=Nframes;
02226 else dn=IndicatedObject->next->firstframe-1;
02227 if(IndicatedFrame <= dn){
02228 IndicatedObject->firstframe=IndicatedFrame;
02229 if(IndicatedObject->firstframe > IndicatedObject->lastframe)
02230 IndicatedObject->firstframe=IndicatedObject->lastframe;
02231 if(IndicatedObject->last != NULL){
02232 if(GetAsyncKeyState(VK_CONTROL) & 0x8000)
02233 IndicatedObject->last->lastframe=min(IndicatedFrame-1,
02234 IndicatedObject->last->lastframe);
02235 else IndicatedObject->last->lastframe=IndicatedFrame-1;
02236 }
02237 }
02238 }
02239 }
02240 else{
02241 if(IndicatedObject->last == NULL)dn=1;
02242 else dn=IndicatedObject->last->lastframe+1;
02243 if(IndicatedFrame >= dn){
02244 if(IndicatedObject->next == NULL)dn=Nframes;
02245 else dn=IndicatedObject->next->lastframe-1;
02246 if(IndicatedFrame <= dn){
02247 IndicatedObject->lastframe=IndicatedFrame;
02248 if(IndicatedObject->firstframe > IndicatedObject->lastframe)
02249 IndicatedObject->firstframe=IndicatedObject->lastframe;
02250 if(IndicatedObject->next != NULL){
02251 if(GetAsyncKeyState(VK_CONTROL) & 0x8000)
02252 IndicatedObject->next->firstframe=max(IndicatedFrame+1,
02253 IndicatedObject->next->firstframe);
02254 else IndicatedObject->next->firstframe=IndicatedFrame+1;
02255 }
02256 }
02257 }
02258 }
02259 update=1;
02260 }
02261
02262 if(IndicatedSky != NULL){
02263 if(bEditKeyStart){
02264 if(IndicatedSky->last == NULL)dn=1;
02265 else dn=IndicatedSky->last->firstframe+1;
02266 if(IndicatedFrame >= dn){
02267 if(IndicatedSky->next == NULL)dn=Nframes;
02268 else dn=IndicatedSky->next->firstframe-1;
02269 if(IndicatedFrame <= dn){
02270 IndicatedSky->firstframe=IndicatedFrame;
02271 if(IndicatedSky->firstframe > IndicatedSky->lastframe)
02272 IndicatedSky->firstframe=IndicatedSky->lastframe;
02273 if(IndicatedSky->last != NULL){
02274 if(GetAsyncKeyState(VK_CONTROL) & 0x8000)
02275 IndicatedSky->last->lastframe=min(IndicatedFrame-1,
02276 IndicatedSky->last->lastframe);
02277 else IndicatedSky->last->lastframe=IndicatedFrame-1;
02278 }
02279 }
02280 }
02281 }
02282 else{
02283 if(IndicatedSky->last == NULL)dn=1;
02284 else dn=IndicatedSky->last->lastframe+1;
02285 if(IndicatedFrame >= dn){
02286 if(IndicatedSky->next == NULL)dn=Nframes;
02287 else dn=IndicatedSky->next->lastframe-1;
02288 if(IndicatedFrame <= dn){
02289 IndicatedSky->lastframe=IndicatedFrame;
02290 if(IndicatedSky->firstframe > IndicatedSky->lastframe)
02291 IndicatedSky->firstframe=IndicatedSky->lastframe;
02292 if(IndicatedSky->next != NULL){
02293 if(GetAsyncKeyState(VK_CONTROL) & 0x8000)
02294 IndicatedSky->next->firstframe=max(IndicatedFrame+1,
02295 IndicatedSky->next->firstframe);
02296 else IndicatedSky->next->firstframe=IndicatedFrame+1;
02297 }
02298 }
02299 }
02300 }
02301 update=1;
02302 }
02303
02304 if(IndicatedDirector != NULL){
02305 if(bEditKeyStart){
02306 if(IndicatedDirector->last == NULL)dn=1;
02307 else dn=IndicatedDirector->last->firstframe+1;
02308 if(IndicatedFrame >= dn){
02309 if(IndicatedDirector->next == NULL)dn=Nframes;
02310 else dn=IndicatedDirector->next->firstframe-1;
02311 if(IndicatedFrame <= dn){
02312 IndicatedDirector->firstframe=IndicatedFrame;
02313 if(IndicatedDirector->firstframe > IndicatedDirector->lastframe)
02314 IndicatedDirector->firstframe=IndicatedDirector->lastframe;
02315 if(IndicatedDirector->last != NULL){
02316 if(GetAsyncKeyState(VK_CONTROL) & 0x8000)
02317 IndicatedDirector->last->lastframe=min(IndicatedFrame-1,
02318 IndicatedDirector->last->lastframe);
02319 else IndicatedDirector->last->lastframe=IndicatedFrame-1;
02320 }
02321 }
02322 }
02323 }
02324 else{
02325 if(IndicatedDirector->last == NULL)dn=1;
02326 else dn=IndicatedDirector->last->lastframe+1;
02327 if(IndicatedFrame >= dn){
02328 if(IndicatedDirector->next == NULL)dn=Nframes;
02329 else dn=IndicatedDirector->next->lastframe-1;
02330 if(IndicatedFrame <= dn){
02331 IndicatedDirector->lastframe=IndicatedFrame;
02332 if(IndicatedDirector->firstframe > IndicatedDirector->lastframe)
02333 IndicatedDirector->firstframe=IndicatedDirector->lastframe;
02334 if(IndicatedDirector->next != NULL){
02335 if(GetAsyncKeyState(VK_CONTROL) & 0x8000)
02336 IndicatedDirector->next->firstframe=max(IndicatedFrame+1,
02337 IndicatedDirector->next->firstframe);
02338 else IndicatedDirector->next->firstframe=IndicatedFrame+1;
02339 }
02340 }
02341 }
02342 }
02343 update=1;
02344 }
02345
02346 if(IndicatedPosition != NULL){
02347 if(bEditKeyStart){
02348 if(IndicatedPosition->last == NULL)dn=1;
02349 else dn=IndicatedPosition->last->firstframe+1;
02350 if(IndicatedFrame >= dn){
02351 if(IndicatedPosition->next == NULL)dn=Nframes;
02352 else dn=IndicatedPosition->next->firstframe-1;
02353 if(IndicatedFrame <= dn){
02354 IndicatedPosition->firstframe=IndicatedFrame;
02355 if(IndicatedPosition->firstframe > IndicatedPosition->lastframe)
02356 IndicatedPosition->firstframe=IndicatedPosition->lastframe;
02357 if(IndicatedPosition->last != NULL){
02358 if(GetAsyncKeyState(VK_CONTROL) & 0x8000)
02359 IndicatedPosition->last->lastframe=min(IndicatedFrame-1,
02360 IndicatedPosition->last->lastframe);
02361 else IndicatedPosition->last->lastframe=IndicatedFrame-1;
02362 }
02363 }
02364 }
02365 }
02366 else{
02367 if(IndicatedPosition->last == NULL)dn=1;
02368 else dn=IndicatedPosition->last->lastframe+1;
02369 if(IndicatedFrame >= dn){
02370 if(IndicatedPosition->next == NULL)dn=Nframes;
02371 else dn=IndicatedPosition->next->lastframe-1;
02372 if(IndicatedFrame <= dn){
02373 IndicatedPosition->lastframe=IndicatedFrame;
02374 if(IndicatedPosition->firstframe > IndicatedPosition->lastframe)
02375 IndicatedPosition->firstframe=IndicatedPosition->lastframe;
02376 if(IndicatedPosition->next != NULL){
02377 if(GetAsyncKeyState(VK_CONTROL) & 0x8000)
02378 IndicatedPosition->next->firstframe=max(IndicatedFrame+1,
02379 IndicatedPosition->next->firstframe);
02380 else IndicatedPosition->next->firstframe=IndicatedFrame+1;
02381 }
02382 }
02383 }
02384 }
02385 update=1;
02386 }
02387 if(IndicatedAlign != NULL){
02388 if(bEditKeyStart){
02389 if(IndicatedAlign->last == NULL)dn=1;
02390 else dn=IndicatedAlign->last->firstframe+1;
02391 if(IndicatedFrame >= dn){
02392 if(IndicatedAlign->next == NULL)dn=Nframes;
02393 else dn=IndicatedAlign->next->firstframe-1;
02394 if(IndicatedFrame <= dn){
02395 IndicatedAlign->firstframe=IndicatedFrame;
02396 if(IndicatedAlign->firstframe > IndicatedAlign->lastframe)
02397 IndicatedAlign->firstframe=IndicatedAlign->lastframe;
02398 if(IndicatedAlign->last != NULL){
02399 if(GetAsyncKeyState(VK_CONTROL) & 0x8000)
02400 IndicatedAlign->last->lastframe=min(IndicatedFrame-1,
02401 IndicatedAlign->last->lastframe);
02402 else IndicatedAlign->last->lastframe=IndicatedFrame-1;
02403 }
02404 }
02405 }
02406 }
02407 else{
02408 if(IndicatedAlign->last == NULL)dn=1;
02409 else dn=IndicatedAlign->last->lastframe+1;
02410 if(IndicatedFrame >= dn){
02411 if(IndicatedAlign->next == NULL)dn=Nframes;
02412 else dn=IndicatedAlign->next->lastframe-1;
02413 if(IndicatedFrame <= dn){
02414 IndicatedAlign->lastframe=IndicatedFrame;
02415 if(IndicatedAlign->firstframe > IndicatedAlign->lastframe)
02416 IndicatedAlign->firstframe=IndicatedAlign->lastframe;
02417 if(IndicatedAlign->next != NULL){
02418 if(GetAsyncKeyState(VK_CONTROL) & 0x8000)
02419 IndicatedAlign->next->firstframe=max(IndicatedFrame+1,
02420 IndicatedAlign->next->firstframe);
02421 else IndicatedAlign->next->firstframe=IndicatedFrame+1;
02422 }
02423 }
02424 }
02425 }
02426 update=1;
02427 }
02428 if(IndicatedSize != NULL){
02429 if(bEditKeyStart){
02430 if(IndicatedSize->last == NULL)dn=1;
02431 else dn=IndicatedSize->last->firstframe+1;
02432 if(IndicatedFrame >= dn){
02433 if(IndicatedSize->next == NULL)dn=Nframes;
02434 else dn=IndicatedSize->next->firstframe-1;
02435 if(IndicatedFrame <= dn){
02436 IndicatedSize->firstframe=IndicatedFrame;
02437 if(IndicatedSize->firstframe > IndicatedSize->lastframe)
02438 IndicatedSize->firstframe=IndicatedSize->lastframe;
02439 if(IndicatedSize->last != NULL){
02440 if(GetAsyncKeyState(VK_CONTROL) & 0x8000)
02441 IndicatedSize->last->lastframe=min(IndicatedFrame-1,
02442 IndicatedSize->last->lastframe);
02443 else IndicatedSize->last->lastframe=IndicatedFrame-1;
02444 }
02445 }
02446 }
02447 }
02448 else{
02449 if(IndicatedSize->last == NULL)dn=1;
02450 else dn=IndicatedSize->last->lastframe+1;
02451 if(IndicatedFrame >= dn){
02452 if(IndicatedSize->next == NULL)dn=Nframes;
02453 else dn=IndicatedSize->next->lastframe-1;
02454 if(IndicatedFrame <= dn){
02455 IndicatedSize->lastframe=IndicatedFrame;
02456 if(IndicatedSize->firstframe > IndicatedSize->lastframe)
02457 IndicatedSize->firstframe=IndicatedSize->lastframe;
02458 if(IndicatedSize->next != NULL){
02459 if(GetAsyncKeyState(VK_CONTROL) & 0x8000)
02460 IndicatedSize->next->firstframe = max(IndicatedFrame+1,
02461 IndicatedSize->next->firstframe);
02462 else IndicatedSize->next->firstframe=IndicatedFrame+1;
02463 }
02464 }
02465 }
02466 }
02467 update=1;
02468 }
02469 if(update)return 1;
02470 return 0;
02471 }
02472
02473 void WaitForUp(void){
02474 MSG msg;
02475 POINT p;
02476 RECT r;
02477 GetCursorPos(&p);
02478 r.top=p.y; r.left=p.x;
02479 r.bottom=p.y; r.right=p.x;
02480 ClipCursor(&r);
02481 while (1) {
02482 GetMessage(&msg,NULL,0,0);
02483 TranslateMessage(&msg);
02484 DispatchMessage(&msg);
02485 if(msg.message == WM_LBUTTONUP)break;
02486 }
02487 }
02488
02489 static node *EditTimeLine(int actor, int frame, int line, BOOL *keystart){
02490 node *Np;
02491 object *Op,*Opp;
02492 sky *Sp,*Spp;
02493 director *Dp,*Dpp;
02494 position *Pp,*Ppp;
02495 align *Ap,*App;
02496 size *Xp,*Xpp;
02497 int i,lf;
02498 short slf,sframe,type;
02499 EDIT_ACTION=YES;
02500 IndicatedSky=NULL; IndicatedObject=NULL;
02501 IndicatedPosition=NULL; IndicatedAlign=NULL; IndicatedSize=NULL;
02502 IndicatedDirector=NULL;
02503 *keystart=FALSE;
02504 Np=FirstNp; if(actor > 1)for(i=1;i<actor;i++)Np=Np->next;
02505 if(Np == NULL)return NULL;
02506
02507 if(line == 0 && Np->type == SKY){
02508 Sp=Np->fsky; Spp=Sp;
02509 while(Sp != NULL){
02510 Spp=Sp;
02511 if(Sp->firstframe > frame){
02512 if(Sp->last == NULL)lf=1;
02513 else lf=Sp->last->lastframe+1;
02514 WaitForUp();
02515 EditObject(Np,(short)lf,(short)frame,YES,NO);
02516 UPDATETIMELINES(IDC_TIMEL_UPDATE)
02517 return NULL;
02518 }
02519 if(Sp->firstframe <= frame && Sp->lastframe >= frame){
02520 if(Sp->lastframe == frame){
02521 IndicatedSky=Sp;
02522 return Np;
02523 }
02524 else if(Sp->firstframe == frame){
02525 IndicatedSky=Sp;
02526 *keystart=TRUE;
02527 return Np;
02528 }
02529 else{
02530 WaitForUp();
02531 if(!(GetKeyState(VK_CONTROL) & 0x8000) &&
02532 SendPrgmQuery(IDQ_BREAKCHANNEL,1) == IDNO)return NULL;
02533 lf=Sp->firstframe;
02534 Sp->firstframe=frame+1;
02535 EditObject(Np,(short)lf,(short)frame,YES,YES);
02536 UPDATETIMELINES(IDC_TIMEL_UPDATE)
02537 }
02538 return NULL;
02539 }
02540 Sp=Sp->next;
02541 }
02542 if(Spp != NULL)lf=Spp->lastframe+1;
02543 else lf=1;
02544 WaitForUp();
02545 EditObject(Np,(short)lf,(short)frame,YES,NO);
02546 UPDATETIMELINES(IDC_TIMEL_UPDATE)
02547 return NULL;
02548 }
02549
02550 else if(line == 0 && Np->type == DIRECTOR){
02551 Dp=Np->fdirector; Dpp=Dp;
02552 while(Dp != NULL){
02553 Dpp=Dp;
02554 if(Dp->firstframe > frame){
02555 if(Dp->last == NULL)lf=1;
02556 else lf=Dp->last->lastframe+1;
02557 WaitForUp();
02558 EditObject(Np,(short)lf,(short)frame,YES,NO);
02559 UPDATETIMELINES(IDC_TIMEL_UPDATE)
02560 return NULL;
02561 }
02562 if(Dp->firstframe <= frame && Dp->lastframe >= frame){
02563 if(Dp->lastframe == frame){
02564 IndicatedDirector=Dp;
02565 return Np;
02566 }
02567 else if(Dp->firstframe == frame){
02568 IndicatedDirector=Dp;
02569 *keystart=TRUE;
02570 return Np;
02571 }
02572 else{
02573 WaitForUp();
02574 if(!(GetKeyState(VK_CONTROL) & 0x8000) &&
02575 SendPrgmQuery(IDQ_BREAKCHANNEL,1) == IDNO)return NULL;
02576 lf=Dp->firstframe;
02577 Dp->firstframe=frame+1;
02578 EditObject(Np,(short)lf,(short)frame,YES,YES);
02579 UPDATETIMELINES(IDC_TIMEL_UPDATE)
02580 }
02581 return NULL;
02582 }
02583 Dp=Dp->next;
02584 }
02585 if(Dpp != NULL)lf=Dpp->lastframe+1;
02586 else lf=1;
02587 WaitForUp();
02588 EditObject(Np,(short)lf,(short)frame,YES,NO);
02589 UPDATETIMELINES(IDC_TIMEL_UPDATE)
02590 return NULL;
02591 }
02592
02593 else if (line == 0){
02594 if(Np->type == CAMERA)return NULL;
02595 Op=Np->fobj; Opp=Op;
02596 while(Op != NULL){
02597 Opp=Op;
02598 if(Op->firstframe > frame){
02599 if(Op->last == NULL)lf=1;
02600 else lf=Op->last->lastframe+1;
02601 WaitForUp();
02602 EditObject(Np,(short)lf,(short)frame,YES,NO);
02603 UPDATETIMELINES(IDC_TIMEL_UPDATE)
02604 UPDATETRIVIEW(0)
02605 return NULL;
02606 }
02607 if(Op->firstframe <= frame && Op->lastframe >= frame){
02608 if(Op->lastframe == frame){
02609 IndicatedObject=Op;
02610 return Np;
02611 }
02612 else if(Op->firstframe == frame){
02613 IndicatedObject=Op;
02614 *keystart=TRUE;
02615 return Np;
02616 }
02617 else{
02618 WaitForUp();
02619 if(!(GetKeyState(VK_CONTROL) & 0x8000) &&
02620 SendPrgmQuery(IDQ_BREAKCHANNEL,1) == IDNO)return NULL;
02621 lf=Op->firstframe;
02622 Op->firstframe=frame+1;
02623 if(Op->type == PATH){
02624 Op->v=ReTweenVelocity(Op,Op->v,
02625 Op->lastframe-lf+1,
02626 Op->lastframe-Op->firstframe+1,
02627 Op->pathlength,
02628 0);
02629 }
02630 EditObject(Np,(short)lf,(short)frame,YES,YES);
02631 UPDATETIMELINES(IDC_TIMEL_UPDATE)
02632 UPDATETRIVIEW(0)
02633 }
02634 return NULL;
02635 }
02636 Op=Op->next;
02637 }
02638 if(Opp != NULL)lf=Opp->lastframe+1;
02639 else lf=1;
02640 WaitForUp();
02641 EditObject(Np,(short)lf,(short)frame,YES,NO);
02642 UPDATETIMELINES(IDC_TIMEL_UPDATE)
02643 UPDATETRIVIEW(0)
02644 return NULL;
02645 }
02646 if(line == 1){
02647 if(Np->type == SKY || Np->type == IMAGEP || Np->type == DIRECTOR)return NULL;
02648 Pp=Np->fpos; Ppp=Pp;
02649 while(Pp != NULL){
02650 Ppp=Pp;
02651 if(Pp->firstframe > frame){
02652 if(Pp->last == NULL)lf=1;
02653 else lf=Pp->last->lastframe+1;
02654 WaitForUp();
02655 type=0; slf=(short)lf; sframe=(short)frame;
02656 EditPosition(Np,slf,sframe,type,ghwndTimeline);
02657 UPDATETIMELINES(IDC_TIMEL_UPDATE)
02658 UPDATETRIVIEW(0)
02659 return NULL;
02660 }
02661 if(Pp->firstframe <= frame && Pp->lastframe >= frame){
02662 if(Pp->lastframe == frame){
02663 IndicatedPosition=Pp;
02664 return Np;
02665 }
02666 else if(Pp->firstframe == frame){
02667 IndicatedPosition=Pp;
02668 *keystart=TRUE;
02669 return Np;
02670 }
02671 else{
02672 WaitForUp();
02673 if(!(GetKeyState(VK_CONTROL) & 0x8000) &&
02674 SendPrgmQuery(IDQ_BREAKCHANNEL,1) == IDNO)return NULL;
02675 MakeKey('P',frame,Np);
02676 UPDATETRIVIEW(0)
02677 }
02678 return NULL;
02679 }
02680 Pp=Pp->next;
02681 }
02682 if(Ppp != NULL)lf=Ppp->lastframe+1;
02683 else lf=1;
02684 WaitForUp();
02685 type=0; slf=(short)lf; sframe=(short)frame;
02686 EditPosition(Np,slf,sframe,type,ghwndTimeline);
02687 UPDATETIMELINES(IDC_TIMEL_UPDATE)
02688 UPDATETRIVIEW(0)
02689 return NULL;
02690 }
02691 else if(line == 2){
02692 if(Np->type == SKY || Np->type == TARGET || Np->type == DIRECTOR ||
02693 Np->type == PATH || Np->type == IMAGEP)return NULL;
02694 Ap=Np->fali; App=Ap;
02695 while(Ap != NULL){
02696 App=Ap;
02697 if(Ap->firstframe > frame){
02698 if(Ap->last == NULL)lf=1;
02699 else lf=Ap->last->lastframe+1;
02700 WaitForUp();
02701 type=0; slf=(short)lf; sframe=(short)frame;
02702 EditAlign(Np,slf,sframe,type,ghwndTimeline);
02703 UPDATETIMELINES(IDC_TIMEL_UPDATE)
02704 UPDATETRIVIEW(0)
02705 return NULL;
02706 }
02707 if(Ap->firstframe <= frame && Ap->lastframe >= frame){
02708 if(Ap->lastframe == frame){
02709 IndicatedAlign=Ap;
02710 return Np;
02711 }
02712 else if(Ap->firstframe == frame){
02713 IndicatedAlign=Ap;
02714 *keystart=TRUE;
02715 return Np;
02716 }
02717 else{
02718 WaitForUp();
02719 if(!(GetKeyState(VK_CONTROL) & 0x8000) &&
02720 SendPrgmQuery(IDQ_BREAKCHANNEL,1) == IDNO)return NULL;
02721 MakeKey('A',frame,Np);
02722 UPDATETRIVIEW(0)
02723 }
02724 return NULL;
02725 }
02726 Ap=Ap->next;
02727 }
02728 if(App != NULL)lf=App->lastframe+1;
02729 else lf=1;
02730 WaitForUp();
02731 type=0; slf=(short)lf; sframe=(short)frame;
02732 EditAlign(Np,slf,sframe,type,ghwndTimeline);
02733 UPDATETIMELINES(IDC_TIMEL_UPDATE)
02734 UPDATETRIVIEW(0)
02735 return NULL;
02736 }
02737 else if(line == 3){
02738 if(Np->type == SKY || Np->type == TARGET || Np->type == DIRECTOR ||
02739 Np->type == PATH || Np->type == IMAGEP)return NULL;
02740 Xp=Np->fsiz; Xpp=Xp;
02741 while(Xp != NULL){
02742 Xpp=Xp;
02743 if(Xp->firstframe > frame){
02744 if(Xp->last == NULL)lf=1;
02745 else lf=Xp->last->lastframe+1;
02746 WaitForUp();
02747 EditSize(Np,(short)lf,(short)frame);
02748 UPDATETIMELINES(IDC_TIMEL_UPDATE)
02749 UPDATETRIVIEW(0)
02750 return NULL;
02751 }
02752 if(Xp->firstframe <= frame && Xp->lastframe >= frame){
02753 if(Xp->lastframe == frame){
02754 IndicatedSize=Xp;
02755 return Np;
02756 }
02757 else if(Xp->firstframe == frame){
02758 IndicatedSize=Xp;
02759 *keystart=TRUE;
02760 return Np;
02761 }
02762 else{
02763 WaitForUp();
02764 if(!(GetKeyState(VK_CONTROL) & 0x8000) &&
02765 SendPrgmQuery(IDQ_BREAKCHANNEL,1) == IDNO)return NULL;
02766 MakeKey('Z',frame,Np);
02767 UPDATETRIVIEW(0)
02768 }
02769 return NULL;
02770 }
02771 Xp=Xp->next;
02772 }
02773 if(Xpp != NULL)lf=Xpp->lastframe+1;
02774 else lf=1;
02775 WaitForUp();
02776 EditSize(Np,(short)lf,(short)frame);
02777 UPDATETIMELINES(IDC_TIMEL_UPDATE)
02778 UPDATETRIVIEW(0)
02779 return NULL;
02780 }
02781 return NULL;
02782 }
02783
02784 static void GetRealClientRect(HWND hwnd, PRECT lprc){
02785 DWORD dwStyle;
02786 dwStyle = GetWindowLong(hwnd, GWL_STYLE);
02787 GetClientRect(hwnd,lprc);
02788 if (dwStyle & WS_HSCROLL)lprc->bottom += GetSystemMetrics(SM_CYHSCROLL);
02789 if (dwStyle & WS_VSCROLL)lprc->right += GetSystemMetrics(SM_CXVSCROLL);
02790 }
02791
02792 static void SetScrollRanges(HWND hwnd,int update){
02793 RECT rc;
02794 int iRangeH,iRangeV,i;
02795 static int iSem = 0;
02796 if(!iSem){
02797 iSem++;
02798 GetRealClientRect(hwnd,&rc);
02799 for(i = 0; i < 2; i++){
02800 iRangeV = ptSize.y - rc.bottom;
02801 iRangeH = ptSize.x - rc.right;
02802 iRangeV = (iRangeV/A_H+1)*A_H;
02803 iRangeH = (iRangeH/F_W+1)*F_W;
02804 if(iRangeH < 0)iRangeH = 0;
02805 if(keyframer_docked)iRangeH=max(iRangeH,F_W);
02806 if(iRangeV < 0)iRangeV = 0;
02807 SetScrollRange(hwnd, SB_VERT, 0, iRangeV, TRUE);
02808 SetScrollRange(hwnd, SB_HORZ, 0, iRangeH, TRUE);
02809 GetClientRect(hwnd, &rc);
02810 }
02811 iSem--;
02812 if(update)InvalidateRect(hwnd,NULL,TRUE);
02813 }
02814 }
02815
02816 static void GetIndicators(int x, int y, RECT rc,
02817 int *frame, int *actor, int *line,
02818 int *firstframe, int *firstactor,
02819 int *lastframe, int *lastactor){
02820 int f,a,ff,aa;
02821 ff=GetScrollPos(ghwndTimelineChild,SB_HORZ);
02822 aa=GetScrollPos(ghwndTimelineChild,SB_VERT);
02823 f=x+ff;
02824 a=y+aa;
02825 *frame =(f/F_W)+1;
02826 *actor =(a/A_H)+1;
02827 *line =(a-(a/A_H)*A_H)/L_H - 2;
02828 *lastframe=(ff+rc.right)/F_W+1;
02829 *lastactor=(aa+rc.bottom)/A_H+1;
02830 *firstframe=ff/F_W+1;
02831 *firstactor=aa/A_H+1;
02832 }
02833
02834 static void UpdateIndicators(int frame, int actor, int line,
02835 int firstframe, int lastframe){
02836 RECT rc,rcW;
02837 char str[128];
02838 if(frame < 0)strcpy(str," ");
02839 else{
02840 sprintf(str,"%s %ld ",linetype[4],frame);
02841 }
02842 if(IsWindow(hwndTimelineInfo))
02843 SendMessage(hwndTimelineInfo,SB_SETTEXT,(WPARAM)0,(LPARAM)str);
02844 else SendPrgmText(str);
02845 strcpy(str," ");
02846 if(frame >= 0 && line >= 0 && line <= 3 && actor <= Nnodes)strcpy(str,linetype[line]);
02847 if(IsWindow(hwndTimelineInfo))
02848 SendMessage(hwndTimelineInfo,SB_SETTEXT,(WPARAM)1,(LPARAM)str);
02849 }
02850
02851 static void DrawHairs(HDC ihdc, HWND hwnd, int frame, int actor, int line){
02852 int x,y,f,a,oldROP;
02853 HDC hdc;
02854 RECT rc;
02855 HPEN holdpen;
02856 HBRUSH holdbrush;
02857 if(ihdc == NULL)hdc=GetDC(hwnd);
02858 else hdc=ihdc;
02859 holdpen=SelectObject(hdc,GetStockObject(WHITE_PEN));
02860 oldROP=SetROP2(hdc,R2_XORPEN);
02861 GetClientRect(hwnd,&rc);
02862 f=GetScrollPos(ghwndTimelineChild,SB_HORZ)/F_W+1;
02863 a=GetScrollPos(ghwndTimelineChild,SB_VERT)/A_H+1;
02864 x=(frame-f)*F_W+F_W/3;
02865 y=(actor-a)*A_H+20+line*10;
02866 MoveToEx(hdc,x,rc.top,NULL); LineTo(hdc,x,rc.bottom);
02867 #if 0
02868 if(line >= 0 && line <= 3 && frame <= Nframes){
02869 MoveToEx(hdc,x,rc.top,NULL); LineTo(hdc,x,y);
02870 holdbrush=SelectObject(hdc,GetStockObject(HOLLOW_BRUSH));
02871 Rectangle(hdc,x-5,y,x+5,y+9);
02872 MoveToEx(hdc,x,y+9,NULL); LineTo(hdc,x,rc.bottom);
02873 SelectObject(hdc,holdbrush);
02874 }
02875 else if(line == -1){
02876 MoveToEx(hdc,x-5,y+4,NULL); LineTo(hdc,x+6,y+4);
02877 MoveToEx(hdc,x-5,y-4,NULL); LineTo(hdc,x+6,y-4);
02878 MoveToEx(hdc,x,y-4,NULL); LineTo(hdc,x,y+5);
02879 }
02880 else {
02881 MoveToEx(hdc,x-5,y+4,NULL); LineTo(hdc,x+6,y+4);
02882 MoveToEx(hdc,x,rc.top,NULL); LineTo(hdc,x,rc.bottom);
02883 }
02884 #endif
02885 SetROP2(hdc,oldROP);
02886 SelectObject(hdc,holdpen);
02887 if(ihdc == NULL)ReleaseDC(hwnd,hdc);
02888 }
02889
02890 static void DrawTime(HDC hdc,int o,int y,int x0,int x1,HPEN hp, HPEN hps){
02891 HPEN holdpen;
02892
02893 holdpen=SelectObject(hdc,hps);
02894 MoveToEx(hdc,x0+1,y-3,NULL); LineTo(hdc,x0+1,y+3);
02895 MoveToEx(hdc,x0+1,y,NULL); LineTo(hdc,x1,y);
02896 y++;
02897 SelectObject(hdc,hps);
02898
02899 Rectangle(hdc,x1,y-4,x1+7,y+3);
02900 SelectObject(hdc,holdpen);
02901 }
02902
02903 static void DrawFrameIndicators(HDC hdc,int x, int y, int ff, int lf){
02904 int i;
02905 char str[128];
02906 SelectObject(hdc,GetStockObject(BLACK_PEN));
02907 for(i=ff;i<lf;i++,x += F_W){
02908 if(x >= 55){
02909 if(i%10 == 0){
02910 sprintf(str,"%ld",i);
02911 TextOut(hdc,x-4,y,str,strlen(str));
02912 }
02913 else{
02914 if(i < 100)Ellipse(hdc,x+1,y+6,x+5,y+10);
02915 else if(i < 999 && i%10 > 1)Ellipse(hdc,x+1,y+6,x+5,y+10);
02916 else if(i%10 > 2)Ellipse(hdc,x+1,y+6,x+5,y+10);
02917 }
02918 }
02919 }
02920 }
02921
02922 static void DrawPopupButton(HDC hDC,int x,int y){
02923 HBITMAP hbm,hbmOld;
02924 BITMAP bmp;
02925 HDC hMemDC;
02926 int cx,cy;
02927 hbm=LoadBitmap(ghinst_main,MAKEINTRESOURCE(IDBM_QT2));
02928 if(hbm != NULL){
02929 GetObject(hbm,sizeof(BITMAP),&bmp);
02930 cx = bmp.bmWidth;
02931 cy = bmp.bmHeight;
02932 hMemDC = CreateCompatibleDC(hDC);
02933 hbmOld = SelectObject(hMemDC,hbm);
02934 BitBlt(hDC,x,y+3,cx,cy,hMemDC,0,0,SRCAND);
02935 SelectObject(hMemDC,hbmOld);
02936 DeleteDC(hMemDC);
02937 DeleteObject(hbm);
02938 }
02939 }
02940
02941 static void DrawActorNames(HWND hWnd, int fg, int ff, int lf){
02942 int a,na,ac=0;
02943 node *np;
02944 HDC hdc;
02945 RECT rc;
02946 hdc=GetDC(hWnd);
02947 GetClientRect(hWnd,&rc);
02948 SetBkMode(hdc,TRANSPARENT);
02949
02950 SelectObject(hdc,GetStockObject(GRAY_BRUSH));
02951
02952 SetTextColor(hdc,RGB(255,255,255));
02953 LoadString(ghinst_main,IDX_MISC_LANGUAGE,res_str,256);
02954 if(strcmp(res_str,"ENGLISH") == 0)
02955 SelectObject(hdc,GetStockObject(ANSI_VAR_FONT));
02956 a=GetScrollPos(ghwndTimelineChild,SB_VERT)/A_H+1;
02957 na=a+rc.bottom/A_H;
02958 if((np=FirstNp) != NULL)while(np != NULL){
02959 ac++;
02960 if(ac >= a && ac <= na){
02961 if(fg){
02962 DrawFrameIndicators(hdc,0,(ac-a)*A_H+7,ff,lf);
02963 TextOut(hdc,1,(ac-a)*A_H+7,np->actorname,min(strlen(np->actorname),8));
02964 SetTextColor(hdc,RGB(0,0,0));
02965 DrawPopupButton(hdc,45,(ac-a)*A_H+7);
02966 SetTextColor(hdc,RGB(255,255,255));
02967 }
02968
02969 else PatBlt(hdc,0,(ac-a)*A_H+6,rc.right,14,PATCOPY);
02970 }
02971 np=np->next;
02972 }
02973 ReleaseDC(hWnd,hdc);
02974 }
02975
02976 static void DrawActorTime(HDC hdc, HPEN hp, HPEN *hps, RECT rc, int f, int a,
02977 int na, int fa, node *np, int ac, int f_f, int l_f){
02978 int ff,lf;
02979 sky *sp;
02980 director *dp;
02981 object *op;
02982 position *pp;
02983 align *ap;
02984 size *xp;
02985 HBRUSH hOldBrush;
02986 HPEN hPen,hOldPen;
02987 SelectObject(hdc,GetStockObject(BLACK_PEN));
02988 hOldBrush=SelectObject(hdc,GetStockObject(NULL_BRUSH));
02989 lf=(Nframes-f+1)*F_W;
02990 MoveToEx(hdc,0,(ac-a)*A_H+24,NULL); LineTo(hdc,lf,(ac-a)*A_H+24);
02991 MoveToEx(hdc,0,(ac-a)*A_H+34,NULL); LineTo(hdc,lf,(ac-a)*A_H+34);
02992 MoveToEx(hdc,0,(ac-a)*A_H+44,NULL); LineTo(hdc,lf,(ac-a)*A_H+44);
02993 MoveToEx(hdc,0,(ac-a)*A_H+54,NULL); LineTo(hdc,lf,(ac-a)*A_H+54);
02994 if(!ScrollingTimeLine){
02995 LoadString(ghinst_main,IDX_MISC_LANGUAGE,res_str,256);
02996 if(strcmp(res_str,"ENGLISH") == 0)
02997 SelectObject(hdc,GetStockObject(ANSI_VAR_FONT));
02998 SetTextColor(hdc,RGB(255,255,255));
02999 DrawFrameIndicators(hdc,0,(ac-a)*A_H+7,f_f,l_f);
03000 TextOut(hdc,1,(ac-a)*A_H+7,np->actorname,min(strlen(np->actorname),8));
03001 SetTextColor(hdc,RGB(0,0,0));
03002 DrawPopupButton(hdc,45,(ac-a)*A_H+7);
03003 }
03004 SelectObject(hdc,GetStockObject(BLACK_BRUSH));
03005 if(np->type == SKY){
03006 if((sp=np->fsky) != NULL)while(sp != NULL){
03007 ff=sp->firstframe; lf=sp->lastframe;
03008 if( (ff >= f && ff <= fa) ||
03009 (lf >= f && lf <= fa) ||
03010 (ff < f && lf > fa) ){
03011 DrawTime(hdc,0,(ac-a)*A_H+24,(ff-f)*F_W,(lf-f)*F_W,hp,hps[0]);
03012 }
03013 sp=sp->next;
03014 }
03015 }
03016 else if(np->type == DIRECTOR){
03017 if((dp=np->fdirector) != NULL)while(dp != NULL){
03018 ff=dp->firstframe; lf=dp->lastframe;
03019 if( (ff >= f && ff <= fa) ||
03020 (lf >= f && lf <= fa) ||
03021 (ff < f && lf > fa) ){
03022 DrawTime(hdc,0,(ac-a)*A_H+24,(ff-f)*F_W,(lf-f)*F_W,hp,hps[0]);
03023 }
03024 dp=dp->next;
03025 }
03026 }
03027 else{
03028 if((op=np->fobj) != NULL)while(op != NULL){
03029 ff=op->firstframe; lf=op->lastframe;
03030 if( (ff >= f && ff <= fa) ||
03031 (lf >= f && lf <= fa) ||
03032 (ff < f && lf > fa) ){
03033 DrawTime(hdc,0,(ac-a)*A_H+24,(ff-f)*F_W,(lf-f)*F_W,hp,hps[0]);
03034 }
03035 op=op->next;
03036 }
03037 }
03038 if((pp=np->fpos) != NULL)while(pp != NULL){
03039 ff=pp->firstframe; lf=pp->lastframe;
03040 if( (ff >= f && ff <= fa) ||
03041 (lf >= f && lf <= fa) ||
03042 (ff < f && lf > fa) ){
03043 DrawTime(hdc,1,(ac-a)*A_H+34,(ff-f)*F_W,(lf-f)*F_W,hp,hps[1]);
03044 }
03045 pp=pp->next;
03046 }
03047 if((ap=np->fali) != NULL)while(ap != NULL){
03048 ff=ap->firstframe; lf=ap->lastframe;
03049 if( (ff >= f && ff <= fa) ||
03050 (lf >= f && lf <= fa) ||
03051 (ff < f && lf > fa) ){
03052 DrawTime(hdc,2,(ac-a)*A_H+44,(ff-f)*F_W,(lf-f)*F_W,hp,hps[2]);
03053 }
03054 ap=ap->next;
03055 }
03056 if((xp=np->fsiz) != NULL)while(xp != NULL){
03057 ff=xp->firstframe; lf=xp->lastframe;
03058 if( (ff >= f && ff <= fa) ||
03059 (lf >= f && lf <= fa) ||
03060 (ff < f && lf > fa) ){
03061 DrawTime(hdc,3,(ac-a)*A_H+54,(ff-f)*F_W,(lf-f)*F_W,hp,hps[3]);
03062 }
03063 xp=xp->next;
03064 }
03065 hPen=CreatePen(PS_SOLID,2,RGB(192,192,192));
03066 hOldPen=SelectObject(hdc,hPen);
03067 MoveToEx(hdc,0,(ac-a)*A_H+59,NULL); LineTo(hdc,rc.right,(ac-a)*A_H+59);
03068 SelectObject(hdc,hOldPen);
03069 DeleteObject(hPen);
03070 SelectObject(hdc,hOldBrush);
03071 return;
03072 }
03073
03074
03075
03076
03077 static BOOL RegisterTimelineClass(HINSTANCE hInstance){
03078 WNDCLASS wc;
03079
03080 wc.lpszClassName = szTimelineClass;
03081 wc.style = 0;
03082 wc.lpfnWndProc = (WNDPROC)TimelineEditorWndProc;
03083 wc.cbClsExtra = 0;
03084 wc.cbWndExtra = 0;
03085 wc.hInstance = hInstance;
03086 wc.hIcon = LoadIcon(hInstance,"ANIMATORICON");
03087 wc.hCursor = LoadCursor(NULL,IDC_ARROW);
03088 wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
03089 if(keyframer_docked)wc.lpszMenuName = NULL;
03090 else wc.lpszMenuName = MAKEINTRESOURCE(TIMELINE_MENU);
03091 if(!RegisterClass( &wc ))return FALSE;
03092
03093 wc.lpszClassName = szTimelineChildClass;
03094 wc.style = CS_DBLCLKS;
03095 wc.lpfnWndProc = (WNDPROC)TimelineChildWndProc;
03096 wc.cbClsExtra = 0;
03097 wc.cbWndExtra = 0;
03098 wc.hInstance = hInstance;
03099 wc.hIcon = NULL;
03100 wc.hCursor = LoadCursor(NULL,IDC_ARROW);
03101 wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
03102
03103 wc.lpszMenuName = NULL;
03104 if(!RegisterClass( &wc ))return FALSE;
03105 FirstTime=FALSE;
03106 return TRUE;
03107 }
03108
03109 static LRESULT CALLBACK TimelineEditorWndProc(HWND hWnd, UINT msg,
03110 WPARAM wparam, LPARAM lparam ){
03111 int i;
03112 RECT rc;
03113 static RECT ClientClip;
03114 switch( msg ){
03115 case WM_DESTROY:{
03116 char str[64];
03117 if(hTimelineBitmap != NULL)DeleteObject(hTimelineBitmap);
03118 hTimelineBitmap=NULL;
03119 DestroyWindow(ghwndTimelineChild);
03120 if(IsZoomed(hWnd) || IsIconic(hWnd) || keyframer_docked > 0)break;
03121 GetWindowRect(hWnd,&rc);
03122 sprintf(str,"%ld %ld %ld %ld",rc.left,rc.top,
03123 rc.right-rc.left,rc.bottom-rc.top);
03124 if(Preferences.use_positions)
03125 WritePrivateProfileString("KEYFRAMER","POSITION",str,IniFilename);
03126 for(i=0;i<5;i++){
03127 X__Free(linetype[i]); linetype[i]=NULL;
03128 }
03129 }
03130 break;
03131 case WM_CREATE: {
03132 HMENU hmenu = GetSystemMenu(hWnd, FALSE);
03133 RemoveMenu(hmenu, 7, MF_BYPOSITION);
03134
03135 RemoveMenu(hmenu, SC_TASKLIST, MF_BYCOMMAND);
03136 if(!keyframer_docked){
03137 hwndTimelineInfo=CreateWindowEx(0L,STATUSCLASSNAME,"",
03138 WS_CHILD | !WS_BORDER | WS_VISIBLE,
03139 0,0,0,0,
03140 hWnd,
03141 (HMENU)101,
03142 ghinst_main,
03143 NULL);
03144 SendMessage(hwndTimelineInfo,SB_SETPARTS,(WPARAM)3,
03145 (LPARAM)TimelineStatusPartsList);
03146 }
03147 else hwndTimelineInfo=NULL;
03148 ghwndTimelineChild = CreateWindow(szTimelineChildClass," ",
03149 fdwStyleC,
03150 0,0,0,0,
03151 hWnd,
03152 (HMENU)102,
03153 ghinst_main,NULL);
03154 hTimelineBitmap=LoadBitmap(ghinst_main,MAKEINTRESOURCE(IDBM_TIMELINE));
03155 }
03156 break;
03157 case WM_PAINT: {
03158 HDC hdc;
03159 PAINTSTRUCT ps;
03160 hdc=BeginPaint(hWnd,&ps);
03161 if(keyframer_docked && hTimelineBitmap != NULL){
03162 HDC hMemDC;
03163 HBITMAP hbmOld;
03164 BITMAP bmp;
03165 hMemDC = CreateCompatibleDC(hdc);
03166 GetObject(hTimelineBitmap,sizeof(BITMAP),&bmp);
03167 hbmOld = SelectObject(hMemDC,hTimelineBitmap);
03168 BitBlt(hdc,0,0,bmp.bmWidth,bmp.bmHeight,hMemDC,0,0,SRCCOPY);
03169 SelectObject(hMemDC, hbmOld);
03170 DeleteDC(hMemDC);
03171 }
03172 EndPaint(hWnd,&ps);
03173 }
03174 break;
03175
03176 case WM_ACTIVATE:
03177 if(IndicatorVisible)DrawHairs(NULL,ghwndTimelineChild,
03178 IndicatedFrame,IndicatedActor,IndicatedLine);
03179 if(wparam)IndicatorActive=YES;
03180 else IndicatorActive=NO;
03181 IndicatorVisible=NO;
03182 break;
03183
03184 case WM_MOUSEMOVE:
03185 case WM_NCMOUSEMOVE:
03186 if(IndicatorVisible)DrawHairs(NULL,ghwndTimelineChild,
03187 IndicatedFrame,IndicatedActor,IndicatedLine);
03188 IndicatorVisible=NO;
03189 UpdateIndicators(-1,-1,-1,-1,-1);
03190 IndicatedFrame = -1; IndicatedActor = -1; IndicatedLine = -1;
03191 break;
03192 case WM_SIZE:{
03193 int yOff=0,xOff=0;
03194 if(keyframer_docked){
03195 yOff=1;
03196 xOff=56;
03197 }
03198 if(IsWindow(hwndTimelineInfo)){
03199 SendMessage(hwndTimelineInfo,msg,wparam,lparam);
03200 i=InfoWindowSize;
03201 }
03202 else i=0;
03203 MoveWindow(ghwndTimelineChild,xOff,yOff,
03204 LOWORD(lparam)-xOff,
03205 HIWORD(lparam)-i-yOff,TRUE);
03206 }
03207 break;
03208 case WM_SYSCOMMAND:
03209 switch(LOWORD(wparam & 0xfff0)){
03210 case SC_MINIMIZE:
03211 PostMessage(ghwnd_main,WM_COMMAND,IDM_FILE_KEYFRAMERDOCK,0);
03212 break;
03213 case SC_CLOSE:
03214 PostMessage(hWnd,WM_COMMAND,IDM_TIMELINE_HIDE,0);
03215 break;
03216 default:
03217 return( DefWindowProc( hWnd, msg, wparam, lparam ) );
03218 break;
03219 }
03220 break;
03221 case WM_COMMAND:{
03222 switch (LOWORD(wparam)){
03223 case IDM_TIMELINE_ACTOR_ADD:
03224 AddOnlyNewNode(hWnd,-1);
03225 UPDATETIMELINES(IDC_TIMEL_UPDATE)
03226 break;
03227 case IDM_TIMELINE_ACTOR_ORDER:
03228 DialogBox(ghinst_main,MAKEINTRESOURCE(DLG_REORDER),
03229 ghwndTimeline,(DLGPROC)ReorderDlgProc);
03230 UPDATETIMELINES(IDC_TIMEL_UPDATE)
03231 break;
03232 case IDM_TIMELINE_ACTOR_DELETE:
03233 case IDM_TIMELINE_ACTOR_RENAME:
03234 case IDM_TIMELINE_ACTOR_INFO:
03235 case IDM_TIMELINE_ACTOR_SAVEANIOBJ:
03236 DoKeyFramerCommand(wparam,0);
03237 break;
03238 case IDM_TIMELINE_FRAMES:
03239 SendMessage(ghwnd_main,WM_COMMAND,IDM_FRAME_SETNUMBER,0);
03240 break;
03241 case IDM_TIMELINE_INSERTFRAMES:
03242 SendMessage(ghwnd_main,WM_COMMAND,IDM_FRAME_INSERT,0);
03243 break;
03244 case IDM_TIMELINE_DELETEFRAMES:
03245 SendMessage(ghwnd_main,WM_COMMAND,IDM_FRAME_DELETE,0);
03246 break;
03247 case IDM_TIMELINE_HIDE:{
03248 char tt[128];
03249 ShowWindow(hWnd,SW_HIDE);
03250 TimeLineVisibleFlag=0;
03251 IndicatorVisible = NO;
03252 IndicatedActor= -1, IndicatedFrame= -1, IndicatedLine= -1;
03253 LoadString(ghinst_main,IDX_MISC_SKEYFRAMER,tt,128);
03254 ModifyMenu(GetMenu(ghwnd_main),IDM_FILE_KEYFRAMER,
03255 MF_BYCOMMAND|MF_STRING,IDM_FILE_KEYFRAMER,tt);
03256 }
03257 break;
03258 case IDC_TIMEL_UPDATE:
03259 SendMessage(ghwndTimelineChild,WM_KEYFRAMEUPDATE,0,0);
03260 break;
03261 default: break;
03262 }
03263 break;
03264 }
03265 default:
03266 return( DefWindowProc( hWnd, msg, wparam, lparam ) );
03267 }
03268 return( 0L );
03269 }
03270
03271 static LRESULT CALLBACK TimelineChildWndProc(HWND hWnd, UINT msg,
03272 WPARAM wparam, LPARAM lparam ){
03273 int i,iPos,iMax,iMin,dn,lastframe,lastactor,firstframe,firstactor;
03274 RECT rc;
03275 POINT pt;
03276 static BOOL bTrackMouse=FALSE,bClientArea=FALSE,bEditKey=FALSE,
03277 bEditKeyStart=FALSE;
03278 static RECT ClientClip;
03279 switch( msg ){
03280 case WM_PAINT: {
03281 HDC hdc;
03282 PAINTSTRUCT ps;
03283 node *np;
03284 HPEN hp,hps[4];
03285 int f,a,ac=0,na,fa;
03286 hdc=BeginPaint(hWnd,&ps);
03287 SetBkMode(hdc,TRANSPARENT);
03288 f=GetScrollPos(hWnd,SB_HORZ)/F_W+1;
03289 a=GetScrollPos(hWnd,SB_VERT)/A_H+1;
03290 hp=CreatePen(PS_SOLID,2,RGB(255,0,0));
03291 #if 0 // the original colours
03292 hps[0]=CreatePen(PS_SOLID,2,RGB(0,255,255));
03293 hps[1]=CreatePen(PS_SOLID,2,RGB(255,255,0));
03294 hps[2]=CreatePen(PS_SOLID,2,RGB(0,255,0));
03295 hps[3]=CreatePen(PS_SOLID,2,RGB(255,0,0));
03296 #endif
03297 hps[0]=CreatePen(PS_SOLID,2,RGB(145,255,94));
03298 hps[1]=CreatePen(PS_SOLID,2,RGB(0,255,255));
03299 hps[2]=CreatePen(PS_SOLID,2,RGB(255,255,0));
03300 hps[3]=CreatePen(PS_SOLID,2,RGB(255,96,0));
03301 na=a+ps.rcPaint.bottom/A_H; fa=f+ps.rcPaint.right/F_W;
03302 if((np=FirstNp) != NULL)while(np != NULL){
03303 ac++;
03304 if(ac >= a && ac <= na){
03305 GetClientRect(hWnd,&rc);
03306 GetIndicators(0,0,rc,&i,&i,&i,&firstframe,&i,&lastframe,&i);
03307 DrawActorTime(hdc,hp,hps,ps.rcPaint,f,a,na,fa,np,ac,
03308 firstframe,lastframe);
03309 }
03310 np=np->next;
03311 }
03312 if(IndicatorVisible){
03313 DrawHairs(hdc,hWnd,IndicatedFrame,IndicatedActor,IndicatedLine);
03314 UpdateWindow(hWnd);
03315 }
03316 DeleteObject(hp);
03317 DeleteObject(hps[0]); DeleteObject(hps[1]);
03318 DeleteObject(hps[2]); DeleteObject(hps[3]);
03319 EndPaint(hWnd,&ps);
03320 }
03321 break;
03322 case WM_LBUTTONDBLCLK:
03323 if(bEditKey){
03324 Save_UndoA();
03325 if(IndicatedLine == 0)EditObject(IndicatedNode,
03326 (short)IndicatedFrame,
03327 (short)IndicatedFrame,
03328 YES,NO);
03329 if(IndicatedLine == 1)EditPosition(IndicatedNode,
03330 (short)IndicatedFrame,
03331 (short)IndicatedFrame,-1,ghwndTimeline);
03332 if(IndicatedLine == 2)EditAlign(IndicatedNode,
03333 (short)IndicatedFrame,
03334 (short)IndicatedFrame,-1,ghwndTimeline);
03335 if(IndicatedLine == 3)EditSize(IndicatedNode,
03336 (short)IndicatedFrame,(short)IndicatedFrame);
03337 IndicatedNode=NULL;
03338 UPDATETIMELINES(IDC_TIMEL_UPDATE)
03339 UPDATETRIVIEW(0)
03340 bEditKey=0;
03341 }
03342
03343 break;
03344 case WM_LBUTTONDOWN:
03345 if(IndicatorActive == YES){
03346
03347 UpdateWindow(hWnd);
03348 if(!IndicatorVisible){
03349 GetClientRect(hWnd,&rc);
03350 GetIndicators((int)LOWORD(lparam),(int)HIWORD(lparam),rc,
03351 &IndicatedFrame,&IndicatedActor,&IndicatedLine,
03352 &firstframe,&firstactor,&lastframe,&lastactor);
03353 DrawHairs(NULL,hWnd,IndicatedFrame,IndicatedActor,IndicatedLine);
03354 UpdateWindow(hWnd);
03355 IndicatorVisible=YES;
03356 }
03357 }
03358 if(tool != NOTOOL){
03359 MessageBeep(MB_OK);
03360 break;
03361 }
03362 bEditKey=FALSE;
03363 if(IndicatedActor > 0 && IndicatedActor <= Nnodes &&
03364 IndicatedFrame > 0 && IndicatedFrame <= Nframes &&
03365 IndicatedLine >= 0 && IndicatedLine < 4){
03366 int f,a;
03367 f=GetScrollPos(hWnd,SB_HORZ)/F_W;
03368 a=GetScrollPos(hWnd,SB_VERT)/A_H;
03369 SetCapture(hWnd);
03370 GetClientRect(hWnd,&rc);
03371 pt.x=0;
03372 pt.y=(IndicatedActor-1-a)*A_H+(IndicatedLine+2)*L_H;
03373 ClientClip.left=pt.x; ClientClip.top=pt.y;
03374 ClientToScreen(hWnd,&pt); rc.left=pt.x; rc.top=pt.y;
03375 pt.x=rc.right;
03376 pt.y=min((IndicatedActor-1-a)*A_H+(IndicatedLine+3)*L_H,rc.bottom);
03377 ClientClip.right=pt.x; ClientClip.bottom=pt.y-1;
03378 ClientToScreen(hWnd,&pt); rc.right=pt.x; rc.bottom=pt.y;
03379 ClipCursor(&rc);
03380 bTrackMouse=TRUE;
03381 if((IndicatedNode=EditTimeLine(IndicatedActor,IndicatedFrame,
03382 IndicatedLine,&bEditKeyStart)) != NULL)bEditKey=TRUE;
03383 }
03384 else if((IndicatedLine == -1 || IndicatedLine == -2)
03385 && IndicatedActor <= Nnodes
03386 && LOWORD(lparam) < 55 && LOWORD(lparam) > 42){
03387 Save_UndoA();
03388 {
03389 POINT pt;
03390 HMENU hMenu=LoadMenu(ghinst_main,"KeyframerPopupMenu");
03391 node *local_node;
03392 if(hMenu == NULL)break;
03393 pt.x=LOWORD(lparam);
03394 pt.y=HIWORD(lparam);
03395 ClientToScreen(hWnd,&pt);
03396 local_node=FirstNp;
03397 if(IndicatedActor > 1)
03398 for(i=1;i<IndicatedActor;i++)local_node=local_node->next;
03399 if(local_node != NULL){
03400 if(local_node->type != NORMAL)
03401 EnableMenuItem(hMenu,IDM_TIMELINE_ACTOR_SAVEANIOBJ,MF_GRAYED);
03402 if(local_node->type == CAMERA ||
03403 local_node->type == DIRECTOR ||
03404 local_node->type == SKY)
03405 EnableMenuItem(hMenu,IDM_TIMELINE_ACTOR_INFO,MF_GRAYED);
03406 }
03407 TrackPopupMenu(GetSubMenu(hMenu,0),TPM_LEFTALIGN | TPM_LEFTBUTTON,
03408 pt.x,pt.y,0,hWnd,NULL);
03409 DestroyMenu(hMenu);
03410 }
03411 }
03412 break;
03413 case WM_LBUTTONUP:
03414 if(IndicatorsChanged){
03415 IndicatorsChanged=NO;
03416 UPDATETRIVIEW(0)
03417 if(IndicatedNode != NULL){
03418 if(IndicatedObject != NULL && IndicatedObject->type == PATH){
03419 int dfn;
03420 dfn=IndicatedObject->lastframe - IndicatedObject->firstframe + 1;
03421 IndicatedObject->v=ReTweenVelocity(IndicatedObject,
03422 IndicatedObject->v,
03423 -1,dfn,
03424 IndicatedObject->pathlength,
03425 0);
03426 }
03427 CheckRecursiveFollow(IndicatedNode,1,(short)Nframes);
03428 }
03429 }
03430 if(bTrackMouse){
03431 bTrackMouse=FALSE;
03432 IndicatedSky=NULL; IndicatedObject=NULL;
03433 IndicatedPosition=NULL; IndicatedAlign=NULL;
03434 IndicatedSize=NULL; IndicatedDirector=NULL;
03435 ClipCursor(NULL);
03436 if(ScrollingTimeLine){
03437 if(IndicatorVisible)DrawHairs(NULL,hWnd,
03438 IndicatedFrame,IndicatedActor,IndicatedLine);
03439 GetClientRect(hWnd,&rc);
03440 GetIndicators(0,0,rc,&i,&i,&i,&firstframe,&i,&lastframe,&i);
03441 DrawActorNames(hWnd,1,firstframe,lastframe);
03442 if(IndicatorVisible)DrawHairs(NULL,hWnd,
03443 IndicatedFrame,IndicatedActor,IndicatedLine);
03444 ScrollingTimeLine=0;
03445 }
03446 ReleaseCapture();
03447 }
03448 break;
03449 case WM_MOUSEMOVE:
03450
03451 bClientArea=TRUE;
03452 GetClientRect(hWnd,&rc);
03453 i=IndicatedFrame;
03454 iMin=IndicatedLine; iMax=IndicatedActor;
03455 GetIndicators((int)LOWORD(lparam),(int)HIWORD(lparam),rc,
03456 &IndicatedFrame,&IndicatedActor,&IndicatedLine,
03457 &firstframe,&firstactor,&lastframe,&lastactor);
03458 if(IndicatorActive && (i != IndicatedFrame ||
03459 iMax != IndicatedActor || iMin != IndicatedLine)){
03460 UpdateWindow(hWnd);
03461 if(IndicatorVisible)DrawHairs(NULL,hWnd,i,iMax,iMin);
03462 DrawHairs(NULL,hWnd,IndicatedFrame,IndicatedActor,IndicatedLine);
03463 IndicatorVisible=YES;
03464 }
03465 UpdateIndicators(IndicatedFrame,IndicatedActor,IndicatedLine,
03466 firstframe,lastframe);
03467 if(i != IndicatedFrame){
03468 if(ChangeIndicatedKeys(bEditKeyStart)){
03469 IndicatorsChanged=YES;
03470 InvalidateRect(hWnd,&ClientClip,TRUE);
03471 UpdateWindow(hWnd);
03472 }
03473 }
03474 if(bTrackMouse && (IndicatedFrame >= lastframe-1 ||
03475 IndicatedFrame == firstframe) ){
03476 GetScrollRange(hWnd, SB_HORZ, &iMin, &iMax);
03477 iPos = GetScrollPos(hWnd, SB_HORZ);
03478 if(IndicatedFrame >= lastframe-1)dn= F_W;
03479 else dn= -F_W;
03480 if ((dn = BOUND (iPos + dn, iMin, iMax) - iPos) != 0) {
03481 if(IndicatorVisible)DrawHairs(NULL,hWnd,
03482 IndicatedFrame,IndicatedActor,IndicatedLine);
03483 DrawActorNames(hWnd,0,firstframe,lastframe);
03484 if(IndicatorVisible)DrawHairs(NULL,hWnd,
03485 IndicatedFrame,IndicatedActor,IndicatedLine);
03486 ScrollingTimeLine=1;
03487 ScrollWindow(hWnd, -dn, 0, NULL, NULL);
03488 SetScrollPos(hWnd, SB_HORZ, iPos + dn, TRUE);
03489 UpdateWindow(hWnd);
03490 GetCursorPos(&pt);
03491 if(IndicatedFrame >= lastframe-1)pt.x -= dn;
03492 else pt.x += (abs(dn));
03493 SetCursorPos(pt.x,pt.y);
03494 }
03495 }
03496 break;
03497 case WM_VSCROLL:
03498 GetScrollRange (hWnd, SB_VERT, &iMin, &iMax);
03499 iPos = GetScrollPos (hWnd, SB_VERT);
03500 GetClientRect (hWnd, &rc);
03501 switch (LOWORD(wparam)) {
03502 case SB_ENDSCROLL:
03503 dn=0;
03504 break;
03505 case SB_LINEDOWN: dn = A_H; break;
03506 case SB_LINEUP: dn = -A_H; break;
03507 case SB_PAGEDOWN: dn = rc.bottom / 2 + A_H; break;
03508 case SB_PAGEUP: dn = -rc.bottom / 2 - A_H; break;
03509 case SB_THUMBTRACK:
03510 case SB_THUMBPOSITION:
03511 dn = HIWORD(wparam)-iPos;
03512 break;
03513 default: dn = 0;
03514 }
03515
03516 dn=(dn/A_H)*A_H;
03517 if ((dn = BOUND (iPos + dn, iMin, iMax) - iPos) != 0) {
03518 ScrollWindow(hWnd, 0, -dn, NULL, NULL);
03519 SetScrollPos(hWnd, SB_VERT, iPos + dn, TRUE);
03520 IndicatedActor=(iPos+dn)/A_H+1;
03521 }
03522 break;
03523 case WM_HSCROLL:
03524
03525 GetScrollRange(hWnd, SB_HORZ, &iMin, &iMax);
03526 iPos = GetScrollPos(hWnd, SB_HORZ);
03527 GetClientRect (hWnd, &rc);
03528 switch (LOWORD(wparam)) {
03529 case SB_ENDSCROLL:
03530 if(ScrollingTimeLine){
03531 ScrollingTimeLine=0;
03532 GetIndicators(0,0,rc,&i,&i,&i,&firstframe,&i,&lastframe,&i);
03533 DrawActorNames(hWnd,1,firstframe,lastframe);
03534 }
03535 dn=0;
03536 break;
03537 case SB_LINEDOWN: dn = F_W; break;
03538 case SB_LINEUP: dn = -F_W; break;
03539 case SB_PAGEDOWN: dn = rc.right/5+F_W; break;
03540 case SB_PAGEUP: dn = -rc.right/5+F_W; break;
03541 case SB_THUMBTRACK:
03542 case SB_THUMBPOSITION:
03543 dn = HIWORD(wparam) - iPos;
03544 break;
03545 default: dn = 0;
03546 }
03547
03548 dn=(dn/F_W)*F_W;
03549 if ((dn = BOUND (iPos + dn, iMin, iMax) - iPos) != 0) {
03550 ScrollingTimeLine=1;
03551 GetIndicators(0,0,rc,&i,&i,&i,&firstframe,&i,&lastframe,&i);
03552 DrawActorNames(hWnd,0,firstframe,lastframe);
03553 ScrollWindow(hWnd, -dn, 0, NULL, NULL);
03554 SetScrollPos(hWnd, SB_HORZ, iPos + dn, TRUE);
03555 iMin=(iPos+dn)/F_W+1;
03556 iMax=(iPos+dn+rc.right)/F_W+1;
03557 UpdateIndicators(iMin,-1,-1,iMin,iMax);
03558 }
03559 break;
03560 case WM_SIZE:
03561 SetScrollRanges(hWnd,1);
03562 break;
03563 case WM_NCMOUSEMOVE:{
03564 if(!bClientArea)break;
03565 bClientArea=FALSE;
03566 if(IndicatorVisible)DrawHairs(NULL,hWnd,
03567 IndicatedFrame,IndicatedActor,IndicatedLine);
03568 IndicatorVisible=NO;
03569 UpdateIndicators(-1,-1,-1,-1,-1);
03570 IndicatedFrame = -1; IndicatedActor = -1; IndicatedLine = -1;
03571 }
03572 break;
03573 case WM_KEYFRAMEUPDATE:
03574 if(!TimeLineVisibleFlag)TimeLineUpdateFlag=1;
03575 else{
03576 TimeLineUpdateFlag=0;
03577 if(Nframes != NoldFrames || NoldNodes != Nnodes){
03578 ptSize.x=Nframes*F_W; ptSize.y=Nnodes*A_H;
03579 SetScrollRanges(hWnd,0);
03580 if(Nframes < NoldFrames){
03581 GetScrollRange(hWnd, SB_HORZ, &iMin, &iMax);
03582 SetScrollPos(hWnd,SB_HORZ,iMin,TRUE);
03583 }
03584 if(Nnodes < NoldNodes){
03585 GetScrollRange(hWnd, SB_VERT, &iMin, &iMax);
03586 SetScrollPos(hWnd,SB_VERT,iMin,TRUE);
03587 }
03588 NoldFrames=Nframes; NoldNodes=Nnodes;
03589 }
03590 InvalidateRect(hWnd,NULL,TRUE);
03591 UpdateWindow(hWnd);
03592 }
03593 break;
03594 case WM_COMMAND:
03595 switch (LOWORD(wparam)){
03596 case IDM_TIMELINE_ACTOR_DELETE:
03597 case IDM_TIMELINE_ACTOR_RENAME:
03598 case IDM_TIMELINE_ACTOR_INFO:
03599 case IDM_TIMELINE_ACTOR_SAVEANIOBJ:
03600 DoKeyFramerCommand(wparam,IndicatedActor);
03601 break;
03602 default:
03603 break;
03604 }
03605 default:
03606 return( DefWindowProc( hWnd, msg, wparam, lparam ) );
03607 }
03608 return( 0L );
03609 }
03610
03611 static void DoKeyFramerCommand(WPARAM wparam, int local_actor){
03612 int i,id;
03613 node *local_node,*temp_node;
03614 char local_nodename[128];
03615 if(local_actor == 0){
03616 if((local_node=SelectNode(local_nodename,YES,ghwndTimeline))
03617 == NULL)return;
03618 }
03619 else {
03620 local_node=FirstNp;
03621 if(local_actor > 1)for(i=1;i<local_actor;i++)local_node=local_node->next;
03622 if(local_node == NULL)return;
03623
03624
03625
03626
03627 strcpy(local_nodename,local_node->actorname);
03628 }
03629 switch (LOWORD(wparam)){
03630 case IDM_TIMELINE_ACTOR_DELETE:
03631 if(local_node->type == CAMERA){
03632 if(local_node == FirstNp){
03633 SendPrgmQuery(IDQ_CAMERANODELETE,0);
03634 break;
03635 }
03636 if(local_node == SelectedCamera)SelectedCamera=FirstNp;
03637 DeleteNode(local_node);
03638 SelectedNode=NULL;
03639 UpdateSelectedActor(FALSE);
03640 Ncameras--;
03641 }
03642 else {
03643 if(local_node->type == GROUND)Nground=0;
03644 if(local_node->type == SKY)Nskys=0;
03645 if(local_node->type == DIRECTOR)Ndirectors=0;
03646 if(local_node->type == ROBOT)Nrobots--;
03647 DeleteNode(local_node);
03648 SelectedNode=NULL;
03649 UpdateSelectedActor(FALSE);
03650 }
03651 UPDATETIMELINES(IDC_TIMEL_UPDATE)
03652 UPDATETRIVIEW(0)
03653 break;
03654 case IDM_TIMELINE_ACTOR_RENAME:
03655 LoadString(ghinst_main,IDX_MISC_RENAMEOBJECT,res_str,256);
03656 RequestCharString(64,local_node->actorname,res_str);
03657 UPDATETIMELINES(IDC_TIMEL_UPDATE)
03658 break;
03659 case IDM_TIMELINE_ACTOR_INFO:
03660 temp_node=SelectedNode;
03661 SelectedNode=local_node;
03662 SelectedInfo();
03663 SelectedNode=temp_node;
03664 break;
03665 case IDM_TIMELINE_ACTOR_SAVEANIOBJ:
03666 SaveAnimFile(local_node);
03667 break;
03668 }
03669 }
03670
03671 void TimelineEditor(void){
03672 char str[64];
03673 char tt[128];
03674 int i,x,y,cx,cy,nf;
03675 if(FirstTime){
03676 if(!RegisterTimelineClass(ghinst_main))return;
03677 xScreen = GetSystemMetrics(SM_CXSCREEN);
03678 yScreen = GetSystemMetrics(SM_CYSCREEN);
03679 nXBorder = (INT)GetSystemMetrics(SM_CXFRAME);
03680 nXTitle = (INT)GetSystemMetrics(SM_CXSIZE);
03681 nYTitle = (INT)GetSystemMetrics(SM_CYSIZE);
03682 x=0; y=nYTitle+GetSystemMetrics(SM_CYFRAME)+GetSystemMetrics(SM_CYMENU)
03683 +GetSystemMetrics(SM_CYBORDER);
03684 if(Xres >= 800)nf=60; else nf=40;
03685 cx=(max(nf,Nframes))*F_W; cy=(max(3,Nnodes))*A_H+25;
03686 GetPrivateProfileString("KEYFRAMER","POSITION","$$$",
03687 str,sizeof(str),IniFilename);
03688 if(Preferences.use_positions && strncmp(str,"$$$",3) != 0){
03689 int xx,yy,cxx,cyy;
03690 sscanf(str,"%ld %ld %ld %ld",&xx,&yy,&cxx,&cyy);
03691 if(xx < Xres-10 && yy < Yres-10){
03692 x=xx; y=yy;
03693 cx=cxx;
03694 cy=cyy;
03695 }
03696 }
03697 NoldFrames=Nframes; NoldNodes=Nnodes;
03698 for(i=0;i<5;i++)linetype[i]=X__Malloc(16);
03699 if(linetype[0] != NULL)LoadString(ghinst_main,IDX_MISC_LINE1,linetype[0],16);
03700 if(linetype[1] != NULL)LoadString(ghinst_main,IDX_MISC_LINE2,linetype[1],16);
03701 if(linetype[2] != NULL)LoadString(ghinst_main,IDX_MISC_LINE3,linetype[2],16);
03702 if(linetype[3] != NULL)LoadString(ghinst_main,IDX_MISC_LINE4,linetype[3],16);
03703 if(linetype[4] != NULL)LoadString(ghinst_main,IDX_MISC_LINE0,linetype[4],16);
03704 LoadString(ghinst_main,IDX_MISC_KEYFRAMER,str,64);
03705 if(keyframer_docked){
03706 RECT rc;
03707 GetClientRect(ghwnd_main,&rc);
03708 if((ghwndTimeline = CreateWindow(szTimelineClass,str,
03709 fdwStyleD,
03710 0,KeyframerYpos,
03711 rc.right,KeyframerSize,
03712 ghwnd_main,NULL,ghinst_main,NULL)) == NULL)return;
03713 }
03714 else{
03715 if((ghwndTimeline = CreateWindow(szTimelineClass,str,
03716 fdwStyleP,
03717 x,y,0,0,ghwnd_main,NULL,ghinst_main,NULL)) == NULL)return;
03718 SetWindowPos(ghwndTimeline,(HWND)NULL,0,0,
03719 min(Xres,cx),min(Yres-100,cy),SWP_NOMOVE | SWP_NOZORDER);
03720 }
03721 ShowWindow(ghwndTimeline,SW_SHOW);
03722 TimeLineVisibleFlag=1;
03723 LoadString(ghinst_main,IDX_MISC_HKEYFRAMER,tt,128);
03724 ModifyMenu(GetMenu(ghwnd_main),IDM_FILE_KEYFRAMER,
03725 MF_BYCOMMAND|MF_STRING,IDM_FILE_KEYFRAMER,tt);
03726 { int iMin,iMax;
03727 ptSize.x=Nframes*F_W; ptSize.y=Nnodes*A_H;
03728 SetScrollRanges(ghwndTimelineChild,0);
03729 GetScrollRange(ghwndTimelineChild, SB_HORZ, &iMin, &iMax);
03730 SetScrollPos(ghwndTimelineChild,SB_HORZ,iMin,TRUE);
03731 GetScrollRange(ghwndTimelineChild, SB_VERT, &iMin, &iMax);
03732 SetScrollPos(ghwndTimelineChild,SB_VERT,iMin,TRUE);
03733 InvalidateRect(ghwndTimeline,NULL,TRUE);
03734 UpdateWindow(ghwndTimeline);
03735 }
03736 if(keyframer_docked)IndicatorActive=YES;
03737 }
03738 else{
03739 if(TimeLineVisibleFlag == 0){
03740 LoadString(ghinst_main,IDX_MISC_HKEYFRAMER,tt,128);
03741 ModifyMenu(GetMenu(ghwnd_main),IDM_FILE_KEYFRAMER,
03742 MF_BYCOMMAND|MF_STRING,IDM_FILE_KEYFRAMER,tt);
03743 ShowWindow(ghwndTimeline,SW_SHOW);
03744 TimeLineVisibleFlag=1;
03745 if(TimeLineUpdateFlag)UPDATETIMELINES(IDC_TIMEL_UPDATE)
03746 }
03747 else SendMessage(ghwndTimeline,WM_COMMAND,IDM_TIMELINE_HIDE,0);
03748 }
03749 }
03750
03751 void DestroyTimelineEditor(void){
03752 if(FirstTime)return;
03753 DestroyWindow(ghwndTimeline);
03754 FirstTime=TRUE;
03755 ScrollingTimeLine=0;
03756 TimeLineUpdateFlag=0;
03757 TimeLineVisibleFlag=0;
03758 keyframer_docked_and_visible=0;
03759 IndicatorVisible = NO; IndicatorActive=NO; IndicatorsChanged=NO;
03760 IndicatedActor= -1; IndicatedFrame= -1; IndicatedLine= -1;
03761 UnregisterClass(szTimelineClass,ghinst_main);
03762 UnregisterClass(szTimelineChildClass,ghinst_main);
03763 ghwndTimeline=NULL;
03764 ghwndTimelineChild=NULL;
03765 hwndTimelineInfo=NULL;
03766 return;
03767 }
03768
03769 void AutoUpdateKeyframerVpos(void){
03770 node *np;
03771 long c;
03772 if(!keyframer_docked_and_visible)return;
03773 if(SelectedNode == NULL)return;
03774 if(ghwndTimelineChild == NULL)return;
03775 if(!Preferences.auto_update_keyframer)return;
03776 c=0;
03777 if((np=FirstNp) != NULL)while(np != NULL){
03778 if(SelectedNode == np){
03779 SetScrollPos(ghwndTimelineChild,SB_VERT,c*A_H,TRUE);
03780 InvalidateRect(ghwndTimelineChild,NULL,TRUE);
03781
03782 return;
03783 }
03784 c++;
03785 np=np->next;
03786 }
03787 return;
03788 }
03789
03790
03791 #define EXTEND 0
03792 #define CHOP 0
03793 #define SCALE 1
03794 #define BLANKS 2
03795
03796 BOOL ActorNameExists(HWND parent,node *this_node,char *name){
03797 node *np;
03798 np=FirstNp; while(np != NULL){
03799 if(np != this_node){
03800 if(strcmpi(np->actorname,name) == 0){
03801 SendPrgmQuery(IDQ_ACTORNAMEEXISTS,0);
03802 return TRUE;
03803 }
03804 }
03805 np=np->next;
03806 }
03807 return FALSE;
03808 }
03809
03810 void ShiftAllKeys(int allActors){
03811 int n;
03812 node *Np,*Nstart;
03813 object *Op,*Op1;
03814 sky *Sp,*Sp1;
03815 director *Dp,*Dp1;
03816 position *Pp,*Pp1;
03817 align *Ap,*Ap1;
03818 size *Xp,*Xp1;
03819 if(allActors)Nstart=FirstNp;
03820 else Nstart=SelectedNode;
03821 if(Nstart == NULL)return;
03822 n=DialogBox(ghinst_main,MAKEINTRESOURCE(DLG_SHIFTKEYS),
03823 ghwnd_main,(DLGPROC)ShiftKeysDlgProc);
03824 if(n == 0)return;
03825 if(n < -Nframes || n > Nframes){
03826 SendPrgmQuery(IDQ_TOOMANYFRAMES,0);
03827 return;
03828 }
03829 Save_UndoA();
03830 if((Np=Nstart) != NULL)while(Np != NULL){
03831 if(n > 0){
03832 if(Np->type != CAMERA && (Op=Np->fobj) != NULL)while(Op != NULL){
03833 Op1=Op; Op=Op->next;
03834 if(Op1->firstframe+n > Nframes)DeleteCostume(Np,Op1->firstframe);
03835 }
03836 if((Sp=Np->fsky) != NULL)while(Sp != NULL){
03837 Sp1=Sp; Sp=Sp->next;
03838 if(Sp1->firstframe+n > Nframes)DeleteSky(Np,Sp1->firstframe);
03839 }
03840 if((Dp=Np->fdirector) != NULL)while(Dp != NULL){
03841 Dp1=Dp; Dp=Dp->next;
03842 if(Dp1->firstframe+n > Nframes)DeleteDirector(Np,Dp1->firstframe);
03843 }
03844 if((Pp=Np->fpos) != NULL)while(Pp != NULL){
03845 Pp1=Pp; Pp=Pp->next;
03846 if(Pp1->firstframe+n > Nframes)DeletePosition(Np,Pp1->firstframe);
03847 }
03848 if((Ap=Np->fali) != NULL)while(Ap != NULL){
03849 Ap1=Ap; Ap=Ap->next;
03850 if(Ap1->firstframe+n > Nframes)DeleteAlign(Np,Ap1->firstframe);
03851 }
03852 if((Xp=Np->fsiz) != NULL)while(Xp != NULL){
03853 Xp1=Xp; Xp=Xp->next;
03854 if(Xp1->firstframe+n > Nframes)DeleteSize(Np,Xp1->firstframe);
03855 }
03856 }
03857 else{
03858 if(Np->type != CAMERA && (Op=Np->fobj) != NULL)while(Op != NULL){
03859 Op1=Op; Op=Op->next;
03860 if(Op1->lastframe+n < 1)DeleteCostume(Np,Op1->firstframe);
03861 }
03862 if((Sp=Np->fsky) != NULL)while(Sp != NULL){
03863 Sp1=Sp; Sp=Sp->next;
03864 if(Sp1->lastframe+n < 1)DeleteSky(Np,Sp1->firstframe);
03865 }
03866 if((Dp=Np->fdirector) != NULL)while(Dp != NULL){
03867 Dp1=Dp; Dp=Dp->next;
03868 if(Dp1->lastframe+n < 1)DeleteDirector(Np,Dp1->firstframe);
03869 }
03870 if((Pp=Np->fpos) != NULL)while(Pp != NULL){
03871 Pp1=Pp; Pp=Pp->next;
03872 if(Pp1->lastframe+n < 1)DeletePosition(Np,Pp1->firstframe);
03873 }
03874 if((Ap=Np->fali) != NULL)while(Ap != NULL){
03875 Ap1=Ap; Ap=Ap->next;
03876 if(Ap1->lastframe+n < 1)DeleteAlign(Np,Ap1->firstframe);
03877 }
03878 if((Xp=Np->fsiz) != NULL)while(Xp != NULL){
03879 Xp1=Xp; Xp=Xp->next;
03880 if(Xp1->lastframe+n < 1)DeleteSize(Np,Xp1->firstframe);
03881 }
03882 }
03883 if(Np->type != CAMERA && (Op=Np->fobj) != NULL)while(Op != NULL){
03884 Op->firstframe += n; Op->lastframe += n;
03885 Op->firstframe=max(1,Op->firstframe);
03886 Op->lastframe=min(Nframes,Op->lastframe);
03887 Op=Op->next;
03888 }
03889 if((Sp=Np->fsky) != NULL)while(Sp != NULL){
03890 Sp->firstframe += n; Sp->lastframe += n;
03891 Sp->firstframe=max(1,Sp->firstframe);
03892 Sp->lastframe=min(Nframes,Sp->lastframe);
03893 Sp=Sp->next;
03894 }
03895 if((Dp=Np->fdirector) != NULL)while(Dp != NULL){
03896 Dp->firstframe += n; Dp->lastframe += n;
03897 Dp->firstframe=max(1,Dp->firstframe);
03898 Dp->lastframe=min(Nframes,Dp->lastframe);
03899 Dp=Dp->next;
03900 }
03901 if((Pp=Np->fpos) != NULL)while(Pp != NULL){
03902 Pp->firstframe += n; Pp->lastframe += n;
03903 Pp->firstframe=max(1,Pp->firstframe);
03904 Pp->lastframe=min(Nframes,Pp->lastframe);
03905 Pp=Pp->next;
03906 }
03907 if((Ap=Np->fali) != NULL)while(Ap != NULL){
03908 Ap->firstframe += n; Ap->lastframe += n;
03909 Ap->firstframe=max(1,Ap->firstframe);
03910 Ap->lastframe=min(Nframes,Ap->lastframe);
03911 Ap=Ap->next;
03912 }
03913 if((Xp=Np->fsiz) != NULL)while(Xp != NULL){
03914 Xp->firstframe += n; Xp->lastframe += n;
03915 Xp->firstframe=max(1,Xp->firstframe);
03916 Xp->lastframe=min(Nframes,Xp->lastframe);
03917 Xp=Xp->next;
03918 }
03919 if(!allActors)break;
03920 Np=Np->next;
03921 }
03922 EDIT_ACTION=YES;
03923 UpdateSelectedActor(FALSE);
03924 UPDATETIMELINES(IDC_TIMEL_UPDATE)
03925 ReDrawStageDisplay(TRUE);
03926 if(ghwndOpenGLview == NULL)PerspectiveView(0,1);
03927 else UpdateGLview(TRUE);
03928 return;
03929 }
03930
03931 void ShiftSelectedPositionAllKeys(void){
03932 int n;
03933 node *Np;
03934 position *Pp;
03935 double x=0.0,y=0.0,z=0.0;
03936 if((Np=SelectedNode)== NULL)return;
03937 LoadString(ghinst_main,IDX_MISC_MOVEBY,res_str,256);
03938 if(Read3Reals(res_str,&x,&y,&z,0) != OK)return;
03939 Save_UndoA();
03940 if((Pp=Np->fpos) != NULL)while(Pp != NULL){
03941 Pp->finish[0] += (long)(x*ruler)+lrulerx;
03942 Pp->finish[1] += (long)(y*ruler)+lrulery;
03943 Pp->finish[2] += (long)(z*ruler)+lrulerz;
03944 Pp=Pp->next;
03945 }
03946 EDIT_ACTION=YES;
03947 UpdateSelectedActor(FALSE);
03948 UPDATETIMELINES(IDC_TIMEL_UPDATE)
03949 ReDrawStageDisplay(TRUE);
03950 if(ghwndOpenGLview == NULL)PerspectiveView(0,1);
03951 else UpdateGLview(TRUE);
03952 return;
03953 }
03954
03955 void SetNumberOfFrames(short query){
03956 char string[10];
03957 short number,appear,newappear,oldff,oldlf;
03958 int action;
03959 double scale,dappear;
03960 node *Np;
03961 object *Op,*OpEnd;
03962 sky *Sp,*SpEnd;
03963 director *Dp,*DpEnd;
03964 position *Pp,*PpEnd;
03965 align *Ap,*ApEnd;
03966 size *Xp,*XpEnd;
03967 HWND hwnd;
03968 if(query < 0){
03969 number= -query;
03970 action=SCALE;
03971 }
03972 else if(query == 0){
03973 if((hwnd=GetActiveWindow()) != ghwndTimeline)hwnd=ghwnd_main;
03974 number=(short)DialogBoxParam(ghinst_main,MAKEINTRESOURCE(DLG_SETFRAMES),
03975 hwnd,(DLGPROC)SetFramesDlgProc,(LPARAM)&action);
03976 if(number < 1)return;
03977 #if __DEMO__
03978 if(number > 70){
03979 LoadString(ghinst_main,IDX_MISC_DEMO1,res_str,256);
03980 MessageBox(NULL,res_str,NULL,MB_OK);
03981 number=70;
03982 }
03983 #endif
03984 if(number < 0)return;
03985 if(number > 0 && number != Nframes){
03986 scale = (double)number/(double)Nframes;
03987 }
03988 }
03989 else{
03990 number=query;
03991 scale = (double)number/(double)Nframes;
03992 action=EXTEND;
03993 }
03994 EDIT_ACTION=YES;
03995 if((Np=FirstNp) != NULL)while(Np != NULL){
03996 OpEnd=NULL;
03997 if((Op=Np->fobj) != NULL)while(Op != NULL){OpEnd=Op; Op=Op->next;}
03998 if(OpEnd != NULL && (action < BLANKS || Np->type == CAMERA)){
03999 if(action == SCALE){
04000 Op=Np->fobj;
04001 while(Op != NULL){
04002 oldff=Op->firstframe; oldlf=Op->lastframe;
04003 appear=Op->lastframe - Op->firstframe + 1 ;
04004 Op->firstframe = (Op->firstframe - 1) * scale + 1;
04005 newappear = (short)((double)appear * scale);
04006 Op->lastframe = Op->firstframe + newappear;
04007 if(Op->last != NULL){
04008 if(Op->last->lastframe >= Op->firstframe){
04009 Op->firstframe = Op->last->lastframe + 1;
04010 if(Op->lastframe < Op->firstframe)
04011 Op->lastframe = Op->firstframe;
04012 }
04013 }
04014 if(Op->type == PATH && Op->v != NULL){
04015 Op->v=ReTweenVelocity(Op,Op->v,
04016 (int)(oldlf-oldff+1),(int)(Op->lastframe-Op->firstframe+1),
04017 Op->pathlength,0);
04018 }
04019 Op=Op->next;
04020 }
04021 }
04022 if(number > OpEnd->lastframe && OpEnd->lastframe >= Nframes){
04023 oldff=OpEnd->firstframe; oldlf=OpEnd->lastframe;
04024 OpEnd->lastframe=number;
04025 if(OpEnd->type == PATH && OpEnd->v != NULL){
04026 OpEnd->v=ReTweenVelocity(OpEnd,OpEnd->v,
04027 (int)(oldlf-oldff+1),
04028 (int)(OpEnd->lastframe-OpEnd->firstframe+1),
04029 OpEnd->pathlength,0);
04030 }
04031 }
04032 }
04033 if(OpEnd != NULL)while(OpEnd != NULL){
04034 Op=OpEnd->last;
04035 if(OpEnd->firstframe > number)DeleteCostume(Np,OpEnd->firstframe);
04036 else if(OpEnd->lastframe > number){
04037 oldff=OpEnd->firstframe; oldlf=OpEnd->lastframe;
04038 OpEnd->lastframe=number;
04039 if(OpEnd->type == PATH && OpEnd->v != NULL){
04040 OpEnd->v=ReTweenVelocity(OpEnd,OpEnd->v,
04041 (int)(oldlf-oldff+1),
04042 (int)(OpEnd->lastframe-OpEnd->firstframe+1),
04043 OpEnd->pathlength,0);
04044 }
04045 }
04046 OpEnd=Op;
04047 }
04048 SpEnd=NULL;
04049 if((Sp=Np->fsky) != NULL)while(Sp != NULL){SpEnd=Sp; Sp=Sp->next;}
04050 if(SpEnd != NULL && action < BLANKS){
04051 if(action == SCALE){
04052 Sp=Np->fsky;
04053 while(Sp != NULL){
04054 appear=Sp->lastframe - Sp->firstframe + 1 ;
04055 Sp->firstframe = (Sp->firstframe - 1) * scale + 1;
04056 newappear = (short)((double)appear * scale);
04057 Sp->lastframe = Sp->firstframe + newappear;
04058 if(Sp->last != NULL){
04059 if(Sp->last->lastframe >= Sp->firstframe){
04060 Sp->firstframe = Sp->last->lastframe + 1;
04061 if(Sp->lastframe < Sp->firstframe)
04062 Sp->lastframe = Sp->firstframe;
04063 }
04064 }
04065 Sp=Sp->next;}
04066 }
04067 if(number > SpEnd->lastframe && SpEnd->lastframe >= Nframes)
04068 SpEnd->lastframe=number;
04069 }
04070 if(SpEnd != NULL)while(SpEnd != NULL){Sp=SpEnd->last;
04071 if(SpEnd->firstframe > number)DeleteSky(Np,SpEnd->firstframe);
04072 else if(SpEnd->lastframe > number)SpEnd->lastframe=number;
04073 SpEnd=Sp;}
04074
04075 DpEnd=NULL;
04076 if((Dp=Np->fdirector) != NULL)while(Dp != NULL){DpEnd=Dp; Dp=Dp->next;}
04077 if(DpEnd != NULL && action < BLANKS){
04078 if(action == SCALE){
04079 Dp=Np->fdirector;
04080 while(Dp != NULL){
04081 appear=Dp->lastframe - Dp->firstframe + 1 ;
04082 Dp->firstframe = (Dp->firstframe - 1) * scale + 1;
04083 newappear = (short)((double)appear * scale);
04084 Dp->lastframe = Dp->firstframe + newappear;
04085 if(Dp->last != NULL){
04086 if(Dp->last->lastframe >= Dp->firstframe){
04087 Dp->firstframe = Dp->last->lastframe + 1;
04088 if(Dp->lastframe < Dp->firstframe)
04089 Dp->lastframe = Dp->firstframe;
04090 }
04091 }
04092 Dp=Dp->next;}
04093 }
04094 if(number > DpEnd->lastframe && DpEnd->lastframe >= Nframes)
04095 DpEnd->lastframe=number;
04096 }
04097 if(DpEnd != NULL)while(DpEnd != NULL){Dp=DpEnd->last;
04098 if(DpEnd->firstframe > number)DeleteDirector(Np,DpEnd->firstframe);
04099 else if(DpEnd->lastframe > number)DpEnd->lastframe=number;
04100 DpEnd=Dp;}
04101
04102 PpEnd=NULL;
04103 if((Pp=Np->fpos) != NULL)while(Pp != NULL){PpEnd=Pp; Pp=Pp->next;}
04104 if(PpEnd != NULL && action < BLANKS){
04105 if(action == SCALE){
04106 Pp=Np->fpos;
04107 while(Pp != NULL){
04108 appear=Pp->lastframe - Pp->firstframe + 1 ;
04109 Pp->firstframe = (Pp->firstframe - 1) * scale + 1;
04110 newappear = (short)((double)appear * scale);
04111 Pp->lastframe = Pp->firstframe + newappear;
04112 if(Pp->last != NULL){
04113 if(Pp->last->lastframe >= Pp->firstframe){
04114 Pp->firstframe = Pp->last->lastframe + 1;
04115 if(Pp->lastframe < Pp->firstframe)
04116 Pp->lastframe = Pp->firstframe;
04117 }
04118 }
04119 Pp=Pp->next;}
04120 }
04121 if(number > PpEnd->lastframe && PpEnd->lastframe >= Nframes)
04122 PpEnd->lastframe=number;
04123 }
04124 if(PpEnd != NULL)while(PpEnd != NULL){Pp=PpEnd->last;
04125 if(PpEnd->firstframe > number)DeletePosition(Np,PpEnd->firstframe);
04126 else if(PpEnd->lastframe > number)PpEnd->lastframe=number;
04127 PpEnd=Pp;}
04128 ApEnd=NULL;
04129 if((Ap=Np->fali) != NULL)while(Ap != NULL){ApEnd=Ap; Ap=Ap->next;}
04130 if(ApEnd != NULL && action < BLANKS){
04131 if(action == SCALE){
04132 Ap=Np->fali;
04133 while(Ap != NULL){
04134 appear=Ap->lastframe - Ap->firstframe + 1 ;
04135 Ap->firstframe = (Ap->firstframe - 1) * scale + 1;
04136 newappear = (short)((double)appear * scale);
04137 Ap->lastframe = Ap->firstframe + newappear;
04138 if(Ap->last != NULL){
04139 if(Ap->last->lastframe >= Ap->firstframe){
04140 Ap->firstframe = Ap->last->lastframe + 1;
04141 if(Ap->lastframe < Ap->firstframe)
04142 Ap->lastframe = Ap->firstframe;
04143 }
04144 }
04145 Ap=Ap->next;}
04146 }
04147 if(number > ApEnd->lastframe && ApEnd->lastframe >= Nframes)
04148 ApEnd->lastframe=number;
04149 }
04150 if(ApEnd != NULL)while(ApEnd != NULL){Ap=ApEnd->last;
04151 if(ApEnd->firstframe > number)DeleteAlign(Np,ApEnd->firstframe);
04152 else if(ApEnd->lastframe > number)ApEnd->lastframe=number;
04153 ApEnd=Ap;}
04154 XpEnd=NULL;
04155 if((Xp=Np->fsiz) != NULL)while(Xp != NULL){XpEnd=Xp; Xp=Xp->next;}
04156 if(XpEnd != NULL && action < BLANKS){
04157 if(action == SCALE){
04158 Xp=Np->fsiz;
04159 while(Xp != NULL){
04160 appear=Xp->lastframe - Xp->firstframe + 1 ;
04161 Xp->firstframe = (Xp->firstframe - 1) * scale + 1;
04162 newappear = (short)((double)appear * scale);
04163 Xp->lastframe = Xp->firstframe + newappear;
04164 if(Xp->last != NULL){
04165 if(Xp->last->lastframe >= Xp->firstframe){
04166 Xp->firstframe = Xp->last->lastframe + 1;
04167 if(Xp->lastframe < Xp->firstframe)
04168 Xp->lastframe = Xp->firstframe;
04169 }
04170 }
04171 Xp=Xp->next;}
04172 }
04173 if(number > XpEnd->lastframe && XpEnd->lastframe >= Nframes)
04174 XpEnd->lastframe=number;
04175 }
04176 if(XpEnd != NULL)while(XpEnd != NULL){Xp=XpEnd->last;
04177 if(XpEnd->firstframe > number)DeleteSize(Np,XpEnd->firstframe);
04178 else if(XpEnd->lastframe > number)XpEnd->lastframe=number;
04179 XpEnd=Xp;}
04180
04181 Np=Np->next;}
04182 Nframes=number;
04183 UpdateSelectedActor(FALSE);
04184 EnableMenuItem(GetMenu(ghwnd_main),IDM_FRAME_RENDERNOW,MF_GRAYED);
04185 }
04186
04187 BOOL InsertFrames(BOOL type, long inf, long cf, long nf){
04188 node *Np;
04189 object *Op;
04190 sky *Sp;
04191 director *Dp;
04192 position *Pp;
04193 align *Ap;
04194 size *Xp;
04195 HWND hwnd;
04196 long oldff,oldlf;
04197 if(type == TRUE){
04198 if((hwnd=GetActiveWindow()) != ghwndTimeline)hwnd=ghwnd_main;
04199 inf=(short)DialogBoxParam(ghinst_main,MAKEINTRESOURCE(DLG_INSERTFRAMES),
04200 hwnd,(DLGPROC)InsertFramesDlgProc,(LPARAM)&cf);
04201 if(inf < 1)return FALSE;
04202 }
04203
04204
04205 if(cf > Nframes || cf < 1)return FALSE;
04206 EDIT_ACTION=YES;
04207 if((Np=FirstNp) != NULL)while(Np != NULL){
04208 if((Op=Np->fobj) != NULL)while(Op != NULL){
04209 oldff=Op->firstframe; oldlf=Op->lastframe;
04210 if(oldff > cf || (Np->type != CAMERA && oldff == cf))Op->firstframe += inf;
04211 if(oldlf >= cf)Op->lastframe += inf;
04212 if(Op->type == PATH && Op->v != NULL && oldff < cf && oldlf > cf){
04213 Op->v=ReTweenVelocity(Op,Op->v,
04214 (int)(oldlf-oldff+1),(int)(Op->lastframe-Op->firstframe+1),
04215 Op->pathlength,0);
04216 }
04217 Op=Op->next;
04218 }
04219 if((Sp=Np->fsky) != NULL)while(Sp != NULL){
04220 oldff=Sp->firstframe; oldlf=Sp->lastframe;
04221 if(oldff >= cf)Sp->firstframe += inf;
04222 if(oldlf >= cf)Sp->lastframe += inf;
04223 Sp=Sp->next;
04224 }
04225 if((Dp=Np->fdirector) != NULL)while(Dp != NULL){
04226 oldff=Dp->firstframe; oldlf=Dp->lastframe;
04227 if(oldff >= cf)Dp->firstframe += inf;
04228 if(oldlf >= cf)Dp->lastframe += inf;
04229 Dp=Dp->next;
04230 }
04231 if((Pp=Np->fpos) != NULL)while(Pp != NULL){
04232 oldff=Pp->firstframe; oldlf=Pp->lastframe;
04233 if(oldff >= cf)Pp->firstframe += inf;
04234 if(oldlf >= cf)Pp->lastframe += inf;
04235 Pp=Pp->next;
04236 }
04237 if((Ap=Np->fali) != NULL)while(Ap != NULL){
04238 oldff=Ap->firstframe; oldlf=Ap->lastframe;
04239 if(oldff >= cf)Ap->firstframe += inf;
04240 if(oldlf >= cf)Ap->lastframe += inf;
04241 Ap=Ap->next;
04242 }
04243 if((Xp=Np->fsiz) != NULL)while(Xp != NULL){
04244 oldff=Xp->firstframe; oldlf=Xp->lastframe;
04245 if(oldff >= cf)Xp->firstframe += inf;
04246 if(oldlf >= cf)Xp->lastframe += inf;
04247 Xp=Xp->next;
04248 }
04249
04250 Np=Np->next;
04251 }
04252 Nframes += inf;
04253 UpdateSelectedActor(FALSE);
04254 return TRUE;
04255 }
04256
04257 BOOL DeleteRangeOfFrames(BOOL type, long inf, long cf, long nf){
04258 node *Np;
04259 object *Op,*OpNext;
04260 sky *Sp,*SpNext;
04261 director *Dp,*DpNext;
04262 position *Pp,*PpNext;
04263 align *Ap,*ApNext;
04264 size *Xp,*XpNext;
04265 HWND hwnd;
04266 long ef,oldff,oldlf;
04267 if(type == TRUE){
04268 if((hwnd=GetActiveWindow()) != ghwndTimeline)hwnd=ghwnd_main;
04269 inf=(short)DialogBoxParam(ghinst_main,MAKEINTRESOURCE(DLG_DELETEFRAMES),
04270 hwnd,(DLGPROC)DeleteFramesDlgProc,(LPARAM)&cf);
04271 if(inf < 1 || inf >= Nframes)return FALSE;
04272 }
04273 if(cf >= Nframes || cf < 1)return FALSE;
04274 EDIT_ACTION=YES;
04275 ef=cf+inf-1;
04276 if((Np=FirstNp) != NULL)while(Np != NULL){
04277 if((Op=Np->fobj) != NULL)while(Op != NULL){
04278 oldff=Op->firstframe; oldlf=Op->lastframe;
04279 if (oldff > ef){Op->firstframe -= inf; Op->lastframe -= inf; Op=Op->next;}
04280 else if(oldlf < cf){Op=Op->next;}
04281 else if(oldff < cf && oldlf <= ef) {Op->lastframe = cf-1; Op=Op->next;}
04282 else if(oldff < cf && oldlf > ef) {Op->lastframe -= inf; Op=Op->next;}
04283 else if(oldff <= ef && oldlf > ef) {Op->firstframe = cf; Op->lastframe -= inf; Op=Op->next;}
04284 else if(oldff >= cf && oldlf <= ef){
04285 OpNext=Op->next;
04286 DeleteCostume(Np,Op->firstframe);
04287 Op=OpNext;
04288 }
04289 else Op=Op->next;
04290 }
04291
04292 if((Sp=Np->fsky) != NULL)while(Sp != NULL){
04293 oldff=Sp->firstframe; oldlf=Sp->lastframe;
04294 if (oldff > ef){Sp->firstframe -= inf; Sp->lastframe -= inf; Sp=Sp->next;}
04295 else if(oldlf < cf){Sp=Sp->next;}
04296 else if(oldff < cf && oldlf <= ef) {Sp->lastframe = cf-1; Sp=Sp->next;}
04297 else if(oldff < cf && oldlf > ef) {Sp->lastframe -= inf; Sp=Sp->next;}
04298 else if(oldff <= ef && oldlf > ef) {Sp->firstframe = cf; Sp->lastframe -= inf; Sp=Sp->next;}
04299 else if(oldff >= cf && oldlf <= ef){
04300 SpNext=Sp->next;
04301 DeleteSky(Np,Sp->firstframe);
04302 Sp=SpNext;
04303 }
04304 else Sp=Sp->next;
04305 }
04306
04307 if((Dp=Np->fdirector) != NULL)while(Dp != NULL){
04308 oldff=Dp->firstframe; oldlf=Dp->lastframe;
04309 if (oldff > ef){Dp->firstframe -= inf; Dp->lastframe -= inf; Dp=Dp->next;}
04310 else if(oldlf < cf){Dp=Dp->next;}
04311 else if(oldff < cf && oldlf <= ef) {Dp->lastframe = cf-1; Dp=Dp->next;}
04312 else if(oldff < cf && oldlf > ef) {Dp->lastframe -= inf; Dp=Dp->next;}
04313 else if(oldff <= ef && oldlf > ef) {Dp->firstframe = cf; Dp->lastframe -= inf; Dp=Dp->next;}
04314 else if(oldff >= cf && oldlf <= ef){
04315 DpNext=Dp->next;
04316 DeleteDirector(Np,Dp->firstframe);
04317 Dp=DpNext;
04318 }
04319 else Dp=Dp->next;
04320 }
04321
04322 if((Pp=Np->fpos) != NULL)while(Pp != NULL){
04323 oldff=Pp->firstframe; oldlf=Pp->lastframe;
04324 if (oldff > ef){Pp->firstframe -= inf; Pp->lastframe -= inf; Pp=Pp->next;}
04325 else if(oldlf < cf){Pp=Pp->next;}
04326 else if(oldff < cf && oldlf <= ef) {Pp->lastframe = cf-1; Pp=Pp->next;}
04327 else if(oldff < cf && oldlf > ef) {Pp->lastframe -= inf; Pp=Pp->next;}
04328 else if(oldff <= ef && oldlf > ef) {Pp->firstframe = cf; Pp->lastframe -= inf; Pp=Pp->next;}
04329 else if(oldff >= cf && oldlf <= ef){
04330 PpNext=Pp->next;
04331 DeletePosition(Np,Pp->firstframe);
04332 Pp=PpNext;
04333 }
04334 else Pp=Pp->next;
04335 }
04336
04337 if((Ap=Np->fali) != NULL)while(Ap != NULL){
04338 oldff=Ap->firstframe; oldlf=Ap->lastframe;
04339 if (oldff > ef){Ap->firstframe -= inf; Ap->lastframe -= inf; Ap=Ap->next;}
04340 else if(oldlf < cf){Ap=Ap->next;}
04341 else if(oldff < cf && oldlf <= ef) {Ap->lastframe = cf-1; Ap=Ap->next;}
04342 else if(oldff < cf && oldlf > ef) {Ap->lastframe -= inf; Ap=Ap->next;}
04343 else if(oldff <= ef && oldlf > ef) {Ap->firstframe = cf; Ap->lastframe -= inf; Ap=Ap->next;}
04344 else if(oldff >= cf && oldlf <= ef){
04345 ApNext=Ap->next;
04346 DeleteAlign(Np,Ap->firstframe);
04347 Ap=ApNext;
04348 }
04349 else Ap=Ap->next;
04350 }
04351
04352 if((Xp=Np->fsiz) != NULL)while(Xp != NULL){
04353 oldff=Xp->firstframe; oldlf=Xp->lastframe;
04354 if (oldff > ef){Xp->firstframe -= inf; Xp->lastframe -= inf; Xp=Xp->next;}
04355 else if(oldlf < cf){Xp=Xp->next;}
04356 else if(oldff < cf && oldlf <= ef) {Xp->lastframe = cf-1; Xp=Xp->next;}
04357 else if(oldff < cf && oldlf > ef) {Xp->lastframe -= inf; Xp=Xp->next;}
04358 else if(oldff <= ef && oldlf > ef) {Xp->firstframe = cf; Xp->lastframe -= inf; Xp=Xp->next;}
04359 else if(oldff >= cf && oldlf <= ef){
04360 XpNext=Xp->next;
04361 DeleteSize(Np,Xp->firstframe);
04362 Xp=XpNext;
04363 }
04364 else Xp=Xp->next;
04365 }
04366
04367 Np=Np->next;
04368 }
04369 Nframes -= inf;
04370 UpdateSelectedActor(FALSE);
04371 return TRUE;
04372 }
04373
04374 static int nActionsList=0;
04375 static char *ActionsList[256],*ActionsText[256];
04376
04377 short StartDefault(short what_function){
04378 int nPresets=7;
04379 short action,nfr,nmodels=0;
04380 node *Np,*Np1,*lastNode,*pathNode;
04381 object *Op,*Op1;
04382 sky *Sp;
04383 position *Pp;
04384 align *Ap,*Ap1;
04385 size *Xp;
04386 char response[16];
04387 nPresets=GetPresets(nPresets);
04388 LoadString(ghinst_main,IDX_MISC_TEMPLATE,res_str,256);
04389 action=SelectScrolledItemList(nPresets,ActionsText,res_str,
04390 TRUE,ghwnd_main);
04391 if(action < 0)goto FINISHED;
04392 if(action > 6){
04393 if(!BuildFromPreset(action))goto ERRORS;
04394 goto FINISHED;
04395 }
04396 if(Nskys == 0){
04397 if(CreateNode() != NULL){
04398 LoadString(ghinst_main,IDX_MISC_NAMESKY,res_str,256);
04399 strcpy(MainNp->actorname,res_str);
04400 MainNp->type=SKY;
04401 MainNp->fsky=NULL;
04402 Nskys=1;
04403 }
04404 else goto FINISHED;
04405 }
04406 if((Sp=CreateSky(MainNp,1,(short)Nframes)) == NULL || fail_op)goto ERRORS;
04407 Sp->type=SKYGRADED;
04408 Sp->colour[0]=0; Sp->colour[1]=255; Sp->colour[2]=255;
04409 Sp->zcolour[0]=0; Sp->zcolour[1]=0; Sp->zcolour[2]=255;
04410 if(CreatePosition(FirstNp,1,(short)Nframes) == NULL || fail_op)goto ERRORS;
04411 FirstNp->fpos->finish[0]=TVpointX+TVsizeX*2;
04412 FirstNp->fpos->finish[1]=TVpointY+TVsizeY*2;
04413 FirstNp->fpos->finish[2]=TVpointZ+TVsizeZ*2;
04414 FirstNp->fpos->type=SPLINE;
04415 if((Ap=CreateAlign(FirstNp,1,(short)Nframes)) == NULL || fail_op)goto ERRORS;
04416 if(CreateNode() == NULL)goto ERRORS;
04417 LoadString(ghinst_main,IDX_MISC_NAMETARGET,res_str,256);
04418 strcpy(MainNp->actorname,res_str);
04419 MainNp->type=TARGET;
04420 if((Op=CreateCostume(MainNp,1,(short)Nframes)) == NULL || fail_op)goto ERRORS;
04421 Op->type=MainNp->type;
04422 FirstNp->fali->type=TRACK; FirstNp->fali->topath=MainNp;
04423
04424
04425 if(action < 6){
04426 char ttt[64];
04427 LoadString(ghinst_main,IDX_MISC_SELECTMODEL,res_str,256);
04428 LoadString(ghinst_main,IDX_MISC_SELECT1,ttt,256);
04429 if((Np1=LoadStandinModel(&nmodels,res_str,ttt)) == NULL)
04430 goto ERRORS;
04431 }
04432 else if(action == 6){
04433 char ttt[64];
04434 LoadString(ghinst_main,IDX_MISC_MODELHEAD,res_str,256);
04435 LoadString(ghinst_main,IDX_MISC_MODELLOAD,ttt,256);
04436 if((Np1=LoadStandinModel(&nmodels,res_str,ttt))
04437 == NULL)goto ERRORS;
04438 }
04439 if(Np1->fobj != NULL){
04440 Op1=Np1->fobj;
04441 FirstNp->fpos->finish[0] += Op1->outline[2][0];
04442 FirstNp->fpos->finish[1] += Op1->outline[2][1];
04443 FirstNp->fpos->finish[2] += Op1->outline[2][2];
04444 }
04445 if(CreateNode() == NULL)goto ERRORS;
04446 LoadString(ghinst_main,IDX_MISC_NAMELIGHT,res_str,256);
04447 strcpy(MainNp->actorname,res_str);
04448 MainNp->type=LIGHT;
04449 if((Op=CreateCostume(MainNp,1,Nframes)) == NULL)goto ERRORS;
04450 Op->type=MainNp->type;
04451 Op->lighttype=SPHERE; Op->colour[0]=Op->colour[1]=Op->colour[2]=255;
04452 if((Pp=CreatePosition(MainNp,1,(short)Nframes)) == NULL || fail_op)goto ERRORS;
04453 Pp->finish[0]=FirstNp->fpos->finish[0]+TVsizeX/2;
04454 Pp->finish[1]=FirstNp->fpos->finish[1]+TVsizeY;
04455 Pp->finish[2]=FirstNp->fpos->finish[2]+TVsizeZ*2;
04456 Pp->type=SPLINE;
04457 if(action < 1)goto FINISHED;
04458 if(action == 1){
04459 if(CreateNode() == NULL)goto ERRORS;
04460 LoadString(ghinst_main,IDX_MISC_NAMEGROUND,res_str,256);
04461 strcpy(MainNp->actorname,res_str);
04462 MainNp->type=GROUND; Nground=1;
04463 if((Op=CreateCostume(MainNp,1,(short)Nframes)) == NULL)goto ERRORS;
04464 Op->type=MainNp->type;
04465 Op->groundtype=PLAIN;
04466 Op->groundTemperature=10;
04467 SetSfxColour(Op->colour,IDX_MISC_GROUND_COLOUR,ghwnd_main);
04468 if((Pp=CreatePosition(MainNp,1,Nframes)) == NULL || fail_op)goto ERRORS;
04469 Pp->finish[0]=0;
04470 Pp->finish[1]=0;
04471 Pp->finish[2]=TVpointZ;
04472 Pp->type=SPLINE;
04473 if((Xp=CreateSize(MainNp,1,Nframes)) == NULL || fail_op)goto ERRORS;
04474 }
04475 if(action > 1){
04476 char ttt[64];
04477 LoadString(ghinst_main,IDX_MISC_NUMFRAMES,res_str,256);
04478 LoadString(ghinst_main,IDX_MISC_FRAMES,ttt,64);
04479 nfr=RequestNumEntry(60,1,999,res_str,ttt);
04480 #if __DEMO__
04481 if(nfr > 70){
04482 LoadString(ghinst_main,IDX_MISC_DEMO1,res_str,256);
04483 MessageBox(NULL,res_str,NULL,MB_OK);
04484 nfr=70;
04485 }
04486 #endif
04487 if(nfr < 0)goto FINISHED;
04488 SetNumberOfFrames(nfr);
04489 if((Ap1=CreateAlign(Np1,1,Nframes)) == NULL || fail_op)goto ERRORS;
04490 if(action == 2){Ap1->im=1; Ap1->ima=1.0;}
04491 }
04492 if(action >= 3 && action <= 5){
04493 if(CreateNode() == NULL)goto ERRORS;
04494 LoadString(ghinst_main,IDX_MISC_NAMEPATH,res_str,256);
04495 strcpy(MainNp->actorname,res_str);
04496 MainNp->type=PATH;
04497 if((Op=CreateCostume(MainNp,1,Nframes)) == NULL)goto ERRORS;
04498 Op->type=MainNp->type;
04499 strcpy(Op->name,"PATH1995");
04500 if(CreatePathObject((short)(action-3),MainNp,Op,1,Nframes) < 0)goto ERRORS;
04501 if((Pp=CreatePosition(Np1,1,Nframes)) == NULL || fail_op)goto ERRORS;
04502 Pp->type=FOLLOW; Pp->onpath=MainNp;
04503 Ap1->type=TOPATH; Ap1->topath=MainNp;
04504 }
04505 else if(action == 6){
04506 if(CreateNode() == NULL)goto ERRORS;
04507 LoadString(ghinst_main,IDX_MISC_NAMEPATH,res_str,256);
04508 strcpy(MainNp->actorname,res_str);
04509 pathNode=MainNp;
04510 MainNp->type=PATH;
04511 if((Op=CreateCostume(MainNp,1,Nframes)) == NULL)goto ERRORS;
04512 Op->type=MainNp->type;
04513 strcpy(Op->name,"PATH1995");
04514 if(CreatePathObject(2,MainNp,Op,1,Nframes) < 0)goto ERRORS;
04515 if((Pp=CreatePosition(Np1,1,Nframes)) == NULL || fail_op)goto ERRORS;
04516 Pp->type=FOLLOW; Pp->onpath=pathNode;
04517 Ap1->type=TOPATH; Ap1->topath=pathNode;
04518 lastNode=Np1;
04519 while(1){
04520 char ttt[64];
04521 LoadString(ghinst_main,IDX_MISC_NEXTCANCEL,res_str,256);
04522 LoadString(ghinst_main,IDX_MISC_ADDNEXT,ttt,64);
04523 if((Np=LoadStandinModel(&nmodels,res_str,ttt))
04524 == NULL)goto ERRORS;
04525 if(Np->fobj == NULL){
04526 DeleteNode(Np);
04527 break;
04528 }
04529 if((Pp=CreatePosition(Np,1,Nframes)) == NULL || fail_op)goto ERRORS;
04530 Pp->type=FOLLOWON; Pp->onpath=lastNode;
04531 if((Ap=CreateAlign(Np,1,Nframes)) == NULL || fail_op)goto ERRORS;
04532 Ap->type=TOPATH; Ap->topath=pathNode;
04533 lastNode=Np;
04534 }
04535 }
04536 goto FINISHED;
04537 ERRORS:
04538 SendPrgmQuery(IDQ_OLD4,0);
04539 FINISHED:
04540 FreePresets();
04541 return 0;
04542 }
04543
04544 static int GetPresets(int nPresets){
04545 int i;
04546 HANDLE h;
04547 FILE *ff;
04548 WIN32_FIND_DATA ffd,*lpffd;
04549 char str[255],title[64],tempstr[256];
04550 int PresetTypeListID[]={
04551 IDX_MISC_PRESET1,
04552 IDX_MISC_PRESET2,
04553 IDX_MISC_PRESET3,
04554 IDX_MISC_PRESET4,
04555 IDX_MISC_PRESET5,
04556 IDX_MISC_PRESET6,
04557 IDX_MISC_PRESET7
04558 };
04559 sprintf(str,"%s\\*.pfx",gszPSTdir);
04560 lpffd=&ffd;
04561 nActionsList=0;
04562 for(i=0;i<nPresets;i++){
04563 ActionsList[nActionsList]=(char *)X__Malloc(8*sizeof(char));
04564 if(ActionsList[nActionsList] != NULL)strcpy(ActionsList[nActionsList],"I");
04565 ActionsText[nActionsList]=(char *)X__Malloc(256*sizeof(char));
04566 if(ActionsText[nActionsList] != NULL){
04567 LoadString(ghinst_main,PresetTypeListID[nActionsList],tempstr,256);
04568 strcpy(ActionsText[nActionsList],tempstr);
04569 }
04570 nActionsList++;
04571 }
04572 if((h=FindFirstFile(str,lpffd)) != INVALID_HANDLE_VALUE){
04573 sprintf(str,"%s\\%s",gszPSTdir,lpffd->cFileName);
04574 ActionsList[nActionsList]=(char *)X__Malloc(256*sizeof(char));
04575 if(ActionsList[nActionsList] != NULL)strcpy(ActionsList[nActionsList],str);
04576 nActionsList++;
04577 while(FindNextFile(h,lpffd)){
04578 sprintf(str,"%s\\%s",gszPSTdir,lpffd->cFileName);
04579 ActionsList[nActionsList]=(char *)X__Malloc(256*sizeof(char));
04580 strcpy(ActionsList[nActionsList],str);
04581 nActionsList++;
04582 }
04583 if(GetLastError() != ERROR_NO_MORE_FILES){
04584 LoadString(ghinst_main,IDX_MISC_ERRORINNEXT,res_str,256);
04585 MessageBox(NULL,res_str,NULL,MB_OK);
04586 }
04587 if(!FindClose(h)){
04588 LoadString(ghinst_main,IDX_MISC_FILEERROR,res_str,256);
04589 MessageBox(NULL,res_str,NULL,MB_OK);
04590 }
04591 if(nActionsList > nPresets)for(i=nPresets;i<nActionsList;i++){
04592 if((ff=fopen(ActionsList[i],"r")) != NULL){
04593 fscanf(ff,"%[^\n]",title);
04594 ActionsText[i]=(char *)X__Malloc(256*sizeof(char));
04595 if(ActionsText[i] != NULL)
04596 strcpy(ActionsText[i],title);
04597 fclose(ff);
04598 }
04599 }
04600 }
04601 return nActionsList;
04602 }
04603
04604 static void FreePresets(void){
04605 int i;
04606 if(nActionsList > 0){
04607 for(i=0;i<nActionsList;i++){
04608 if(ActionsList[i] != NULL)X__Free(ActionsList[i]);
04609 if(ActionsText[i] != NULL)X__Free(ActionsText[i]);
04610 }
04611 nActionsList=0;
04612 }
04613 }
04614
04615 static BOOL BuildFromPreset(int action){
04616 BOOL status=FALSE;
04617 HMODULE hLib;
04618 FARPROC fpFun;
04619 ANI_STRUCTURE *Evs;
04620 BOOL (*fpFun1)(HWND, ANI_STRUCTURE *);
04621 int l;
04622 char fname[255];
04623 strcpy(fname,ActionsList[action]);
04624 l=strlen(fname);
04625 fname[l-1]='l'; fname[l-2]='l'; fname[l-3]='d';
04626 Evs=&AniStructure;
04627 if((hLib=LoadLibrary(fname)) != NULL){
04628 if((fpFun=GetProcAddress(hLib,"_ExternalPreset")) != NULL){
04629 fpFun1 = (void *)fpFun;
04630 status=(*fpFun1)(ghwnd_main,Evs);
04631 }
04632 else MessageBox(ghwnd_main,(LPCTSTR) "Failed function",(LPCTSTR)" ",
04633 MB_OK | MB_TASKMODAL );
04634 FreeLibrary(hLib);
04635 }
04636 else MessageBox(ghwnd_main,(LPCTSTR)fname,(LPCTSTR)"Failed to find DLL",
04637 MB_OK | MB_TASKMODAL );
04638 return status;
04639 }