From 6751c1df102921a16334d814b73979a5b1ee53c4 Mon Sep 17 00:00:00 2001 From: Nariman <89722698+aryanariman@users.noreply.github.com> Date: Sat, 6 Dec 2025 17:41:02 +0330 Subject: [PATCH 1/7] Add try except to main.py --- main.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 68c06ad..c15350f 100644 --- a/main.py +++ b/main.py @@ -1,4 +1,7 @@ import ui -if __name__ == "__main__": - ui() \ No newline at end of file +try: + if __name__ == "__main__": + ui() +except Exception as e: + pass \ No newline at end of file From e559a8cdd66b26b7ae9af79c116921646388a08f Mon Sep 17 00:00:00 2001 From: Nariman <89722698+aryanariman@users.noreply.github.com> Date: Sat, 6 Dec 2025 17:42:25 +0330 Subject: [PATCH 2/7] Change Window Title --- ui.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui.py b/ui.py index 849bda1..a340bf0 100644 --- a/ui.py +++ b/ui.py @@ -7,7 +7,7 @@ class App: def __init__(self, root): #setting title - root.title("undefined") + root.title("apti_tex Tool") #setting window size width=600 height=500 @@ -49,7 +49,7 @@ def __init__(self, root): import_button["font"] = ft import_button["fg"] = "#000000" import_button["justify"] = "center" - import_button["text"] = "Import" + import_button["text"] = "Import!" import_button.place(x=380,y=160,width=160,height=53) import_button["command"] = self.import_button_command From cae81414b06fbeabff37d0977da53555376a60f4 Mon Sep 17 00:00:00 2001 From: Nariman <89722698+aryanariman@users.noreply.github.com> Date: Sat, 6 Dec 2025 17:44:18 +0330 Subject: [PATCH 3/7] Add Messege box Error And Done --- export_import.py | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/export_import.py b/export_import.py index c7d6e4a..488bb49 100644 --- a/export_import.py +++ b/export_import.py @@ -2,12 +2,27 @@ import os from binary_reader import BinaryReader from cv2 import exp +from tkinter import Tk, messagebox + apti_tex_magic = bytes.fromhex('6D 32 F3 C3') DDS_Header = b'DDS |\x00\x00\x00\x07\x10\x08\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x01\x00\x00\x00GIMP-DDS\\\t\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x04\x00\x00\x00DXT5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' apti_tex_header = b'm2\xf3\xc3\xd1\x9ce\xe9\x9a\xbc\x0f\r"\xdb\xdaO\x00Q5!k\xc7\xd8\x01;\x00\x04\x007\x00\x00\x00\x04\x00\x04\x00\x0c\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\xbc\x0f\r"\xdb\xdaO\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x04\x00\xc5\x04\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x02\x00\x00\x00\x00\xff\x00' zeros = b'\x00'*4 +def notify(msg): + root = Tk() + root.withdraw() + messagebox.showinfo("Info", msg) + root.destroy() + +def error(msg): + root = Tk() + root.withdraw() + messagebox.showerror("Error", msg) + root.destroy() + + def export_command(file_path, dirname): try: file_name = os.path.basename(file_path) @@ -26,14 +41,16 @@ def export_command(file_path, dirname): out_file.write(DDS_Header + dosya) out_file.seek(-4, io.SEEK_END) out_file.truncate() + notify("Done!") return 'Done!' except: + error('Something went wrong.') return 'Something went wrong.' def import_command(file_path, dirname): try: file_name = os.path.basename(file_path) - outputfile = dirname + '\\' + file_name[:-4] + '.APTI_TEX' + outputfile = dirname + '\\' + file_name[:-4] + '.apti_tex_NEW' file_stats = os.stat(file_path) f = open(file_path, "rb") @@ -54,6 +71,8 @@ def import_command(file_path, dirname): size_dosya = reader_for_dds.size() out_file.write(apti_tex_header + reader_for_dds.read_bytes(size_dosya) + zeros) + notify("Done!") return 'Done!' except: - return 'Something went wrong' + error('Something went wrong.') + return 'Something went wrong.' \ No newline at end of file From 9595af3735b61d4d93d5bffe8b0b4754947b9ab5 Mon Sep 17 00:00:00 2001 From: Nariman <89722698+aryanariman@users.noreply.github.com> Date: Sat, 6 Dec 2025 17:56:08 +0330 Subject: [PATCH 4/7] Sorting Files --- .gitattributes | 2 - .gitignore | 154 ----------------------- export_import.py => Lib/export_import.py | 0 ui.py => Lib/ui.py | 2 +- main.py => apti_texTool.py | 2 +- 5 files changed, 2 insertions(+), 158 deletions(-) delete mode 100644 .gitattributes delete mode 100644 .gitignore rename export_import.py => Lib/export_import.py (100%) rename ui.py => Lib/ui.py (99%) rename main.py => apti_texTool.py (81%) diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index dfe0770..0000000 --- a/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -# Auto detect text files and perform LF normalization -* text=auto diff --git a/.gitignore b/.gitignore deleted file mode 100644 index bbfb8f8..0000000 --- a/.gitignore +++ /dev/null @@ -1,154 +0,0 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -share/python-wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.nox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -*.py,cover -.hypothesis/ -.pytest_cache/ -cover/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py -db.sqlite3 -db.sqlite3-journal - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -.pybuilder/ -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# IPython -profile_default/ -ipython_config.py - -# pyenv -# For a library or package, you might want to ignore these files since the code is -# intended to run in multiple environments; otherwise, check them in: -# .python-version - -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - -# poetry -# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. -# This is especially recommended for binary packages to ensure reproducibility, and is more -# commonly ignored for libraries. -# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control -#poetry.lock - -# PEP 582; used by e.g. github.com/David-OConnor/pyflow -__pypackages__/ - -# Celery stuff -celerybeat-schedule -celerybeat.pid - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ -.dmypy.json -dmypy.json - -# Pyre type checker -.pyre/ - -# pytype static type analyzer -.pytype/ - -# Cython debug symbols -cython_debug/ - -# PyCharm -# JetBrains specific template is maintainted in a separate JetBrains.gitignore that can -# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore -# and can be added to the global gitignore or merged into this file. For a more nuclear -# option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ -*.dds -*.apti_tex diff --git a/export_import.py b/Lib/export_import.py similarity index 100% rename from export_import.py rename to Lib/export_import.py diff --git a/ui.py b/Lib/ui.py similarity index 99% rename from ui.py rename to Lib/ui.py index a340bf0..09796b0 100644 --- a/ui.py +++ b/Lib/ui.py @@ -1,7 +1,7 @@ import tkinter as tk import tkinter.font as tkFont from tkinter import filedialog -import export_import +from Lib import export_import class App: diff --git a/main.py b/apti_texTool.py similarity index 81% rename from main.py rename to apti_texTool.py index c15350f..8fdb6af 100644 --- a/main.py +++ b/apti_texTool.py @@ -1,4 +1,4 @@ -import ui +from Lib import ui try: if __name__ == "__main__": From 1d0a8df92667161fedea33a5133a4f1a4d1088e6 Mon Sep 17 00:00:00 2001 From: Nariman <89722698+aryanariman@users.noreply.github.com> Date: Sat, 6 Dec 2025 18:01:57 +0330 Subject: [PATCH 5/7] Update README.md --- README.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/README.md b/README.md index 148db98..2704246 100644 --- a/README.md +++ b/README.md @@ -8,3 +8,29 @@ You need to edit this DDS or at least make sure to convert it through GIMP "BC3/ Other compression support will add soon. After your editing is done, you can use the Import button to import your DDS file to the *.apti_tex file. Simple enough. + +# apti_tex Tool + +A lightweight GUI utility for exporting and importing `*.apti_tex` texture files. +The tool converts `*.apti_tex` files into `*.DDS` (BC3/DXT5) for editing in applications such as GIMP, and then repacks edited DDS files back into the apti_tex format. + +## Features +- Export `.apti_tex` files to `.DDS` +- Supports editing DDS files in BC3/DXT5 format +- Import edited `.DDS` files back into `.apti_tex` +- Simple Tkinter-based interface +- Error and status notifications via message boxes + +## How It Works +- **Export:** Reads the custom header, extracts raw texture data, and builds a valid DDS output file. +- **Import:** Validates the DDS header, rebuilds the apti_tex structure, and writes a new `.apti_tex_NEW` file. + +## Requirements +- Python 3.x +- `binary-reader` +- `tkinter` +- `opencv-python` + +## Usage +Run the main script: + From 65e1540bd8e17c941051099e0b7090429805b38e Mon Sep 17 00:00:00 2001 From: Nariman <89722698+aryanariman@users.noreply.github.com> Date: Sat, 6 Dec 2025 18:04:07 +0330 Subject: [PATCH 6/7] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 2704246..3d1093e 100644 --- a/README.md +++ b/README.md @@ -33,4 +33,7 @@ The tool converts `*.apti_tex` files into `*.DDS` (BC3/DXT5) for editing in appl ## Usage Run the main script: +**python apti_texTool.py** + +Then use the GUI buttons to export or import textures. From 90ea312764f784ba3f9241e047e66d869e6fd955 Mon Sep 17 00:00:00 2001 From: Nariman <89722698+aryanariman@users.noreply.github.com> Date: Thu, 18 Jun 2026 17:33:31 +0330 Subject: [PATCH 7/7] Added .gitattributes and .gitignore --- .gitattributes | 2 + .gitignore | 154 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bbfb8f8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,154 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintainted in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ +*.dds +*.apti_tex