CVSROOT: /sources/gnash Module name: gnash Changes by: Sandro Santilli <strk> 08/01/20 19:38:04
Modified files: . : ChangeLog server : character.cpp character.h sprite_instance.cpp testsuite/misc-ming.all: masks_test.c Log message: dynamic masks have a 1:1 relation, a character can't be a mask for multiple maskees. Consider dynamic masks for hit test (pointInVisibleShape only for now). CVSWeb URLs: http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.5437&r2=1.5438 http://cvs.savannah.gnu.org/viewcvs/gnash/server/character.cpp?cvsroot=gnash&r1=1.73&r2=1.74 http://cvs.savannah.gnu.org/viewcvs/gnash/server/character.h?cvsroot=gnash&r1=1.120&r2=1.121 http://cvs.savannah.gnu.org/viewcvs/gnash/server/sprite_instance.cpp?cvsroot=gnash&r1=1.451&r2=1.452 http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/misc-ming.all/masks_test.c?cvsroot=gnash&r1=1.6&r2=1.7 Patches: Index: ChangeLog =================================================================== RCS file: /sources/gnash/gnash/ChangeLog,v retrieving revision 1.5437 retrieving revision 1.5438 diff -u -b -r1.5437 -r1.5438 --- ChangeLog 20 Jan 2008 17:17:19 -0000 1.5437 +++ ChangeLog 20 Jan 2008 19:38:03 -0000 1.5438 @@ -1,3 +1,17 @@ +2008-01-20 Sandro Santilli <[EMAIL PROTECTED]> + + * server/character.{cpp,h}: keep a pointer from the mask to + the maskee, as every character can dynamically mask at most + a single maskee, so need to get an handle of old maskees + when new are registered; have pointInVisibleShape return + false for dynamic masks. + * server/sprite_instance.cpp: (pointInVisibleShape): if a character + is a mask return false, if it's dynamically masked check hit test + against the mask too; (setMask): return a boolean value. + * testsuite/misc-ming.all/masks_test.c: update expected results, most + tests pass now, except a couple in which I'd thing Gnash is correct + despite the official results... + 2008-01-20 Rob Savoye <[EMAIL PROTECTED]> * cygnal/Makefile.am: Build a library of dependant files, instead Index: server/character.cpp =================================================================== RCS file: /sources/gnash/gnash/server/character.cpp,v retrieving revision 1.73 retrieving revision 1.74 diff -u -b -r1.73 -r1.74 --- server/character.cpp 18 Jan 2008 17:48:26 -0000 1.73 +++ server/character.cpp 20 Jan 2008 19:38:04 -0000 1.74 @@ -17,7 +17,7 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // -/* $Id: character.cpp,v 1.73 2008/01/18 17:48:26 bwy Exp $ */ +/* $Id: character.cpp,v 1.74 2008/01/20 19:38:04 strk Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -854,6 +854,108 @@ _destroyed = true; } +void +character::markCharacterReachable() const +{ + if ( m_parent ) m_parent->setReachable(); + if ( _mask ) + { + // Stop being masked if the mask was unloaded + if ( _mask->isUnloaded() ) + { + const_cast<character*>(this)->setMask(0); + } + else _mask->setReachable(); + } + if ( _maskee ) + { + // Stop masking if the masked character was unloaded + if ( _maskee->isUnloaded() ) + { + const_cast<character*>(this)->setMaskee(0); + } + else _maskee->setReachable(); + } + markAsObjectReachable(); +} + +void +character::setMask(character* mask) +{ + if ( _mask != mask ) + { + set_invalidated(); + } + + // Backup these before messing up + character* prevMask = _mask; + character* prevMaskee = _maskee; + + // If we had a previous mask unregister with it + if ( _mask && _mask != mask ) + { + // the mask will call setMask(NULL) + // on any previously registered maskee + // so we make sure to set our _mask to + // NULL before getting called again + _mask->setMaskee(NULL); + } + + // if we had a maskee, notify it to stop using + // us as a mask + if ( prevMaskee ) + { + prevMaskee->setMask(0); + } + + // TODO: should we reset any original clip depth + // specified by PlaceObject tag ? + set_clip_depth(noClipDepthValue); // this will set _mask !! + _mask = mask; + _maskee = 0; + + if ( _mask ) + { + log_debug(" %s.setMask(%s): registering with new mask %s", + getTarget().c_str(), + mask ? mask->getTarget().c_str() : "null", + _mask->getTarget().c_str()); + /// Register as as masked by the mask + _mask->setMaskee(this); + } +} + +/*private*/ +void +character::setMaskee(character* maskee) +{ + if ( _maskee == maskee ) + { + return; + } + if ( _maskee ) + { + // We don't want the maskee to call setMaskee(null) + // on us again + log_debug(" %s.setMaskee(%s) : previously masked char %s being set as non-masked", + getTarget().c_str(), maskee ? maskee->getTarget().c_str() : "null", _maskee->getTarget().c_str()); + _maskee->_mask = NULL; + } + + _maskee = maskee; + + if ( maskee ) + { + set_clip_depth(dynClipDepthValue); + } + else + { + // TODO: should we reset any original clip depth + // specified by PlaceObject tag ? + set_clip_depth(noClipDepthValue); + } +} + } // namespace gnash Index: server/character.h =================================================================== RCS file: /sources/gnash/gnash/server/character.h,v retrieving revision 1.120 retrieving revision 1.121 diff -u -b -r1.120 -r1.121 --- server/character.h 16 Jan 2008 10:20:29 -0000 1.120 +++ server/character.h 20 Jan 2008 19:38:04 -0000 1.121 @@ -19,7 +19,7 @@ // // -/* $Id: character.h,v 1.120 2008/01/16 10:20:29 strk Exp $ */ +/* $Id: character.h,v 1.121 2008/01/20 19:38:04 strk Exp $ */ #ifndef GNASH_CHARACTER_H #define GNASH_CHARACTER_H @@ -100,9 +100,15 @@ /// The character masking this instance (if any) character* _mask; + /// The character masked by this instance (if any) + character* _maskee; + /// Original target, as at construction time std::string _origTarget; + /// Register a character masked by this instance + void setMaskee(character* maskee); + protected: /// Register currently computable target as @@ -132,19 +138,10 @@ /// Mark character-specific reachable resources // - /// These are: the character's parent, mask and the default + /// These are: the character's parent, mask, maskee and the default /// as_object reachable stuff. /// - void markCharacterReachable() const - { - if ( m_parent ) m_parent->setReachable(); - if ( _mask ) - { - // TODO: check if we should drop when isUnloaded() or isDestroyed() - _mask->setReachable(); - } - markAsObjectReachable(); - } + void markCharacterReachable() const; #endif // GNASH_USE_GC const Events& get_event_handlers() const @@ -370,6 +367,7 @@ _unloaded(false), _destroyed(false), _mask(0), + _maskee(0), _origTarget(), m_visible(true), m_parent(parent), @@ -479,7 +477,6 @@ void set_clip_depth(int d) { m_clip_depth = d; - _mask = 0; // in case we're masked by some other char } /// Returns true when the character (and it's childs) is used as a mask @@ -501,7 +498,7 @@ /// /// NOTE: there's no way to obtain the maskee from a dynamic mask /// - /// See also isMaskLeyer() and isMask() + /// See also isMaskLayer() and isMask() /// bool isDynamicMask() const { @@ -510,36 +507,27 @@ character* to_character() { return this; } - /// Return the character masked by this instance (if any) + /// Return the character masking this instance (if any) character* getMask() const { + if ( ! _mask ) return NULL; + if ( _mask->_maskee != this ) + { + // TODO: fix this ! + log_error("Our mask maskee is not us"); + return NULL; // for correctness; + } return _mask; } /// Register a character as a mask for this instance. /// /// @param mask The character to use as a mask, possibly NULL. + /// A reference to us will be registered with the mask, if + /// not null, so it'll know it's a mask for us, and would stop + /// being a mask for anything else. /// - void setMask(character* mask) - { - if ( _mask == mask ) return; - - set_invalidated(); - - if ( _mask ) - { - // TODO: should we reset any original clip depth - // specified by PlaceObject tag ? - _mask->set_clip_depth(noClipDepthValue); - } - _mask = mask; - if ( mask ) - { - /// Mark the mask as a dynamic one - mask->set_clip_depth(dynClipDepthValue); - } - } - + void setMask(character* mask); /// Returns true if this character is a mask (either layer or dynamic mask) bool isMask() const @@ -719,8 +707,9 @@ /// virtual bool pointInVisibleShape(float x, float y) const { - if ( get_visible() ) return pointInShape(x, y); - else return false; + if ( ! get_visible() ) return false; + if ( isMask() ) return false; + return pointInShape(x, y); } /// Return the relative or absolute root of this character Index: server/sprite_instance.cpp =================================================================== RCS file: /sources/gnash/gnash/server/sprite_instance.cpp,v retrieving revision 1.451 retrieving revision 1.452 diff -u -b -r1.451 -r1.452 --- server/sprite_instance.cpp 16 Jan 2008 15:14:24 -0000 1.451 +++ server/sprite_instance.cpp 20 Jan 2008 19:38:04 -0000 1.452 @@ -1154,7 +1154,7 @@ //log_debug("MovieClip.setMask() TESTING"); - return as_value(); + return as_value(true); } static as_value @@ -3313,7 +3313,7 @@ bool operator() (character* ch) { - if ( ch->get_visible() && ch->pointInShape(_x, _y) ) + if ( ch->pointInVisibleShape(_x, _y) ) { _found = true; return false; @@ -3337,6 +3337,18 @@ bool sprite_instance::pointInVisibleShape(float x, float y) const { + if ( ! get_visible() ) return false; + if ( isMask() ) + { + log_debug("%s is a mask, no point will hit it", getTarget().c_str()); + return false; + } + character* mask = getMask(); + if ( mask && mask->get_visible() && ! mask->pointInShape(x, y) ) + { + log_debug("%s is masked by %s, which doesn't hit point %g,%g", getTarget().c_str(), mask->getTarget().c_str(), x, y); + return false; + } VisibleShapeContainerFinder finder(x, y); const_cast<DisplayList&>(m_display_list).visitBackward(finder); if ( finder.hitFound() ) return true; Index: testsuite/misc-ming.all/masks_test.c =================================================================== RCS file: /sources/gnash/gnash/testsuite/misc-ming.all/masks_test.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -b -r1.6 -r1.7 --- testsuite/misc-ming.all/masks_test.c 19 Jan 2008 17:00:15 -0000 1.6 +++ testsuite/misc-ming.all/masks_test.c 20 Jan 2008 19:38:04 -0000 1.7 @@ -211,19 +211,19 @@ "dm54 = dynamicmc5.setMask(dynamicmc4);" // light blue masked by dark green ); - xcheck_equals(mo, "typeof(sm23)", "'boolean'"); - xcheck_equals(mo, "sm23", "true"); - xcheck_equals(mo, "typeof(sm54)", "'boolean'"); - xcheck_equals(mo, "sm54", "true"); - xcheck_equals(mo, "typeof(dm23)", "'boolean'"); - xcheck_equals(mo, "dm23", "true"); - xcheck_equals(mo, "typeof(dm54)", "'boolean'"); - xcheck_equals(mo, "dm54", "true"); + check_equals(mo, "typeof(sm23)", "'boolean'"); + check_equals(mo, "sm23", "true"); + check_equals(mo, "typeof(sm54)", "'boolean'"); + check_equals(mo, "sm54", "true"); + check_equals(mo, "typeof(dm23)", "'boolean'"); + check_equals(mo, "dm23", "true"); + check_equals(mo, "typeof(dm54)", "'boolean'"); + check_equals(mo, "dm54", "true"); // Red rect is now masked by yellow // Red rect (staticmc2) is at 0,200-60,260 // Yellow rect (staticmc3) is at 30,200-90,260 - xcheck(mo, "!staticmc2.hitTest(10, 210, true)"); + check(mo, "!staticmc2.hitTest(10, 210, true)"); check(mo, "staticmc2.hitTest(10, 210, false)"); // bounding box hitTest not affected by masks check(mo, "staticmc2.hitTest(50, 250, true)"); @@ -232,14 +232,14 @@ // while hitTest() using 'bounding box' semantic will check(mo, "staticmc3.hitTest(40, 210, false)"); check(mo, "staticmc3.hitTest(80, 250, false)"); - xcheck(mo, "!staticmc3.hitTest(40, 210, true)"); - xcheck(mo, "!staticmc3.hitTest(80, 250, true)"); + check(mo, "!staticmc3.hitTest(40, 210, true)"); + check(mo, "!staticmc3.hitTest(80, 250, true)"); // Green rect is now a mask // hitTest() using 'shape' semantic won't see it, // while hitTest() using 'bounding box' semantic will - xcheck(mo, "!staticmc4.hitTest(210, 210, true)"); - xcheck(mo, "!staticmc4.hitTest(250, 250, true)"); + check(mo, "!staticmc4.hitTest(210, 210, true)"); + check(mo, "!staticmc4.hitTest(250, 250, true)"); check(mo, "staticmc4.hitTest(210, 210, false)"); check(mo, "staticmc4.hitTest(250, 250, false)"); @@ -247,27 +247,27 @@ // Green rect (staticmc4) is at 200,200-260,260 // Cyan rect (staticmc5) is at 230,200-290,260 check(mo, "staticmc5.hitTest(240, 210, true)"); - xcheck(mo, "!staticmc5.hitTest(280, 250, true)"); + check(mo, "!staticmc5.hitTest(280, 250, true)"); check(mo, "staticmc5.hitTest(280, 250, false)"); // Blue rect now is masked by Violet rect // Violet rect (dynamicmc3) is at 30,300-90,360 // Blue rect (dynamicmc2) is at 0,300-60,360 - xcheck(mo, "!dynamicmc2.hitTest(10, 310, true)"); + check(mo, "!dynamicmc2.hitTest(10, 310, true)"); check(mo, "dynamicmc2.hitTest(10, 310, false)"); check(mo, "dynamicmc2.hitTest(50, 350, true)"); // Violet rect is now a mask // hitTest() using 'shape' semantic won't see it, // while hitTest() using 'bounding box' semantic will - xcheck(mo, "!dynamicmc3.hitTest(40, 310, true)"); - xcheck(mo, "!dynamicmc3.hitTest(80, 350, true)"); + check(mo, "!dynamicmc3.hitTest(40, 310, true)"); + check(mo, "!dynamicmc3.hitTest(80, 350, true)"); check(mo, "dynamicmc3.hitTest(40, 310, false)"); check(mo, "dynamicmc3.hitTest(80, 350, false)"); // Dark green rect is now a mask - xcheck(mo, "!dynamicmc4.hitTest(210, 310, true)"); - xcheck(mo, "!dynamicmc4.hitTest(250, 350, true)"); + check(mo, "!dynamicmc4.hitTest(210, 310, true)"); + check(mo, "!dynamicmc4.hitTest(250, 350, true)"); check(mo, "dynamicmc4.hitTest(210, 310, false)"); check(mo, "dynamicmc4.hitTest(250, 350, false)"); @@ -275,7 +275,7 @@ // Light blue rect (dynamicmc5) is at 230,300-290,360 // Dark green rect (dynamicmc4) is at 200,300-260,360 check(mo, "dynamicmc5.hitTest(240, 310, true)"); - xcheck(mo, "!dynamicmc5.hitTest(280, 350, true)"); + check(mo, "!dynamicmc5.hitTest(280, 350, true)"); check(mo, "dynamicmc5.hitTest(280, 350, false)"); SWFMovie_nextFrame(mo); // FRAME 4 starts here @@ -303,7 +303,7 @@ // Red rect is now masked by yellow // Red rect (staticmc2) is at 0,200-60,260 // Yellow rect (staticmc3) is at 30,200-90,260 - xcheck(mo, "!staticmc2.hitTest(10, 210, true)"); + check(mo, "!staticmc2.hitTest(10, 210, true)"); check(mo, "staticmc2.hitTest(10, 210, false)"); // bounding box hitTest not affected by masks check(mo, "staticmc2.hitTest(50, 250, true)"); @@ -312,42 +312,42 @@ // while hitTest() using 'bounding box' semantic will check(mo, "staticmc3.hitTest(40, 210, false)"); check(mo, "staticmc3.hitTest(80, 250, false)"); - xcheck(mo, "!staticmc3.hitTest(40, 210, true)"); - xcheck(mo, "!staticmc3.hitTest(80, 250, true)"); + check(mo, "!staticmc3.hitTest(40, 210, true)"); + check(mo, "!staticmc3.hitTest(80, 250, true)"); // Green rect is now a mask // hitTest() using 'shape' semantic won't see it, // while hitTest() using 'bounding box' semantic will check(mo, "staticmc4.hitTest(210, 210, false)"); check(mo, "staticmc4.hitTest(250, 250, false)"); - xcheck(mo, "!staticmc4.hitTest(210, 210, true)"); - xcheck(mo, "!staticmc4.hitTest(250, 250, true)"); + check(mo, "!staticmc4.hitTest(210, 210, true)"); + check(mo, "!staticmc4.hitTest(250, 250, true)"); // Cyan rect is now masked by green // Green rect (staticmc4) is at 200,200-260,260 // Cyan rect (staticmc5) is at 230,200-290,260 check(mo, "staticmc5.hitTest(240, 210, true)"); - xcheck(mo, "!staticmc5.hitTest(280, 250, true)"); + check(mo, "!staticmc5.hitTest(280, 250, true)"); check(mo, "staticmc5.hitTest(280, 250, false)"); // Blue rect now is masked by Violet rect // Violet rect (dynamicmc3) is at 30,300-90,360 // Blue rect (dynamicmc2) is at 0,300-60,360 - xcheck(mo, "!dynamicmc2.hitTest(10, 310, true)"); + check(mo, "!dynamicmc2.hitTest(10, 310, true)"); check(mo, "dynamicmc2.hitTest(10, 310, false)"); check(mo, "dynamicmc2.hitTest(50, 350, true)"); // Violet rect is now a mask // hitTest() using 'shape' semantic won't see it, // while hitTest() using 'bounding box' semantic will - xcheck(mo, "!dynamicmc3.hitTest(40, 310, true)"); - xcheck(mo, "!dynamicmc3.hitTest(80, 350, true)"); + check(mo, "!dynamicmc3.hitTest(40, 310, true)"); + check(mo, "!dynamicmc3.hitTest(80, 350, true)"); check(mo, "dynamicmc3.hitTest(40, 310, false)"); check(mo, "dynamicmc3.hitTest(80, 350, false)"); // Dark green rect is now a mask - xcheck(mo, "!dynamicmc4.hitTest(210, 310, true)"); - xcheck(mo, "!dynamicmc4.hitTest(250, 350, true)"); + check(mo, "!dynamicmc4.hitTest(210, 310, true)"); + check(mo, "!dynamicmc4.hitTest(250, 350, true)"); check(mo, "dynamicmc4.hitTest(210, 310, false)"); check(mo, "dynamicmc4.hitTest(250, 350, false)"); @@ -355,7 +355,7 @@ // Light blue rect (dynamicmc5) is at 230,300-290,360 // Dark green rect (dynamicmc4) is at 200,300-260,360 check(mo, "dynamicmc5.hitTest(240, 310, true)"); - xcheck(mo, "!dynamicmc5.hitTest(280, 350, true)"); + check(mo, "!dynamicmc5.hitTest(280, 350, true)"); check(mo, "dynamicmc5.hitTest(280, 350, false)"); SWFMovie_nextFrame(mo); // FRAME 5 starts here @@ -366,65 +366,71 @@ "sm32 = staticmc3.setMask(staticmc2);" // yellow masked by red "sm45 = staticmc4.setMask(staticmc5);" // green masked by cyan "dm32 = dynamicmc3.setMask(dynamicmc2);" // violet masked by blue - "dm45 = dynamicmc4.setMask(dynamicmc5);" // dark green masked light blue + "dm45 = dynamicmc4.setMask(dynamicmc5);" // dark green masked by light blue ); - xcheck_equals(mo, "typeof(sm32)", "'boolean'"); - xcheck_equals(mo, "sm32", "true"); - xcheck_equals(mo, "typeof(sm45)", "'boolean'"); - xcheck_equals(mo, "sm45", "true"); - xcheck_equals(mo, "typeof(dm32)", "'boolean'"); - xcheck_equals(mo, "dm32", "true"); - xcheck_equals(mo, "typeof(dm45)", "'boolean'"); - xcheck_equals(mo, "dm45", "true"); + check_equals(mo, "typeof(sm32)", "'boolean'"); + check_equals(mo, "sm32", "true"); + check_equals(mo, "typeof(sm45)", "'boolean'"); + check_equals(mo, "sm45", "true"); + check_equals(mo, "typeof(dm32)", "'boolean'"); + check_equals(mo, "dm32", "true"); + check_equals(mo, "typeof(dm45)", "'boolean'"); + check_equals(mo, "dm45", "true"); // Red rect is now a mask - xcheck(mo, "!staticmc2.hitTest(10, 210, true)"); - xcheck(mo, "!staticmc2.hitTest(50, 250, true)"); + check(mo, "!staticmc2.hitTest(10, 210, true)"); + check(mo, "!staticmc2.hitTest(50, 250, true)"); check(mo, "staticmc2.hitTest(10, 210, false)"); check(mo, "staticmc2.hitTest(50, 250, false)"); // Yellow rect is now masked by Red rect + // Yellow rect (staticmc3) is at 30,200-90,260 + // Red rect (staticmc2) is at 0,200-60,260 + // Intersection is 30,200-60,260 // TODO: why no hitTest ?? - xcheck(mo, "!staticmc3.hitTest(40, 210, true)"); - xcheck(mo, "!staticmc3.hitTest(80, 250, true)"); + xcheck(mo, "!staticmc3.hitTest(40, 210, true)"); // I'd think this should be true, why not ? + check(mo, "!staticmc3.hitTest(80, 250, true)"); // out of masked area check(mo, "staticmc3.hitTest(80, 250, false)"); check(mo, "staticmc3.hitTest(40, 210, false)"); // Green rect is now masked by Cyan + // Green rect (staticmc4) is at 200,200-260,260 + // Cyan rect (staticmc5) is at 230,200-290,260 + // Intersection is 230,200-260,260 // TODO: why no hitTest ?? - xcheck(mo, "!staticmc4.hitTest(210, 210, true)"); - xcheck(mo, "!staticmc4.hitTest(250, 250, true)"); + check(mo, "!staticmc4.hitTest(210, 210, true)"); // out of masked area + xcheck(mo, "!staticmc4.hitTest(250, 250, true)"); // I'd think this should be true, why not? check(mo, "staticmc4.hitTest(210, 210, false)"); check(mo, "staticmc4.hitTest(250, 250, false)"); // Cyan rect is now a mask - xcheck(mo, "!staticmc5.hitTest(240, 210, true)"); - xcheck(mo, "!staticmc5.hitTest(280, 250, true)"); + check(mo, "!staticmc5.hitTest(240, 210, true)"); + check(mo, "!staticmc5.hitTest(280, 250, true)"); check(mo, "staticmc5.hitTest(240, 210, false)"); check(mo, "staticmc5.hitTest(280, 250, false)"); // Blue rect is now a mask - xcheck(mo, "!dynamicmc2.hitTest(10, 310, true)"); - xcheck(mo, "!dynamicmc2.hitTest(50, 350, true)"); + check(mo, "!dynamicmc2.hitTest(10, 310, true)"); + check(mo, "!dynamicmc2.hitTest(50, 350, true)"); check(mo, "dynamicmc2.hitTest(10, 310, false)"); check(mo, "dynamicmc2.hitTest(50, 350, false)"); // Violet rect is now masked by Blue rect check(mo, "dynamicmc3.hitTest(40, 310, true)"); - xcheck(mo, "!dynamicmc3.hitTest(80, 350, true)"); + check(mo, "!dynamicmc3.hitTest(80, 350, true)"); check(mo, "dynamicmc3.hitTest(80, 350, false)"); // Dark green rect is masked by Light blue - xcheck(mo, "!dynamicmc4.hitTest(210, 310, true)"); + check(mo, "!dynamicmc4.hitTest(210, 310, true)"); check(mo, "dynamicmc4.hitTest(210, 310, false)"); check(mo, "dynamicmc4.hitTest(250, 350, true)"); // Light blue is now a mask check(mo, "dynamicmc5.hitTest(240, 310, false)"); check(mo, "dynamicmc5.hitTest(280, 350, false)"); - xcheck(mo, "!dynamicmc5.hitTest(240, 310, true)"); - xcheck(mo, "!dynamicmc5.hitTest(280, 350, true)"); + check(mo, "!dynamicmc5.hitTest(240, 310, true)"); + check(mo, "!dynamicmc5.hitTest(280, 350, true)"); add_actions(mo, "_root.totals(134); stop();"); _______________________________________________ Gnash-commit mailing list Gnash-commit@gnu.org http://lists.gnu.org/mailman/listinfo/gnash-commit