Last active
October 1, 2025 02:21
-
-
Save uyjulian/9d25961af34ef46d9960afc4c6ac4553 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# SPDX-License-Identifier: MIT | |
# Attempting to figure out shader filenames for FDK (ED9 / Kuro no Kiseki) mdl format materials. | |
# Example: basic#3f0668ce.fxo | |
import os | |
import sys | |
import json | |
import zlib | |
def file_iter(path, ext2): | |
for dirpath, dirnames, filenames in os.walk(path): | |
for filename in filenames: | |
ext = os.path.splitext(filename)[1] | |
if ext != "" and ext.lower().endswith(ext2): | |
yield os.path.join(dirpath, filename) | |
def calc_hash(instr): | |
return zlib.crc32(instr, len(instr) ^ 0xFFFFFFFF) ^ 0xFFFFFFFF | |
shaders_all = [] | |
with open("shader_list.txt", "r") as f: | |
for l in f.readlines(): | |
strx = l.rstrip() | |
if strx != "": | |
shaders_all.append(strx) | |
matinfo_all = [] | |
for filepath in file_iter("ed6_1r_matinfo", ".json"): | |
with open(filepath, "r") as f: | |
matinfo_all.append(json.load(f)) | |
print(len(matinfo_all)) | |
def gen_variant(base, mat): | |
arr = base[:] | |
if "" in arr: | |
arr.remove("") | |
matswitches = mat["material_switches"] | |
for matswitch in mat["material_switch_order"]: | |
matswitch_append = "" | |
matswitch_val = matswitches[matswitch] | |
if matswitch_val != 0xFFFFFFFF and matswitch_val >= 0x80000000: | |
raise Exception("Out of range value not yet implemented") | |
if matswitch_val != 0xFFFFFFFF: | |
matswitch_append = " %d" % matswitch_val | |
arr.append(matswitch + matswitch_append) | |
return arr | |
shader_dic = {} | |
shader_variant_dic = {} | |
for matinfo in matinfo_all: | |
for mat in matinfo: | |
shader_name = mat["shader_name"] | |
str3 = mat["str3"] | |
if shader_name != str3: | |
raise Exception("shader name not equal to str3") | |
unk_int3 = mat["unk_int3"] | |
# has_shadow = (unk_int3 & 1) != 0 | |
has_shadow = True | |
variants_list = [] | |
for i in range(2): | |
# is_tesselation = "" | |
# if (unk_int3 & 0x20) != 0: | |
# is_tesselation = "BUILD_TESSELLATION" | |
is_tesselation = "" | |
if i == 1: | |
is_tesselation = "BUILD_TESSELLATION" | |
variants_list.append(gen_variant(["COMPILE_VS", is_tesselation], mat)) | |
variants_list.append(gen_variant(["COMPILE_VS", is_tesselation, "BUILD_SKIN"], mat)) | |
if has_shadow: | |
variants_list.append(gen_variant(["COMPILE_VS", "BUILD_SHADOW", is_tesselation], mat)) | |
variants_list.append(gen_variant(["COMPILE_VS", "BUILD_SHADOW", is_tesselation, "BUILD_SKIN"], mat)) | |
variants_list.append(gen_variant(["COMPILE_VS", is_tesselation, "BUILD_TRANSPARENT"], mat)) | |
variants_list.append(gen_variant(["COMPILE_VS", is_tesselation, "BUILD_SKIN", "BUILD_TRANSPARENT"], mat)) | |
variants_list.append(gen_variant(["COMPILE_HS", is_tesselation], mat)) | |
if has_shadow: | |
variants_list.append(gen_variant(["COMPILE_HS", "BUILD_SHADOW", is_tesselation], mat)) | |
variants_list.append(gen_variant(["COMPILE_HS", is_tesselation, "BUILD_TRANSPARENT"], mat)) | |
variants_list.append(gen_variant(["COMPILE_DS", is_tesselation], mat)) | |
if has_shadow: | |
variants_list.append(gen_variant(["COMPILE_DS", "BUILD_SHADOW", is_tesselation], mat)) | |
variants_list.append(gen_variant(["COMPILE_DS", is_tesselation, "BUILD_TRANSPARENT"], mat)) | |
variants_list.append(gen_variant(["COMPILE_PS", is_tesselation], mat)) | |
if has_shadow: | |
variants_list.append(gen_variant(["COMPILE_PS", "BUILD_SHADOW", is_tesselation], mat)) | |
variants_list.append(gen_variant(["COMPILE_PS", is_tesselation], mat)) | |
for variant in variants_list: | |
shader_file_name = "%s#%08x.fxo" % (str3, calc_hash("".join(variant).encode("ASCII"))) | |
if shader_file_name not in shader_dic: | |
shader_dic[shader_file_name] = shader_file_name in shaders_all | |
if shader_dic[shader_file_name]: | |
shader_variant_dic[shader_file_name] = variant | |
true_has_count = 0 | |
false_has_count = 0 | |
for x in shader_dic: | |
if shader_dic[x]: | |
true_has_count += 1 | |
else: | |
false_has_count += 1 | |
print(true_has_count, false_has_count) | |
missingx = [] | |
true_hit_count = 0 | |
false_hit_count = 0 | |
for x in shaders_all: | |
if x in shader_dic: | |
true_hit_count += 1 | |
else: | |
missingx.append(x) | |
false_hit_count += 1 | |
print(true_hit_count, false_hit_count) | |
with open("missingx.txt", "w") as f: | |
for x in missingx: | |
f.write(x + "\n") | |
jsondata = json.dumps(shader_variant_dic, indent=4).encode("utf-8") | |
with open("variants.json", "wb") as f: | |
f.write(jsondata) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment