Skip to content

Commit

Permalink
Merge pull request #29 from matyalatte/dev
Browse files Browse the repository at this point in the history
v0.5.6 update
  • Loading branch information
matyalatte authored Mar 3, 2024
2 parents 16f8048 + ab2558b commit 779a3a1
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 42 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:

env:
ZIP_NAME: UE4-DDS-Tools
GUI_VERSION: v0.5.1
GUI_VERSION: v0.6.3

jobs:
build:
Expand Down Expand Up @@ -51,11 +51,11 @@ jobs:
cp bat/* release
shell: bash

- name: Download Simple Command Runner
- name: Download Tuw
run: |
curl -OL https://github.com/matyalatte/Simple-Command-Runner/releases/download/${{env.GUI_VERSION}}/SimpleCommandRunner-${{env.GUI_VERSION}}-${{ runner.os }}.zip
unzip -d SimpleCommandRunner SimpleCommandRunner-${{env.GUI_VERSION}}-${{ runner.os }}.zip
cp SimpleCommandRunner/SimpleCommandRunner.exe release_gui/GUI.exe
curl -OL https://github.com/matyalatte/tuw/releases/download/${{env.GUI_VERSION}}/Tuw-${{env.GUI_VERSION}}-${{ runner.os }}-x64.zip
unzip -d Tuw Tuw-${{env.GUI_VERSION}}-${{ runner.os }}-x64.zip
cp Tuw/Tuw.exe release_gui/GUI.exe
cp gui_definition.json release_gui
shell: bash

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/download_portable_python.bat
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ cd python-%PYTHON_VERSION%-embed-amd64

REM Remove unnecessary files
del pythonw.exe python.cat python%PYTHON_VER_SHORT%._pth
del python3.dll libcrypto-1_1.dll libssl-1_1.dll sqlite3.dll
del python3.dll libcrypto-*.dll libssl-*.dll sqlite*.dll
del _asyncio.pyd _bz2.pyd _decimal.pyd _elementtree.pyd _hashlib.pyd
del _lzma.pyd _msi.pyd _overlapped.pyd _queue.pyd
del _sqlite3.pyd _ssl.pyd _uuid.pyd _zoneinfo.pyd
Expand All @@ -26,7 +26,7 @@ REM Remove unnecessary files from pythonXXX.zip
powershell Expand-Archive -Force -Path python%PYTHON_VER_SHORT%.zip
cd python%PYTHON_VER_SHORT%
rmdir /s /q curses dbm distutils email html http lib2to3 msilib
rmdir /s /q pydoc_data site-packages sqlite3 unittest urllib
rmdir /s /q pydoc_data site-packages sqlite3 tomllib unittest urllib
rmdir /s /q wsgiref xml xmlrpc zoneinfo
del ast.pyc bz2.pyc calendar.pyc csv.pyc doctest.pyc ftplib.pyc gzip.pyc
del imaplib.pyc ipaddress.pyc mailbox.pyc nntplib.pyc nturl2path.pyc
Expand Down
12 changes: 7 additions & 5 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
[![discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/Qx2Ff3MByF)
![build](https://github.com/matyalatte/UE4-DDS-tools/actions/workflows/build.yml/badge.svg)
![test](https://github.com/matyalatte/UE4-DDS-tools/actions/workflows/test.yml/badge.svg)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

# UE4-DDS-Tools ver0.5.5
# UE4-DDS-Tools ver0.5.6

Texture modding tools for UE games.
You can inject texture files (.dds, .tga, .hdr, etc.) into UE assets.
Expand Down Expand Up @@ -67,6 +66,9 @@ This tool can convert textures between the following file formats.
- ASTC_8x8
- ASTC_10x10
- ASTC_12x12
- ETC1
- ETC2_RGB
- ETC2_RGBA

</details>

Expand Down Expand Up @@ -114,13 +116,13 @@ It's the best DDS converter as far as I know.
And [Texconv-Custom-DLL](https://github.com/matyalatte/Texconv-Custom-DLL) is a cross-platform implementation I made.
The official Texconv only supports Windows but you can use it on other platforms.

### Simple-Command-Runner
### Tuw

[Simple Command Runner](https://github.com/matyalatte/Simple-Command-Runner) is a GUI wrapper for command-line tools.
[Tuw](https://github.com/matyalatte/tuw) is a GUI wrapper for command-line tools.
It can define a simple GUI with a json file.

## License

* The files in this repository (including all submodules) are available under the [MIT license](https://github.com/matyalatte/UE4-DDS-Tools/blob/main/LICENSE).
* Released packeges contain [Simple Command Runner](https://github.com/matyalatte/Simple-Command-Runner) (`GUI.exe`) for GUI. It is released under the [GPL2+](https://github.com/matyalatte/Simple-Command-Runner/blob/main/license.txt).
* Released packeges contain [Tuw](https://github.com/matyalatte/tuw) (`GUI.exe`) for GUI. It is released under the [MIT license](https://github.com/matyalatte/UE4-DDS-Tools/blob/main/LICENSE).
* Released packeges contain [Windows embeddable package](https://www.python.org/downloads/windows/) for python. It is released under the [PSF license](https://docs.python.org/3/license.html).
6 changes: 6 additions & 0 deletions docs/changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
ver 0.5.6
- Added support for ETC formats. (ETC1, ETC2_RGB, and ETC2_RGBA)
- Fixed an error when injecting texture arrays.
- Fixed an error when injecting ASTC textures.
- Updated GUI to v0.6.3

ver 0.5.5
- Supported UE5.3

Expand Down
2 changes: 1 addition & 1 deletion gui_definition.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"recommended": "0.5.1",
"recommended": "0.6.3",
"minimum_required": "0.5.0",
"gui": [
{
Expand Down
16 changes: 11 additions & 5 deletions src/directx/dds.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ class PF_FLAGS(IntEnum):

UNCANONICAL_FOURCC = [
# fourCC for uncanonical formats (ETC, PVRTC, ATITC, ASTC)
b"ETC",
b"ETC1",
b"ETC2",
b"ET2A",
b"PTC2",
b"PTC4",
b"ATC",
Expand Down Expand Up @@ -94,6 +90,15 @@ def get_dxgi(self) -> DXGI_FORMAT:
else:
return detected_dxgi

def update(self, new_dxgi):
if new_dxgi > DXGI_FORMAT.get_max_dx10():
# When dx10 doesn't support the specified dxgi format.
for cc_list, dxgi in FOURCC_TO_DXGI:
if new_dxgi == dxgi:
self.fourCC = cc_list[0]
else:
self.fourCC = b"DX10"

def is_bit_mask(self, bit_mask):
for b1, b2 in zip(self.bit_mask, bit_mask):
if b1 != b2:
Expand Down Expand Up @@ -233,7 +238,7 @@ class DX10Header(c.LittleEndianStructure):
]

def get_dxgi(self):
if self.dxgi_format > DXGI_FORMAT.get_max():
if self.dxgi_format > DXGI_FORMAT.get_max_dx10():
raise RuntimeError(f"Unsupported DXGI format detected. ({self.dxgi_format})")
return DXGI_FORMAT(self.dxgi_format)

Expand Down Expand Up @@ -365,6 +370,7 @@ def update(self, width, height, depth, mipmap_num, dxgi_format: DXGI_FORMAT, is_
self.caps = DDS_CAPS.get_caps(has_mips, is_cube)
self.caps2 = DDS_CAPS2.get_caps2(is_cube, is_3d)
self.dx10_header.update(self.dxgi_format, is_cube, is_3d, array_size)
self.pixel_format.update(self.dxgi_format)

def is_compressed(self):
return DXGI_FORMAT.is_compressed(self.dxgi_format)
Expand Down
42 changes: 27 additions & 15 deletions src/directx/dxgi_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,19 @@ class DXGI_FORMAT(IntEnum):
ASTC_12X12_TYPELESS = 185
ASTC_12X12_UNORM = 186

# only used in UE4-DDS-Tools
ETC_RGB = 1024
# ETC_RGBA = 1025 Idk if etc1 support alpha
ETC2_RGB = 1026
ETC2_RGBA = 1027

@classmethod
def is_valid_format(cls, fmt_name):
return fmt_name in cls._member_names_

@staticmethod
def get_max():
return 134
def get_max_dx10():
return DXGI_FORMAT.ASTC_12X12_UNORM

@staticmethod
def get_max_canonical():
Expand Down Expand Up @@ -179,7 +185,7 @@ def get_signed(fmt):
@staticmethod
def get_block_size(fmt):
name = fmt.name
if "BC" in name:
if "BC" in name or "ETC" in name:
return 4
if "ASTC" not in name:
return 1
Expand All @@ -197,7 +203,7 @@ def get_block_size(fmt):
@staticmethod
def is_compressed(fmt):
name = fmt.name
return "BC" in name or "ASTC" in name
return "BC" in name or "TC" in name


# Used to get the size of a mipmap
Expand Down Expand Up @@ -322,16 +328,19 @@ def is_compressed(fmt):
DXGI_FORMAT.P208: 2,
DXGI_FORMAT.V208: 2,
DXGI_FORMAT.V408: 3,
DXGI_FORMAT.ASTC_4X4_TYPELESS: 8,
DXGI_FORMAT.ASTC_4X4_UNORM: 8,
DXGI_FORMAT.ASTC_6X6_TYPELESS: 128 / 36,
DXGI_FORMAT.ASTC_6X6_UNORM: 128 / 36,
DXGI_FORMAT.ASTC_8X8_TYPELESS: 2,
DXGI_FORMAT.ASTC_8X8_UNORM: 2,
DXGI_FORMAT.ASTC_10X10_TYPELESS: 1.28,
DXGI_FORMAT.ASTC_10X10_UNORM: 1.28,
DXGI_FORMAT.ASTC_12X12_TYPELESS: 128 / 144,
DXGI_FORMAT.ASTC_12X12_UNORM: 128 / 144
DXGI_FORMAT.ASTC_4X4_TYPELESS: 1,
DXGI_FORMAT.ASTC_4X4_UNORM: 1,
DXGI_FORMAT.ASTC_6X6_TYPELESS: 128 / 288,
DXGI_FORMAT.ASTC_6X6_UNORM: 128 / 288,
DXGI_FORMAT.ASTC_8X8_TYPELESS: 0.25,
DXGI_FORMAT.ASTC_8X8_UNORM: 0.25,
DXGI_FORMAT.ASTC_10X10_TYPELESS: 0.16,
DXGI_FORMAT.ASTC_10X10_UNORM: 0.16,
DXGI_FORMAT.ASTC_12X12_TYPELESS: 128 / 1152,
DXGI_FORMAT.ASTC_12X12_UNORM: 128 / 1152,
DXGI_FORMAT.ETC_RGB: 0.5,
DXGI_FORMAT.ETC2_RGB: 0.5,
DXGI_FORMAT.ETC2_RGBA: 1,
}


Expand Down Expand Up @@ -360,7 +369,10 @@ def int_to_byte(n):
[[int_to_byte(113)], DXGI_FORMAT.R16G16B16A16_FLOAT],
[[int_to_byte(114)], DXGI_FORMAT.R32_FLOAT],
[[int_to_byte(115)], DXGI_FORMAT.R32G32_FLOAT],
[[int_to_byte(116)], DXGI_FORMAT.R32G32B32A32_FLOAT]
[[int_to_byte(116)], DXGI_FORMAT.R32G32B32A32_FLOAT],
[[b"ETC", b"ETC1"], DXGI_FORMAT.ETC_RGB],
[[b"ETC2"], DXGI_FORMAT.ETC2_RGB],
[[b"ETCA"], DXGI_FORMAT.ETC2_RGBA],
]


Expand Down
19 changes: 12 additions & 7 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from directx.dxgi_format import DXGI_FORMAT
from directx.texconv import Texconv, is_windows

TOOL_VERSION = "0.5.5"
TOOL_VERSION = "0.5.6"

# UE version: 4.0 ~ 5.3, ff7r, borderlands3
UE_VERSIONS = ["4." + str(i) for i in range(28)] + ["5." + str(i) for i in range(4)] + ["ff7r", "borderlands3"]
Expand Down Expand Up @@ -187,6 +187,9 @@ def inject(folder, file, args, texture_file=None):
if textures[0].is_empty():
src_files = [None]
else:
splitted = file_base.split("-")
if len(splitted) >= 2 and splitted[-1] == "0":
file_base = "-".join(splitted[:-1])
index2 = "-0" if textures[0].is_array or textures[0].is_3d else None
src_files = [search_texture_file(file_base, ext_list, index2=index2)]
else:
Expand All @@ -212,15 +215,16 @@ def inject(folder, file, args, texture_file=None):

if args.force_uncompressed:
tex.to_uncompressed()
elif "ASTC" in tex.dxgi_format.name:
print("Warning: DDS converter doesn't support ASTC. "
"The texture will use an uncompressed format.")
tex.to_uncompressed()

# Get a image as a DDS object
if get_ext(src) == "dds":
dds = DDS.load(src)
else:
if tex.dxgi_format > DXGI_FORMAT.get_max_canonical():
print(f"Warning: DDS converter doesn't support {tex.dxgi_format.name}. "
"The texture will use an uncompressed format.")
tex.to_uncompressed()

with get_temp_dir(disable_tempfile=args.disable_tempfile) as temp_dir:
print(f"convert: {src}")
if tex.is_array or tex.is_3d:
Expand Down Expand Up @@ -299,8 +303,9 @@ def export(folder, file, args, texture_file=None):
dds = tex.get_dds()
if args.export_as == "dds":
dds.save(file_name)
elif "ASTC" in dds.header.dxgi_format.name:
print("Warning: DDS converter doesn't support ASTC. The texture will be exported as DDS.")
elif dds.header.dxgi_format > DXGI_FORMAT.get_max_canonical():
print(f"Warning: DDS converter doesn't support {dds.header.dxgi_format.name}. "
"The texture will be exported as DDS.")
dds.save(file_name)
else:
# Convert if the export format is not DDS
Expand Down
10 changes: 8 additions & 2 deletions src/unreal/utexture.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@
"PF_ASTC_6x6": DXGI_FORMAT.ASTC_6X6_UNORM,
"PF_ASTC_8x8": DXGI_FORMAT.ASTC_8X8_UNORM,
"PF_ASTC_10x10": DXGI_FORMAT.ASTC_10X10_UNORM,
"PF_ASTC_12x12": DXGI_FORMAT.ASTC_12X12_UNORM
"PF_ASTC_12x12": DXGI_FORMAT.ASTC_12X12_UNORM,
"PF_ETC1": DXGI_FORMAT.ETC_RGB,
"PF_ETC2_RGB": DXGI_FORMAT.ETC2_RGB,
"PF_ETC2_RGBA": DXGI_FORMAT.ETC2_RGBA,
}

PF_TO_UNCOMPRESSED = {
Expand All @@ -49,7 +52,10 @@
"PF_ASTC_6x6": "PF_B8G8R8A8",
"PF_ASTC_8x8": "PF_B8G8R8A8",
"PF_ASTC_10x10": "PF_B8G8R8A8",
"PF_ASTC_12x12": "PF_B8G8R8A8"
"PF_ASTC_12x12": "PF_B8G8R8A8",
"PF_ETC1": "PF_B8G8R8A8",
"PF_ETC2_RGB": "PF_B8G8R8A8",
"PF_ETC2_RGBA": "PF_B8G8R8A8",
}


Expand Down

0 comments on commit 779a3a1

Please sign in to comment.