improve performance by selectively extracting textures

This commit is contained in:
Joseph Montanaro 2021-04-20 20:40:04 -07:00
parent 2bf5ed2b80
commit 78bc9eb88a
3 changed files with 124 additions and 42 deletions

View File

@ -1,64 +1,63 @@
import json import json
import os, os.path import os
import pathlib import pathlib
import sys import sys
import tempfile import tempfile
from deppth import deppth # not sure why the nested path from deppth import deppth, sggpio # not sure why the nested path
from PIL import Image, ImageDraw from PIL import Image, ImageDraw
def get_list(filename): entries_file = pathlib.Path(__file__).parent / 'entries.json'
d = pathlib.Path(__file__).parent with open(entries_file) as f:
lines = (d / filename).read_text().splitlines() ENTRIES = json.load(f)
return set(lines)
def remove_subtexture(package_dir, manifest, sub_atlas): def find_subtextures(pkg_reader):
filename = manifest['name'].split(os.path.sep)[-1] + '.png' for entry in pkg_reader:
file = package_dir / 'textures/atlases' / filename if entry.typeName != 'texture':
img = Image.open(file) continue
for sub in entry.manifest_entry.subAtlases:
subname = sub['name']
if 'aphrodite' in subname.lower():
if subname in ENTRIES:
if ENTRIES[subname]:
yield entry, sub
else:
print(f'WARNING: Found new subtexture: {subname}. This probably means that Supergiant has added new content to the game. This should probably be re-examined.')
def remove_subtexture(path, sub_atlas):
img = Image.open(path)
draw = ImageDraw.Draw(img) draw = ImageDraw.Draw(img)
r = sub_atlas['rect'] r = sub_atlas['rect']
top_left = (r['x'], r['y']) top_left = (r['x'], r['y'])
bottom_right = (r['x'] + r['width'], r['y'] + r['height']) bottom_right = (r['x'] + r['width'], r['y'] + r['height'])
draw.rectangle(xy=(top_left, bottom_right), fill=(0, 0, 0, 0)) draw.rectangle(xy=(top_left, bottom_right), fill=(0, 0, 0, 0))
img.save(file) img.save(path)
def process_pkg(src_path, include, exclude): def process_pkg(pkg_path):
print('Processing package', src_path,)
with tempfile.TemporaryDirectory() as tmp: with tempfile.TemporaryDirectory() as tmp:
tmp = pathlib.Path(tmp) tmp = pathlib.Path(tmp)
pkg_dir = str(tmp / 'package') extracted = set()
print('Extracting package - this may take some time.') print(' Extracting textures')
deppth.extract(src_path, pkg_dir) with sggpio.PackageWithManifestReader(pkg_path) as reader:
pkg_tmp = tmp / 'package'
for entry, sub in find_subtextures(reader):
entry.manifest_entry.extract(pkg_tmp)
entry.extract(str(pkg_tmp))
manifests = [] filename = pkg_tmp / f'textures/atlases/{entry.short_name()}.png'
for m in (tmp / 'package/manifest').iterdir(): remove_subtexture(filename, sub)
with open(m) as f:
manifests.append(json.load(f))
print('Removing subtextures') print(' Patching package')
modified = [] patch_path = tmp / 'patch.pkg'
for manifest in manifests: deppth.pack(str(pkg_tmp), str(patch_path))
for sub in manifest['subAtlases']: deppth.patch(pkg_path, patch_path)
if 'aphrodite' in sub['name'].lower():
if sub['name'] in include:
remove_subtexture(tmp / 'package', manifest, sub)
manifest_name = manifest['name'].split(os.path.sep)[-1]
modified.append(manifest_name)
elif sub['name'] not in exclude:
print(f'WARNING: Unknown texture "{sub["name"]}". You may wish to add this texture to include.txt or exclude.txt.')
print('Constructing patches')
patch_path = str(tmp / 'patch.pkg')
deppth.pack(pkg_dir, patch_path, *modified)
print('Repacking package')
deppth.patch(src_path, patch_path)
print('Finished processing package.')
def run(): def run():
@ -71,12 +70,12 @@ def run():
print(f'Could not find Hades game files. Is {steam_dir} the correct location for your Steam library?') print(f'Could not find Hades game files. Is {steam_dir} the correct location for your Steam library?')
return 1 return 1
include = get_list('include.txt')
exclude = get_list('exclude.txt')
for pkg in 'GUI.pkg', '720p/GUI.pkg', 'BC3/GUI.pkg': for pkg in 'GUI.pkg', '720p/GUI.pkg', 'BC3/GUI.pkg':
path = str(base_dir / pkg) path = str(base_dir / pkg)
process_pkg(path, include, exclude) print('Processing package:', pkg)
process_pkg(path)
print() print()
print('Finished.') print('Finished.')

