Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

program.cc

Go to the documentation of this file.
00001 
00002 // Flash Plugin and Player
00003 // Copyright (C) 1998,1999 Olivier Debon
00004 // 
00005 // This program is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 // 
00010 // This program is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 // 
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018 // 
00020 //  Author : Olivier Debon  <odebon@club-internet.fr>
00021 //  
00022 
00023 #include "swf.h"
00024 
00025 #define NOTHING  0x0
00026 #define WAKEUP   0x1
00027 #define GOTO     0x2
00028 #define REFRESH  0x4
00029 
00030 #ifdef RCSID
00031 static char *rcsid = "$Id: program.cc,v 1.1.1.1 2002/01/25 22:14:58 kergoth Exp $";
00032 #endif
00033 
00034 #define PRINT 0
00035 
00036 int debug = 0;
00037 
00038 Program::Program(FlashMovie *movie, long n)
00039 {
00040         long f;
00041 
00042         this->movie = movie;
00043 
00044         totalFrames = 0;
00045 
00046         dl = new DisplayList(movie);
00047         if (dl == NULL) return;
00048         frames = new Frame[n];
00049         if (frames == NULL) {
00050                 delete dl;
00051                 return;
00052         }
00053 
00054         nbFrames = 0;
00055         totalFrames = n;
00056         currentFrame = 0;
00057         loadingFrame = 0;
00058         movieWait = 1;
00059         nextFrame = currentFrame;
00060         for(f = 0; f < n; f++)
00061         {
00062                 frames[f].controls = 0;
00063                 frames[f].label = NULL;
00064         }
00065 
00066         movieStatus = MoviePlay;
00067         settings = 0;
00068 }
00069 
00070 Program::~Program()
00071 {
00072     int i;
00073     Control *ctrl, *ctrl1;
00074 
00075     delete dl;
00076 
00077     if (frames != NULL) {
00078             for(i=0;i<nbFrames;i++) {
00079                 ctrl = frames[i].controls;
00080                 if (frames[i].label) free(frames[i].label);
00081                 while (ctrl != NULL) {
00082                     ctrl1 = ctrl->next;
00083                     ctrl->next = NULL;
00084                     delete ctrl;
00085                     ctrl = ctrl1;
00086                 }
00087             }
00088 
00089             delete[] frames;
00090     }
00091 }
00092 
00093 void
00094 Program::validateLoadingFrame()
00095 {
00096         nbFrames = loadingFrame;
00097         loadingFrame++;
00098         movieWait = 0;
00099 }
00100 
00101 Frame   *
00102 Program::getFrames()
00103 {
00104         return frames;
00105 }
00106 
00107 long
00108 Program::getNbFrames()
00109 {
00110         return nbFrames;
00111 }
00112 
00113 DisplayList *
00114 Program::getDisplayList()
00115 {
00116         return dl;
00117 }
00118 
00119 long
00120 Program::getCurrentFrame()
00121 {
00122         return currentFrame;
00123 }
00124 
00125 void
00126 Program::setCurrentFrame(long n)
00127 {
00128         currentFrame = n;
00129         nextFrame = n;
00130         //refresh = 1;
00131 }
00132 
00133 void
00134 Program::gotoFrame(GraphicDevice *gd, long frame)
00135 {
00136         long f;
00137 
00138         //printf("GotoFrame %d  (Current = %d)\n", frame, currentFrame);
00139         dl->clearList();
00140 
00141         for(f=0; f <= frame; f++) {
00142                 runFrame(gd, 0, f, 0);
00143         }
00144 }
00145 
00146 long
00147 Program::runFrame(GraphicDevice *gd, SoundMixer *sm, long f, long action)
00148 {
00149         Control         *ctrl;
00150         Character       *character;
00151         Matrix          *matrix;
00152         Cxform          *cxform;
00153         long             status = NOTHING;
00154         long             update = 0;
00155         char            *name;
00156 
00157 #if PRINT&1
00158         if (action) printf("Prog %x (dl=%x): Frame N° %d/%d\n", this, this->dl, f, nbFrames-1);
00159 #endif
00160         movie->buttons_updated = 0;
00161 
00162         for(ctrl = frames[f].controls; ctrl; ctrl = ctrl->next)
00163         {
00164                 switch (ctrl->type)
00165                 {
00166                         case ctrlPlaceObject:
00167                         case ctrlPlaceObject2:
00168                                 character = 0;
00169                                 matrix = 0;
00170                                 cxform = 0;
00171                                 name = "";
00172                                 if (ctrl->flags & placeHasCharacter) {
00173                                         character = ctrl->character;
00174                                 }
00175                                 if (ctrl->flags & placeHasMatrix) {
00176                                         matrix = &ctrl->matrix;
00177                                 }
00178                                 if (ctrl->flags & placeHasColorXform) {
00179                                         cxform = &ctrl->cxform;
00180                                 }
00181                                 if (ctrl->flags & placeHasName) {
00182                                         name = ctrl->name;
00183                                 }
00184                                 if (!ctrl->clipDepth) { // Ignore
00185                                         dl->placeObject(gd,character, ctrl->depth, matrix, cxform, name);
00186                                         update = 1;
00187                                 }
00188                                 break;
00189                         case ctrlRemoveObject:
00190                                 character = ctrl->character;
00191 
00192                                 if (!character) break;  // Should not happen
00193 
00194                                 dl->removeObject(gd, character, ctrl->depth);
00195                                 if (action) {
00196                                         character->reset();
00197                                         update = 1;
00198                                 }
00199                                 break;
00200                         case ctrlRemoveObject2:
00201                                 character = dl->removeObject(gd,NULL, ctrl->depth);
00202                                 if (character && action) {
00203                                         character->reset();
00204                                         update = 1;
00205                                 }
00206                                 break;
00207                 // Actions
00208                         case ctrlDoAction:
00209                                 if (action) {
00210                                         status = doAction(gd, ctrl->actionRecords, sm);
00211                                 }
00212                                 break;
00213                         case ctrlStartSound:
00214                                 if (action && sm) {
00215                                         sm->startSound( (Sound *)ctrl->character );
00216                                 }
00217                                 break;
00218                         case ctrlStopSound:
00219                                 if (action && sm) {
00220                                         sm->stopSounds();
00221                                 }
00222                                 break;
00223                         case ctrlBackgroundColor:
00224                                 if (action) {
00225                                         if (gd->setBackgroundColor(ctrl->color)) {
00226                                                 dl->bbox.xmin = -32768;
00227                                                 dl->bbox.ymin = -32768;
00228                                                 dl->bbox.xmax =  32768;
00229                                                 dl->bbox.ymax =  32768;
00230                                         }
00231                                 }
00232                                 break;
00233                 }
00234         }
00235         if (movie->buttons_updated) {
00236             dl->updateButtons(movie);
00237         }
00238 
00239         if (status & GOTO) {
00240                 if (nextFrame < nbFrames) {
00241                         gotoFrame(gd,nextFrame);
00242                         if (nextFrame != f)
00243                         if (movieStatus == MoviePaused) runFrame(gd,sm,nextFrame);
00244                         update = 1;
00245                 }
00246         }
00247 
00248 #if PRINT&1
00249         if (action) printf("Frame N° %d ready\n", f);
00250 #endif
00251         return update;
00252 }
00253 
00254 long
00255 Program::nestedMovie(GraphicDevice *gd, SoundMixer *sm, Matrix *mat, Cxform *cxform)
00256 {
00257         if (movieStatus == MoviePlay) {
00258                 // Movie Beeing Played
00259                 advanceFrame();
00260                 if (currentFrame == 0) {
00261                         dl->clearList();
00262                 }
00263                 runFrame(gd, sm, currentFrame);
00264                 if (nbFrames == 1) {
00265                         pauseMovie();
00266                 }
00267         }
00268 
00269         return (movieStatus == MoviePlay);
00270 }
00271 
00272 long
00273 Program::processMovie(GraphicDevice *gd, SoundMixer *sm)
00274 {
00275         int wakeUp = 0;
00276 
00277 #if PRINT&1
00278         printf("Prog %x (dl=%x): Current = %d     Next = %d    Wait = %d  Status = %d\n", this, this->dl, currentFrame, nextFrame, movieWait, movieStatus);
00279 #endif
00280 
00281         if (movieStatus == MoviePlay && movieWait == 0) {
00282                 // Movie Beeing Played
00283                 advanceFrame();
00284                 if (currentFrame == 0) {
00285                         dl->clearList();
00286                 }
00287                 wakeUp |= runFrame(gd, sm, currentFrame);
00288                 wakeUp |= dl->updateSprites();
00289                 if (nextFrame == nbFrames) {
00290                         if (nbFrames != totalFrames) {
00291                                 movieWait = 1;
00292                         } else if ((settings & PLAYER_LOOP) == 0) {
00293                                 pauseMovie();
00294                         }
00295                 }
00296         } else {
00297                 wakeUp |= dl->updateSprites();
00298         }
00299 
00300         if (wakeUp) {
00301                 render = 1;
00302         }
00303 
00304         return (wakeUp || movieStatus == MoviePlay);
00305 }
00306 
00307 /* timer (ms) -1 = delete timer */
00308 void setFlashTimer(struct timeval *tv, int time_ms)
00309 {
00310     if (time_ms == -1) {
00311         tv->tv_sec = -1;
00312     } else {
00313         gettimeofday(tv,0);
00314         
00315         tv->tv_usec += time_ms*1000;
00316         while (tv->tv_usec > 1000000) {
00317             tv->tv_usec -= 1000000;
00318             tv->tv_sec++;
00319         }
00320     }
00321 }
00322 
00323 int checkFlashTimer(struct timeval *tv)
00324 {
00325     struct timeval now;
00326 
00327     if (tv->tv_sec == -1) return 0;
00328 
00329     gettimeofday(&now,0);
00330     return (now.tv_sec > tv->tv_sec ||
00331             (now.tv_sec == tv->tv_sec && now.tv_usec >= tv->tv_usec));
00332 }
00333 
00334 /* bbox */
00335 typedef struct {
00336     long x1,y1,x2,y2;
00337 } ButtonBoundingBox;
00338 
00339 
00340 static void button_bbox_func(void *id, long y, long start, long end)
00341 {
00342     ButtonBoundingBox *h = (ButtonBoundingBox *) id;
00343 
00344     if (y < h->y1) h->y1 = y;
00345     if (y > h->y2) h->y2 = y;
00346     if (start < h->x1) h->x1 = start;
00347     if (end > h->x2) h->x2 = end;
00348 }
00349 
00350 void computeBBox(FlashMovie *movie, Rect *rect, DisplayListEntry *e)
00351 {
00352     ButtonBoundingBox bb;
00353 
00354     bb.x1 = LONG_MAX;
00355     bb.y1 = LONG_MAX;
00356     bb.x2 = LONG_MIN;
00357     bb.y2 = LONG_MIN;
00358     
00359     e->character->getRegion(movie->gd,&e->renderMatrix,&bb,button_bbox_func);
00360     
00361     rect->xmin = bb.x1 / FRAC;
00362     rect->xmax = bb.x2 / FRAC;
00363     rect->ymin = bb.y1;
00364     rect->ymax = bb.y2;
00365 }
00366 
00367 void transform_coords(long *x_ptr,long *y_ptr, long cx, long cy, long dx, long dy)
00368 {
00369     long x,y,x1,y1;
00370     x = *x_ptr;
00371     y = *y_ptr;
00372 
00373     x -= cx;
00374     y -= cy;
00375 
00376     if (dx < 0) {
00377         /* left */
00378         x1 = - x;
00379         y1 = y;
00380     } else if (dy < 0) {
00381         /* up */
00382         y1 = x;
00383         x1 = -y;
00384     } else if (dy > 0) {
00385         /* down */
00386         y1 = x;
00387         x1 = y;
00388     } else {
00389         /* right */
00390         x1 = x;
00391         y1 = y;
00392     }
00393         
00394     *x_ptr = x1;
00395     *y_ptr = y1;
00396 }
00397 
00398 typedef struct {
00399     FlashMovie *movie;
00400     DisplayListEntry *emin,*cur_focus;
00401     long dmin;
00402     long w,cx,cy,dx,dy;
00403 } ButtonFocus;
00404 
00405 static int button_focus(void *opaque, Program *prg, DisplayListEntry *e)
00406 {
00407     ButtonFocus *h=(ButtonFocus *)opaque;
00408     Rect rect;
00409     long d,x,y;
00410 
00411     if (e != h->cur_focus) {
00412         computeBBox(h->movie,&rect,e);
00413         x = (rect.xmin + rect.xmax) / 2;
00414         y = (rect.ymin + rect.ymax) / 2;
00415         
00416         /* transform the coords so that the angular sector is directed to the right */
00417         transform_coords(&x,&y,h->cx,h->cy,h->dx,h->dy);
00418         
00419         /* inside it ? */
00420         if ( x >= 0 && 
00421              (y - x - h->w) <= 0 && 
00422              (y + x + h->w) >= 0) {
00423             d = x*x + y*y;
00424             
00425             if (d < h->dmin) {
00426                 h->dmin = d;
00427                 h->emin = e;
00428             }
00429         }
00430     }
00431     return 0;
00432 }
00433 
00434 DisplayListEntry *moveFocus(FlashMovie *movie, long dx, long dy, 
00435                             DisplayListEntry *cur_focus)
00436 {
00437     Rect cur_rect;
00438     ButtonFocus h;
00439 
00440     h.movie = movie;
00441     h.dx = dx;
00442     h.dy = dy;
00443 
00444     computeBBox(movie,&cur_rect,cur_focus);
00445     /* center */
00446     h.cx = (cur_rect.xmin + cur_rect.xmax) / 2;
00447     h.cy = (cur_rect.ymin + cur_rect.ymax) / 2;
00448     
00449     /* width/2 of the 45 degrees angular sector */
00450     if (dy != 0) {
00451         /* for vertical displacement, we have a larger width */
00452         h.w = (cur_rect.xmax - cur_rect.xmin) / 2;
00453     } else {
00454         /* zero width for horizontal displacement */
00455         h.w = 0;
00456     }
00457 
00458     /* now we select the nearest button in the angular sector */
00459     h.dmin = LONG_MAX;
00460     h.emin = NULL;
00461     h.cur_focus = cur_focus;
00462 
00463     exploreButtons(movie, &h, button_focus);
00464     
00465     return h.emin;
00466 }
00467 
00468 static int button_newfocus(void *opaque, Program *prg, DisplayListEntry *e)
00469 {
00470     * (DisplayListEntry **)opaque = e;
00471     return 2;
00472 }
00473 
00474 static int button_nextfocus(void *opaque, Program *prg, DisplayListEntry *e)
00475 {
00476     static int found = 0;
00477     DisplayListEntry **focus;
00478 
00479     focus = (DisplayListEntry **)opaque;
00480     if (found) {
00481         *focus = e;
00482         found = 0;
00483         return 2;
00484     }
00485     if (e == *focus) {
00486         found = 1;
00487     }
00488     return 0;
00489 }
00490 
00491 
00492 /* XXX: should not be here (one level upper) */
00493 long
00494 Program::handleEvent(GraphicDevice *gd, SoundMixer *sm, FlashEvent *fe)
00495 {
00496     ActionRecord        *action;
00497     Program             *prog;
00498     long                 status = 0;
00499     DisplayListEntry *cur_focus, *new_focus;
00500     long dx,dy;
00501     int                  refresh;
00502 
00503     refresh = 0;
00504 
00505     switch(fe->type) {
00506 
00507     case FeKeyRelease:
00508         if (movie->mouse_active == 0) {
00509             
00510             if (movie->cur_focus) {
00511                 movie->cur_focus->owner->updateBoundingBox(movie->cur_focus);
00512                 movie->cur_focus->renderState = stateOver;
00513                 movie->cur_focus->owner->updateBoundingBox(movie->cur_focus);
00514             }
00515         }
00516         break;
00517 
00518     case FeKeyPress:
00519 
00520         movie->mouse_active = 0;
00521 
00522         /* find the button which has the focus */
00523         cur_focus = movie->cur_focus;
00524 
00525         if (fe->key == FeKeyEnter) {
00526             /* selection */
00527             if (cur_focus) {
00528                 /* select the button */
00529                 cur_focus->owner->updateBoundingBox(cur_focus);
00530                 cur_focus->renderState = stateDown;
00531                 ((Button *)cur_focus->character)->updateButtonState(cur_focus);
00532                 cur_focus->owner->updateBoundingBox(cur_focus);
00533 
00534                 movie->scheduledEvent.type = FeKeyRelease;
00535                 movie->scheduledEvent.key = FeKeyEnter;
00536 
00537                 setFlashTimer(&movie->scheduledTime, 250); /* 250 ms down */
00538             }
00539         } else {
00540             /* displacement */
00541 
00542             if (cur_focus == NULL) {
00543                 /* no current focus : set one */
00544                 exploreButtons(movie, &cur_focus, button_newfocus);
00545                 if (cur_focus) {
00546                     cur_focus->renderState = stateOver;
00547                     ((Button *)cur_focus->character)->updateButtonState(cur_focus);
00548                     cur_focus->owner->updateBoundingBox(cur_focus);
00549                 }
00550                 movie->cur_focus = cur_focus;
00551             } else {
00552                 /* move the focus (test) */
00553                 switch(fe->key) {
00554                 case FeKeyNext:
00555                     /* Next available */
00556                     cur_focus->owner->updateBoundingBox(cur_focus);
00557                     cur_focus->renderState = stateUp;
00558                     ((Button *)cur_focus->character)->updateButtonState(cur_focus);
00559                     cur_focus->owner->updateBoundingBox(cur_focus);
00560                     exploreButtons(movie, &cur_focus, button_nextfocus);
00561                     if (cur_focus) {
00562                         cur_focus->renderState = stateOver;
00563                         ((Button *)cur_focus->character)->updateButtonState(cur_focus);
00564                         cur_focus->owner->updateBoundingBox(cur_focus);
00565                     }
00566                     movie->cur_focus = cur_focus;
00567                     dx = 0;
00568                     dy = 0;
00569                     break;
00570                 case FeKeyUp:
00571                     dx = 0;
00572                     dy = -1;
00573                     break;
00574                 case FeKeyDown:
00575                     dx = 0;
00576                     dy = 1;
00577                     break;
00578                 case FeKeyLeft:
00579                     dx = -1;
00580                     dy = 0;
00581                     break;
00582                 case FeKeyRight:
00583                     dx = 1;
00584                     dy = 0;
00585                     break;
00586                 default:
00587                     /* should not happen */
00588                     dx = 0;
00589                     dy = 0;
00590                     break;
00591                 }
00592 
00593                 if (dx != 0 || dy != 0) {
00594 
00595                     new_focus = moveFocus(movie, dx, dy, cur_focus);
00596                     if (new_focus) {
00597                         cur_focus->owner->updateBoundingBox(cur_focus);
00598                         cur_focus->renderState = stateUp;
00599                         ((Button *)cur_focus->character)->updateButtonState(cur_focus);
00600                         cur_focus->owner->updateBoundingBox(cur_focus);
00601 
00602                         if (computeActions(movie, &prog, &action)) {
00603                             status |= prog->doAction(gd, action, sm);
00604                         }
00605                             
00606                         new_focus->renderState = stateOver;
00607                         ((Button *)new_focus->character)->updateButtonState(new_focus);
00608                         movie->cur_focus = new_focus;
00609                         new_focus->owner->updateBoundingBox(new_focus);
00610                     } else {
00611                         return 0;
00612                     }
00613                 }
00614             }
00615             if (movie->cur_focus == NULL) return 0;
00616         }
00617         break;
00618 
00619     case FeMouseMove:
00620         movie->mouse_active = 1;
00621         movie->mouse_x = fe->x * FRAC;
00622         movie->mouse_y = fe->y * FRAC;
00623         dl->updateButtons(movie);
00624         break;
00625 
00626     case FeButtonPress:
00627         movie->mouse_active = 1;
00628         movie->button_pressed = 1;
00629         dl->updateButtons(movie);
00630         break;
00631 
00632     case FeButtonRelease:
00633         movie->mouse_active = 1;
00634         movie->button_pressed = 0;
00635         dl->updateButtons(movie);
00636         break;
00637         
00638     default:
00639         return 0;
00640     }
00641 
00642     if (computeActions(movie, &prog, &action)) {
00643         status |= prog->doAction(gd, action, sm);
00644     }
00645 
00646     if (status & REFRESH) {
00647         status |= WAKEUP;
00648         refresh = 1;
00649     }
00650     if (status & GOTO) {
00651         if (nextFrame < nbFrames) {
00652                 gotoFrame(gd, nextFrame);
00653                 if (movieStatus == MoviePaused) runFrame(gd,sm,nextFrame);
00654                 refresh = 1;
00655         }
00656     }
00657 
00658     if (refresh) {
00659                 dl->updateSprites();
00660                 render = 1;
00661     }
00662     return (refresh || movieStatus == MoviePlay);
00663 }
00664 
00665 long
00666 Program::doAction(GraphicDevice *gd, ActionRecord *action, SoundMixer *sm)
00667 {
00668         long status = NOTHING;
00669         long f;
00670         char *target = "";
00671         long skip = 0;
00672 
00673         while(action)
00674         {
00675                 if (skip) skip--;
00676                 else
00677                 switch (action->action)
00678                 {
00679                         case ActionPlaySound:
00680 #if PRINT&2
00681                                 printf("Prog %x : PlaySound\n", this);
00682 #endif
00683                                 if (sm) {
00684                                     sm->startSound(action->sound);
00685                                 }
00686                                 status |= WAKEUP;
00687                                 break;
00688                         case ActionRefresh:
00689 #if PRINT&2
00690                                 printf("Prog %x : Refresh\n", this);
00691 #endif
00692                                 status |= REFRESH;
00693                                 break;
00694                         case ActionGotoFrame:
00695 #if PRINT&2
00696                                 printf("Prog %x : GotoFrame %d\n", this, action->frameIndex);
00697 #endif
00698                                 if (target[0] == 0) {
00699                                         if (action->frameIndex < nbFrames) {
00700                                                 currentFrame = action->frameIndex;
00701                                                 pauseMovie();
00702                                                 status |= WAKEUP|GOTO;
00703                                         }
00704                                 }
00705                                 break;
00706                         case ActionGetURL:
00707 #if PRINT&2
00708                                 printf("Prog %x : GetURL %s target = %s\n", this, action->url, action->target);
00709 #endif
00710                                 {
00711                                     int len,level;
00712                                     len = strlen(action->target);
00713                                     
00714                                     if (len > 6 && memcmp(action->target,"_level", 6) == 0) {
00715                                         level = atoi(action->target + 6);
00716                                         loadNewSwf(movie, action->url, level);
00717                                     } else {
00718                                         if (movie->getUrl) {
00719                                             movie->getUrl(action->url, action->target, movie->getUrlClientData);
00720                                         }
00721                                     }
00722                                 }
00723                                 break;
00724                         case ActionNextFrame:
00725                                 nextFrame = currentFrame+1;
00726                                 movieStatus = MoviePlay;
00727                                 status |= WAKEUP;
00728                                 break;
00729                         case ActionPrevFrame:
00730                                 nextFrame = currentFrame-1;
00731                                 status |= WAKEUP|GOTO;
00732                                 break;
00733                         case ActionPlay:
00734 #if PRINT&2
00735                                 printf("Prog %x : Play\n", this);
00736 #endif
00737                                 if (target[0] == 0) {
00738                                         movieStatus = MoviePlay;
00739                                         if ((status & GOTO) == 0) {
00740                                                 if (currentFrame == nextFrame) advanceFrame();
00741                                         }
00742                                         status |= WAKEUP;
00743                                 }
00744                                 break;
00745                         case ActionStop:
00746 #if PRINT&2
00747                                 printf("Prog %x : Stop\n", this);
00748 #endif
00749                                 if (target[0] == 0) {
00750                                         movieStatus = MoviePaused;
00751                                         nextFrame = currentFrame;
00752                                 }
00753                                 break;
00754                         case ActionToggleQuality:
00755                                 break;
00756                         case ActionStopSounds:
00757                                 if (sm) {
00758                                         sm->stopSounds();
00759                                 }
00760                                 break;
00761                         case ActionWaitForFrame:
00762                                 if (action->frameIndex >= nbFrames) {
00763                                         skip = action->skipCount;
00764                                 }
00765                                 break;
00766                         case ActionSetTarget:
00767 #if PRINT&2
00768                                 printf("Prog %x : SetTarget '%s'\n", this, action->target);
00769 #endif
00770                                 target = action->target;
00771                                 break;
00772                         case ActionGoToLabel:
00773 #if PRINT&2
00774                                 printf("Prog %x : GotoFrame '%s'\n", this, action->frameLabel);
00775 #endif
00776                                 f = searchFrame(gd, action->frameLabel, target);
00777                                 if (f >= 0) {
00778                                     currentFrame = f;
00779                                     pauseMovie();
00780                                     status |= WAKEUP|GOTO;
00781                                 } else {
00782                                     status |= REFRESH;
00783                                 }
00784                                 break;
00785                 }
00786                 action = action->next;
00787         }
00788         return status;
00789 }
00790 
00791 void
00792 Program::setCurrentFrameLabel(char *label)
00793 {
00794     frames[loadingFrame].label = label;
00795 }
00796 
00797 void
00798 Program::rewindMovie()
00799 {
00800         currentFrame = 0;
00801         nextFrame = 0;
00802 }
00803 
00804 void
00805 Program::pauseMovie()
00806 {
00807         movieStatus = MoviePaused;
00808         nextFrame = currentFrame;
00809 }
00810 
00811 void
00812 Program::continueMovie()
00813 {
00814         movieStatus = MoviePlay;
00815 }
00816 
00817 void
00818 Program::nextStepMovie()
00819 {
00820         if (movieStatus == MoviePaused) {
00821                 advanceFrame();
00822         }
00823 }
00824 
00825 void
00826 Program::advanceFrame()
00827 {
00828         currentFrame = nextFrame;
00829         nextFrame = currentFrame+1;
00830         if (currentFrame == nbFrames) {
00831                 currentFrame = 0;
00832                 nextFrame = 0;
00833                 movieStatus = MoviePlay;
00834         }
00835 }
00836 
00837 void
00838 Program::addControlInCurrentFrame(Control *ctrl)
00839 {
00840         Control *c;
00841 
00842         ctrl->next = 0;
00843         if (frames[loadingFrame].controls == 0) {
00844                 frames[loadingFrame].controls = ctrl;
00845         } else {
00846                 for(c = frames[loadingFrame].controls; c->next; c = c->next);
00847                 c->next = ctrl;
00848         }
00849 }
00850 
00851 void
00852 Program::modifySettings(long flags)
00853 {
00854         settings = flags;
00855 }
00856 
00857 long
00858 Program::searchFrame(GraphicDevice *gd, char *label, char *target)
00859 {
00860         long f;
00861         DisplayListEntry *e;
00862         Program *prg;
00863 
00864         // Current movie
00865         if (target[0] == 0) {
00866                 for(f=0; f < nbFrames; f++)
00867                 {
00868                     if (frames[f].label && !strcmp(label,frames[f].label)) {
00869                         return f;
00870                     }
00871                 }
00872         }
00873 
00874         // Kludge !!!
00875         for (e = dl->list; e; e = e->next) {
00876             if (e->character->isSprite()) {
00877                 prg = ((Sprite *)e->character)->program;
00878                 f = prg->searchFrame(gd,label,"");
00879                 if (f >= 0 && f < prg->nbFrames) {
00880                     prg->dl->updateBoundingBox(e);
00881                     prg->gotoFrame(gd, f);
00882                     prg->nextFrame = f;
00883                     prg->dl->updateBoundingBox(e);
00884                     return -1;
00885                 }
00886             }
00887         }
00888 
00889         return -1;
00890 }
00891 
00892 void loadNewSwf(FlashMovie *movie, char *url, int level)
00893 {
00894     CInputScript *s,*prev,**l;
00895 
00896     if (movie->getSwf == NULL) return;
00897 
00898     for(s = movie->main, prev = 0; s != NULL; prev = s, s = s->next) {
00899         if (s->level == level) {
00900                 // Mark movie to be deleted
00901                 s->level = -1;
00902                 break;
00903         }
00904     }
00905 
00906     //printf("Unload movie @ %d\n", level);
00907 
00908     if (*url == 0) return;      // Just UnloadMovie
00909 
00910     s = new CInputScript(level);
00911     if (s == NULL) return;
00912 
00913     /* insert it in the right order */
00914     l = &movie->main;
00915     while (*l != NULL && (*l)->level < level) l = &(*l)->next;
00916     s->next = *l;
00917     *l = s;
00918 
00919     // Notify the external loader of a new movie to load
00920     movie->getSwf(url, level, movie->getSwfClientData);
00921 }

Generated on Sat Nov 5 16:15:35 2005 for OPIE by  doxygen 1.4.2