if (heapSize < 200000) then
        heapSize = 2000000 -- allow ~ 40 MB instead of just 7.5 MB. Prevents "Runtime Error: Out of scripter memory"

fname = getOpenFileName \
caption:"Open .flver from Mesh folder" \
types:"Demon's Souls (*.flver)|*.flver" \
historyCategory:"DemonsSoulsSObjectPresets"
f = fopen fname "rb"

clearlistener()

fn readBElong fstream = (bit.swapBytes (bit.swapBytes (readlong fstream #unsigned) 1 4) 2 3)


fn ReadBEshort fstream = (
return (bit.swapBytes (readshort fstream #unsigned) 1 2)
)

fn readBEword fstream = (
short = readshort fstream #unsigned
short = bit.swapBytes short 1 2
return short
)

fn readBEfloat fstream = (bit.intAsFloat (bit.swapBytes (bit.swapBytes (readlong fstream #unsigned) 1 4) 2 3))	

fn ReadBEHalfFloat fstream = 
	(
	hf=readBEword fstream
	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 readFixedString bstream fixedLen = (
local str = ""
for i = 1 to fixedLen do (
str += bit.intAsChar (ReadByte bstream #unsigned))
str
)
struct weight_data
(
	boneids,weights
)
struct Mesh_Info_Struct
(
VertexCount, FaceCount, VertexSize, VertexOffset, VertSecSize, FaceOffset, FaceSecSize
)		
clearlistener()

fseek f 0x6 #seek_set
Endian = ReadByte f
Unk=ReadByte f
type1=ReadBEword f
type2=ReadBEword f
dataOffset = readBElong f	
print (dataOffset as string)
dataSize = readBElong f	
count = readBElong f
numMat = readBElong f	
BoneCount = readBElong f		
numParts = readBElong f	
numMesh = readBElong f	

fseek f 0x80  #seek_set

for a = 1 to count  do (
getPos = ftell f + 64
fseek f getPos #seek_set	
)		
for a = 1 to numMat do (
getPos = ftell f + 32
fseek f getPos #seek_set	
)	

Print ("Bone Start @ 0x"+((bit.intAsHex(ftell f))as string))
	
BNArr = #()
Mesh_Info = #()
Bone_Names_Array = #()	
Trans_array = #()
Rotation_array = #()
Scale_array = #()		
BoneMapCount = 29	
	
BonePos=ftell f
	
for a = 1 to BoneCount do (

fseek f 0xC #seek_cur

BPos=ftell f
BoneNameOff = ReadBElong f	
fseek f BoneNameOff #seek_set
BoneName=readFixedString f 20
fseek f BPos #seek_set
	
fseek f 0x74 #seek_cur
append Bone_Names_Array BoneName		
)
	
fseek f BonePos #seek_set

  BONEarray = #()

  for a = 1 to BoneCount do (
   getPos = ftell f + 128 
   px = readBEFloat f
   py = readBEFloat f
   pz = readBEFloat f
   BONEposition = [px,py,pz]
   ofsBONEname = readBElong f
   rx = readBEFloat f ; ry = readBEFloat f ; rz = readBEFloat f 
   BoneRotation = ((eulerAngles (RadToDeg (rx)) (RadToDeg (ry)) (RadToDeg (rz))) as quat)
   ParentID = readBEword f
   Unknown01 = readBEword f
   sx = readBEFloat f
   sy = readBEFloat f
   sz = readBEFloat f
   BONEscale = [sx,sy,sz]
   Unknown02 = readBEword f
   Unknown03 = readBEword f
   fseek f getPos #seek_set 
	  
   bne = dummy showLinks:true showLinksOnly:true
   bne.scale = BONEscale
   bne.rotation = conjugate BoneRotation
   bne.pos = BONEposition 
   append BONEarray bne
   if ParentID!=(0xFFFF) then (
    bne.parent = BONEarray[(ParentID+1)]
    bne.transform *= bne.parent.transform   
   )
  )

Print ("Bone End @ 0x"+((bit.intAsHex(ftell f))as string))

MeshInfo=ftell f	
	
for a = 1 to numParts do (
LodId= readBElong f
FaceCount= readBElong f		
VertexCount = readBElong f
for a = 1 to BoneMapCount do (	
Bone_Map = ReadBEword f
)	
Null = ReadBEword f
FaceSecSize= readBElong f 
FaceOffset = readBElong f 
VertSecSize = readBElong f
VertexOffset = readBElong f
VertexOffset2 = readBElong f
null2= readBElong f
null3= readBElong f	
VertexSize = (VertSecSize/VertexCount )
append Mesh_Info (Mesh_Info_Struct VertexCount:VertexCount FaceCount:FaceCount VertexSize:VertexSize VertexOffset:VertexOffset VertSecSize:VertSecSize FaceOffset:FaceOffset FaceSecSize:FaceSecSize )				
)

print Mesh_Info

Print ("Mesh Info End @ 0x"+((bit.intAsHex(ftell f))as string))

fseek f MeshInfo #seek_set			
for i = 1 to numParts do (
	
vertArray = #()
Facearray = #()	
UV_array = #()
Weight_array=#()
BoneMapArray = #()	
	
fseek f 0xC #seek_cur		
for a = 1 to BoneMapCount do (	
BoneMapIds = ReadBEword f
if BoneMapIds!=(0xFFFF) then
append BoneMapArray (BoneMapIds+1)
)	
fseek f 0x1E #seek_cur	

print BoneMapArray
Print ("Bone Map End @ 0x"+((bit.intAsHex(ftell f))as string))	
BoneMapEnd=ftell f

	
FaceOffset=(dataOffset+(Mesh_Info[i].FaceOffset))		
fseek f (dataOffset+(Mesh_Info[i].FaceOffset)) #seek_set	
	
Print ("Face Start @ 0x"+((bit.intAsHex(ftell f))as string))	

StartDirection = 1
f1 = ((ReadBEshort f) + 1) 
f2 = ((ReadBEshort f) + 1) 
FaceDirection = StartDirection
while ((ftell f) < (FaceOffset + (Mesh_Info[i].FaceSecSize))) Do (
f3 = (ReadBEshort f)
if (f3==0xFFFF) then (
f1 = ((ReadBEshort f) + 1) 
f2 = ((ReadBEshort f) + 1) 
FaceDirection = StartDirection 
) else (
f3 += 1
FaceDirection *= -1
if (f1!=f2)AND(f2!=f3)AND(f3!=f1) then (
if FaceDirection > 0 then append Facearray [f1,f2,f3]
else append Facearray [f1,f3,f2]
)
f1 = f2
f2 = f3
) 
) 
	
VertOffset=(dataOffset+(Mesh_Info[i].VertexOffset))	
fseek f (dataOffset+(Mesh_Info[i].VertexOffset))	#seek_set	

Print ("Vertex Start @ 0x"+((bit.intAsHex(ftell f))as string))	
if Mesh_Info[i].VertexSize==52 then
for x = 1 to Mesh_Info[i].VertexCount do (
getPos = ftell f + Mesh_Info[i].VertexSize
vx = readBEFloat f
vy = readBEFloat f
vz = readBEFloat f
		
bone1 = readbyte f #unsigned	
bone2 = readbyte f #unsigned	
bone3 = readbyte f #unsigned	
bone4 = readbyte f #unsigned
	
weight1 = (ReadBEword f /32767.00)
weight2 = (ReadBEword f /32767.00)
weight3 = (ReadBEword f /32767.00)
weight4 = (ReadBEword f /32767.00)
	
fseek f 0x14 #seek_cur
	
tu=ReadBEfloat f	
tv=ReadBEfloat f*-1	

w = (weight_data boneids:#() weights:#())
maxweight = 0
if(weight1 != 0) then
   maxweight = maxweight + weight1
if(weight2 != 0) then
   maxweight = maxweight + weight2
if(weight3 != 0) then
   maxweight = maxweight + weight3
if(weight4 != 0) then
   maxweight = maxweight + weight4


if(maxweight != 0) then (
      if(weight1 != 0) then (
         w1 = weight1 as float
         append w.boneids (bone1 + 2)
         append w.weights (w1)
      )
      if(weight2 != 0) then (
         w2 = weight2 as float
         append w.boneids (bone2 + 2)
         append w.weights (w2)
      )
      if(weight3 != 0) then (
         w3 = weight3 as float
         append w.boneids (bone3 + 2)
         append w.weights (w3)
      )
      if(weight4 != 0) then (
         w4 = weight4 as float
         append w.boneids (bone4 + 2)
        append w.weights (w4)
      )      
   )
append Weight_array w	
fseek f getPos #seek_set
append vertArray [vx,vy,vz]
append UV_array [tu,tv,0]	
)		
if Mesh_Info[i].VertexSize==40 then
for x = 1 to Mesh_Info[i].VertexCount do (
getPos = ftell f + Mesh_Info[i].VertexSize
vx = readBEFloat f
vy = readBEFloat f
vz = readBEFloat f
		
bone1 = readbyte f #unsigned	
bone2 = readbyte f #unsigned	
bone3 = readbyte f #unsigned	
bone4 = readbyte f #unsigned
	
weight1 = (ReadBEword f /32767.00)
weight2 = (ReadBEword f /32767.00)
weight3 = (ReadBEword f /32767.00)
weight4 = (ReadBEword f /32767.00)
	
fseek f 0xC #seek_cur
	
tu=ReadBEword f/1024.00	
tv=(ReadBEword f/1024.00)*-1	

w = (weight_data boneids:#() weights:#())
maxweight = 0
if(weight1 != 0) then
   maxweight = maxweight + weight1
if(weight2 != 0) then
   maxweight = maxweight + weight2
if(weight3 != 0) then
   maxweight = maxweight + weight3
if(weight4 != 0) then
   maxweight = maxweight + weight4


if(maxweight != 0) then (
      if(weight1 != 0) then (
         w1 = weight1 as float
         append w.boneids (bone1 + 2)
         append w.weights (w1)
      )
      if(weight2 != 0) then (
         w2 = weight2 as float
         append w.boneids (bone2 + 2)
         append w.weights (w2)
      )
      if(weight3 != 0) then (
         w3 = weight3 as float
         append w.boneids (bone3 + 2)
         append w.weights (w3)
      )
      if(weight4 != 0) then (
         w4 = weight4 as float
         append w.boneids (bone4 + 2)
        append w.weights (w4)
      )      
   )
append Weight_array w	
fseek f getPos #seek_set
append vertArray [vx,vy,vz]
append UV_array [tu,tv,0]	
)	
if Mesh_Info[i].VertexSize==36 then
for x = 1 to Mesh_Info[i].VertexCount do (
getPos = ftell f + Mesh_Info[i].VertexSize
vx = readBEFloat f
vy = readBEFloat f
vz = readBEFloat f
		
bone1 = readbyte f #unsigned	
bone2 = readbyte f #unsigned	
bone3 = readbyte f #unsigned	
bone4 = readbyte f #unsigned
	
weight1 = (ReadBEword f /32767.00)
weight2 = (ReadBEword f /32767.00)
weight3 = (ReadBEword f /32767.00)
weight4 = (ReadBEword f /32767.00)
	
fseek f 0x8 #seek_cur
	
tu=ReadBEword f/1024.00	
tv=(ReadBEword f/1024.00)*-1	

w = (weight_data boneids:#() weights:#())
maxweight = 0
if(weight1 != 0) then
   maxweight = maxweight + weight1
if(weight2 != 0) then
   maxweight = maxweight + weight2
if(weight3 != 0) then
   maxweight = maxweight + weight3
if(weight4 != 0) then
   maxweight = maxweight + weight4


if(maxweight != 0) then (
      if(weight1 != 0) then (
         w1 = weight1 as float
         append w.boneids (bone1 + 2)
         append w.weights (w1)
      )
      if(weight2 != 0) then (
         w2 = weight2 as float
         append w.boneids (bone2 + 2)
         append w.weights (w2)
      )
      if(weight3 != 0) then (
         w3 = weight3 as float
         append w.boneids (bone3 + 2)
         append w.weights (w3)
      )
      if(weight4 != 0) then (
         w4 = weight4 as float
         append w.boneids (bone4 + 2)
        append w.weights (w4)
      )      
   )
append Weight_array w	
fseek f getPos #seek_set
append vertArray [vx,vy,vz]
append UV_array [tu,tv,0]	
)	
if Mesh_Info[i].VertexSize==32 then
for x = 1 to Mesh_Info[i].VertexCount do (
getPos = ftell f + Mesh_Info[i].VertexSize
vx = readBEFloat f
vy = readBEFloat f
vz = readBEFloat f
		
bone1 = readbyte f #unsigned	
bone2 = readbyte f #unsigned	
bone3 = readbyte f #unsigned	
bone4 = readbyte f #unsigned
	
weight1 = (ReadBEword f /32767.00)
weight2 = (ReadBEword f /32767.00)
weight3 = 0
weight4 = 0
	
fseek f 0x8 #seek_cur
	
tu=ReadBEword f/1024.00	
tv=(ReadBEword f/1024.00)*-1	

w = (weight_data boneids:#() weights:#())
maxweight = 0
if(weight1 != 0) then
   maxweight = maxweight + weight1
if(weight2 != 0) then
   maxweight = maxweight + weight2
if(weight3 != 0) then
   maxweight = maxweight + weight3
if(weight4 != 0) then
   maxweight = maxweight + weight4


if(maxweight != 0) then (
      if(weight1 != 0) then (
         w1 = weight1 as float
         append w.boneids (bone1 + 2)
         append w.weights (w1)
      )
      if(weight2 != 0) then (
         w2 = weight2 as float
         append w.boneids (bone2 + 2)
         append w.weights (w2)
      )
      if(weight3 != 0) then (
         w3 = weight3 as float
         append w.boneids (bone3 + 2)
         append w.weights (w3)
      )
      if(weight4 != 0) then (
         w4 = weight4 as float
         append w.boneids (bone4 + 2)
        append w.weights (w4)
      )      
   )
append Weight_array w	
fseek f getPos #seek_set
append vertArray [vx,vy,vz]
append UV_array [tu,tv,0]	
)	
if Mesh_Info[i].VertexSize==28 then
for x = 1 to Mesh_Info[i].VertexCount do (
getPos = ftell f + Mesh_Info[i].VertexSize
vx = readBEFloat f
vy = readBEFloat f
vz = readBEFloat f
		
bone1 = readbyte f #unsigned	
bone2 = readbyte f #unsigned	
bone3 = readbyte f #unsigned	
bone4 = readbyte f #unsigned
	
weight1 = 1.00
	
fseek f 0x8 #seek_cur
	
tu=ReadBEword f/1024.00	
tv=(ReadBEword f/1024.00)*-1	

w = (weight_data boneids:#() weights:#())
maxweight = 0
if(weight1 != 0) then
   maxweight = maxweight + weight1


if(maxweight != 0) then (
      if(weight1 != 0) then (
         w1 = weight1 as float
         append w.boneids (bone1 + 2)
         append w.weights (w1)
      )
   
   )
append Weight_array w	
fseek f getPos #seek_set
append vertArray [vx,vy,vz]
append UV_array [tu,tv,0]	
)	

fseek f BoneMapEnd #seek_set

try(
msh = mesh vertices:vertArray faces:faceArray
msh.numTVerts = UV_array.count
buildTVFaces msh
for j = 1 to UV_array.count do setTVert msh j UV_array[j]
for j = 1 to faceArray.count do setTVFace msh j faceArray[j]
msh.displayByLayer = false
msh.backfacecull = false
msh.wirecolor = (color 230 200 210)

max modify mode
select msh
skinMod = skin ()
addModifier msh skinMod
for i = 1 to BoneMapArray.Count do
(
	maxbone = BONEarray[(BoneMapArray[i])] 
	if i != BoneMapArray.Count then 
		skinOps.addBone skinMod maxbone 0
	else
		skinOps.addBone skinMod maxbone 1
)
modPanel.setCurrentObject skinMod
for i = 1 to (Mesh_Info[i].VertexCount) do (
   w = Weight_array[i]
   bi = #() --bone index array
   wv = #() --weight value array
   
   for j = 1 to w.boneids.count do
   (
      boneid = w.boneids[j]
      weight = w.weights[j]
      append bi boneid
      append wv weight
   )   
   
   skinOps.ReplaceVertexWeights skinMod i bi wv
   
)
)catch(format "failed!!\n")
)

fclose f