Skip to content

Commit 747bea1

Browse files
Place sprites fix, refactoring
1 parent 4784aa4 commit 747bea1

File tree

10 files changed

+131
-99
lines changed

10 files changed

+131
-99
lines changed

system/languages/en-EU.json

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"encode_sc_description": "Converts PNG to SC",
2727
"decode_by_parts_description": "Converts SC in PNG and cuts texture to sprites",
2828
"encode_by_parts_description": "Puts sprites on the texture and converts PNG in SC",
29-
"overwrite_by_parts_description": "Repeats the action of the previous function but consider the \"overwrite\" folder",
29+
"overwrite_by_parts_description": "Do the same as the previous but consider the \"overwrite\" folder",
3030

3131
"csv_label": "CSV",
3232
"decompress_csv": "Decompress the CSV",
@@ -51,15 +51,14 @@
5151
"collecting_inf": "Collecting information...",
5252
"about_sc": "About texture. Filename: %s (%d), Pixel type: %d, Size: %sx%s",
5353
"decompression_error": "Error while decompressing! Trying to decode as is...",
54-
"skip_not_installed": "%s isn\"t installed! Reinitialize",
54+
"skip_not_installed": "%s isn't installed! Reinitialize",
5555
"detected_comp": "Detected %s compression!",
5656
"unk_type": "Unknown pixel type: %s",
5757
"crt_pic": "Creating picture...",
5858
"join_pic": "Joining picture...",
5959
"png_save": "Saving to png...",
6060
"saved": "Saving completed!",
61-
"not_xcod": ".xcod file doesn\"t exist!",
62-
"default_types": "We will use default fileType and subType (1, 0).\n And also LZMA compression (as in Brawl Stars sc)",
61+
"xcod_not_found": "File '%s.xcod' doesn't exist!",
6362
"illegal_size": "Illegal image size! Expected %sx%s but we got %sx%s",
6463
"resize_qu": "Would you like to resize an image?",
6564
"resizing": "Resizing...",
@@ -69,16 +68,16 @@
6968
"compressing_with": "Compressing texture with %s...",
7069
"compression_error": "Compression failed",
7170
"compression_done": "Compression done!",
72-
"dir_empty": "Dir \"%s\" is empty!",
73-
"not_found": "\"%s\" file isn\"t found!",
74-
"cut_sprites_process": "Cutting sprites... (%s/%s)",
75-
"place_sprites_process": "Placing sprites... (%s/%s)",
71+
"dir_empty": "Dir '%s' is empty!",
72+
"not_found": "File '%s' not found!",
73+
"cut_sprites_process": "Cutting sprites... (%d/%d)",
74+
"place_sprites_process": "Placing sprites... (%d/%d)",
7675
"not_implemented": "This feature will be added in future updates.\nYou can follow XCoder updates here: github.com/Vorono4ka/XCoder",
7776
"want_exit": "Want to exit?",
7877
"dec_sc": "Decoding .sc file...",
7978
"error": "ERROR! (%s.%s: %s)",
8079
"e1sc1": "Overwrite SC sprites",
81-
"cgl": "Changelog:\n%s\n",
80+
"cgl": "Changelog:\n%s",
8281
"upd_av": "\nUpdate is available!\nVersion: %s\n",
8382
"upd_qu": "Do you want to update?",
8483
"upd": "Updating...",
@@ -89,5 +88,5 @@
8988
"enabled": "Enabled",
9089
"disabled": "Disabled",
9190

92-
"install_to_unlock": "Install \"%s\" to unlock more functions!"
91+
"install_to_unlock": "Install '%s' to unlock more functions!"
9392
}

system/languages/ru-RU.json

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"encode_sc_description": "Конвертирует PNG в SC",
2727
"decode_by_parts_description": "Конвертирует SC в PNG и разрезает текстуру на части",
2828
"encode_by_parts_description": "Собирает части текстуры и конвертирует PNG в SC",
29-
"overwrite_by_parts_description": "Повторяет действие предыдущей функции, но учитывает папку \"overwrite\"",
29+
"overwrite_by_parts_description": "Повторяет действие предыдущей функции, но учитывает папку 'overwrite'",
3030

