summaryrefslogtreecommitdiff
path: root/core/multimedia/opieplayer/libflash/program.cc
Side-by-side diff
Diffstat (limited to 'core/multimedia/opieplayer/libflash/program.cc') (more/less context) (ignore whitespace changes)
-rw-r--r--core/multimedia/opieplayer/libflash/program.cc921
1 files changed, 921 insertions, 0 deletions
diff --git a/core/multimedia/opieplayer/libflash/program.cc b/core/multimedia/opieplayer/libflash/program.cc
new file mode 100644
index 0000000..c6e8c0f
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/program.cc
@@ -0,0 +1,921 @@
+/////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998,1999 Olivier Debon
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+///////////////////////////////////////////////////////////////
+// Author : Olivier Debon <odebon@club-internet.fr>
+//
+
+#include "swf.h"
+
+#define NOTHING 0x0
+#define WAKEUP 0x1
+#define GOTO 0x2
+#define REFRESH 0x4
+
+#ifdef RCSID
+static char *rcsid = "$Id$";
+#endif
+
+#define PRINT 0
+
+int debug = 0;
+
+Program::Program(FlashMovie *movie, long n)
+{
+ long f;
+
+ this->movie = movie;
+
+ totalFrames = 0;
+
+ dl = new DisplayList(movie);
+ if (dl == NULL) return;
+ frames = new Frame[n];
+ if (frames == NULL) {
+ delete dl;
+ return;
+ }
+
+ nbFrames = 0;
+ totalFrames = n;
+ currentFrame = 0;
+ loadingFrame = 0;
+ movieWait = 1;
+ nextFrame = currentFrame;
+ for(f = 0; f < n; f++)
+ {
+ frames[f].controls = 0;
+ frames[f].label = NULL;
+ }
+
+ movieStatus = MoviePlay;
+ settings = 0;
+}
+
+Program::~Program()
+{
+ int i;
+ Control *ctrl, *ctrl1;
+
+ delete dl;
+
+ if (frames != NULL) {
+ for(i=0;i<nbFrames;i++) {
+ ctrl = frames[i].controls;
+ if (frames[i].label) free(frames[i].label);
+ while (ctrl != NULL) {
+ ctrl1 = ctrl->next;
+ ctrl->next = NULL;
+ delete ctrl;
+ ctrl = ctrl1;
+ }
+ }
+
+ delete[] frames;
+ }
+}
+
+void
+Program::validateLoadingFrame()
+{
+ nbFrames = loadingFrame;
+ loadingFrame++;
+ movieWait = 0;
+}
+
+Frame *
+Program::getFrames()
+{
+ return frames;
+}
+
+long
+Program::getNbFrames()
+{
+ return nbFrames;
+}
+
+DisplayList *
+Program::getDisplayList()
+{
+ return dl;
+}
+
+long
+Program::getCurrentFrame()
+{
+ return currentFrame;
+}
+
+void
+Program::setCurrentFrame(long n)
+{
+ currentFrame = n;
+ nextFrame = n;
+ //refresh = 1;
+}
+
+void
+Program::gotoFrame(GraphicDevice *gd, long frame)
+{
+ long f;
+
+ //printf("GotoFrame %d (Current = %d)\n", frame, currentFrame);
+ dl->clearList();
+
+ for(f=0; f <= frame; f++) {
+ runFrame(gd, 0, f, 0);
+ }
+}
+
+long
+Program::runFrame(GraphicDevice *gd, SoundMixer *sm, long f, long action)
+{
+ Control *ctrl;
+ Character *character;
+ Matrix *matrix;
+ Cxform *cxform;
+ long status = NOTHING;
+ long update = 0;
+ char *name;
+
+#if PRINT&1
+ if (action) printf("Prog %x (dl=%x): Frame N° %d/%d\n", this, this->dl, f, nbFrames-1);
+#endif
+ movie->buttons_updated = 0;
+
+ for(ctrl = frames[f].controls; ctrl; ctrl = ctrl->next)
+ {
+ switch (ctrl->type)
+ {
+ case ctrlPlaceObject:
+ case ctrlPlaceObject2:
+ character = 0;
+ matrix = 0;
+ cxform = 0;
+ name = "";
+ if (ctrl->flags & placeHasCharacter) {
+ character = ctrl->character;
+ }
+ if (ctrl->flags & placeHasMatrix) {
+ matrix = &ctrl->matrix;
+ }
+ if (ctrl->flags & placeHasColorXform) {
+ cxform = &ctrl->cxform;
+ }
+ if (ctrl->flags & placeHasName) {
+ name = ctrl->name;
+ }
+ if (!ctrl->clipDepth) { // Ignore
+ dl->placeObject(gd,character, ctrl->depth, matrix, cxform, name);
+ update = 1;
+ }
+ break;
+ case ctrlRemoveObject:
+ character = ctrl->character;
+
+ if (!character) break; // Should not happen
+
+ dl->removeObject(gd, character, ctrl->depth);
+ if (action) {
+ character->reset();
+ update = 1;
+ }
+ break;
+ case ctrlRemoveObject2:
+ character = dl->removeObject(gd,NULL, ctrl->depth);
+ if (character && action) {
+ character->reset();
+ update = 1;
+ }
+ break;
+ // Actions
+ case ctrlDoAction:
+ if (action) {
+ status = doAction(gd, ctrl->actionRecords, sm);
+ }
+ break;
+ case ctrlStartSound:
+ if (action && sm) {
+ sm->startSound( (Sound *)ctrl->character );
+ }
+ break;
+ case ctrlStopSound:
+ if (action && sm) {
+ sm->stopSounds();
+ }
+ break;
+ case ctrlBackgroundColor:
+ if (action) {
+ if (gd->setBackgroundColor(ctrl->color)) {
+ dl->bbox.xmin = -32768;
+ dl->bbox.ymin = -32768;
+ dl->bbox.xmax = 32768;
+ dl->bbox.ymax = 32768;
+ }
+ }
+ break;
+ }
+ }
+ if (movie->buttons_updated) {
+ dl->updateButtons(movie);
+ }
+
+ if (status & GOTO) {
+ if (nextFrame < nbFrames) {
+ gotoFrame(gd,nextFrame);
+ if (nextFrame != f)
+ if (movieStatus == MoviePaused) runFrame(gd,sm,nextFrame);
+ update = 1;
+ }
+ }
+
+#if PRINT&1
+ if (action) printf("Frame N° %d ready\n", f);
+#endif
+ return update;
+}
+
+long
+Program::nestedMovie(GraphicDevice *gd, SoundMixer *sm, Matrix *mat, Cxform *cxform)
+{
+ if (movieStatus == MoviePlay) {
+ // Movie Beeing Played
+ advanceFrame();
+ if (currentFrame == 0) {
+ dl->clearList();
+ }
+ runFrame(gd, sm, currentFrame);
+ if (nbFrames == 1) {
+ pauseMovie();
+ }
+ }
+
+ return (movieStatus == MoviePlay);
+}
+
+long
+Program::processMovie(GraphicDevice *gd, SoundMixer *sm)
+{
+ int wakeUp = 0;
+
+#if PRINT&1
+ printf("Prog %x (dl=%x): Current = %d Next = %d Wait = %d Status = %d\n", this, this->dl, currentFrame, nextFrame, movieWait, movieStatus);
+#endif
+
+ if (movieStatus == MoviePlay && movieWait == 0) {
+ // Movie Beeing Played
+ advanceFrame();
+ if (currentFrame == 0) {
+ dl->clearList();
+ }
+ wakeUp |= runFrame(gd, sm, currentFrame);
+ wakeUp |= dl->updateSprites();
+ if (nextFrame == nbFrames) {
+ if (nbFrames != totalFrames) {
+ movieWait = 1;
+ } else if ((settings & PLAYER_LOOP) == 0) {
+ pauseMovie();
+ }
+ }
+ } else {
+ wakeUp |= dl->updateSprites();
+ }
+
+ if (wakeUp) {
+ render = 1;
+ }
+
+ return (wakeUp || movieStatus == MoviePlay);
+}
+
+/* timer (ms) -1 = delete timer */
+void setFlashTimer(struct timeval *tv, int time_ms)
+{
+ if (time_ms == -1) {
+ tv->tv_sec = -1;
+ } else {
+ gettimeofday(tv,0);
+
+ tv->tv_usec += time_ms*1000;
+ while (tv->tv_usec > 1000000) {
+ tv->tv_usec -= 1000000;
+ tv->tv_sec++;
+ }
+ }
+}
+
+int checkFlashTimer(struct timeval *tv)
+{
+ struct timeval now;
+
+ if (tv->tv_sec == -1) return 0;
+
+ gettimeofday(&now,0);
+ return (now.tv_sec > tv->tv_sec ||
+ (now.tv_sec == tv->tv_sec && now.tv_usec >= tv->tv_usec));
+}
+
+/* bbox */
+typedef struct {
+ long x1,y1,x2,y2;
+} ButtonBoundingBox;
+
+
+static void button_bbox_func(void *id, long y, long start, long end)
+{
+ ButtonBoundingBox *h = (ButtonBoundingBox *) id;
+
+ if (y < h->y1) h->y1 = y;
+ if (y > h->y2) h->y2 = y;
+ if (start < h->x1) h->x1 = start;
+ if (end > h->x2) h->x2 = end;
+}
+
+void computeBBox(FlashMovie *movie, Rect *rect, DisplayListEntry *e)
+{
+ ButtonBoundingBox bb;
+
+ bb.x1 = LONG_MAX;
+ bb.y1 = LONG_MAX;
+ bb.x2 = LONG_MIN;
+ bb.y2 = LONG_MIN;
+
+ e->character->getRegion(movie->gd,&e->renderMatrix,&bb,button_bbox_func);
+
+ rect->xmin = bb.x1 / FRAC;
+ rect->xmax = bb.x2 / FRAC;
+ rect->ymin = bb.y1;
+ rect->ymax = bb.y2;
+}
+
+void transform_coords(long *x_ptr,long *y_ptr, long cx, long cy, long dx, long dy)
+{
+ long x,y,x1,y1;
+ x = *x_ptr;
+ y = *y_ptr;
+
+ x -= cx;
+ y -= cy;
+
+ if (dx < 0) {
+ /* left */
+ x1 = - x;
+ y1 = y;
+ } else if (dy < 0) {
+ /* up */
+ y1 = x;
+ x1 = -y;
+ } else if (dy > 0) {
+ /* down */
+ y1 = x;
+ x1 = y;
+ } else {
+ /* right */
+ x1 = x;
+ y1 = y;
+ }
+
+ *x_ptr = x1;
+ *y_ptr = y1;
+}
+
+typedef struct {
+ FlashMovie *movie;
+ DisplayListEntry *emin,*cur_focus;
+ long dmin;
+ long w,cx,cy,dx,dy;
+} ButtonFocus;
+
+static int button_focus(void *opaque, Program *prg, DisplayListEntry *e)
+{
+ ButtonFocus *h=(ButtonFocus *)opaque;
+ Rect rect;
+ long d,x,y;
+
+ if (e != h->cur_focus) {
+ computeBBox(h->movie,&rect,e);
+ x = (rect.xmin + rect.xmax) / 2;
+ y = (rect.ymin + rect.ymax) / 2;
+
+ /* transform the coords so that the angular sector is directed to the right */
+ transform_coords(&x,&y,h->cx,h->cy,h->dx,h->dy);
+
+ /* inside it ? */
+ if ( x >= 0 &&
+ (y - x - h->w) <= 0 &&
+ (y + x + h->w) >= 0) {
+ d = x*x + y*y;
+
+ if (d < h->dmin) {
+ h->dmin = d;
+ h->emin = e;
+ }
+ }
+ }
+ return 0;
+}
+
+DisplayListEntry *moveFocus(FlashMovie *movie, long dx, long dy,
+ DisplayListEntry *cur_focus)
+{
+ Rect cur_rect;
+ ButtonFocus h;
+
+ h.movie = movie;
+ h.dx = dx;
+ h.dy = dy;
+
+ computeBBox(movie,&cur_rect,cur_focus);
+ /* center */
+ h.cx = (cur_rect.xmin + cur_rect.xmax) / 2;
+ h.cy = (cur_rect.ymin + cur_rect.ymax) / 2;
+
+ /* width/2 of the 45 degrees angular sector */
+ if (dy != 0) {
+ /* for vertical displacement, we have a larger width */
+ h.w = (cur_rect.xmax - cur_rect.xmin) / 2;
+ } else {
+ /* zero width for horizontal displacement */
+ h.w = 0;
+ }
+
+ /* now we select the nearest button in the angular sector */
+ h.dmin = LONG_MAX;
+ h.emin = NULL;
+ h.cur_focus = cur_focus;
+
+ exploreButtons(movie, &h, button_focus);
+
+ return h.emin;
+}
+
+static int button_newfocus(void *opaque, Program *prg, DisplayListEntry *e)
+{
+ * (DisplayListEntry **)opaque = e;
+ return 2;
+}
+
+static int button_nextfocus(void *opaque, Program *prg, DisplayListEntry *e)
+{
+ static int found = 0;
+ DisplayListEntry **focus;
+
+ focus = (DisplayListEntry **)opaque;
+ if (found) {
+ *focus = e;
+ found = 0;
+ return 2;
+ }
+ if (e == *focus) {
+ found = 1;
+ }
+ return 0;
+}
+
+
+/* XXX: should not be here (one level upper) */
+long
+Program::handleEvent(GraphicDevice *gd, SoundMixer *sm, FlashEvent *fe)
+{
+ ActionRecord *action;
+ Program *prog;
+ long status = 0;
+ DisplayListEntry *cur_focus, *new_focus;
+ long dx,dy;
+ int refresh;
+
+ refresh = 0;
+
+ switch(fe->type) {
+
+ case FeKeyRelease:
+ if (movie->mouse_active == 0) {
+
+ if (movie->cur_focus) {
+ movie->cur_focus->owner->updateBoundingBox(movie->cur_focus);
+ movie->cur_focus->renderState = stateOver;
+ movie->cur_focus->owner->updateBoundingBox(movie->cur_focus);
+ }
+ }
+ break;
+
+ case FeKeyPress:
+
+ movie->mouse_active = 0;
+
+ /* find the button which has the focus */
+ cur_focus = movie->cur_focus;
+
+ if (fe->key == FeKeyEnter) {
+ /* selection */
+ if (cur_focus) {
+ /* select the button */
+ cur_focus->owner->updateBoundingBox(cur_focus);
+ cur_focus->renderState = stateDown;
+ ((Button *)cur_focus->character)->updateButtonState(cur_focus);
+ cur_focus->owner->updateBoundingBox(cur_focus);
+
+ movie->scheduledEvent.type = FeKeyRelease;
+ movie->scheduledEvent.key = FeKeyEnter;
+
+ setFlashTimer(&movie->scheduledTime, 250); /* 250 ms down */
+ }
+ } else {
+ /* displacement */
+
+ if (cur_focus == NULL) {
+ /* no current focus : set one */
+ exploreButtons(movie, &cur_focus, button_newfocus);
+ if (cur_focus) {
+ cur_focus->renderState = stateOver;
+ ((Button *)cur_focus->character)->updateButtonState(cur_focus);
+ cur_focus->owner->updateBoundingBox(cur_focus);
+ }
+ movie->cur_focus = cur_focus;
+ } else {
+ /* move the focus (test) */
+ switch(fe->key) {
+ case FeKeyNext:
+ /* Next available */
+ cur_focus->owner->updateBoundingBox(cur_focus);
+ cur_focus->renderState = stateUp;
+ ((Button *)cur_focus->character)->updateButtonState(cur_focus);
+ cur_focus->owner->updateBoundingBox(cur_focus);
+ exploreButtons(movie, &cur_focus, button_nextfocus);
+ if (cur_focus) {
+ cur_focus->renderState = stateOver;
+ ((Button *)cur_focus->character)->updateButtonState(cur_focus);
+ cur_focus->owner->updateBoundingBox(cur_focus);
+ }
+ movie->cur_focus = cur_focus;
+ dx = 0;
+ dy = 0;
+ break;
+ case FeKeyUp:
+ dx = 0;
+ dy = -1;
+ break;
+ case FeKeyDown:
+ dx = 0;
+ dy = 1;
+ break;
+ case FeKeyLeft:
+ dx = -1;
+ dy = 0;
+ break;
+ case FeKeyRight:
+ dx = 1;
+ dy = 0;
+ break;
+ default:
+ /* should not happen */
+ dx = 0;
+ dy = 0;
+ break;
+ }
+
+ if (dx != 0 || dy != 0) {
+
+ new_focus = moveFocus(movie, dx, dy, cur_focus);
+ if (new_focus) {
+ cur_focus->owner->updateBoundingBox(cur_focus);
+ cur_focus->renderState = stateUp;
+ ((Button *)cur_focus->character)->updateButtonState(cur_focus);
+ cur_focus->owner->updateBoundingBox(cur_focus);
+
+ if (computeActions(movie, &prog, &action)) {
+ status |= prog->doAction(gd, action, sm);
+ }
+
+ new_focus->renderState = stateOver;
+ ((Button *)new_focus->character)->updateButtonState(new_focus);
+ movie->cur_focus = new_focus;
+ new_focus->owner->updateBoundingBox(new_focus);
+ } else {
+ return 0;
+ }
+ }
+ }
+ if (movie->cur_focus == NULL) return 0;
+ }
+ break;
+
+ case FeMouseMove:
+ movie->mouse_active = 1;
+ movie->mouse_x = fe->x * FRAC;
+ movie->mouse_y = fe->y * FRAC;
+ dl->updateButtons(movie);
+ break;
+
+ case FeButtonPress:
+ movie->mouse_active = 1;
+ movie->button_pressed = 1;
+ dl->updateButtons(movie);
+ break;
+
+ case FeButtonRelease:
+ movie->mouse_active = 1;
+ movie->button_pressed = 0;
+ dl->updateButtons(movie);
+ break;
+
+ default:
+ return 0;
+ }
+
+ if (computeActions(movie, &prog, &action)) {
+ status |= prog->doAction(gd, action, sm);
+ }
+
+ if (status & REFRESH) {
+ status |= WAKEUP;
+ refresh = 1;
+ }
+ if (status & GOTO) {
+ if (nextFrame < nbFrames) {
+ gotoFrame(gd, nextFrame);
+ if (movieStatus == MoviePaused) runFrame(gd,sm,nextFrame);
+ refresh = 1;
+ }
+ }
+
+ if (refresh) {
+ dl->updateSprites();
+ render = 1;
+ }
+ return (refresh || movieStatus == MoviePlay);
+}
+
+long
+Program::doAction(GraphicDevice *gd, ActionRecord *action, SoundMixer *sm)
+{
+ long status = NOTHING;
+ long f;
+ char *target = "";
+ long skip = 0;
+
+ while(action)
+ {
+ if (skip) skip--;
+ else
+ switch (action->action)
+ {
+ case ActionPlaySound:
+#if PRINT&2
+ printf("Prog %x : PlaySound\n", this);
+#endif
+ if (sm) {
+ sm->startSound(action->sound);
+ }
+ status |= WAKEUP;
+ break;
+ case ActionRefresh:
+#if PRINT&2
+ printf("Prog %x : Refresh\n", this);
+#endif
+ status |= REFRESH;
+ break;
+ case ActionGotoFrame:
+#if PRINT&2
+ printf("Prog %x : GotoFrame %d\n", this, action->frameIndex);
+#endif
+ if (target[0] == 0) {
+ if (action->frameIndex < nbFrames) {
+ currentFrame = action->frameIndex;
+ pauseMovie();
+ status |= WAKEUP|GOTO;
+ }
+ }
+ break;
+ case ActionGetURL:
+#if PRINT&2
+ printf("Prog %x : GetURL %s target = %s\n", this, action->url, action->target);
+#endif
+ {
+ int len,level;
+ len = strlen(action->target);
+
+ if (len > 6 && memcmp(action->target,"_level", 6) == 0) {
+ level = atoi(action->target + 6);
+ loadNewSwf(movie, action->url, level);
+ } else {
+ if (movie->getUrl) {
+ movie->getUrl(action->url, action->target, movie->getUrlClientData);
+ }
+ }
+ }
+ break;
+ case ActionNextFrame:
+ nextFrame = currentFrame+1;
+ movieStatus = MoviePlay;
+ status |= WAKEUP;
+ break;
+ case ActionPrevFrame:
+ nextFrame = currentFrame-1;
+ status |= WAKEUP|GOTO;
+ break;
+ case ActionPlay:
+#if PRINT&2
+ printf("Prog %x : Play\n", this);
+#endif
+ if (target[0] == 0) {
+ movieStatus = MoviePlay;
+ if ((status & GOTO) == 0) {
+ if (currentFrame == nextFrame) advanceFrame();
+ }
+ status |= WAKEUP;
+ }
+ break;
+ case ActionStop:
+#if PRINT&2
+ printf("Prog %x : Stop\n", this);
+#endif
+ if (target[0] == 0) {
+ movieStatus = MoviePaused;
+ nextFrame = currentFrame;
+ }
+ break;
+ case ActionToggleQuality:
+ break;
+ case ActionStopSounds:
+ if (sm) {
+ sm->stopSounds();
+ }
+ break;
+ case ActionWaitForFrame:
+ if (action->frameIndex >= nbFrames) {
+ skip = action->skipCount;
+ }
+ break;
+ case ActionSetTarget:
+#if PRINT&2
+ printf("Prog %x : SetTarget '%s'\n", this, action->target);
+#endif
+ target = action->target;
+ break;
+ case ActionGoToLabel:
+#if PRINT&2
+ printf("Prog %x : GotoFrame '%s'\n", this, action->frameLabel);
+#endif
+ f = searchFrame(gd, action->frameLabel, target);
+ if (f >= 0) {
+ currentFrame = f;
+ pauseMovie();
+ status |= WAKEUP|GOTO;
+ } else {
+ status |= REFRESH;
+ }
+ break;
+ }
+ action = action->next;
+ }
+ return status;
+}
+
+void
+Program::setCurrentFrameLabel(char *label)
+{
+ frames[loadingFrame].label = label;
+}
+
+void
+Program::rewindMovie()
+{
+ currentFrame = 0;
+ nextFrame = 0;
+}
+
+void
+Program::pauseMovie()
+{
+ movieStatus = MoviePaused;
+ nextFrame = currentFrame;
+}
+
+void
+Program::continueMovie()
+{
+ movieStatus = MoviePlay;
+}
+
+void
+Program::nextStepMovie()
+{
+ if (movieStatus == MoviePaused) {
+ advanceFrame();
+ }
+}
+
+void
+Program::advanceFrame()
+{
+ currentFrame = nextFrame;
+ nextFrame = currentFrame+1;
+ if (currentFrame == nbFrames) {
+ currentFrame = 0;
+ nextFrame = 0;
+ movieStatus = MoviePlay;
+ }
+}
+
+void
+Program::addControlInCurrentFrame(Control *ctrl)
+{
+ Control *c;
+
+ ctrl->next = 0;
+ if (frames[loadingFrame].controls == 0) {
+ frames[loadingFrame].controls = ctrl;
+ } else {
+ for(c = frames[loadingFrame].controls; c->next; c = c->next);
+ c->next = ctrl;
+ }
+}
+
+void
+Program::modifySettings(long flags)
+{
+ settings = flags;
+}
+
+long
+Program::searchFrame(GraphicDevice *gd, char *label, char *target)
+{
+ long f;
+ DisplayListEntry *e;
+ Program *prg;
+
+ // Current movie
+ if (target[0] == 0) {
+ for(f=0; f < nbFrames; f++)
+ {
+ if (frames[f].label && !strcmp(label,frames[f].label)) {
+ return f;
+ }
+ }
+ }
+
+ // Kludge !!!
+ for (e = dl->list; e; e = e->next) {
+ if (e->character->isSprite()) {
+ prg = ((Sprite *)e->character)->program;
+ f = prg->searchFrame(gd,label,"");
+ if (f >= 0 && f < prg->nbFrames) {
+ prg->dl->updateBoundingBox(e);
+ prg->gotoFrame(gd, f);
+ prg->nextFrame = f;
+ prg->dl->updateBoundingBox(e);
+ return -1;
+ }
+ }
+ }
+
+ return -1;
+}
+
+void loadNewSwf(FlashMovie *movie, char *url, int level)
+{
+ CInputScript *s,*prev,**l;
+
+ if (movie->getSwf == NULL) return;
+
+ for(s = movie->main, prev = 0; s != NULL; prev = s, s = s->next) {
+ if (s->level == level) {
+ // Mark movie to be deleted
+ s->level = -1;
+ break;
+ }
+ }
+
+ //printf("Unload movie @ %d\n", level);
+
+ if (*url == 0) return; // Just UnloadMovie
+
+ s = new CInputScript(level);
+ if (s == NULL) return;
+
+ /* insert it in the right order */
+ l = &movie->main;
+ while (*l != NULL && (*l)->level < level) l = &(*l)->next;
+ s->next = *l;
+ *l = s;
+
+ // Notify the external loader of a new movie to load
+ movie->getSwf(url, level, movie->getSwfClientData);
+}