Author Topic: [FFVII] Snowboard Progress  (Read 4001 times)


  • *
  • Posts: 282
  • Maktub
    • View Profile
    • Behemoth Productions
[FFVII] Snowboard Progress
« on: 2019-06-17 17:31:07 »
Snowboard Minigame modding scene progress by Maki.

Cheers Qhimm community.
« Last Edit: 2019-07-01 20:19:23 by Kuraudo. »


  • *
  • Posts: 282
  • Maktub
    • View Profile
    • Behemoth Productions
Re: [FFVII] Snowboard?
« Reply #1 on: 2019-06-18 06:35:13 »
Spoiler: show
Doing a little research:

Kaldarasha was in touch with MaKiPL, some updates here.

Any progress?

« Last Edit: 2019-07-01 20:20:17 by Kuraudo. »


  • 0xBAADF00D
  • *
  • Posts: 613
    • View Profile
Re: [FFVII] Snowboard?
« Reply #2 on: 2019-07-01 16:35:29 »

Code: [Select]
# Final Fantasy VII Snowboard TMD (Playstation TMD) to OBJ by Maki ([email protected])
# Made @ 01.07.2019
# version 0.1

#Based on structure by

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",[0]

def GetVertices(pVert, nVert):
    vertices = [], 0)
    for n in range(0, nVert):
        x = struct.unpack('<h',[0]
        y = struct.unpack('<h',[0]
        z = struct.unpack('<h',[0]
        w = struct.unpack('<h',[0]
        vertices += [[x,y,z]]
    return vertices

def GetPolygons(pPrim, nPrim):
    polygons = [], 0)

    for n in range(0, nPrim):
        modeVariable = struct.unpack('<I',[0]
        if(modeVariable != 0x31010506):
            print('unknown mode at: ' + str(fd.tell()))
            return [],1) # unknown, UV?
        A = struct.unpack('<H',[0]
        B = struct.unpack('<H',[0]
        C = struct.unpack('<H',[0]
        polygons += [[A,B,C]],1)
    return polygons


fd = open(filename,"rb")
    print("cannot open file. Exiting")
if(ReadInt() != 0x41):
    print("tmd version is not 0x41")
    exit(),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))

This for 0.1 version. Looks like for_gs.tmd and for_en.tmd have the same data (huh??)
I'll be digging for UVs and thankfully for reimport. Should be easy

Vertices (as in TMD):
Code: [Select]
short X;
short -Y;
short Z;
short W; //unused

Polygon type A:
Code: [Select]
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?

Polygon type B:
Code: [Select]
0x80808000 //const?
ushort A; //untested
ushort B; //untested
ushort C; //untested
ushort PAD;
char unk[16]; //not sure
« Last Edit: 2019-07-01 16:44:46 by Maki »


  • *
  • Posts: 282
  • Maktub
    • View Profile
    • Behemoth Productions
Re: [FFVII] Snowboard Progress
« Reply #3 on: 2019-07-01 20:21:11 »
Just Brilliant. Are there Cid and Tifa's model too?


  • *
  • Posts: 282
  • Maktub
    • View Profile
    • Behemoth Productions
Re: [FFVII] Snowboard Progress
« Reply #4 on: 2020-07-03 06:16:55 »
So, just to update you all and for the sake of keeping track of any progress done and what has to be done:

That's a pre-release tool by Maki:

However, as per Kaldarasha we are missing the skeleton info.

Kaldarasha: "I need also the skeleton info, and a way to modify it. Best would be if the pieces are seen at the skeleton as on kimera. Even if there would be a limit for the tris I could make a stretched recolor of the default model. The final touch would be to edit the animations to adjust the models hight."
Maki: "There's no skeleton info in TMD file, every chunk/object like Clouds right arm is just a model without anything else, there's no animation data inside the .TMD files"
TrueOdin was suggesting: "Something I would do personally for this topic is to start the game in RenderDoc, get to the minigame and catch several frames.
Afterwards analyze the various draw call for each frame and try to find out how the engine is passing the information.
Once it's clear what the engine it's passing, the first step it's to find those models that are being passed and try to reassemble them"

So that's where we stand at with snowboard modding scene so far.