3131
"csv_label": "CSV - Таблицы",
3232
"decompress_csv": "Разжать CSV",
@@ -58,8 +58,7 @@
5858
"join_pic": "Соединяем картинку...",
5959
"png_save": "Сохраняем в png...",
6060
"saved": "Сохранение прошло успешно!",
61-
"not_xcod": ".xcod файл не обнаружен!",
62-
"default_types": "Мы используем стандартные типы текстур (1, 0).\n И ещё LZMA сжатие (как в SC из Brawl Stars)",
61+
"xcod_not_found": "Файл '%s.xcod' не обнаружен!",
6362
"illegal_size": "Размер картинки не совпадает с оригиналом! Ожидалось %sx%s, но мы получили %sx%s",
6463
"resize_qu": "Хотите изменить размер?",
6564
"resizing": "Изменяем размер...",
@@ -69,16 +68,16 @@
6968
"compressing_with": "Сохраняем с применением %s сжатия...",
7069
"compression_error": "Сжатие не удалось",
7170
"compression_done": "Сжатие прошло успешно!",
72-
"dir_empty": "Папка \"%s\" пуста!",
73-
"not_found": "Не был найден \"%s\" файл!",
74-
"cut_sprites_process": "Вырезаем спрайты... (%s/%s)",
75-
"place_sprites_process": "Ставим спрайты на место... (%s/%s)",
71+
"dir_empty": "Папка '%s' пуста!",
72+
"not_found": "Файл '%s' не найден!",
73+
"cut_sprites_process": "Вырезаем спрайты... (%d/%d)",
74+
"place_sprites_process": "Ставим спрайты на место... (%d/%d)",
7675
"not_implemented": "Данная возможность будет добавлена в будущих обновлениях.\nЗа обновлениями XCoder вы можете следить здесь: github.com/Vorono4ka/XCoder",
7776
"want_exit": "Хотите выйти?",
7877
"dec_sc": "Декодируем SC...",
7978
"error": "ОШИБКА! (%s.%s: %s)",
8079
"e1sc1": "Перезапись спрайтов",
81-
"cgl": "Список изменений:\n%s\n",
80+
"cgl": "Список изменений: \n%s",
8281
"upd_av": "\nДоступно обновление!\nВерсия: %s\n",
8382
"upd_qu": "Обновить?",
8483
"upd": "Обновляем...",
@@ -89,5 +88,5 @@
8988
"enabled": "Включено",
9089
"disabled": "Выключено",
9190

92-
"install_to_unlock": "Установите \"%s\" чтобы открыть больше функций!"
91+
"install_to_unlock": "Установите '%s' чтобы открыть больше функций!"
9392
}

system/lib/features/place_sprites.py

Lines changed: 32 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,52 +2,47 @@
22

33
from PIL import Image, ImageDraw
44

5-
from system.bytestream import Reader
65
from system.lib import Console
6+
from system.lib.images import pixel_type2str
7+
from system.lib.xcod import parse_info, FileInfo
78
from system.localization import locale
89

910

10-
def place_sprites(xcod, folder, overwrite=False):
11-
xcod = Reader(open(xcod, 'rb').read(), 'big')
12-
files = os.listdir(f'{folder}{"/overwrite" if overwrite else ""}')
13-
tex = os.listdir(f'{folder}/textures')
14-
15-
xcod.read(4)
16-
use_lzham, pictures_count = xcod.read_ubyte(), xcod.read_ubyte()
17-
sheet_image = []
18-
sheet_image_data = {'use_lzham': use_lzham, 'data': []}
19-
for i in range(pictures_count):
20-
file_type, sub_type, width, height = xcod.read_ubyte(), \
21-
xcod.read_ubyte(), \
22-
xcod.read_uint16(), \
23-
xcod.read_uint16()
24-
sheet_image.append(
25-
Image.open(f'{folder}/textures/{tex[i]}')
11+
def place_sprites(xcod_path: str, folder: str, overwrite: bool = False) -> (list, FileInfo):
12+
file_info, xcod = parse_info(xcod_path)
13+
14+
files_to_overwrite = os.listdir(f'{folder}{"/overwrite" if overwrite else ""}')
15+
texture_files = os.listdir(f'{folder}/textures')
16+
17+
sheets = []
18+
for i in range(len(file_info.sheets)):
19+
sheet_info = file_info.sheets[i]
20+
21+
sheets.append(
22+
Image.open(f'{folder}/textures/{texture_files[i]}')
2623
if overwrite else
27-
Image.new('RGBA', (width, height)))
28-
sheet_image_data['data'].append({'file_type': file_type, 'pixel_type': sub_type})
24+
Image.new(pixel_type2str(sheet_info.pixel_type), sheet_info.size)
25+
)
2926

