# Final Fantasy VII Snowboard TMD (Playstation TMD) to OBJ by Maki ([email protected])
# Made @ 01.07.2019
# version 0.1
#Based on structure by http://wiki.xentax.com/index.php/Playstation_TMD
import sys
import struct
filename = "for_ev.tmd" #change that for other
outfilename = "for_ev.obj" #change that also
def ReadInt():
return struct.unpack("<I", fd.read(4))[0]
def GetVertices(pVert, nVert):
vertices = []
fd.seek(pVert, 0)
for n in range(0, nVert):
x = struct.unpack('<h', fd.read(2))[0]
y = struct.unpack('<h', fd.read(2))[0]
z = struct.unpack('<h', fd.read(2))[0]
w = struct.unpack('<h', fd.read(2))[0]
vertices += [[x,y,z]]
return vertices
def GetPolygons(pPrim, nPrim):
polygons = []
fd.seek(pPrim, 0)
for n in range(0, nPrim):
modeVariable = struct.unpack('<I', fd.read(4))[0]
if(modeVariable != 0x31010506):
print('unknown mode at: ' + str(fd.tell()))
return []
fd.seek(12,1) # unknown, UV?
A = struct.unpack('<H', fd.read(2))[0]
B = struct.unpack('<H', fd.read(2))[0]
C = struct.unpack('<H', fd.read(2))[0]
polygons += [[A,B,C]]
fd.seek(2,1)
return polygons
fd = open(filename,"rb")
if(fd==None):
print("cannot open file. Exiting")
exit()
if(ReadInt() != 0x41):
print("tmd version is not 0x41")
exit()
fd.seek(4,1) # we don't really care for flags here. It's always 0
objCount = ReadInt()
#Main arrays
pVerts = []
nVerts = []
pNorms = []
nNorms = []
pPrims = []
nPrims = []
#Step 1- Gather info about every single object to arrays
for i in range(0,objCount):
pVerts += [ReadInt()]
nVerts += [ReadInt()]
pNorms += [ReadInt()]
nNorms += [ReadInt()]
pPrims += [ReadInt()]
nPrims += [ReadInt()]
print("===Object: {}===\nVertices: {}\tPointer: {}\nNormals: {}\tPointer: {}\nPrims: {}\tPointer: {}\nScale: {}".format(i, nVerts[i], pVerts[i], nNorms[i], pNorms[i], nPrims[i], pPrims[i], ReadInt()))
#Step 2- Process gathered data
for i in range(0,objCount):
vertices = GetVertices(pVerts[i]+12, nVerts[i])
fda = open('obj{}.obj'.format(i), 'wt')
for n in vertices:
fda.write("v {} {} {}\n".format(n[0], -n[1], n[2]))
polygons = GetPolygons(pPrims[i]+12, nPrims[i])
for n in polygons:
fda.write("f {} {} {}\n".format(n[0]+1,n[1]+1,n[2]+1))
fda.close()
short X;
short -Y;
short Z;
short W; //unused
0x06050131 //polygon type const. Probably that means triangle and the other unknown one is quad, but that's just assumption
char unk[12] //unkown, I'm missing three UVs, but what are other values?
ushort A;
ushort B;
ushort C;
ushort pad; //maybe a place for D?
0x80808000 //const?
ushort A; //untested
ushort B; //untested
ushort C; //untested
ushort PAD;
char unk[16]; //not sure
0x007321D7
cmp dword ptr [ebp-0C],0x54
Change it to NOPs6 90sTherefore 6 times 0x90 (NOP) works on opcode 0x007321D7