clearlistener ()
fsource = "D:\\_DLCREPACK\\UNPACK\\KASUMI_DLC_006.TMC"
fsource = ("D:\\DOA5JtagRip_Boobooman\\DOA5JtagRip_Boobooman\\"+\
"Dead_or_Alive_5\\chara_common\\_Dump\\_Dump\\AYANE_COS_005.TMC")
fsource = GetOpenFileName \
caption:"Select TMC File" \
types: "Tecmo Memory Catelog(*.tmc)|*.TMC|All files (*.*)|*.*|"
if (fsource!=undefined) then (
fpath=getFilenamePath fsource
fname=getFilenameFile fsource
fsize=getFileSize fsource
lsource = (fpath+fname+".TMCL")
if ((doesFileExist fsource)==false) do (
lsource = GetOpenFileName \
caption:"Select TMCL File" \
types: "Tecmo Memory Catelog Load(*.tmcl)|*.TMCL|All files (*.*)|*.*|")
if (lsource!=undefined) AND ((doesFileExist fsource)==true) then (
printTex = false
printMat = true
buildMsh = true
drawp = true
dumpDDS = true
dumpXPR = false
model_scale = 100
-- obj = $*;delete obj
f = fopen fsource "rb"
l = fopen lsource "rb"
GLOBAL dataArray = #()
struct TMC (filename,id,offset)
-- struct MdlGeo ()
struct ObjGeo (name,GeoDecl,modeldata)
-- struct TTX ()
struct VtxLay (offset)
struct IdxLay (offset)
-- struct MtrCol ()
-- struct MdlInfo ()
-- struct HieLay ()
struct LHeader (offset,size)
-- struct NodeLay ()
-- struct GlblMtx ()
-- struct BnOfsMtx ()
-- struct cpf ()
-- struct MCAPACK ()
struct MCAPARAM (ukn1)
-- struct ACSCLS ()
struct bone_data (obj,name,matrix,parent,children)
struct entry (tag,flags,size,adr,data,offsets,sizes,children)
struct mesh_data (subobj_index,vertex_start,face_start,vertex_stride,vertex_type,vertex_counts,face_counts)
struct xpr2_entry (magic,offset,size,string_offset,string)
struct tx2d_entry (ukn01,ukn02,ukn03,ukn04,ukn05,ukn06,ukn07,ukn08,ukn09, \
ukn10,ukn11,ukn12,ukn13,ukn14,ukn15,ukn16,ukn17,ukn18,ukn19)
fn Get_TMCSUBBLOCK id= (
case id of (
0x80000001: #MdlGeo -- Mesh Info
0x80000002: #TTX -- Texture Info (XPR2 Header)
0x80000003: #VtxLay -- Vertex Buffer Info
0x80000004: #IdxLay -- Index Buffer Info
0x80000005: #MtrCol -- Material Colours?
0x80000006: #MdlInfo --
0x80000010: #HieLay -- Bone Hierarchy
0x80000020: #LHeader -- L File Header
0x80000030: #NodeLay -- Bone Names
0x80000040: #GlblMtx --
0x80000050: #BnOfsMtx --
0x80000060: #cpf --
0x80000070: #MCAPACK --
0x80000080: #RENPACK --
0x00000001: #GEOXTRAS --
0x00000002: #ACSCLS -- ACSCLS, render and hide flags?
default: #UNKNOWN
)
)
fn Get_D3DDECLUSAGE id= (
case id of (
--Position data
0x00: #POSITION
--Blending weight data
0x01: #BLENDWEIGHT
--Blending indices data
0x02: #BLENDINDICES
--Vertex normal data
0x03: #NORMAL
--Point size data
0x04: #PSIZE
--Texture coordinate data
0x05: #TEXCOORD
--Vertex tangent data.
0x06: #TANGENT
--Vertex binormal data.
0x07: #BINORMAL
--Tessellation factor (Single positive floating point value)
0x08: #TESSFACTOR
--Vertex data contains transformed position data
0x09: #POSITIONT
--Vertex data contains diffuse or specular color
0x0A: #COLOUR
--Vertex data contains fog data
0x0B: #FOG
--Vertex data contains depth data.
0x0C: #DEPTH
--Vertex data contains sampler data
0x0D: #SAMPLE
default: #UNKNOWN
)
)
fn Get_D3DDECLTYPE id= (
case id of (
0x00: #FLOAT1
0x01: #FLOAT2
0x02: #FLOAT3
0x03: #FLOAT4
0x04: #INT1
0x05: #INT2
0x06: #INT4
0x07: #UINT1
0x08: #UINT2
0x09: #UINT4
0x0A: #UINT1N
0x0B: #UINT2N
0x0C: #UINT4N
0x0D: #D3DCOLOR
0x0E: #UBYTE4
0x0F: #UINT4N
0x10: #D3DCOLOR
0x11: #UBYTE4
0x12: #BYTE4
0x13: #UBYTE4N
0x14: #BYTE4N
0x15: #SHORT2
0x16: #SHORT4
0x17: #USHORT2
0x18: #USHORT4
0x19: #SHORT2N
0x1A: #SHORT4N
0x1B: #USHORT2N
0x1C: #USHORT4N
0x1D: #UDEC3
0x1E: #DEC3
0x1F: #UDEC3N
0x20: #DEC3N
0x21: #UDEC4
0x22: #DEC4
0x23: #UDEC4N
0x24: #DEC4N
0x25: #UHEND3
0x26: #HEND3
0x27: #UHEND3N
0x28: #HEND3N
0x29: #UDHEN3
0x2A: #DHEN3
0x2B: #UDHEN3N
0x2C: #DDECLTYPE_DHEN3N
0x2D: #FLOAT16_2
0x2E: #FLOAT16_4
0x2F: #UNUSED
default: #UNKNOWN
)
)
xpr2entry = (xpr2_entry magic:#() offset:#() size:#() string_offset:#() string:#())
tx2dentry = (tx2d_entry ukn01:#() ukn02:#() ukn03:#() ukn04:#() ukn05:#() \
ukn06:#() ukn07:#() ukn08:#() ukn09:#() ukn10:#() ukn11:#() ukn12:#() \
ukn13:#() ukn14:#() ukn15:#() ukn16:#() ukn17:#() ukn18:#() ukn19:#())
boneArray = (bone_data obj:#() name:#() matrix:#() parent:#() children:#())
tmclBuffer = (LHeader offset:#() size:#())
objArray = (ObjGeo name:#() GeoDecl:#() modeldata:#())
VtxLayArray = (VtxLay offset:#())
IdxLayArray = (IdxLay offset:#())
MCAPARAMARRAY = (MCAPARAM ukn1:#())
fn readBElong fstream = (bit.swapBytes (bit.swapBytes (readlong fstream #unsigned) 1 4) 2 3)
fn readBEshort fstream = (bit.swapBytes (readshort fstream #unsigned) 1 2)
fn readBEtriplet fstream = (((readbyte f #unsigned)*0x00010000)+((readbyte f #unsigned)*0x00000100)+((readbyte f #unsigned)*0x00000001))
fn ReadBE_HEND3N fstream = (
nz=(bit.swapBytes (readshort fstream #unsigned) 1 2)
fseek fstream -1 #seek_cur
ny=(bit.swapBytes (readshort fstream #unsigned) 1 2)
fseek fstream -1 #seek_cur
nx=(bit.swapBytes (readshort fstream #unsigned) 1 2)
-- [11,11,10] Signed
nx=bit.shift nx -5
ny=bit.shift (bit.set (bit.set ny 15 false) 16 false) -3
nz=bit.set (bit.set (bit.set (bit.set (bit.set nz 12 false) 13 false) 14 false) 15 false) 16 false
if nx>=1023 do nx-=2048
if ny>=1023 do ny-=2048
if nz>=511 do nz-=1024
nx=nx/1023.0
ny=ny/1023.0
nz=nz/511.0
return (normalize [nx,-nz,ny])
)
fn ReadBEfloat fstream = (
bit.intAsFloat (bit.swapBytes (bit.swapBytes (readlong fstream #unsigned) 1 4) 2 3)
)
fn readBEHalfFloat fstream = (
hf=bit.swapBytes (readshort fstream #unsigned) 1 2
sign = bit.get hf 16
exponent = (bit.shift (bit.and hf (bit.hexasint "7C00")) -10) as integer - 16
fraction = bit.and hf (bit.hexasint "03FF")
if sign==true then sign = 1 else sign = 0
exponentF = exponent + 127
outputAsFloat = bit.or (bit.or (bit.shift fraction 13) \
(bit.shift exponentF 23)) (bit.shift sign 31)
return bit.intasfloat outputasfloat*2)
fn readcol fstream = (
color ((readBEfloat fstream)*255) \
((readBEfloat fstream)*255) \
((readBEfloat fstream)*255) \
((readBEfloat fstream)*255)
)
fn writeBEshort fstream num = (
writeshort fstream (bit.swapBytes num 1 2) #unsigned)
fn writeBEtriplet fstream num = (
v1=num/0x01
v2=num/0x0100
v3=num/0x010000
v4=num/0x01000000
-- writebyte fstream (v4) #unsigned
writebyte fstream (v3-(v4*0x100)) #unsigned
writebyte fstream (v2-(v3*0x100)) #unsigned
writebyte fstream (v1-(v2*0x100)) #unsigned
)
fn writeBElong fstream num = (
writelong fstream (bit.swapBytes (bit.swapBytes (num) 1 4) 2 3) #unsigned)
fn ReadFixedString bstream fixedLen = (
local str = ""
for i = 1 to fixedLen do (
str += bit.intAsChar (ReadByte bstream #unsigned))
str
)
fn getpadding num alignment = ((mod (alignment-(mod num alignment)) alignment))
fn paddstring len instring = (
instring=instring as string
local str="";if instring.count <=len then(
for i = 1 to (len-instring.count) do(str+="0")
str = (str+instring))else(
for i = 1 to len do(str+="0";str[i]=instring[i]));str)
fn uppercase instring = (
local upper, lower, outstring
upper="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
lower="abcdefghijklmnopqrstuvwxyz"
outstring=copy instring
for i=1 to outstring.count do (
j=findString lower outstring[i]
if (j != undefined) do outstring[i]=upper[j])
outstring)
fn printblockpos bname badr = (
str=((bit.intAsHex badr)as string)
if str[str.count]=="L" do(str = substring str 1 (str.count-1))
format "% @ 0xDD%\n" bname (paddstring 6 (uppercase str))
)
fn decodedimension long = (
texW=0
texH=0
texD=0
texV=0
for i = 1 to 12 do (
texW = bit.set texW i (bit.get long i)
)
texW+=1
for i = 14 to 26 do (
texH = bit.set texH (i-13) (bit.get long i)
)
texH+=1
for i = 27 to 32 do (
texD = bit.set texD (i-26) (bit.get long i)
)
texD+=1
IF ((bit.get (texW-1) 12)==true) \
AND ((bit.get (texH-1) 10)==true)
THEN (
texV=1
texW=(1+(bit.set (texW-1) 12 false))
texH=(1+(bit.set (texH-1) 10 false))*4
-- format "image: % x % x % *Morphable\n"texW texH texD
)
ELSE (
-- format "image: % x % x %\n"texW texH texD
)
return [texW,texH,texD,texV]
)
fn writeDDSheader fstream texW texH texM texC = (
texP=0
writelong fstream 0x20534444 #unsigned -- File ID
writelong fstream 0x7C #unsigned -- Header Size
case of( -- dwFlags
(texC=="DXT1"): (writelong fstream 0x00081007 #unsigned;texP=((texW*texH)/0x02))
(texC=="DXT3"): (writelong fstream 0x00081007 #unsigned;texP=(texW*texH))
(texC=="DXT5"): (writelong fstream 0x00081007 #unsigned;texP=(texW*texH))
(texC=="ATI1"): (writelong fstream 0x000A1007 #unsigned;texP=((texW*texH)/0x20))
(texC=="ATI2"): (writelong fstream 0x000A1007 #unsigned;texP=(texW*texH))
(texC=="P8"): (writelong fstream 0x000A1007 #unsigned;texP=((texW*texH)/0x02))
(texC=="ARGB16"): (writelong fstream 0x00081007 #unsigned;texP=(((texW*texH)/0x8)*0x10))
(texC=="ARBG32"): (writelong fstream 0x00081007 #unsigned;texP=(((texW*texH)/0x4)*0x10)))
writelong fstream texW #unsigned -- Texture Width
writelong fstream texH #unsigned -- Texture Height
writelong fstream texP #unsigned -- Pitch (#of bytes in a single row across the texture)
writelong fstream 0x00 #unsigned -- Image Depth? Not Used, for Image Volume
writelong fstream texM #unsigned -- Texture MIP Count
for i = 1 to 11 do writelong fstream 0x00 #unsigned -- Reserved Space
writelong fstream 0x20 #unsigned -- Size of PIXEL_FORMAT info, always 32bytes;
case of(
(texC=="DXT1"): (writelong fstream 0x04;writelong fstream 0x31545844 #unsigned
writelong s 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
writebyte s 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
writebyte s 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
writebyte s 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
writebyte s 0x00;writelong fstream 0x00001000 #unsigned)
(texC=="DXT3"): (writelong fstream 0x04;writelong fstream 0x33545844 #unsigned
writelong s 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
writebyte s 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
writebyte s 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
writebyte s 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
writebyte fstream 0x00;writelong fstream 0x00001000 #unsigned)
(texC=="DXT5"): (writelong fstream 0x04;writelong fstream 0x35545844 #unsigned
writelong fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
writebyte fstream 0x00;writelong fstream 0x00001000 #unsigned)
(texC=="ATI1"): (writelong fstream 0x04;writelong fstream 0x31495441 #unsigned
writelong fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
writebyte fstream 0x00;writelong fstream 0x00401008 #unsigned)
(texC=="ATI2"): (writelong fstream 0x04;writelong fstream 0x32495441 #unsigned
writelong fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
writebyte fstream 0x00;writelong fstream 0x00401008 #unsigned)
(texC=="P8"): (writelong fstream 0x20;writelong fstream 0x20203850 #unsigned
writelong fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
writebyte fstream 0x00;writelong fstream 0x00401008 #unsigned)
(texC=="ARGB16"): (writelong fstream 0x41;writelong fstream 0x00000000 #unsigned
writelong fstream 0x10;writebyte fstream 0x00;writebyte fstream 0x0F;writebyte fstream 0x00
writebyte fstream 0x00;writebyte fstream 0xF0;writebyte fstream 0x00;writebyte fstream 0x00
writebyte fstream 0x00;writebyte fstream 0x0F;writebyte fstream 0x00;writebyte fstream 0x00
writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0xF0;writebyte fstream 0x00
writebyte fstream 0x00;writelong fstream 0x00001000 #unsigned)
(texC=="ARBG32"): (writelong fstream 0x41;writelong fstream 0x00000000 #unsigned
writelong fstream 0x20;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0xFF
writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0xFF;writebyte fstream 0x00
writebyte fstream 0x00;writebyte fstream 0xFF;writebyte fstream 0x00;writebyte fstream 0x00
writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
writebyte fstream 0xFF;writelong fstream 0x00001000 #unsigned))
for i = 1 to 4 do writelong fstream 0x00 #unsigned) -- Reserved Space for CAPS
fn readtag fstream = (
local tempArray = (entry tag:#() flags:#() size:#() adr:#() data:#() offsets:#() sizes:#() children:#())
block_address = ftell fstream
block_magic = ReadFixedString fstream 8
block_flags = [(readbyte fstream),(readbyte fstream),(readbyte fstream),(readbyte fstream)]
if block_flags[1]==-1 then(
block_header_size = readBElong fstream
block_size = readBElong fstream
child_count = readBElong fstream
child_count2 = readBElong fstream
ukn01 = readBElong fstream -- padding?
child_offset = readBElong fstream -- offsets
child_offset2 = readBElong fstream -- sizes?
ukn03 = readBElong fstream -- if an address is present a small index table follows
ukn04 = readBElong fstream -- padding?
data_start = ftell fstream
if data_start!=child_offset then( -- I think this is specific user data. so the struct is different depending on which block
-- format "Props @ 0x%\n" ((bit.intAsHex(ftell fstream))as string)
-- blc_mem_type = readBEshort fstream
-- blc_mem_flag = readBEshort fstream
-- blc_mem_adr = readBElong fstream
-- blc_mem_ukn01 = readBElong fstream -- padding?
-- blc_mem_idx_cnt = readBElong fstream -- padding?
-- for mem = 1 to blc_mem_idx_cnt do (
-- blc_mem_idx = (readBEshort fstream) + 1
-- );fseek fstream (getpadding (ftell fstream) 16) #seek_cur
-- blc_mem_id = readBElong fstream
-- blc_mem_offset = readBElong fstream
-- blc_mem_size = readBElong fstream
-- blc_mem_ukn02 = readBElong fstream -- padding?
append tempArray.data [data_start,(ftell fstream)] -- log area, encase its needed, and I've parsed it wrong
)else(append tempArray.data [0,0])
if child_offset != 0 do (
fseek fstream (child_offset+block_address) #seek_set
for x = 1 to child_count do (
child_offset = readBElong fstream
-- if child_offset!=0 do (child_offset+=block_start)
append tempArray.offsets child_offset
)
)
if child_offset2 != 0 do (
fseek fstream (child_offset2+block_address) #seek_set
for x = 1 to child_count2 do (
child_offset = readBElong fstream
-- if child_offset!=0 do (child_offset+=block_start)
append tempArray.sizes child_offset
)
)
)else(
block_size = 0
block_flags = [0,0,0,0]
)
append tempArray.tag block_magic
append tempArray.flags block_flags
append tempArray.size block_size
append tempArray.adr block_address
return tempArray
)
fn loopchildren active_node fstream = (
active_node.children = #()
num_children = active_node.offsets.count
for m = 1 to num_children do (
if active_node.offsets[m]!=0 do(
fseek fstream (active_node.offsets[m]+active_node.adr[1]) #seek_set
append active_node.children (readtag fstream)))
return active_node
)
append dataArray (readtag f)
case of (
(dataArray[1].tag[1]=="TMC"): (
fseek f (dataArray[1].adr[1]+0x50) #seek_set
tmc_name = readstring f
fseek f (getpadding (ftell f) 16) #seek_cur
tmc_ukn01_01 = readBEfloat f -- B1
tmc_ukn01_02 = readBEfloat f
tmc_ukn01_03 = readBEfloat f
tmc_ukn01_04 = readBEfloat f
tmc_ukn01_05 = readBEfloat f -- B2
tmc_ukn01_06 = readBEfloat f
tmc_ukn01_07 = readBEfloat f
tmc_ukn01_08 = readBEfloat f
tmc_ukn01_09 = readBEfloat f -- B3
tmc_ukn01_10 = readBEfloat f
tmc_ukn01_11 = readBEfloat f
tmc_ukn01_12 = readBEfloat f
tmc_ukn01_13 = readBEfloat f -- B4
tmc_ukn01_14 = readBEfloat f
tmc_ukn01_15 = readBEfloat f
tmc_ukn01_16 = readBEfloat f
tmc_ukn01_17 = readBEfloat f -- B5 (Z?)
tmc_ukn01_18 = readBEfloat f
tmc_ukn01_19 = readBEfloat f
tmc_ukn01_20 = readBEfloat f
tmc_ukn01_21 = readBEfloat f -- B6 (X?)
tmc_ukn01_22 = readBEfloat f
tmc_ukn01_23 = readBEfloat f
tmc_ukn01_24 = readBEfloat f
tmc_ukn01_25 = readBEfloat f -- B7 (Y?)
tmc_ukn01_26 = readBEfloat f
tmc_ukn01_27 = readBEfloat f
tmc_ukn01_28 = readBEfloat f
tmc_ukn01_29 = readBEfloat f -- B8
tmc_ukn01_30 = readBEfloat f
tmc_ukn01_31 = readBEfloat f
tmc_ukn01_32 = readBEfloat f
if drawp==true do (
bb = dummy ()
bb.boxsize = [(abs(tmc_ukn01_21*2)),(abs (tmc_ukn01_27*2)),(abs(tmc_ukn01_18*2))]*100
bb = dummy ();bb.position = [tmc_ukn01_01,-tmc_ukn01_03,tmc_ukn01_02]*100
bb = dummy ();bb.position = [tmc_ukn01_05,-tmc_ukn01_07,tmc_ukn01_06]*100
bb = dummy ();bb.position = [tmc_ukn01_09,-tmc_ukn01_11,tmc_ukn01_10]*100
bb = dummy ();bb.position = [tmc_ukn01_13,-tmc_ukn01_15,tmc_ukn01_14]*100
bb = dummy ();bb.position = [tmc_ukn01_17,-tmc_ukn01_19,tmc_ukn01_18]*100
bb = dummy ();bb.position = [tmc_ukn01_21,-tmc_ukn01_23,tmc_ukn01_22]*100
bb = dummy ();bb.position = [tmc_ukn01_25,-tmc_ukn01_27,tmc_ukn01_26]*100
bb = dummy ();bb.position = [tmc_ukn01_29,-tmc_ukn01_31,tmc_ukn01_30]*100
print tmc_ukn01_21
print tmc_ukn01_22
print tmc_ukn01_23
)
loopchildren dataArray[1] f
-- clearlistener()
for x in dataArray[1].children do (
print x.tag[1]
case of (
(x.tag[1]=="MdlGeo"): ( -- describes the vertex and face buffers
loopchildren x f -- collect offsets for ObjGeo Children
format "Number of Objects: %\n" x.offsets.count
for i = 1 to x.offsets.count do( -- "ObjGeo" Number of Sub Objects
format "Object %\n" i
meshArray = (mesh_data subobj_index:#() vertex_start:#() face_start:#() vertex_stride:#() vertex_type:#() vertex_counts:#() face_counts:#())
fseek f x.children[i].data[1][1] #seek_set
fseek f 32 #seek_cur -- skips unknown ints
append objArray.name (readstring f) -- Object Name? but multiple objects are described under it. Sub Mats?
fseek f (getpadding (ftell f) 16) #seek_cur
fseek f (x.children[i].offsets.count*4) #seek_cur -- they wedge the offset table here O_o ..skipping over
fseek f (getpadding (ftell f) 16) #seek_cur
geodecl_ukn00 = ftell f -- collect block position
geodecl_ukn01 = readFixedString f 8 -- Hello GeoDecl !!
geodecl_ukn02 = readBElong f -- flags
geodecl_ukn03 = readBElong f -- header size
geodecl_ukn04 = readBElong f -- block size
geodecl_ukn05 = readBElong f -- count
geodecl_ukn06 = readBElong f -- count2
geodecl_ukn07 = readBElong f -- reserved space?
geodecl_ukn08 = readBElong f -- offset to table
fseek f ((geodecl_ukn08)+geodecl_ukn00) #seek_set -- seek past header
geodecl_ukn08_array = #()
format "\nObject (%): %\n" i objArray.name[i]
format "\tMaterials: %\n" x.children[i].offsets.count
for y = 1 to geodecl_ukn05 do ( -- loop through the blocks children offsets
geodecl_ukn08_offset = readBElong f
if geodecl_ukn08_offset!=0 do ( -- Collect the children offsets
append geodecl_ukn08_array (geodecl_ukn08_offset+geodecl_ukn00)))
for y = 1 to geodecl_ukn05 do ( -- Multi Data properties, in some relations describe how to read buffer
fseek f geodecl_ukn08_array[y] #seek_set -- set cursor to childs position
format "subobj: %\n" y
geodecl_ukn05_01 = readBElong f -- always 0?
geodecl_ukn05_02 = readBElong f -- header size
geodecl_ukn05_03 = readBElong f -- always 1?
geodecl_ukn05_04 = readBElong f -- chroxx describes as "vert type"
geodecl_ukn05_05 = readBElong f -- chroxx describes as "faceCount"
geodecl_ukn05_06 = readBElong f -- chroxx describes as "vertCount"
geodecl_ukn05_07 = readBElong f -- always 3?
geodecl_ukn05_08 = readBElong f -- always 0?, maybe padding?
geodecl_ukn05_09 = readBElong f -- reserved for memry addressing
geodecl_ukn05_10 = readBElong f -- always 0? padding again?
geodecl_ukn05_11 = readBElong f -- reserved for memry addressing
geodecl_ukn05_12 = readBElong f -- reserved for memry addressing
fseek f (geodecl_ukn08_array[y]+geodecl_ukn05_02) #seek_set
geodecl_ukn05_13 = readBElong f -- index
-- format "START @ 0x%\n" ((bit.intAsHex(ftell f))as string)
geodecl_ukn05_14 = readBElong f -- stride of vertex entry, chroxx describes as "vSize"
geodecl_ukn05_15 = readBElong f -- elements in vertex definition?, chroxx describes as "fvfCount"
geodecl_ukn05_16 = readBElong f -- reserved memory address
format "fvf count: %\n" geodecl_ukn05_15
for y = 1 to geodecl_ukn05_15 do ( -- chroxx describes as "fvfTable"
geodecl_ukn05_17 = readBElong f -- ?? index or count, ...it increments
geodecl_ukn05_18 = readBElong f -- appears to be offsets
geodecl_ukn05_19 = readBElong f -- large enough to be offsets, but are mults of 0x1000
format "\t> % % % \n" (paddstring 2 geodecl_ukn05_17) (paddstring 6 (uppercase(bit.intAsHex(geodecl_ukn05_18)))) (paddstring 6 (uppercase(bit.intAsHex(geodecl_ukn05_19))))
)
fseek f (getpadding (ftell f) 16) #seek_cur
append meshArray.vertex_type geodecl_ukn05_04
append meshArray.vertex_stride geodecl_ukn05_14
) -- ends loop on GeoDeclar !! too much data lol
geo_ukn05_array = #()
for y = 1 to x.children[i].offsets.count do( -- ObjGeo, SubObject or Material
fseek f (x.children[i].offsets[y]+x.children[i].adr[1]) #seek_set
geo_ukn01 = readBElong f -- index, increments
geo_ukn02 = readBElong f -- ID?
geo_ukn03 = readBElong f -- Reserved Memory Address
geo_ukn04 = readBElong f -- chroxx describes as "Texture Count"
for z = 1 to geo_ukn04 do ( -- collect sub blocks, texture info
append geo_ukn05_array (readBElong f) -- offset
)
fseek f (getpadding (ftell f) 16) #seek_cur
-- 00 00 00 00 00 00 00 00 00 00 00 00 40 33 43 A0
-- 00 00 00 00 00 00 00 00 00 00 00 01 BD A7 69 30
-- 00 00 00 00 00 00 00 00 00 00 00 C0 00 00 00 00
-- 00 00 00 00 00 00 00 00 BD A7 87 60 BE 77 3C D0
-- 00 00 00 01 00 00 00 05 00 00 00 01 00 00 00 01
-- 00 00 20 16 00 00 04 5E 00 00 11 37 00 00 02 61
-- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-- 00 00 00 00 00 00 00 00 3F 80 00 00 00 00 00 00
-- 3F 80 00 00 3F 80 00 00 00 00 00 00 00 00 00 00
-- 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00
-- 00 00 00 00 00 00 00 00 24 D0 08 10 00 00 00 00
geo_ukn06 = readBElong f -- always 0 ?
geo_ukn07 = readBElong f -- always 0 ?
geo_ukn08 = readBElong f -- always 0 ?
geo_ukn09 = readBElong f -- reserved memory space
geo_ukn10 = readBElong f -- always 0 ?
geo_ukn11 = readBElong f -- always 0 ?
geo_ukn12 = readBElong f -- chroxx describes as "meshIndex",
-- turns out this number links the materials to the object properties.
-- such as vertex description
geo_ukn13 = readBElong f -- reserved memory space
geo_ukn14 = readBElong f -- 0x00=Transparent | 0x01=Solid
geo_ukn15 = readBElong f -- always 0 ?
geo_ukn16 = readBElong f -- always 192 ?
geo_ukn17 = readBElong f -- always 0 ?
geo_ukn18 = readBElong f -- always 0 ?
geo_ukn19 = readBElong f -- always 0 ?
geo_ukn20 = readBElong f -- reserved memory space
geo_ukn21 = readBElong f -- reserved memory space
geo_ukn22 = readBElong f -- always 1 ?
geo_ukn23 = readBElong f
-- 0x00=RGB is Opacity | 0x01=turns black | 0x02=glows | 0x03=RGBA is opacity | 0x04=RGB inverted, A enabled
-- 0x00=RGB normal, A enabled as oacity | 0xFFFF=Disable Material
geo_ukn24 = readBElong f -- always 1 ?
geo_ukn25 = readBElong f -- 0x00 = ?? | 0x01= ??
geo_ukn26 = readBElong f -- chroxx describes as "FaceStart"
geo_ukn27 = readBElong f -- chroxx describes as "FaceCount"
geo_ukn28 = readBElong f -- chroxx describes as "vertStart"
geo_ukn29 = readBElong f -- chroxx describes as "vertCount"
geo_ukn30 = readBElong f -- always 0 ?
geo_ukn31 = readBElong f -- float?
geo_ukn32 = readBElong f -- float?
geo_ukn33 = readBElong f -- float?
geo_ukn34 = readBElong f -- float?
geo_ukn35 = readBElong f -- float?
geo_ukn36 = readBEfloat f -- float?
geo_ukn37 = readBElong f -- float?
geo_ukn38 = readBEfloat f -- float?
geo_ukn39 = readBEfloat f -- always 0 ?
geo_ukn40 = readBElong f -- always 0 ?
geo_ukn41 = readBElong f -- always 1 ?
geo_ukn42 = readBElong f -- always 1 ?
geo_ukn43 = readBElong f -- always 0 ?
geo_ukn44 = readBElong f -- always 0 ?
geo_ukn45 = readBElong f -- always 0 ?
geo_ukn46 = readBElong f -- always 0 ?
geo_ukn47 = readBElong f -- reserved memory space
geo_ukn48 = readBElong f -- 0x24D80800=?? | 0x14D80800=Reflective?
if printMat != false OR printTex!= False do(
format "\nMaterial(%): % @ 0x%\n" (geo_ukn01+1) (geo_ukn02+1) ((bit.intAsHex(x.children[i].offsets[y]+x.children[i].adr[1]))as string)
printblockpos "RAM" (x.children[i].offsets[y]+x.children[i].adr[1]+0xA76600)
)
if printMat == true do (
format "\tUnknowns;\n\t% % % %\n\t% % % %\n\t% % % %\n\t% % % %\n\t% % % %\n\t% % % %\n\t% % % %\n\t% % % %\n\t% %\n-------------\n" \
geo_ukn06 geo_ukn07 geo_ukn08 geo_ukn10 \
geo_ukn11 geo_ukn14 geo_ukn15 geo_ukn16 \
geo_ukn17 geo_ukn18 geo_ukn19 geo_ukn22 \
geo_ukn23 geo_ukn24 geo_ukn25 geo_ukn30 \
geo_ukn31 geo_ukn32 geo_ukn33 geo_ukn34 \
geo_ukn35 geo_ukn36 geo_ukn37 geo_ukn38 \
geo_ukn39 geo_ukn40 geo_ukn41 geo_ukn42 \
geo_ukn43 geo_ukn44 geo_ukn45 geo_ukn46 \
geo_ukn47 ("0x"+(paddstring 8 (uppercase ((bit.intAsHex(geo_ukn48))as string))))
)
for z = 1 to geo_ukn04 do ( -- Loop Textures for Material, each entry is 112bytes long
fseek f (x.children[i].offsets[y]+x.children[i].adr[1]+geo_ukn05_array[z]) #seek_set
geo_ukn04_01 = readBElong f -- ID, Assigned to each texture, relative to which are loaded into material
geo_ukn04_02 = readBElong f -- 0x00=DiffuseMap | 0x01=NormalMap | 0x02=SpecMap
geo_ukn04_03 = readBElong f -- Index, Which Texture from XPR2 to use
geo_ukn04_04 = readBElong f -- reserved memory space
geo_ukn04_05 = readBElong f -- always 5? is 3 on sweat texture?
geo_ukn04_06 = readBElong f -- always 1
geo_ukn04_07 = readBElong f -- always 0?
geo_ukn04_08 = readBElong f -- always 0?
geo_ukn04_09 = readBElong f -- always 0?
geo_ukn04_10 = readBElong f -- always 0?
geo_ukn04_11 = readBElong f -- always 0?
geo_ukn04_12 = readBElong f -- always 0?
geo_ukn04_13 = readBElong f -- always 0?
geo_ukn04_14 = readBElong f -- always 0?
geo_ukn04_15 = readBElong f -- always 0?
geo_ukn04_16 = readBElong f -- always 0?
geo_ukn04_17 = readBElong f -- always 1
geo_ukn04_18 = readBElong f -- always 1
geo_ukn04_19 = readBElong f -- always 1
geo_ukn04_20 = readBElong f -- always 0
geo_ukn04_21 = readBElong f -- always 0
geo_ukn04_22 = readBEfloat f -- float?
geo_ukn04_23 = readBEfloat f -- float?
geo_ukn04_24 = readBEfloat f -- float?
geo_ukn04_25 = readBEfloat f -- float?
geo_ukn04_26 = readBEfloat f -- float?
geo_ukn04_27 = readBEfloat f -- float?
geo_ukn04_28 = readBElong f -- always 1
if printTex==true do ( -- mostly all constant :-(
format "\tTexture(%): %\n" geo_ukn04_01 geo_ukn04_03
format "\tUnknowns;\n\t% % % %\n\t% % % %\n\t% % % %\n\t% % % %\n\t% % % %\n\t% % % %\n\t% % % %\n-------------\n" \
geo_ukn04_02 geo_ukn04_05 geo_ukn04_06 geo_ukn04_07 \
geo_ukn04_08 geo_ukn04_09 geo_ukn04_10 geo_ukn04_10 \
geo_ukn04_11 geo_ukn04_11 geo_ukn04_12 geo_ukn04_13 \
geo_ukn04_14 geo_ukn04_15 geo_ukn04_16 geo_ukn04_17 \
geo_ukn04_18 geo_ukn04_19 geo_ukn04_20 geo_ukn04_21 \
geo_ukn04_21 geo_ukn04_22 geo_ukn04_23 geo_ukn04_24 \
geo_ukn04_25 geo_ukn04_26 geo_ukn04_27 geo_ukn04_28
)
-- 00 00 00 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 05 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 41 40 00 00 BF 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
-- 00 00 00 01 00 00 00 01 00 00 00 04 00 00 00 00 00 00 00 05 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 41 40 00 00 BF 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
-- 00 00 00 02 00 00 00 02 00 00 00 05 00 00 00 00 00 00 00 05 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 41 40 00 00 BF 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
)
format "Vertex Count: %\nFace Count: %\n\n" geo_ukn27 geo_ukn29
append meshArray.vertex_counts geo_ukn29
append meshArray.face_counts geo_ukn27
append meshArray.vertex_start geo_ukn28
append meshArray.face_start geo_ukn26
append meshArray.subobj_index geo_ukn12
)
append objArray.modeldata meshArray
) -- End Object Loop (2)
)
(x.tag[1]=="TTX"): ( -- XPR2 Resource, Buffer is located in TMCL @ 0x1000
-- TTX area has some node info, could be flags. largest problem is exhange of the layered textures.
if x.offsets[1]!=0 do (
fseek f (x.offsets[1]+x.adr[1]) #seek_set
xpr2_magic = readBElong f
xpr2_buffer_offset = readBElong f
xpr2_buffer_size = readBElong f
xpr2_buffer_count = readBElong f
for i = 1 to xpr2_buffer_count do (
append xpr2entry.magic (readBElong f)
append xpr2entry.offset (readBElong f)
append xpr2entry.size (readBElong f)
append xpr2entry.string_offset (readBElong f)
)
for i = 1 to xpr2_buffer_count do (
fseek f (xpr2entry.string_offset[i]+x.offsets[1]+x.adr[1]+12) #seek_set
append xpr2entry.string (readstring f)
)
-- fseek f (xpr2entry.offset[1]+(8*4)) #seek_set
-- tmcl_offset = readBEtriplet f
for i = 1 to xpr2_buffer_count do (
fseek f (xpr2entry.offset[i]+x.offsets[1]+x.adr[1]+12) #seek_set
append tx2dentry.ukn01 (readBElong f) -- 00 00 00 03
append tx2dentry.ukn02 (readBElong f) -- 0 00 00 01
append tx2dentry.ukn03 (readBElong f) -- 00 00 00 00
append tx2dentry.ukn04 (readBElong f) -- 00 00 00 00
append tx2dentry.ukn05 (readBElong f) -- 00 00 00 00
append tx2dentry.ukn06 (readBEshort f) -- FF FF
append tx2dentry.ukn07 (readBEshort f) -- 00 00
append tx2dentry.ukn08 (readBEshort f) -- FF FF
append tx2dentry.ukn09 (readBEshort f) -- 00 00
append tx2dentry.ukn10 (readbyte f #unsigned) -- 81
append tx2dentry.ukn11 (readbyte f #unsigned) -- 00
append tx2dentry.ukn12 (readbyte f #unsigned) -- 00
append tx2dentry.ukn13 (readbyte f #unsigned) -- 02
append tx2dentry.ukn14 (readBEtriplet f) -- base offset * 0x6000 from Buffer Start = Texture Offset
append tx2dentry.ukn15 (readbyte f #unsigned) -- compression type
-- (byte 02 = CTES Compression {ETC RGBA Introploated Alpha 8bpp} dword: ETCI) /like DXT5
-- (byte 52 = dxt1)
-- (byte 53 = dxt3)
-- (byte 54 = dxt5)
-- (byte 56 = 32bitargb)
-- (byte 86 = 32bitargb)
-- (byte 4A) = 16bitargb)
-- (byte 71 = ATI2)
-- (byte 7C = ATI1 - CTX1) set to 54 to unswizzle
append tx2dentry.ukn16 (readBElong f) -- dimension
append tx2dentry.ukn17 (readBElong f) -- 00 00 0D 10
append tx2dentry.ukn18 (readBElong f) -- 00 00 00 0C
append tx2dentry.ukn19 (readBElong f) -- mip offset
)
)
-- for i = 1 to xpr2_buffer_count do (
-- format "Texture % @ 0x%\n" (i-1) ((bit.intAsHex((tx2dentry.ukn14[i] * 0x100)+xpr2_buffer_offset+12))as string))
if dumpXPR == true do(
s = fopen (fpath+fname+"_ttx.xpr") "wb"
writeBElong s xpr2_magic
writeBElong s xpr2_buffer_offset
writeBElong s xpr2_buffer_size
writeBElong s xpr2_buffer_count
for i = 1 to xpr2_buffer_count do (
writeBElong s xpr2entry.magic[i]
writeBElong s xpr2entry.offset[i]
writeBElong s xpr2entry.size[i]
writeBElong s xpr2entry.string_offset[i]
)
writeBElong s 0
for i = 1 to xpr2_buffer_count do (
writestring s xpr2entry.string[i]
)
writeBElong s 0
for i = 1 to xpr2_buffer_count do (
fseek f xpr2entry.offset[i] #seek_set
writeBElong s tx2dentry.ukn01[i]
writeBElong s tx2dentry.ukn02[i]
writeBElong s tx2dentry.ukn03[i]
writeBElong s tx2dentry.ukn04[i]
writeBElong s tx2dentry.ukn05[i]
writeBEshort s tx2dentry.ukn06[i]
writeBEshort s tx2dentry.ukn07[i]
writeBEshort s tx2dentry.ukn08[i]
writeBEshort s tx2dentry.ukn09[i]
writebyte s tx2dentry.ukn10[i] #unsigned
writebyte s tx2dentry.ukn11[i] #unsigned
writebyte s tx2dentry.ukn12[i] #unsigned
writebyte s tx2dentry.ukn13[i] #unsigned
writeBEtriplet s tx2dentry.ukn14[i]
writebyte s tx2dentry.ukn15[i] #unsigned
writeBElong s tx2dentry.ukn16[i]
writeBElong s tx2dentry.ukn17[i]
writeBElong s tx2dentry.ukn18[i]
writeBElong s tx2dentry.ukn19[i]
)
for i = 1 to ((xpr2_buffer_offset+12)-(ftell s)) do(writebyte s 99) -- pad remaning space
fseek l 0x1000 #seek_set
for i = 1 to xpr2_buffer_size do(writebyte s (readbyte l #unsigned) #unsigned)
print "XPR Write Complete!"
fclose s
)
if dumpDDS == true do(
tempArray=#()
for z = 1 to tx2dentry.ukn16.count do (
append tempArray (tx2dentry.ukn14[z]*0x0100)
)
deleteitem tempArray 1
append tempArray (xpr2_buffer_size)
print tempArray
for z = 1 to tx2dentry.ukn16.count do (
tempArray[z]=tempArray[z]-(tx2dentry.ukn14[z]*0x0100)
)
for z = 1 to tx2dentry.ukn16.count do (
texD=decodedimension tx2dentry.ukn16[z]
texC = tx2dentry.ukn15[z]
case of (
(texC==0x02): (texC="DXT5") -- CTES Compression {ETC RGBA Introploated Alpha 8bpp} dword: ETCI) /like DXT5
(texC==0x52): (texC="DXT1") -- dxt1
(texC==0x53): (texC="DXT3") -- dxt3
(texC==0x54): (texC="DXT5") -- dxt5
(texC==0x56): (texC="ARGB32") -- 32bitargb
(texC==0x86): (texC="ARGB32") -- 32bitargb
(texC==0x4A): (texC="ARGB16") -- 16bitargb
(texC==0x71): (texC="ATI2") -- ATI2
(texC==0x7C): (texC="ATI1") -- ATI1 - CTX1 set to 54 to unswizzle
default:(
format "Unknown Texture Compression: %\n" texC
texC="DXT1"
)
)
xpr2entry.string[z]=("0x"+(paddstring 8 (uppercase (bit.intAsHex((0x1000+(tx2dentry.ukn14[z]*0x0100)))))))
makeDir (fpath+fname)
if texD[4]==0 then (
s = fopen (fpath+fname+"\\"+(getFilenameFile xpr2entry.string[z]+"_"+texC+"_TX2D.dds")) "wb"
)else(
s = fopen (fpath+fname+"\\"+(getFilenameFile xpr2entry.string[z]+"_"+texC+"_TX3D.dds")) "wb"
)
if texD[4]==0 then (
writeDDSheader s texD[1] texD[2] 0 texC
)else (
writeDDSheader s texD[1] (texD[2]*2) 0 texC
)
fseek l (0x1000+(tx2dentry.ukn14[z]*0x0100)) #seek_set
if texD[4]==0 then(
case of (
(texC=="DXT1"): (for r = 1 to (tempArray[z]/2) do(writeshort s (ReadBEshort l) #unsigned))
(texC=="DXT3"): (for r = 1 to (tempArray[z]/2) do(writeshort s (ReadBEshort l) #unsigned))
(texC=="DXT5"): (for r = 1 to (tempArray[z]/2) do(writeshort s (ReadBEshort l) #unsigned))
(texC=="ATI1"): (for r = 1 to (tempArray[z]/2) do(writeshort s (ReadBEshort l) #unsigned))
(texC=="ATI2"): (for r = 1 to (tempArray[z]/2) do(writeshort s (ReadBEshort l) #unsigned))
(texC=="ARGB16"): (for r = 1 to tempArray[z] do(writebyte s (readbyte l #unsigned) #unsigned))
(texC=="ARGB32"): (for r = 1 to tempArray[z] do(writebyte s (readbyte l #unsigned) #unsigned))
)
)else(
case of (
(texC=="DXT1"): (
for c = 1 to (tempArray[z]/8192) do(
for r = 1 to (8192/2) do (writeshort s (ReadBEshort l) #unsigned)
fseek l 8192 #seek_cur))
(texC=="DXT3"): (
for c = 1 to (tempArray[z]/16384) do(
for r = 1 to (16384/2) do (writeshort s (ReadBEshort l) #unsigned)
fseek l 16384 #seek_cur))
(texC=="DXT5"): (
for c = 1 to (tempArray[z]/16384) do(
for r = 1 to (16384/2) do (writeshort s (ReadBEshort l) #unsigned)
fseek l 16384 #seek_cur))
(texC=="ATI1"): (
for c = 1 to (tempArray[z]/8192) do(
for r = 1 to (8192/2) do (writeshort s (ReadBEshort l) #unsigned)
fseek l 8192 #seek_cur))
(texC=="ATI2"): (
for c = 1 to (tempArray[z]/16384) do(
for r = 1 to (16384/2) do (writeshort s (ReadBEshort l) #unsigned)
fseek l 16384 #seek_cur))
(texC=="ARGB16"): (for r = 1 to tempArray[z] do(writebyte s (readbyte l #unsigned) #unsigned))
(texC=="ARGB32"): (for r = 1 to tempArray[z] do(writebyte s (readbyte l #unsigned) #unsigned))
)
)
fclose s
)
print "XPR Write Complete!"
)
)
(x.tag[1]=="VtxLay"): (
-- fseek f x.adr[1] #seek_set
VtxLayArray.offset = copy x.offsets #nomap
)
(x.tag[1]=="IdxLay"): (
IdxLayArray.offset = copy x.offsets #nomap
)
(x.tag[1]=="MtrCol"): ( -- Material Colour?
loopchildren x f
for i = 1 to x.offsets.count do(
fseek f (x.offsets[i]+x.adr[1]) #seek_set
printblockpos ("MtrCol "+(i as string)) (x.offsets[i]+x.adr[1]+0xA76600)
mtr_ukn01 = readcol f -- Diffuse Colour?
mtr_ukn02 = readcol f
mtr_ukn03 = readcol f
mtr_ukn04 = readcol f
mtr_ukn05 = readcol f
mtr_ukn06 = readcol f
mtr_ukn07 = readBElong f -- Reserved Memory Space
fseek f (getpadding (ftell f) 16) #seek_cur
mtr_ukn08 = readcol f -- Diffuse Colour?
mtr_ukn09 = readcol f
mtr_ukn10 = readcol f
mtr_ukn11 = readcol f
mtr_ukn12 = readcol f
mtr_ukn13 = readcol f
-- for i = 1 to 1 do (
-- mtr_ukn14 = readBElong f
-- mtr_ukn15 = readBElong f
-- )
)
)
(x.tag[1]=="MdlInfo"): ( -- Same as ObjGeo Count
loopchildren x f
for i = 1 to x.offsets.count do(
fseek f (x.offsets[i]+x.adr[1]+0xE0) #seek_set
-- printblockpos "MODEL INFO" ((ftell f)+0xA76600)
p01=readBEfloat f
p02=readBEfloat f
p03=readBEfloat f
p04=readBEfloat f
p05=readBEfloat f
p06=readBEfloat f
p07=readBEfloat f
p08=readBEfloat f
p09=readBEfloat f
p10=readBEfloat f
p11=readBEfloat f
p12=readBEfloat f
p13=readBEfloat f
p14=readBEfloat f
p15=readBEfloat f
p16=readBEfloat f
p17=readBEfloat f
p18=readBEfloat f
p19=readBEfloat f
p20=readBEfloat f
p21=readBEfloat f
p22=readBEfloat f
p23=readBEfloat f
p24=readBEfloat f
p25=readBEfloat f
p26=readBEfloat f
p27=readBEfloat f
p28=readBEfloat f
if drawp == true do (
bb = sphere();bb.radius=3 -- RED
bb.position=[p01,-p03,p02]*model_scale
bb.wirecolor = color 255 0 0
bb.name = ("SPHERE_01_"+(paddstring 2 (i as string)))
bb = sphere();bb.radius=3 -- GREEN
bb.position=[p05,-p07,p06]*model_scale
bb.wirecolor = color 0 75 0
bb.name = ("SPHERE_02_"+(paddstring 2 (i as string)))
bb = sphere();bb.radius=3 -- BLUE
bb.position=[p09,-p11,p10]*model_scale
bb.wirecolor = color 0 0 255
bb.name = ("SPHERE_03_"+(paddstring 2 (i as string)))
bb = sphere();bb.radius=3 -- ORANGE
bb.position=[p13,-p15,p14]*model_scale
bb.wirecolor = color 239 68 0
bb.name = ("SPHERE_04_"+(paddstring 2 (i as string)))
bb = sphere();bb.radius=3 -- PINK
bb.position=[p17,-p19,p18]*model_scale
bb.wirecolor = color 255 0 216
bb.name = ("SPHERE_05_"+(paddstring 2 (i as string)))
bb = sphere();bb.radius=3 -- AQUA
bb.position=[p21,-p23,p22]*model_scale
bb.wirecolor = color 0 240 198
bb.name = ("SPHERE_06_"+(paddstring 2 (i as string)))
bb = sphere();bb.radius=3 -- LIME
bb.position=[p21,-p23,p22]*model_scale
bb.wirecolor = color 98 246 0
bb.name = ("SPHERE_07_"+(paddstring 2 (i as string)))
)
-- for y = 1 to x.children[i].offsets.count do(
-- fseek f (x.children[i].offsets[y]+x.children[i].adr[1]) #seek_set
-- mfn_ukn01 = ReadBElong f -- Object Index
-- mfn_ukn01 = ReadBElong f -- ??
-- mfn_ukn01 = ReadBElong f -- always 0?
-- mfn_ukn01 = ReadBElong f -- always 0?
-- mfn_ukn01 = ReadBElong f -- always 0?
-- mfn_ukn01 = ReadBElong f -- always 0?
-- mfn_ukn01 = ReadBElong f -- always 0?
-- mfn_ukn01 = ReadBElong f -- always 0?
-- mfn_ukn01 = ReadBElong f -- reserved memory space
-- mfn_ukn01 = ReadBElong f -- padding?
-- mfn_ukn01 = ReadBElong f -- padding?
-- mfn_ukn01 = ReadBElong f -- padding?
-- )
)
)
(x.tag[1]=="HieLay"): ( -- Bones
for i = 1 to x.offsets.count do ( -- bone entry is 112bytes
fseek f (x.offsets[i]+x.adr[1]) #seek_set
bone_row1 = [(readBEfloat f),(readBEfloat f),(readBEfloat f),(readBEfloat f)]
bone_row2 = [(readBEfloat f),(readBEfloat f),(readBEfloat f),(readBEfloat f)]
bone_row3 = [(readBEfloat f),(readBEfloat f),(readBEfloat f),(readBEfloat f)]
bone_row4 = [(readBEfloat f),(readBEfloat f),(readBEfloat f),(readBEfloat f)]
-- mScaleX mRotateZa mRotateYa
-- mRotateZb mScaleY mRotateXa
-- mRotateYb mRotateXb mScaleZ
-- mMoveX mMoveZ mMoveY
bone_transform = (matrix3 \
([(bone_row1[1]),(bone_row1[2]),(bone_row1[3])]) \
([(bone_row2[1]),(bone_row2[2]),(bone_row2[3])]) \
([(bone_row3[1]),(bone_row3[2]),(bone_row3[3])]) \
([(bone_row4[1]),(bone_row4[2]),(bone_row4[3])]*bone_row4[4]*model_scale))
bone_parent = (readBElong f)+1
bone_chlidren_count = readBElong f
bone_ukn01 = readBElong f
bone_ukn02 = readBElong f
format "Bone: %\n\t>>% %\n" i bone_ukn01 bone_ukn02
bone_chlidren = #()
for i = 1 to bone_chlidren_count do (append bone_chlidren ((readBElong f)+1))
append boneArray.name ("Bone_"+(paddstring 3 (i as string)))
append boneArray.matrix bone_transform
append boneArray.parent bone_parent
append boneArray.children bone_chlidren
)
)
(x.tag[1]=="LHeader"): ( -- TMCL Info
-- Sub Buffers are on 0x1000 alignment
-- Given Size doesn't include padding
-- fseek f adr #seek_set
print (x.offsets[1]+x.adr[1])
for i = 1 to x.offsets.count do (
append tmclBuffer.offset x.offsets[i]
)
for i = 1 to x.sizes.count do (
append tmclBuffer.size x.sizes[i]
)
-- tmclBuffer
)
(x.tag[1]=="NodeLay"): ( -- Bone Names
-- expects "HieLay" to have been read in first
for i = 1 to x.offsets.count do ( -- bone entry is 112bytes
fseek f (x.offsets[i]+x.adr[1]+0x30) #seek_set
NodeLay_01 = readBElong f -- always 0? flag for bones?
NodeLay_02 = readBElong f -- always -1?
NodeLay_03 = readBElong f + 1 -- Index
NodeLay_04 = readBElong f -- reversed memory address
NodeLay_05 = readstring f
-- pad to 16byte alignment
boneArray.name[NodeLay_03]=NodeLay_05
format "Node: %\n\t>>% % %\n" NodeLay_05 NodeLay_01 NodeLay_02 NodeLay_03
)
)
(x.tag[1]=="xGlblMtx"): ( -- same as "HieLay"? but no parenting info
)
(x.tag[1]=="xBnOfsMtx"): ( -- same as "HieLay"? but no parenting info
)
(x.tag[1]=="xcpf"): ( -- ?? bone related
)
(x.tag[1]=="xMCAPACK"): ( -- ?? material related?
for i = 1 to x.offsets.count do( -- block dont follow my previous understanding :/
fseek f (x.offsets[i]+x.adr[1]) #seek_set
-- format "MCAMTRL @ 0x%\n" ((bit.intAsHex(ftell f))as string)
fseek f 0x14 #seek_cur
mcam_count1 = readBElong f -- count duplicated in "ACSCLS" section
mcam_count2 = readBElong f -- ?
fseek f 0x14 #seek_cur
mcam_count2_array = #()
for y = 1 to mcam_count1 do ( -- alot of white space?
mcam_offset1 = readBElong f
if mcam_offset1!=0 do(
append mcam_count2_array (mcam_offset1+x.offsets[i]+x.adr[1])
)
)
MCAPARAMARRAY2 = #()
for x = 1 to mcam_count2_array.count do (
fseek f (mcam_count2_array[x]+0x30) #seek_set
-- format "MCAPARAM @ 0x%\n" ((bit.intAsHex(ftell f-0x30))as string)
-- append MCAPARAMARRAY2 [(readBElong f),(readBElong f),(readBElong f),(readBElong f)]
append MCAPARAMARRAY2 (readBElong f)
)
append MCAPARAMARRAY.ukn1 MCAPARAMARRAY2
)
-- print MCAPARAMARRAY
)
(x.tag[1]=="xRENPACK"): ( -- block is empty ?
)
(x.tag[1]=="xACSCLS"): ( -- ??parsing of this area is incorrect
loopchildren x f
for i = 1 to x.offsets.count do(
fseek f (x.offsets[i]+x.adr[1]) #seek_set
-- format "SACL @ 0x%\n" ((bit.intAsHex(ftell f))as string)
-- print x.children[i].offsets.count
for y = 1 to x.children[i].offsets.count do(
fseek f (x.children[i].offsets[y]+x.children[i].adr[1]) #seek_set
mfn_ukn01 = ReadBElong f -- Object Index
mfn_ukn01 = ReadBElong f -- ??
mfn_ukn01 = ReadBElong f -- always 0?
mfn_ukn01 = ReadBElong f -- always 0?
mfn_ukn01 = ReadBElong f -- always 0?
mfn_ukn01 = ReadBElong f -- always 0?
mfn_ukn01 = ReadBElong f -- always 0?
mfn_ukn01 = ReadBElong f -- always 0?
mfn_ukn01 = ReadBElong f -- reserved memory space
mfn_ukn01 = ReadBElong f -- padding?
mfn_ukn01 = ReadBElong f -- padding?
mfn_ukn01 = ReadBElong f -- padding?
)
)
)
default: (format "*New Block: %\n" x.tag[1])
)
)
)
default:()
)
if buildMsh == true do ( -- build mesh
for i = 1 to boneArray.name.count do ( -- Create Bones
bone_ext = [0,0,0]
if boneArray.parent[i]!=0 do (bone_ext = boneArray.matrix[(boneArray.parent[i])].row4)
bb=BoneSys.createBone boneArray.matrix[i].row4 bone_ext [0,0,1]
bb.showLinks = true
bb.showLinksOnly = true
bb.transform = boneArray.matrix[i]
bb.name = boneArray.name[i]
append boneArray.obj bb
)
for i = 1 to boneArray.name.count do ( -- realtive to world positions
if boneArray.parent[i]!=0 then (
boneArray.obj[i].transform*= boneArray.obj[(boneArray.parent[i])].transform
boneArray.obj[i].parent = boneArray.obj[(boneArray.parent[i])]
)else(boneArray.obj[i].transform=rotateX boneArray.obj[i].transform 90
)
)
-- clearlistener()
-- try (
for i = 1 to objArray.modeldata.count do ( -- Mesh Count
-- for i = 1 to 1 do ( -- Mesh Count
format ">>>>>>>NEW OBJECT: %\n" i
num_elements = objArray.modeldata[i].vertex_start.count
-- num_elements = 3
faceaddon = 1
vertArray=#()
normArray=#()
uvwArray1=#()
uvwArray2=#()
uvwArray3=#()
uvwArray4=#()
faceArray=#()
matidArray=#()
logArray1=#()
logArray2=#()
logArray3=#()
mat = multimaterial numsubs:num_elements
mat.numsubs = num_elements
for x = 1 to num_elements do ( -- Mesh Elements
num_verts = objArray.modeldata[i].vertex_counts[x]
format "Number Vertices: %\n" num_verts
pos = tmclBuffer.offset[2] + VtxLayArray.offset[(objArray.modeldata[i].vertex_type[(objArray.modeldata[i].subobj_index[x]+1)]+1)]
stride = objArray.modeldata[i].vertex_stride[(objArray.modeldata[i].subobj_index[x]+1)]
pos += objArray.modeldata[i].vertex_start[x]*stride
-- append logArray [stride,num_verts,pos] -- here for quick vertex injection
append logArray1 stride -- here for quick vertex injection
append logArray2 num_verts -- here for quick vertex injection
append logArray3 pos
format "Mesh Index: %\n" (objArray.modeldata[i].subobj_index[x]+1)
case of (
(stride==16): (
for v = 1 to num_verts do (
fseek l pos #seek_set
vx = ReadBEfloat l
vy = ReadBEfloat l
vz = ReadBEfloat l
tu1 = readBEHalfFloat l
tv1 = readBEHalfFloat l
-- ReadBE_HEND3N fstream
append vertArray ([vx,-vz,vy]*model_scale)
append uvwArray1 [(1-tu1),(1-tv1),0]
append uvwArray2 [0,0,0]
append uvwArray3 [0,0,0]
append uvwArray4 [0,0,0]
-- append vertArray [0,0,0]
-- append uvwArray1 [0,0,0]
-- append uvwArray2 [0,0,0]
-- append uvwArray3 [0,0,0]
-- append uvwArray4 [0,0,0]
pos += stride
)
)
(stride==24): (
for v = 1 to num_verts do (
fseek l pos #seek_set
vx = ReadBEfloat l
vy = ReadBEfloat l
vz = ReadBEfloat l
nx = ReadBEfloat l
nx = ReadBEfloat l
tu1 = readBEHalfFloat l
tv1 = readBEHalfFloat l
append vertArray ([vx,-vz,vy]*model_scale)
append uvwArray1 [(1-tu1),(1-tv1),0]
append uvwArray2 [0,0,0]
append uvwArray3 [0,0,0]
append uvwArray4 [0,0,0]
-- append vertArray [0,0,0]
-- append uvwArray1 [0,0,0]
-- append uvwArray2 [0,0,0]
-- append uvwArray3 [0,0,0]
-- append uvwArray4 [0,0,0]
pos += stride
)
)
(stride==28): ( -- not verified! 2 unknowns
for v = 1 to num_verts do (
fseek l pos #seek_set
vx = ReadBEfloat l
vy = ReadBEfloat l
vz = ReadBEfloat l
nx = ReadBEfloat l
nx = ReadBEfloat l
ukn1 = readBEHalfFloat l
ukn1 = readBEHalfFloat l
tu1 = readBEHalfFloat l
tv1 = readBEHalfFloat l
append vertArray ([vx,-vz,vy]*model_scale)
append uvwArray1 [(1-tu1),(1-tv1),0]
append uvwArray2 [0,0,0]
append uvwArray3 [0,0,0]
append uvwArray4 [0,0,0]
-- append vertArray [0,0,0]
-- append uvwArray1 [0,0,0]
-- append uvwArray2 [0,0,0]
-- append uvwArray3 [0,0,0]
-- append uvwArray4 [0,0,0]
pos += stride
)
)
(stride==32): (
for v = 1 to num_verts do (
fseek l pos #seek_set
vx = ReadBEfloat l
vy = ReadBEfloat l
vz = ReadBEfloat l
nx = ReadBEfloat l
nx = ReadBEfloat l
tu1 = readBEHalfFloat l
tv1 = readBEHalfFloat l
tu2 = readBEHalfFloat l
tv2 = readBEHalfFloat l
tu3 = readBEHalfFloat l
tv3 = readBEHalfFloat l
append vertArray ([vx,-vz,vy]*model_scale)
append uvwArray1 [(1-tu1),(1-tv1),0]
append uvwArray2 [(1-tu2),(1-tv2),0]
append uvwArray3 [(1-tu3),(1-tv3),0]
append uvwArray4 [0,0,0]
-- append vertArray [0,0,0]
-- append uvwArray1 [0,0,0]
-- append uvwArray2 [0,0,0]
-- append uvwArray3 [0,0,0]
-- append uvwArray4 [0,0,0]
pos += stride
)
)
(stride==36): ( -- not verified! 4 unknowns
for v = 1 to num_verts do (
fseek l pos #seek_set
vx = ReadBEfloat l
vy = ReadBEfloat l
vz = ReadBEfloat l
nx = ReadBEfloat l
nx = ReadBEfloat l
ukn1 = readBEHalfFloat l
ukn2 = readBEHalfFloat l
ukn3 = readBEHalfFloat l
ukn4 = readBEHalfFloat l
tu1 = readBEHalfFloat l
tv1 = readBEHalfFloat l
tu2 = readBEHalfFloat l
tv2 = readBEHalfFloat l
append vertArray ([vx,-vz,vy]*model_scale)
append uvwArray1 [(1-tu1),(1-tv1),0]
append uvwArray2 [(1-tu2),(1-tv2),0]
append uvwArray3 [0,0,0]
append uvwArray4 [0,0,0]
-- append vertArray [0,0,0]
-- append uvwArray1 [0,0,0]
-- append uvwArray2 [0,0,0]
-- append uvwArray3 [0,0,0]
-- append uvwArray4 [0,0,0]
pos += stride
)
)
(stride==40): (
for v = 1 to num_verts do (
fseek l pos #seek_set
vx = ReadBEfloat l
vy = ReadBEfloat l
vz = ReadBEfloat l
nx = ReadBEfloat l
w4 = readbyte l #unsigned
w3 = readbyte l #unsigned
w2 = readbyte l #unsigned
w1 = readbyte l #unsigned
b4 = readbyte l #unsigned
b3 = readbyte l #unsigned
b2 = readbyte l #unsigned
b1 = readbyte l #unsigned
nx = ReadBEfloat l
tu1 = readBEHalfFloat l
tv1 = readBEHalfFloat l
tu2 = readBEHalfFloat l
tv2 = readBEHalfFloat l
tu3 = readBEHalfFloat l
tv3 = readBEHalfFloat l
append vertArray ([vx,-vz,vy]*model_scale)
append uvwArray1 [(1-tu1),(1-tv1),0]
append uvwArray2 [(1-tu2),(1-tv2),0]
append uvwArray3 [(1-tu3),(1-tv3),0]
append uvwArray4 [0,0,0]
-- append vertArray [0,0,0]
-- append uvwArray1 [0,0,0]
-- append uvwArray2 [0,0,0]
-- append uvwArray3 [0,0,0]
-- append uvwArray4 [0,0,0]
pos += stride
)
)
(stride==44): (
for v = 1 to num_verts do (
fseek l pos #seek_set
vx = ReadBEfloat l
vy = ReadBEfloat l
vz = ReadBEfloat l
nx = ReadBEfloat l
w4 = readbyte l #unsigned
w3 = readbyte l #unsigned
w2 = readbyte l #unsigned
w1 = readbyte l #unsigned
b4 = readbyte l #unsigned
b3 = readbyte l #unsigned
b2 = readbyte l #unsigned
b1 = readbyte l #unsigned
nx = ReadBEfloat l
tu1 = readBEHalfFloat l
tv1 = readBEHalfFloat l
tu2 = readBEHalfFloat l
tv2 = readBEHalfFloat l
tu3 = readBEHalfFloat l
tv3 = readBEHalfFloat l
tu4 = readBEHalfFloat l
tv4 = readBEHalfFloat l
append vertArray ([vx,-vz,vy]*model_scale)
-- append vertArray [nx,-nz,ny]
append uvwArray1 [(1-tu1),(1-tv1),0]
append uvwArray2 [(1-tu2),(1-tv2),0]
append uvwArray3 [(1-tu3),(1-tv3),0]
append uvwArray4 [(1-tu4),(1-tv4),0]
-- append vertArray [0,0,0]
-- append uvwArray [0,0,0]
pos += stride
)
)
(stride==96): (
for v = 1 to num_verts do (
fseek l pos #seek_set
vx = ReadBEfloat l
vy = ReadBEfloat l
vz = ReadBEfloat l
nx = ReadBEfloat l
w4 = readbyte l #unsigned
w3 = readbyte l #unsigned
w2 = readbyte l #unsigned
w1 = readbyte l #unsigned
b4 = readbyte l #unsigned
b3 = readbyte l #unsigned
b2 = readbyte l #unsigned
b1 = readbyte l #unsigned
nx = ReadBEfloat l
tu1 = readBEHalfFloat l
tv1 = readBEHalfFloat l
tu2 = readBEHalfFloat l
tv2 = readBEHalfFloat l
tu3 = readBEHalfFloat l
tv3 = readBEHalfFloat l
tu4 = readBEHalfFloat l
tv4 = readBEHalfFloat l
append vertArray ([vx,-vz,vy]*model_scale)
-- append vertArray [nx,-nz,ny]
append uvwArray1 [(1-tu1),(1-tv1),0]
append uvwArray2 [(1-tu2),(1-tv2),0]
append uvwArray3 [(1-tu3),(1-tv3),0]
append uvwArray4 [(1-tu4),(1-tv4),0]
-- append vertArray [0,0,0]
-- append uvwArray [0,0,0]
pos += stride
)
)
default:(
format "New Stride (%) @ 0x%\n" stride ((bit.intAsHex(pos))as string)
messagebox ("Yay, You've Discovered a New Vertex Size!\nHelp solve the FVF flags by telling me which file this failed on :-)")
)
)
pos+=getpadding (pos) 8
)
for x = 1 to num_elements do ( -- Mesh Elements
pos = tmclBuffer.offset[3] + IdxLayArray.offset[(objArray.modeldata[i].vertex_type[(objArray.modeldata[i].subobj_index[x]+1)]+1)]
pos += objArray.modeldata[i].face_start[x]*0x02
num_faces = objArray.modeldata[i].face_counts[x]
fseek l pos #seek_set
-- format "Face START @ 0x%\n" ((bit.intAsHex(ftell l))as string)
-- format "Start face: % \n" objArray.modeldata[i].face_start[x]
-- faceaddon =
StartDirection = -1
fa =((readBEshort l)-objArray.modeldata[i].vertex_start[x]) + faceaddon
fb =((readBEshort l)-objArray.modeldata[i].vertex_start[x]) + faceaddon
FaceDirection = StartDirection
IndexCounter = 2
Do (
fc =(readBEshort l)
IndexCounter += 1
if (fc==0xFFFF) then (
fa =((readBEshort l)-objArray.modeldata[i].vertex_start[x]) + faceaddon
fb =((readBEshort l)-objArray.modeldata[i].vertex_start[x]) + faceaddon
FaceDirection = StartDirection
IndexCounter += 2
) else (
fc-=objArray.modeldata[i].vertex_start[x]
fc += faceaddon
FaceDirection *= -1
if (fa!=fb)AND(fb!=fc)AND(fc!=fa) then (
if FaceDirection > 0 then (append faceArray [fa,fb,fc];append matidArray x)
else (append faceArray [fa,fc,fb];append matidArray x)
)
fa = fb
fb = fc
)
)
while IndexCounter !=num_faces
faceaddon += objArray.modeldata[i].vertex_counts[x]
-- faceaddon -= objArray.modeldata[i].face_start[x]
-- print faceArray[1]
-- print faceArray[2]
-- print faceArray[3]
-- faceArray=#()
-- format "Face Ended @ 0x%\n" ((bit.intAsHex(ftell l))as string)
-- format "VertCount: %\n" vertArray.count
)
msh = mesh vertices:vertArray faces:faceArray materialIDs:matidArray
msh.numTVerts = uvwArray1.count
buildTVFaces msh
msh.displayByLayer = false
msh.backfacecull = on
msh.wirecolor = random (color 0 0 0) (color 255 255 255)
msh.material = mat
for j = 1 to msh.material.count do
(msh.material.materialList[j].Diffuse = random (color 0 0 0) (color 255 255 255))
for j = 1 to uvwArray1.count do setTVert msh j uvwArray1[j]
for j = 1 to faceArray.count do setTVFace msh j faceArray[j]
-- for j = 1 to normArray.count do setNormal msh j normArray[j]
if uvwArray2.count!=0 do(meshop.setNumMaps msh 3 keep:true
for j = 1 to uvwArray2.count do (meshOp.setMapVert msh 2 j uvwArray2[j]))
if uvwArray3.count!=0 do(meshop.setNumMaps msh 4 keep:true
for j = 1 to uvwArray3.count do (meshOp.setMapVert msh 3 j uvwArray3[j]))
if uvwArray3.count!=0 do(meshop.setNumMaps msh 5 keep:true
for j = 1 to uvwArray4.count do (meshOp.setMapVert msh 4 j uvwArray3[j]))
setUserProp msh "mesh_data" #(logArray1,logArray2,logArray3)
)
-- )catch(print "Error,Failed to Draw Meshes")
)
format "Last Read @ 0x%\n" ((bit.intAsHex(ftell f))as string)
fclose l
fclose f
) else (Print "Failed to Locate TMCL")) else (Print "Aborted.")