3027
shapes_count = xcod.read_uint16()
3128
for shape_index in range(shapes_count):
3229
Console.progress_bar(locale.place_sprites_process % (shape_index + 1, shapes_count), shape_index, shapes_count)
3330
shape_id = xcod.read_uint16()
34-
regions_count = xcod.read_uint16()
3531

32+
regions_count = xcod.read_uint16()
3633
for region_index in range(regions_count):
3734
texture_id, points_count = xcod.read_ubyte(), xcod.read_ubyte()
38-
texture_width, texture_height = sheet_image[texture_id].width, sheet_image[texture_id].height
35+
texture_width, texture_height = sheets[texture_id].width, sheets[texture_id].height
3936
polygon = [(xcod.read_uint16(), xcod.read_uint16()) for _ in range(points_count)]
4037
mirroring, rotation = xcod.read_ubyte() == 1, xcod.read_ubyte() * 90
4138

4239
filename = f'shape_{shape_id}_{region_index}.png'
43-
if filename not in files:
40+
if filename not in files_to_overwrite:
4441
continue
4542

4643
tmp_region = Image.open(
4744
f'{folder}{"/overwrite" if overwrite else ""}/{filename}'
48-
) \
49-
.convert('RGBA') \
50-
.rotate(360 - rotation, expand=True)
45+
).convert('RGBA').rotate(360 - rotation, expand=True)
5146

5247
img_mask = Image.new('L', (texture_width, texture_height), 0)
5348
color = 255
@@ -71,23 +66,25 @@ def place_sprites(xcod, folder, overwrite=False):
7166
img_mask.putpixel((max_x - 1, max_y - 1), color)
7267
bbox = img_mask.getbbox()
7368

74-
a, b, c, d = bbox
75-
if c - a - 1:
76-
c -= 1
77-
if d - b - 1:
78-
d -= 1
69+
left, top, right, bottom = bbox
70+
if right - left - 1:
71+
right -= 1
72+
if bottom - top - 1:
73+
bottom -= 1
7974

80-
bbox = a, b, c, d
75+
bbox = left, top, right, bottom
8176

82-
region_size = bbox[2] - bbox[0], bbox[3] - bbox[1]
77+
width = right - left
78+
height = bottom - top
79+
region_size = width, height
8380
tmp_region = tmp_region.resize(region_size, Image.ANTIALIAS)
8481

8582
if mirroring:
8683
tmp_region = tmp_region.transform(region_size, Image.EXTENT,
8784
(tmp_region.width, 0, 0, tmp_region.height))
8885

89-
sheet_image[texture_id].paste(Image.new('RGBA', region_size), bbox[:2], img_mask.crop(bbox))
90-
sheet_image[texture_id].paste(tmp_region, bbox[:2], tmp_region)
86+
sheets[texture_id].paste(Image.new('RGBA', region_size), (left, top), img_mask.crop(bbox))
87+
sheets[texture_id].paste(tmp_region, (left, top), tmp_region)
9188
print()
9289

93-
return sheet_image, sheet_image_data
90+
return sheets, file_info

system/lib/features/sc/__init__.py

Lines changed: 17 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@
88
from system.lib.console import Console
99
from system.lib.features.files import write_sc
1010
from system.lib.images import get_pixel_size, split_image, rgba2bytes
11+
from system.lib.xcod import FileInfo
1112
from system.localization import locale
1213

1314

14-
def compile_sc(_dir, from_memory=None, img_data=None, folder_export=None):
15-
sc_data = None
16-
15+
def compile_sc(_dir, file_info: FileInfo, sheets: list = None, output_folder: str = None):
1716
name = _dir.split('/')[-2]
18-
if from_memory:
19-
files = from_memory
17+
18+
if sheets:
19+
files = sheets
2020
else:
2121
files = []
2222
[files.append(i) if i.endswith('.png') else None for i in os.listdir(_dir)]
@@ -28,39 +28,22 @@ def compile_sc(_dir, from_memory=None, img_data=None, folder_export=None):
2828
logger.info(locale.collecting_inf)
2929
sc = Writer()
3030

31-
has_xcod = False
32-
use_lzham = False
33-
if from_memory:
34-
use_lzham = img_data['use_lzham']
35-
else:
36-
try:
37-
sc_data = open(f'{_dir}/{name}.xcod', 'rb')
38-
sc_data.read(4)
39-
use_lzham, = struct.unpack('?', sc_data.read(1))
40-
sc_data.read(1)
41-
has_xcod = True
42-
except OSError:
43-
logger.info(locale.not_xcod)
44-
logger.info(locale.default_types)
31+
use_lzham = file_info.use_lzham
4532