82
aphremove/entries.json Normal file
View File

@ -0,0 +1,82 @@
{
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0001": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0002": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0003": false,
"GUI\\Screens\\BoonIcons\\Aphrodite_05_Large": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0004": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0005": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0006": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0007": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0008": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0009": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0045": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0047": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0048": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0049": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0010": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0050": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0011": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0040": false,
"GUI\\HUD\\BoonIconAphrodite": false,
"GUI\\Screens\\BoonIcons\\Aphrodite_13_Large": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0041": false,
"GUI\\Screens\\BoonIcons\\Aphrodite_09_Large": false,
"GUI\\Screens\\BoonIcons\\Aphrodite_11_Large": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0012": false,
"GUI\\Icons\\RoomReward\\Aphrodite": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0042": false,
"GUI\\Screens\\BoonIcons\\Aphrodite_secondary_attack": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0043": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0044": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0014": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0046": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0015": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0016": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0017": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0018": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0019": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0021": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0022": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0023": false,
"GUI\\Screens\\BoonIcons\\Aphrodite_07_Large": false,
"GUI\\Screens\\BoonIcons\\Aphrodite_12_Large": false,
"GUI\\Screens\\BoonIcons\\Aphrodite_Athena_01": false,
"GUI\\Screens\\BoonIcons\\Aphrodite_01_Large": false,
"GUI\\Screens\\AwardMenu\\KeepsakeMaxGift\\Aphrodite_02": false,
"GUI\\Screens\\AwardMenu\\KeepsakeMaxGift\\Aphrodite": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0013": false,
"GUI\\Screens\\BoonSelectSymbols\\Aphrodite": false,
"GUI\\Epilogue\\Olympus_Aphrodite": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0024": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0025": false,
"GUI\\Screens\\BoonSelectSymbols\\Aphrodite2": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0020": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0026": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0032": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0034": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0027": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0035": false,
"GUI\\Screens\\BoonIcons\\Ares_Aphrodite_01": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0028": false,
"GUI\\Screens\\BoonIcons\\Zeus_Aphrodite_01": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0029": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0030": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0031": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0033": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0037": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0036": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0038": false,
"GUI\\Screens\\BoonSelectSymbols\\Spin\\AphroditeIconSpin\\AphroditeIconSpin0039": false,
"GUI\\Screens\\BoonIcons\\Aphrodite_03_Large": false,
"GUI\\Screens\\BoonIcons\\Aphrodite_04_Large": false,
"GUI\\Screens\\BoonIcons\\Artemis_Aphrodite_01": false,
"GUI\\Screens\\BoonIcons\\Aphrodite_06_Large": false,
"GUI\\Screens\\BoonIcons\\Aphrodite_10_Large": false,
"GUI\\Screens\\BoonIcons\\Aphrodite_Demeter_01": false,
"GUI\\Screens\\BoonIcons\\Aphrodite_Poseidon_01": false,
"GUI\\Screens\\BoonIcons\\Dionysus_Aphrodite_01": false,
"GUI\\Screens\\BoonIcons\\Aphrodite_02_Large": false,
"GUI\\Screens\\BoonIcons\\Aphrodite_08_Large": false,
"Portraits\\Codex\\CodexPortrait_Aphrodite": true,
"Portraits\\Portraits_Aphrodite_01": true
}

View File

@ -6,7 +6,8 @@ setup(
author='Joseph Montanaro', author='Joseph Montanaro',
install_requires=[ install_requires=[
'deppth@https://github.com/quaerus/deppth/releases/download/v0.1.0.0/deppth-0.1.0.0-py3-none-any.whl', 'deppth@https://github.com/quaerus/deppth/releases/download/v0.1.0.0/deppth-0.1.0.0-py3-none-any.whl',
'pillow' 'pillow',
'lz4',
], ],
packages=find_packages(), packages=find_packages(),
entry_points = { entry_points = {