Skip to content

Instantly share code, notes, and snippets.

@floxay
Last active February 12, 2023 16:47
Show Gist options
  • Select an option

  • Save floxay/3f311d00dac1986f65d2aabb48b4b13f to your computer and use it in GitHub Desktop.

Select an option

Save floxay/3f311d00dac1986f65d2aabb48b4b13f to your computer and use it in GitHub Desktop.
# original:
# https://github.com/SteamDatabase/ValveResourceFormat/blob/8ff0321c9ec6f5c0d487515fc87346cd02fac949/ValveResourceFormat/ClosedCaptions/ClosedCaptions.cs
import struct
FILE_PATH = r"D:\subtitles_english.dat"
with open(FILE_PATH, "rb") as f:
magic, version = struct.unpack("<4sI", f.read(8))
if magic != b"VCCD":
raise ValueError("Invalid magic.")
if version not in (1, 2):
raise ValueError(f"Unsupported version: {version}")
block_count, block_size, directory_size, offset = struct.unpack("<4I", f.read(16))
entry_lengths_per_block = [[] for _ in range(block_count)]
for i in range(directory_size):
hash_ = struct.unpack("<I", f.read(4))
if version >= 2:
hash_text = struct.unpack("<I", f.read(4))
block_index, relative_offset, length = struct.unpack("<IHH", f.read(8))
# this allows me to only set the position of the file pointer per block
# instead of per entry, which is what the original does
entry_lengths_per_block[block_index].append(length)
with open(f"{FILE_PATH[:-4]}.txt", "w", encoding="utf-8", newline="\n") as out:
for block_index, entry_lengths in enumerate(entry_lengths_per_block):
f.seek(offset + block_index * block_size)
for entry_length in entry_lengths:
text = f.read(entry_length)[:-2]
out.write(text.decode("utf-16-le"))
out.write("\n")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment