Skip to content

Commit ab416fe

Browse files
Merge pull request #20 from xcoder-tool/khronos-texture-tags
feat(tags): support for new texture and movie clip tags
2 parents d64e1f7 + 6cc21ef commit ab416fe

File tree

4 files changed

+47
-19
lines changed

4 files changed

+47
-19
lines changed

system/lib/features/sc/decode.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def decode_and_render_objects():
5959
files = os.listdir(input_folder)
6060

6161
for file in files:
62-
if file.endswith("_tex.sc"):
62+
if file.endswith("_tex.sc") or not file.endswith(".sc"):
6363
continue
6464

6565
try:
@@ -99,9 +99,9 @@ def get_file_basename(swf: SupercellSWF):
9999

100100
def _create_objects_output_folder(output_folder: Path, base_name: str) -> Path:
101101
objects_output_folder = output_folder / base_name
102-
if os.path.isdir(objects_output_folder):
102+
if objects_output_folder.exists():
103103
shutil.rmtree(objects_output_folder)
104-
os.mkdir(objects_output_folder)
104+
objects_output_folder.mkdir(parents=True)
105105
return objects_output_folder
106106

107107

system/lib/objects/movie_clip.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ def load(self, swf: "SupercellSWF", tag: int):
6262
if tag in (3, 14):
6363
pass
6464
else:
65+
if tag == 49:
66+
swf.reader.read_char() # unknown
67+
6568
transforms_count = swf.reader.read_uint()
6669

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

82-
if tag in (12, 35):
85+
if tag in (12, 35, 49):
8386
for i in range(binds_count):
8487
blend = swf.reader.read_char() # blend
8588
self.blends.append(blend)

system/lib/objects/texture.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
from __future__ import annotations
2+
13
import os
4+
from typing import TYPE_CHECKING
25

6+
import zstandard
37
from PIL import Image
48

59
from system.lib.images import (
@@ -10,19 +14,25 @@
1014
)
1115
from system.lib.pvr_tex_tool import get_image_from_ktx_data
1216

17+
if TYPE_CHECKING:
18+
from system.lib.swf import SupercellSWF
19+
1320

1421
class SWFTexture:
1522
def __init__(self):
1623
self.width = 0
1724
self.height = 0
1825

1926
self.pixel_type = -1
27+
self.khronos_texture_filename: str | None = None
2028

21-
self.image: Image.Image
29+
self.image: Image.Image | None = None
2230

23-
def load(self, swf, tag: int, has_texture: bool):
31+
def load(self, swf: SupercellSWF, tag: int, has_texture: bool):
2432
if tag == 45:
2533
khronos_texture_length = swf.reader.read_int()
34+
elif tag == 47:
35+
self.khronos_texture_filename = swf.reader.read_string()
2636

2737
self.pixel_type = swf.reader.read_char()
2838
self.width, self.height = (swf.reader.read_ushort(), swf.reader.read_ushort())
@@ -35,6 +45,14 @@ def load(self, swf, tag: int, has_texture: bool):
3545
khronos_texture_data = swf.reader.read(khronos_texture_length)
3646
self.image = get_image_from_ktx_data(khronos_texture_data)
3747
return
48+
elif tag == 47:
49+
with open(
50+
swf.filepath.parent / self.khronos_texture_filename, "rb"
51+
) as file:
52+
decompressor = zstandard.ZstdDecompressor()
53+
decompressed = decompressor.decompress(file.read())
54+
self.image = get_image_from_ktx_data(decompressed)
55+
return
3856

3957
img = Image.new(
4058
get_format_by_pixel_type(self.pixel_type), (self.width, self.height)

system/lib/swf.py

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import os
2+
from pathlib import Path
23
from typing import List, Tuple
34

45
from loguru import logger
@@ -14,15 +15,15 @@
1415

1516

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

2122
TEXTURE_EXTENSION = "_tex.sc"
2223

2324
def __init__(self):
24-
self.filename: str
25-
self.reader: Reader
25+
self.filename: str | None = None
26+
self.reader: Reader | None = None
2627

2728
self.use_lowres_texture: bool = False
2829

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

3334
self.xcod_writer = Writer("big")
3435

35-
self._filepath: str
36-
self._uncommon_texture_path: str
36+
self._filepath: Path | None = None
37+
self._uncommon_texture_path: str | os.PathLike | None = None
3738

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

5253
self._matrix_banks: List[MatrixBank] = []
53-
self._matrix_bank: MatrixBank
54+
self._matrix_bank: MatrixBank | None = None
5455

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

5859
texture_loaded, use_lzham = self._load_internal(
59-
self._filepath, self._filepath.endswith("_tex.sc")
60+
self._filepath, self._filepath.name.endswith("_tex.sc")
6061
)
6162

6263
if not texture_loaded:
@@ -65,12 +66,14 @@ def load(self, filepath: str | os.PathLike) -> Tuple[bool, bool]:
6566
self._uncommon_texture_path, True
6667
)
6768
else:
68-
texture_path = self._filepath[:-3] + SupercellSWF.TEXTURE_EXTENSION
69+
texture_path = str(self._filepath)[:-3] + SupercellSWF.TEXTURE_EXTENSION
6970
texture_loaded, use_lzham = self._load_internal(texture_path, True)
7071

7172
return texture_loaded, use_lzham
7273

73-
def _load_internal(self, filepath: str, is_texture_file: bool) -> Tuple[bool, bool]:
74+
def _load_internal(
75+
self, filepath: str | os.PathLike, is_texture_file: bool
76+
) -> Tuple[bool, bool]:
7477
self.filename = os.path.basename(filepath)
7578

7679
logger.info(locale.collecting_inf % self.filename)
@@ -180,12 +183,12 @@ def _load_tags(self, is_texture_file: bool) -> bool:
180183
elif tag == 30:
181184
self._use_uncommon_texture = True
182185
highres_texture_path = (
183-
self._filepath[:-3]
186+
str(self._filepath)[:-3]
184187
+ self._highres_suffix
185188
+ SupercellSWF.TEXTURE_EXTENSION
186189
)
187190
lowres_texture_path = (
188-
self._filepath[:-3]
191+
str(self._filepath)[:-3]
189192
+ self._lowres_suffix
190193
+ SupercellSWF.TEXTURE_EXTENSION
191194
)
@@ -231,3 +234,7 @@ def get_display_object(
231234

232235
def get_matrix_bank(self, index: int) -> MatrixBank:
233236
return self._matrix_banks[index]
237+
238+
@property
239+
def filepath(self) -> Path:
240+
return self._filepath

0 commit comments

Comments
 (0)