1
0
mirror of synced 2024-11-28 07:50:51 +01:00

Support nested animations as well as update object requests.

This commit is contained in:
Jennifer Taylor 2021-04-15 23:19:56 +00:00
parent 3f5760343a
commit d835c46320
2 changed files with 38 additions and 19 deletions

View File

@ -103,7 +103,19 @@ class AFPRenderer(VerboseOutput):
return clips return clips
elif isinstance(tag, AP2PlaceObjectTag): elif isinstance(tag, AP2PlaceObjectTag):
if tag.update: if tag.update:
raise Exception("Don't support update tags yet!") self.vprint(f"{prefix} Updating Object ID {tag.object_id} on Depth {tag.depth}")
updated = False
for obj in self.__placed_objects:
if obj.tag.object_id == tag.object_id and obj.tag.depth == tag.depth:
# As far as I can tell, pretty much only color and matrix stuff can be updated.
obj.tag.mult_color = tag.mult_color or obj.tag.mult_color
obj.tag.add_color = tag.add_color or obj.tag.add_color
obj.tag.transform = tag.transform or obj.tag.transform
updated = True
if not updated:
raise Exception("Couldn't find tag to update!")
else: else:
self.vprint(f"{prefix} Placing Object ID {tag.object_id} onto Depth {tag.depth}") self.vprint(f"{prefix} Placing Object ID {tag.object_id} onto Depth {tag.depth}")
@ -133,7 +145,7 @@ class AFPRenderer(VerboseOutput):
else: else:
raise Exception(f"Failed to process tag: {tag}") raise Exception(f"Failed to process tag: {tag}")
def __render_object(self, img: Any, tag: AP2PlaceObjectTag) -> Any: def __render_object(self, img: Any, tag: AP2PlaceObjectTag, parent_transform: Matrix, parent_origin: Point) -> Any:
if tag.source_tag_id is None: if tag.source_tag_id is None:
self.vprint(" Nothing to render!") self.vprint(" Nothing to render!")
return img return img
@ -146,12 +158,21 @@ class AFPRenderer(VerboseOutput):
transform = tag.transform or Matrix.identity() transform = tag.transform or Matrix.identity()
origin = tag.rotation_offset or Point.identity() origin = tag.rotation_offset or Point.identity()
# TODO: Need to do actual affine transformations here.
if transform.b != 0.0 or transform.c != 0.0 or transform.a != 1.0 or transform.d != 1.0:
raise Exception("Don't support affine transformations yet!")
if parent_transform.b != 0.0 or parent_transform.c != 0.0 or parent_transform.a != 1.0 or parent_transform.d != 1.0:
raise Exception("Don't support affine transformations yet!")
offset = parent_transform.multiply_point(transform.multiply_point(Point.identity().subtract(origin).subtract(parent_origin)))
# Look up source shape. # Look up source shape.
if tag.source_tag_id not in self.__registered_shapes: if tag.source_tag_id not in self.__registered_shapes:
# TODO: Lots of animations are referencing other sprite tags with transform # This is probably a sprite placement reference.
# offsets and such. We need to support this. However, I'm not sure how the for obj in self.__placed_objects:
# original gets hidden... if obj.parent_sprite == tag.source_tag_id:
raise Exception(f"Failed to find shape tag {tag.source_tag_id} for object render!") self.vprint(f" Rendering placed object ID {obj.tag.object_id} from sprite {obj.parent_sprite} onto Depth {obj.tag.depth}")
img = self.__render_object(img, obj.tag, transform, origin)
return img
shape = self.__registered_shapes[tag.source_tag_id] shape = self.__registered_shapes[tag.source_tag_id]
for params in shape.draw_params: for params in shape.draw_params:
@ -169,19 +190,17 @@ class AFPRenderer(VerboseOutput):
raise Exception(f"Cannot find texture reference {params.region}!") raise Exception(f"Cannot find texture reference {params.region}!")
texture = self.textures[params.region] texture = self.textures[params.region]
# TODO: Need to do actual affine transformations here.
offset = transform.multiply_point(Point.identity().subtract(origin))
# Now, render out the texture. # Now, render out the texture.
cutin = Point(offset.x, offset.y)
cutoff = Point.identity() cutoff = Point.identity()
if offset.x < 0: if cutin.x < 0:
cutoff.x = -offset.x cutoff.x = -cutin.x
offset.x = 0 cutin.x = 0
if offset.y < 0: if cutin.y < 0:
cutoff.y = -offset.y cutoff.y = -cutin.y
offset.y = 0 cutin.y = 0
img.alpha_composite(texture, offset.as_tuple(), cutoff.as_tuple()) img.alpha_composite(texture, cutin.as_tuple(), cutoff.as_tuple())
return img return img
def __render(self, swf: SWF, export_tag: Optional[str]) -> Tuple[int, List[Any]]: def __render(self, swf: SWF, export_tag: Optional[str]) -> Tuple[int, List[Any]]:
@ -255,7 +274,7 @@ class AFPRenderer(VerboseOutput):
continue continue
self.vprint(f" Rendering placed object ID {obj.tag.object_id} from sprite {obj.parent_sprite} onto Depth {obj.tag.depth}") self.vprint(f" Rendering placed object ID {obj.tag.object_id} from sprite {obj.parent_sprite} onto Depth {obj.tag.depth}")
curimage = self.__render_object(curimage, obj.tag) curimage = self.__render_object(curimage, obj.tag, Matrix.identity(), Point.identity())
# Advance all the clips and frame now that we processed and rendered them. # Advance all the clips and frame now that we processed and rendered them.
for clip in clips: for clip in clips:

View File

@ -368,7 +368,7 @@ class SWF(TrackedCoverage, VerboseOutput):
self.vprint(f"{prefix} BOOLEAN: False") self.vprint(f"{prefix} BOOLEAN: False")
elif obj_to_create == 0x7: elif obj_to_create == 0x7:
# Integer object. # Integer object.
ival = struct.unpack(">I", datachunk[offset_ptr:(offset_ptr + 4)])[0] ival = struct.unpack(">i", datachunk[offset_ptr:(offset_ptr + 4)])[0]
offset_ptr += 4 offset_ptr += 4
self.vprint(f"{prefix} INTEGER: {ival}") self.vprint(f"{prefix} INTEGER: {ival}")
@ -555,7 +555,7 @@ class SWF(TrackedCoverage, VerboseOutput):
# versions of 0x34. # versions of 0x34.
elif obj_to_create == 0x37: elif obj_to_create == 0x37:
# Integer object but one byte. # Integer object but one byte.
ival = struct.unpack(">B", datachunk[offset_ptr:(offset_ptr + 1)])[0] ival = struct.unpack(">b", datachunk[offset_ptr:(offset_ptr + 1)])[0]
offset_ptr += 1 offset_ptr += 1
self.vprint(f"{prefix} INTEGER: {ival}") self.vprint(f"{prefix} INTEGER: {ival}")