4633
for picture_index in range(len(files)):
34+
sheet_info = file_info.sheets[picture_index]
4735
img = files[picture_index]
4836
print()
4937

50-
if from_memory:
51-
file_type = img_data['data'][picture_index]['file_type']
52-
pixel_type = img_data['data'][picture_index]['pixel_type']
53-
else:
54-
if has_xcod:
55-
file_type, pixel_type, width, height = struct.unpack('>BBHH', sc_data.read(6))
56-
57-
if (width, height) != img.size:
58-
logger.info(locale.illegal_size % (width, height, img.width, img.height))
59-
if Console.question(locale.resize_qu):
60-
logger.info(locale.resizing)
61-
img = img.resize((width, height), Image.ANTIALIAS)
62-
else:
63-
file_type, pixel_type = 1, 0
38+
file_type = sheet_info.file_type
39+
pixel_type = sheet_info.pixel_type
40+
41+
if img.size != sheet_info.size:
42+
logger.info(locale.illegal_size % (sheet_info.width, sheet_info.height, img.width, img.height))
43+
44+
if Console.question(locale.resize_qu):
45+
logger.info(locale.resizing)
46+
img = img.resize(sheet_info.size, Image.ANTIALIAS)
6447

6548
width, height = img.size
6649
pixel_size = get_pixel_size(pixel_type)
@@ -81,4 +64,4 @@ def compile_sc(_dir, from_memory=None, img_data=None, folder_export=None):
8164
sc.write(bytes(5))
8265
print()
8366

84-
write_sc(f'{folder_export}/{name}.sc', sc.getvalue(), use_lzham)
67+
write_sc(f'{output_folder}/{name}.sc', sc.getvalue(), use_lzham)

system/lib/features/sc/assembly_encode.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
def sc1_encode(overwrite: bool = False):
1111
folder = './SC/In-Sprites/'
12-
folder_export = './SC/Out-Compressed/'
12+
output_folder = './SC/Out-Compressed/'
1313
files = os.listdir(folder)
1414

1515
for file in files:
@@ -19,9 +19,9 @@ def sc1_encode(overwrite: bool = False):
1919
else:
2020
try:
2121
logger.info(locale.dec_sc)
22-
sheet_image, sheet_image_data = place_sprites(f'{folder}{file}/{xcod}', f'{folder}{file}', overwrite)
22+
sheets, file_info = place_sprites(f'{folder}{file}/{xcod}', f'{folder}{file}', overwrite)
2323
logger.info(locale.dec_sc)
24-
compile_sc(f'{folder}{file}/', sheet_image, sheet_image_data, folder_export)
24+
compile_sc(f'{folder}{file}/', file_info, sheets, output_folder)
2525
except Exception as exception:
2626
logger.exception(locale.error % (exception.__class__.__module__, exception.__class__.__name__, exception))
2727
print()

system/lib/features/sc/sc_encode.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,22 @@
33
from loguru import logger
44

55
from system.lib.features.sc import compile_sc
6+
from system.lib.xcod import parse_info
67
from system.localization import locale
78

89

910
def sc_encode():
10-
folder = './SC/In-Decompressed'
11-
folder_export = './SC/Out-Compressed'
11+
input_folder = './SC/In-Decompressed'
12+
output_folder = './SC/Out-Compressed'
1213

13-
for file in os.listdir(folder):
14+
for folder in os.listdir(input_folder):
1415
try:
15-
compile_sc(f'{folder}/{file}/', folder_export=folder_export)
16+
file_info, _ = parse_info(f'{input_folder}/{folder}/{folder}.xcod')
17+
18+
compile_sc(f'{input_folder}/{folder}/', file_info, output_folder=output_folder)
19+
except FileNotFoundError:
20+
logger.info(locale.xcod_not_found % folder)
1621
except Exception as exception:
1722
logger.exception(locale.error % (exception.__class__.__module__, exception.__class__.__name__, exception))
1823

19-
print()
24+
print()

system/lib/features/update/check.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ def check_update():
6363

6464
check_for_outdated()
6565

66+
logger.info(locale.check_update)
6667
if config.version != latest_tag_name:
6768
logger.error(locale.not_latest)
6869

system/lib/images.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ def get_pixel_size(_type):
111111

112112

113113
def pixel_type2str(_type):
114-
if _type in range(4):
114+
if _type in (0, 1, 2, 3):
115115
return 'RGBA'
116116
elif _type == 4:
117117
return 'RGB'

0 commit comments

Comments
 (0)