ruffle-rs / ruffle

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

Cut 3D Stuck Loading at White Screen #11527

Closed Rno-1 closed 1 year ago

Rno-1 commented 1 year ago

Describe the bug

http://onemorelevel.com/static/games3/cut-3d.swf After loading up this game and pressing "Click to play," the game gets stuck on a white screen and wouldn't load the main menu. No sound plays, either.

WARN ruffle_core::tag_utils: Unknown tag code: 255 WARN ruffle_core::display_object::movie_clip: DefineFont4 tag (TLF text) is not implemented WARN ruffle_core::display_object::movie_clip: DefineFont4 tag (TLF text) is not implemented WARN ruffle_core::display_object::movie_clip: DefineFont4 tag (TLF text) is not implemented WARN ruffle_core::display_object::movie_clip: DefineFont4 tag (TLF text) is not implemented WARN ruffle_core::library: Can't register export LocalizationPack_mspgothicCls_CFF: Character ID 47 doesn't exist WARN ruffle_core::library: Can't register export LocalizationPack_simplifiedarabicCls_CFF: Character ID 49 doesn't exist WARN ruffle_core::library: Can't register export LocalizationPack_simheiCls_CFF: Character ID 51 doesn't exist WARN ruffle_core::library: Can't register export LocalizationPack_arialboldCls_CFF: Character ID 52 doesn't exist WARN ruffle_core::display_object::movie_clip: Symbol class LocalizationPack_simplifiedarabicCls_CFF cannot be assigned to invalid character id 49 WARN ruffle_core::display_object::movie_clip: Symbol class LocalizationPack_simheiCls_CFF cannot be assigned to invalid character id 51 WARN ruffle_core::display_object::movie_clip: Symbol class LocalizationPack_arialboldCls_CFF cannot be assigned to invalid character id 52 WARN ruffle_core::display_object::movie_clip: Symbol class LocalizationPack_mspgothicCls_CFF cannot be assigned to invalid character id 47 WARN ruffle_core::tag_utils: Unknown tag code: 255 WARN ruffle_core::stub: Encountered stub: AVM2 flash.system.Security.allowDomain() WARN ruffle_core::avm2::globals::flash::display::display_object_container: Display object container has no child with name MenuButtons WARN ruffle_core::stub: Encountered stub: AVM2 flash.display.Graphics.drawTriangles() WARN ruffle_core::avm2::globals::flash::display::display_object_container: Display object container has no child with name btnBack WARN ruffle_core::avm2::globals::flash::display::display_object_container: Display object container has no child with name image WARN ruffle_core::avm2::amf: Serialization is not implemented for class other than Object: VectorObject(VectorObject { ptr: 0x1e4c9027188 }) WARN ruffle_core::stub: Encountered stub: AVM2 flash.net.SharedObject.close() WARN ruffle_core::avm2::amf: Serialization is not implemented for class other than Object: VectorObject(VectorObject { ptr: 0x1e4c7b60a18 }) ERROR ruffle_core::avm2::events: Error dispatching event EventObject(EventObject { type: "enterFrame", class: flash.events::Event, ptr: 0x1e4c8f78348 }) to handler FunctionObject(FunctionObject { ptr: 0x1e4c6c8ba38 }) : ReferenceError: Error #1065: Variable init is not defined.

Expected behavior

The main menu is supposed to load.

Affected platform

Desktop app

Operating system

Windows 10

Browser

No response

Additional information

Using Nightly 2023-06-13

Lord-McSweeney commented 1 year ago

Stack trace of the last error:

Error dispatching `enterFrame` event : ReferenceError: Error #1065: Variable init is not defined.
    at Objects3d/OnGameInit()
    at Objects3d/onShowComplete()
    at Function/apply()
    at com.greensock::TweenLite/render()
    at com.greensock.core::SimpleTimeline/render()
    at com.greensock.core::Animation$/_updateRoot()
n0samu commented 1 year ago

@Lord-McSweeney and I investigated this further. The error is coming from this line: removeEventListener(Event.ADDED_TO_STAGE,init);

The init variable actually isn't defined anywhere, and this line only works in FP by a very strange coincidence. Here is the instruction that pushes the value of the init variable onto the stack:

getlex Multiname("init",[PrivateNamespace("*","48"),PrivateNamespace("*","49"),PackageNamespace(""),PackageInternalNs(""),Namespace("http://adobe.com/AS3/2006/builtin"),PackageNamespace("menu.pages"),ProtectedNamespace("Objects3d"),StaticProtectedNs("Objects3d"),StaticProtectedNs("flash.display:Sprite"),StaticProtectedNs("flash.display:DisplayObjectContainer"),StaticProtectedNs("flash.display:InteractiveObject"),StaticProtectedNs("flash.display:DisplayObject"),StaticProtectedNs("flash.events:EventDispatcher"),StaticProtectedNs("Object")])

The compiler happened to include PackageInternalNs in the multiname, which causes FP to search the internal fields of Objects3d and its ancestors. Objects3d extends Sprite, and the inheritance chain of Sprite looks like this: Sprite => DisplayObjectContainer => InteractiveObject => DisplayObject => EventDispatcher => Object

Now in Playerglobal, Object happens to have an internal function called init(). This is the init that FP is finding. @Lord-McSweeney verified this by checking Object.init === init, and it is true!

Once we add an init function to Object to match playerglobal, the game will be playable (but the graphics are messed up).

Lord-McSweeney commented 1 year ago

The graphics issue is probably because of flash.display.Graphics.drawTriangles being unimplemented.

Lord-McSweeney commented 5 months ago

If anyone ever stumbles on this in the future, there's some more information at https://bugzilla.mozilla.org/show_bug.cgi?id=605660.