mirror of
https://github.com/OpenFusionProject/scripts.git
synced 2024-11-22 14:10:04 +00:00
Compare commits
No commits in common. "7b750db9f95f0f6d52027198c44e164f0508970e" and "d0e67d55c9547e23eea1fa75069ef845ed684922" have entirely different histories.
7b750db9f9
...
d0e67d55c9
@ -6,6 +6,6 @@ Tools for converting d3d9 shader assembly to HLSL/Cg.
|
|||||||
|
|
||||||
## Known issues
|
## Known issues
|
||||||
- Only vertex shaders with profile `vs_1_1` are supported
|
- Only vertex shaders with profile `vs_1_1` are supported
|
||||||
- Only fragment shaders with profile `ps_2_0` are supported
|
- No fragment shaders are supported yet
|
||||||
|
- Only one subprogram in a subshader will be converted (for now)
|
||||||
- Only a limited set of instructions (those used by FF and Unity 2.6) are supported
|
- Only a limited set of instructions (those used by FF and Unity 2.6) are supported
|
||||||
- Properties that don't begin with an underscore do not get captured as locals
|
|
||||||
|
@ -30,7 +30,7 @@ reserved = {
|
|||||||
|
|
||||||
decls = {
|
decls = {
|
||||||
"dcl_position": "float4 {0} = vdat.vertex;",
|
"dcl_position": "float4 {0} = vdat.vertex;",
|
||||||
"dcl_normal": "float4 {0} = float4(vdat.normal, 0);",
|
"dcl_normal": "float4 {0} = float4(vdat.normal.x, vdat.normal.y, vdat.normal.z, 0);",
|
||||||
"dcl_texcoord0": "float4 {0} = vdat.texcoord;",
|
"dcl_texcoord0": "float4 {0} = vdat.texcoord;",
|
||||||
"dcl_texcoord1": "float4 {0} = vdat.texcoord1;",
|
"dcl_texcoord1": "float4 {0} = vdat.texcoord1;",
|
||||||
"dcl_color": "float4 {0} = vdat.color;",
|
"dcl_color": "float4 {0} = vdat.color;",
|
||||||
@ -53,7 +53,7 @@ ops = {
|
|||||||
"slt": "{0} = float4(({1}.x < {2}.x) ? 1.0f : 0.0f, ({1}.y < {2}.y) ? 1.0f : 0.0f, ({1}.z < {2}.z) ? 1.0f : 0.0f, ({1}.w < {2}.w) ? 1.0f : 0.0f);",
|
"slt": "{0} = float4(({1}.x < {2}.x) ? 1.0f : 0.0f, ({1}.y < {2}.y) ? 1.0f : 0.0f, ({1}.z < {2}.z) ? 1.0f : 0.0f, ({1}.w < {2}.w) ? 1.0f : 0.0f);",
|
||||||
"sge": "{0} = float4(({1}.x >= {2}.x) ? 1.0f : 0.0f, ({1}.y >= {2}.y) ? 1.0f : 0.0f, ({1}.z >= {2}.z) ? 1.0f : 0.0f, ({1}.w >= {2}.w) ? 1.0f : 0.0f);",
|
"sge": "{0} = float4(({1}.x >= {2}.x) ? 1.0f : 0.0f, ({1}.y >= {2}.y) ? 1.0f : 0.0f, ({1}.z >= {2}.z) ? 1.0f : 0.0f, ({1}.w >= {2}.w) ? 1.0f : 0.0f);",
|
||||||
"rcp": "{0} = ({1} == 0.0f) ? FLT_MAX : (({1} == 1.0f) ? {1} : (1 / {1}));",
|
"rcp": "{0} = ({1} == 0.0f) ? FLT_MAX : (({1} == 1.0f) ? {1} : (1 / {1}));",
|
||||||
"texld": "{0} = tex2D({2}, (float2){1});",
|
"texld": "{0} = tex2D({2}, {1});",
|
||||||
}
|
}
|
||||||
|
|
||||||
struct_a2v = """struct a2v {
|
struct_a2v = """struct a2v {
|
||||||
@ -80,7 +80,7 @@ struct_v2f = f"""struct v2f {{
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
struct_f2a = """struct f2a {
|
struct_f2a = """struct f2a {
|
||||||
\tfloat4 c0 : COLOR0;
|
\tfloat4 c0;
|
||||||
};
|
};
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -102,19 +102,20 @@ vertex_func = """v2f vert(a2v vdat) {{
|
|||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
fragment_func = """f2a frag(v2f pdat) {{
|
fragment_func = """float4 frag(v2f pdat) {{
|
||||||
\tfloat4 r0, r1, r2, r3, r4;
|
\tfloat4 r0, r1, r2, r3, r4;
|
||||||
\tfloat4 tmp;
|
\tfloat4 tmp;
|
||||||
\tf2a o;
|
\tf2a o;
|
||||||
|
|
||||||
{0}
|
{0}
|
||||||
|
|
||||||
\treturn o;
|
\treturn o.c0;
|
||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def process_header(prog):
|
def process_header(prog):
|
||||||
keywords = []
|
keywords = []
|
||||||
|
header = []
|
||||||
loctab = {}
|
loctab = {}
|
||||||
locdecl = []
|
locdecl = []
|
||||||
binds = []
|
binds = []
|
||||||
@ -154,11 +155,6 @@ def process_header(prog):
|
|||||||
if lightval:
|
if lightval:
|
||||||
val = f"glstate.light[{lightval[1]}].{lightval[2]}"
|
val = f"glstate.light[{lightval[1]}].{lightval[2]}"
|
||||||
lighting = True
|
lighting = True
|
||||||
elif val == "_ObjectSpaceCameraPos" and not legacy:
|
|
||||||
val = "mul(_World2Object, float4(_WorldSpaceCameraPos, 1.0f))"
|
|
||||||
elif val == "_ObjectSpaceLightPos0" and not legacy:
|
|
||||||
val = "mul(_World2Object, _WorldSpaceLightPos0)"
|
|
||||||
lighting = True
|
|
||||||
elif val == "glstate_lightmodel_ambient":
|
elif val == "glstate_lightmodel_ambient":
|
||||||
val = "glstate.lightmodel.ambient"
|
val = "glstate.lightmodel.ambient"
|
||||||
lighting = True
|
lighting = True
|
||||||
@ -197,9 +193,18 @@ def process_header(prog):
|
|||||||
i = i - 1
|
i = i - 1
|
||||||
i = i + 1
|
i = i + 1
|
||||||
|
|
||||||
|
if len(binds) > 0:
|
||||||
|
header.append("BindChannels {")
|
||||||
|
for b in binds:
|
||||||
|
header.append(f"\t{b}")
|
||||||
|
header.append("}")
|
||||||
|
|
||||||
|
if lighting:
|
||||||
|
header.append("Lighting On")
|
||||||
|
|
||||||
# print(loctab)
|
# print(loctab)
|
||||||
|
|
||||||
return (keywords, loctab, locdecl, binds, lighting)
|
return (keywords, header, loctab, locdecl)
|
||||||
|
|
||||||
def resolve_args(args, loctab, consts):
|
def resolve_args(args, loctab, consts):
|
||||||
for a in range(0, len(args)):
|
for a in range(0, len(args)):
|
||||||
@ -301,52 +306,28 @@ def process_asm(asm, loctab):
|
|||||||
|
|
||||||
return (shadertype, translated)
|
return (shadertype, translated)
|
||||||
|
|
||||||
def disassemble(blocks):
|
def disassemble(text):
|
||||||
shaders = {}
|
asm = text.split('\n')[1:-1]
|
||||||
keywords = set()
|
(keywords, header, loctab, locdecl) = process_header(asm)
|
||||||
locdecl = set()
|
(shadertype, disasm) = process_asm(asm, loctab)
|
||||||
binds = set()
|
|
||||||
lighting = False
|
|
||||||
for block in blocks:
|
|
||||||
asm = block.split('\n')[1:-1]
|
|
||||||
|
|
||||||
(kw, ltab, ldecl, bds, light) = process_header(asm)
|
|
||||||
keywords.update(kw)
|
|
||||||
locdecl.update(ldecl)
|
|
||||||
binds.update(bds)
|
|
||||||
lighting |= light
|
|
||||||
|
|
||||||
(shadertype, disasm) = process_asm(asm, ltab)
|
|
||||||
shaders[shadertype] = disasm
|
|
||||||
|
|
||||||
text = ""
|
|
||||||
if len(binds) > 0:
|
|
||||||
text += "BindChannels {\n"
|
|
||||||
for b in binds:
|
|
||||||
text += f"\t{b}\n"
|
|
||||||
text += "}\n"
|
|
||||||
|
|
||||||
if lighting:
|
|
||||||
text += "Lighting On\n"
|
|
||||||
|
|
||||||
|
text = "\n".join(header) + "\n" if len(header) > 0 else ""
|
||||||
text += cg_header
|
text += cg_header
|
||||||
if len(keywords) > 0:
|
if keywords:
|
||||||
text += "#pragma multi_compile " + " ".join(keywords)
|
text += "#pragma multi_compile " + " ".join(keywords)
|
||||||
if "vertex" in shaders:
|
if shadertype == "vertex":
|
||||||
text += "#pragma vertex vert\n"
|
text += "#pragma vertex vert\n"
|
||||||
if "fragment" in shaders:
|
if shadertype == "fragment":
|
||||||
text += "#pragma fragment frag\n"
|
text += "#pragma fragment frag\n"
|
||||||
text += "\n"
|
text += "\n"
|
||||||
if "vertex" in shaders:
|
|
||||||
text += struct_a2v + "\n"
|
text += struct_a2v + "\n"
|
||||||
text += struct_v2f + "\n"
|
text += struct_v2f + "\n"
|
||||||
if "fragment" in shaders:
|
|
||||||
text += struct_f2a + "\n"
|
text += struct_f2a + "\n"
|
||||||
text += "\n".join(locdecl) + "\n"
|
text += "\n".join(locdecl) + "\n"
|
||||||
if "vertex" in shaders:
|
if shadertype == "vertex":
|
||||||
text += "\n" + vertex_func.format("\t" + "\n\t".join(shaders["vertex"]))
|
text += vertex_func.format("\t" + "\n\t".join(disasm))
|
||||||
if "fragment" in shaders:
|
if shadertype == "fragment":
|
||||||
text += "\n" + fragment_func.format("\t" + "\n\t".join(shaders["fragment"]))
|
text += fragment_func.format("\t" + "\n\t".join(disasm))
|
||||||
text += cg_footer
|
text += cg_footer
|
||||||
return text
|
return text
|
||||||
|
|
||||||
@ -356,5 +337,5 @@ if __name__ == "__main__":
|
|||||||
else:
|
else:
|
||||||
with open(sys.argv[1], "r") as fi:
|
with open(sys.argv[1], "r") as fi:
|
||||||
buf = fi.read()
|
buf = fi.read()
|
||||||
disasm = disassemble(buf.split('~'))
|
disasm = disassemble(buf)
|
||||||
print(disasm)
|
print(disasm)
|
||||||
|
@ -27,24 +27,18 @@ def find_closing_bracket(block, i):
|
|||||||
raise ValueError(f"Block at {i} has no closing bracket")
|
raise ValueError(f"Block at {i} has no closing bracket")
|
||||||
|
|
||||||
def process_program(prog):
|
def process_program(prog):
|
||||||
# print("processing:\n" + prog)
|
|
||||||
subprogs = []
|
|
||||||
subprog_index = prog.find("SubProgram \"d3d9")
|
subprog_index = prog.find("SubProgram \"d3d9")
|
||||||
while subprog_index > -1:
|
if subprog_index == -1:
|
||||||
|
raise ValueError(f"Program has no d3d9 subprogram")
|
||||||
subprog_end_index = find_closing_bracket(prog, subprog_index)
|
subprog_end_index = find_closing_bracket(prog, subprog_index)
|
||||||
subprog = prog[subprog_index:subprog_end_index+1]
|
subprog = prog[subprog_index:subprog_end_index+1]
|
||||||
subprogs.append(subprog)
|
processed = disassemble(subprog) + "\n"
|
||||||
prog = prog[subprog_end_index+1:]
|
|
||||||
subprog_index = prog.find("SubProgram \"d3d9")
|
|
||||||
if len(subprogs) < 1:
|
|
||||||
raise ValueError(f"Program has no d3d9 subprograms")
|
|
||||||
processed = disassemble(subprogs) + "\n"
|
|
||||||
return indent(processed)
|
return indent(processed)
|
||||||
|
|
||||||
def process_shader(shader):
|
def process_shader(shader):
|
||||||
buf = shader
|
buf = shader
|
||||||
processed = ''
|
processed = ''
|
||||||
program_index = buf.find("Program \"\"")
|
program_index = buf.find('Program')
|
||||||
while program_index > -1:
|
while program_index > -1:
|
||||||
processed = processed + buf[:program_index]
|
processed = processed + buf[:program_index]
|
||||||
buf = buf[program_index:]
|
buf = buf[program_index:]
|
||||||
@ -52,11 +46,11 @@ def process_shader(shader):
|
|||||||
if not line:
|
if not line:
|
||||||
raise ValueError(f"Program at {program_index} has no #LINE marker")
|
raise ValueError(f"Program at {program_index} has no #LINE marker")
|
||||||
end_index = line.end() + 1
|
end_index = line.end() + 1
|
||||||
program_section = buf[:end_index+1]
|
program_section = buf[program_index:end_index+1]
|
||||||
processed = processed + process_program(program_section)
|
processed = processed + process_program(program_section)
|
||||||
buf = buf[end_index+1:]
|
buf = buf[end_index+1:]
|
||||||
|
|
||||||
program_index = buf.find("Program \"\"")
|
program_index = buf.find('Program')
|
||||||
processed = processed + buf
|
processed = processed + buf
|
||||||
return processed
|
return processed
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user