ruffle-rs / ruffle

A Flash Player emulator written in Rust
https://ruffle.rs
Other
15.67k stars 815 forks source link

Accurate Slapshot: Level select screen does not load #8766

Closed n0samu closed 1 year ago

n0samu commented 1 year ago

Describe the bug

Link to SWF: http://i.notdoppler.com/files/accurateslapshot.swf Note: Requires a stub of SharedObject.size.

In Accurate Slapshot, there are 2 related issues:

Both buttons are supposed to go to the level select screen. And in both cases the following error is shown in the terminal: [ERROR ruffle_core::avm2::events] Error dispatching event EventObject(EventObject { type: "enterFrame", class: flash.events::Event, ptr: 0x29adda9bf20 }) to handler FunctionObject(FunctionObject(GcCell(Gc { ptr: 0x29ac48bac88 }))) : RustError("Cannot access property ::length of null or undefined")

Expected behavior

Both buttons should take you to the level select screen.

Affected platform

Desktop app

Operating system

Windows 10

Browser

No response

Additional information

Both problems are caused by code in the game's TweenMax package. Here is an SWF with many trace statements added to demonstrate: accurateslapshot_trace.zip

After clicking the Continue button, the showLevelManager() function runs:

         if(contains(this._menu))
         {
            trace("About to run killChildTweensOf");
            TweenMax.killChildTweensOf(this._menu,true);
            trace("Just ran killChildTweensOf");
            removeChild(this._menu);
         }

Notice that in Ruffle, the first trace is shown right before the error, and the second trace never shows.

The killChildTweensOf function calls getAllTweens():

         trace("About to run getAllTweens");
         var _loc3_:Array = getAllTweens();
         trace("Just ran getAllTweens");

Notice that in Ruffle, the first trace is shown right before the error, and the second trace never shows.

And finally in getAllTweens, we have the offending use of length:

         var _loc4_:Array = null;
         var _loc5_:int = 0;
         var _loc1_:Dictionary = masterList;
         var _loc2_:int = 0;
         var _loc3_:Array = [];
         for each(_loc4_ in _loc1_)
         {
            _loc5_ = int(_loc4_.length);
            while(--_loc5_ > -1)
            {
               if(!TweenLite(_loc4_[_loc5_]).gc)
               {
                  var _loc8_:*;
                  _loc3_[_loc8_ = _loc2_++] = _loc4_[_loc5_];
               }
            }
         }

This code is very difficult to read, and I can't figure out why _loc4_.length causes the error, but it does.

n0samu commented 1 year ago

The same error is displayed when trying to start the game in Koutack and when trying to start a level in Track the Ball. Both games use tweening when transitioning between screens. Is it the same problem?

Benman2785 commented 1 year ago

same problem with Road_of_the_Dead.swf

screen goes white link to swf

n0samu commented 1 year ago

Update: I found that the issue with Koutack is indeed the same problem. On the other hand, the issue with Track the Ball occurs because the levels are stored as XML data, and the required XML functions are not yet implemented.

n0samu commented 1 year ago

same problem with Road_of_the_Dead.swf

screen goes white link to swf

This does indeed seem to be the same problem - it's also fixed by #9007!