1
0
mirror of synced 2024-11-27 23:50:47 +01:00

Support simple frame control bytecode.

This commit is contained in:
Jennifer Taylor 2021-05-23 20:33:05 +00:00
parent 14c8ac9347
commit 9df33fcec3

View File

@ -4,7 +4,7 @@ from PIL import Image # type: ignore
from .blend import affine_composite from .blend import affine_composite
from .swf import SWF, Frame, Tag, AP2ShapeTag, AP2DefineSpriteTag, AP2PlaceObjectTag, AP2RemoveObjectTag, AP2DoActionTag, AP2DefineFontTag, AP2DefineEditTextTag, AP2PlaceCameraTag from .swf import SWF, Frame, Tag, AP2ShapeTag, AP2DefineSpriteTag, AP2PlaceObjectTag, AP2RemoveObjectTag, AP2DoActionTag, AP2DefineFontTag, AP2DefineEditTextTag, AP2PlaceCameraTag
from .decompile import ByteCode from .decompile import ByteCode
from .types import Color, Matrix, Point, Rectangle, AP2Trigger, AP2Action, PushAction, StoreRegisterAction, StringConstant, Register, THIS, UNDEFINED from .types import Color, Matrix, Point, Rectangle, AP2Trigger, AP2Action, PushAction, StoreRegisterAction, StringConstant, Register, THIS, UNDEFINED, GLOBAL
from .geo import Shape, DrawParams from .geo import Shape, DrawParams
from .util import VerboseOutput from .util import VerboseOutput
@ -138,6 +138,17 @@ class PlacedClip(PlacedObject):
return f"PlacedClip(object_id={self.object_id}, depth={self.depth}, source={self.source}, frame={self.frame}, total_frames={len(self.source.frames)}, finished={self.finished})" return f"PlacedClip(object_id={self.object_id}, depth={self.depth}, source={self.source}, frame={self.frame}, total_frames={len(self.source.frames)}, finished={self.finished})"
# The following are attributes and functions necessary to support some simple bytecode. # The following are attributes and functions necessary to support some simple bytecode.
def gotoAndStop(self, frame: Any) -> None:
if not isinstance(frame, int):
# TODO: Technically this should also allow string labels to frames as identified in the
# SWF specification, but we don't support that here.
print(f"WARNING: Non-integer frame {frame} to gotoAndStop function!")
return
if frame <= 0 or frame > len(self.source.frames):
return
self.requested_frame = frame
self.playing = False
def gotoAndPlay(self, frame: Any) -> None: def gotoAndPlay(self, frame: Any) -> None:
if not isinstance(frame, int): if not isinstance(frame, int):
# TODO: Technically this should also allow string labels to frames as identified in the # TODO: Technically this should also allow string labels to frames as identified in the
@ -149,6 +160,12 @@ class PlacedClip(PlacedObject):
self.requested_frame = frame self.requested_frame = frame
self.playing = True self.playing = True
def stop(self) -> None:
self.playing = False
def play(self) -> None:
self.playing = True
@property @property
def frameOffset(self) -> int: def frameOffset(self) -> int:
return self.requested_frame or self.frame return self.requested_frame or self.frame
@ -398,6 +415,10 @@ class AFPRenderer(VerboseOutput):
stack.append(obj.alias) stack.append(obj.alias)
else: else:
stack.append(StringConstant.property_to_name(obj.const)) stack.append(StringConstant.property_to_name(obj.const))
elif obj is THIS:
stack.append(clip)
elif obj is GLOBAL:
stack.append(self.__movie)
else: else:
stack.append(obj) stack.append(obj)
elif isinstance(action, StoreRegisterAction): elif isinstance(action, StoreRegisterAction):
@ -954,7 +975,7 @@ class AFPRenderer(VerboseOutput):
# Now play the frames of the root clip. # Now play the frames of the root clip.
try: try:
while not root_clip.finished: while root_clip.playing and not root_clip.finished:
# Create a new image to render into. # Create a new image to render into.
time = spf * frameno time = spf * frameno
color = swf.color or Color(0.0, 0.0, 0.0, 0.0) color = swf.color or Color(0.0, 0.0, 0.0, 0.0)