Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(tags): support for new texture and movie clip tags #20

Merged
merged 1 commit into from
Aug 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions system/lib/features/sc/decode.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def decode_and_render_objects():
files = os.listdir(input_folder)

for file in files:
if file.endswith("_tex.sc"):
if file.endswith("_tex.sc") or not file.endswith(".sc"):
continue

try:
Expand Down Expand Up @@ -99,9 +99,9 @@ def get_file_basename(swf: SupercellSWF):

def _create_objects_output_folder(output_folder: Path, base_name: str) -> Path:
objects_output_folder = output_folder / base_name
if os.path.isdir(objects_output_folder):
if objects_output_folder.exists():
shutil.rmtree(objects_output_folder)
os.mkdir(objects_output_folder)
objects_output_folder.mkdir(parents=True)
return objects_output_folder


Expand Down
5 changes: 4 additions & 1 deletion system/lib/objects/movie_clip.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ def load(self, swf: "SupercellSWF", tag: int):
if tag in (3, 14):
pass
else:
if tag == 49:
swf.reader.read_char() # unknown

transforms_count = swf.reader.read_uint()

for i in range(transforms_count):
Expand All @@ -79,7 +82,7 @@ def load(self, swf: "SupercellSWF", tag: int):
bind_id = swf.reader.read_ushort() # bind_id
self.binds.append(bind_id)

if tag in (12, 35):
if tag in (12, 35, 49):
for i in range(binds_count):
blend = swf.reader.read_char() # blend
self.blends.append(blend)
Expand Down
22 changes: 20 additions & 2 deletions system/lib/objects/texture.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
from __future__ import annotations

import os
from typing import TYPE_CHECKING

import zstandard
from PIL import Image

from system.lib.images import (
Expand All @@ -10,19 +14,25 @@
)
from system.lib.pvr_tex_tool import get_image_from_ktx_data

if TYPE_CHECKING:
from system.lib.swf import SupercellSWF


class SWFTexture:
def __init__(self):
self.width = 0
self.height = 0

self.pixel_type = -1
self.khronos_texture_filename: str | None = None

self.image: Image.Image
self.image: Image.Image | None = None

def load(self, swf, tag: int, has_texture: bool):
def load(self, swf: SupercellSWF, tag: int, has_texture: bool):
if tag == 45:
khronos_texture_length = swf.reader.read_int()
elif tag == 47:
self.khronos_texture_filename = swf.reader.read_string()

self.pixel_type = swf.reader.read_char()
self.width, self.height = (swf.reader.read_ushort(), swf.reader.read_ushort())
Expand All @@ -35,6 +45,14 @@ def load(self, swf, tag: int, has_texture: bool):
khronos_texture_data = swf.reader.read(khronos_texture_length)
self.image = get_image_from_ktx_data(khronos_texture_data)
return
elif tag == 47:
with open(
swf.filepath.parent / self.khronos_texture_filename, "rb"
) as file:
decompressor = zstandard.ZstdDecompressor()
decompressed = decompressor.decompress(file.read())
self.image = get_image_from_ktx_data(decompressed)
return

img = Image.new(
get_format_by_pixel_type(self.pixel_type), (self.width, self.height)
Expand Down
33 changes: 20 additions & 13 deletions system/lib/swf.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
from pathlib import Path
from typing import List, Tuple

from loguru import logger
Expand All @@ -14,15 +15,15 @@


class SupercellSWF:
TEXTURES_TAGS = (1, 16, 28, 29, 34, 19, 24, 27, 45)
TEXTURES_TAGS = (1, 16, 28, 29, 34, 19, 24, 27, 45, 47)
SHAPES_TAGS = (2, 18)
MOVIE_CLIPS_TAGS = (3, 10, 12, 14, 35)
MOVIE_CLIPS_TAGS = (3, 10, 12, 14, 35, 49)

TEXTURE_EXTENSION = "_tex.sc"

def __init__(self):
self.filename: str
self.reader: Reader
self.filename: str | None = None
self.reader: Reader | None = None

self.use_lowres_texture: bool = False

Expand All @@ -32,8 +33,8 @@ def __init__(self):

self.xcod_writer = Writer("big")

self._filepath: str
self._uncommon_texture_path: str
self._filepath: Path | None = None
self._uncommon_texture_path: str | os.PathLike | None = None

self._lowres_suffix: str = DEFAULT_LOWRES_SUFFIX
self._highres_suffix: str = DEFAULT_HIGHRES_SUFFIX
Expand All @@ -50,13 +51,13 @@ def __init__(self):
self._export_names: List[str] = []

self._matrix_banks: List[MatrixBank] = []
self._matrix_bank: MatrixBank
self._matrix_bank: MatrixBank | None = None

def load(self, filepath: str | os.PathLike) -> Tuple[bool, bool]:
self._filepath = str(filepath)
self._filepath = Path(filepath)

texture_loaded, use_lzham = self._load_internal(
self._filepath, self._filepath.endswith("_tex.sc")
self._filepath, self._filepath.name.endswith("_tex.sc")
)

if not texture_loaded:
Expand All @@ -65,12 +66,14 @@ def load(self, filepath: str | os.PathLike) -> Tuple[bool, bool]:
self._uncommon_texture_path, True
)
else:
texture_path = self._filepath[:-3] + SupercellSWF.TEXTURE_EXTENSION
texture_path = str(self._filepath)[:-3] + SupercellSWF.TEXTURE_EXTENSION
texture_loaded, use_lzham = self._load_internal(texture_path, True)

return texture_loaded, use_lzham

def _load_internal(self, filepath: str, is_texture_file: bool) -> Tuple[bool, bool]:
def _load_internal(
self, filepath: str | os.PathLike, is_texture_file: bool
) -> Tuple[bool, bool]:
self.filename = os.path.basename(filepath)

logger.info(locale.collecting_inf % self.filename)
Expand Down Expand Up @@ -180,12 +183,12 @@ def _load_tags(self, is_texture_file: bool) -> bool:
elif tag == 30:
self._use_uncommon_texture = True
highres_texture_path = (
self._filepath[:-3]
str(self._filepath)[:-3]
+ self._highres_suffix
+ SupercellSWF.TEXTURE_EXTENSION
)
lowres_texture_path = (
self._filepath[:-3]
str(self._filepath)[:-3]
+ self._lowres_suffix
+ SupercellSWF.TEXTURE_EXTENSION
)
Expand Down Expand Up @@ -231,3 +234,7 @@ def get_display_object(

def get_matrix_bank(self, index: int) -> MatrixBank:
return self._matrix_banks[index]

@property
def filepath(self) -> Path:
return self._filepath
Loading