BTW: I'm ignoring "elite" HOD's and "Backgroud" HOD's...I don't care about the right now.
Code:
Public Module HOD
Public Class FORM_HEADER
Public tid As String 'Always FORM/NRML
Public rev_len As Integer 'Reversed 4 bytes!
Public Sub ReadHOD(ByVal f As Integer)
ReadString(f, tid, 4)
ReadRevInt32(f, rev_len)
End Sub
Public Sub WriteHOD(ByVal f As Integer)
WriteString(f, tid, 4)
WriteRevInt32(f, rev_len)
End Sub
End Class
Public Class BMSH_VT1B
Public vCo(2) As Single ' vertex coordinates
Public sepr1 As Integer ' '{00 00 80 3F} (interpreted as a separator)
Public vN(2) As Single ' vertex normal
Public sepr2 As Integer ' '{00 00 80 3F} (interpreted as a separator)
Public tCo(1) As Single ' texture coordinates
Public Sub ReadHOD(ByVal f As Integer)
FileGet(f, vCo)
ReadInt32(f, sepr1)
FileGet(f, vN)
ReadInt32(f, sepr2)
FileGet(f, tCo)
End Sub
Public Sub WriteHOD(ByVal f As Integer)
FilePut(f, vCo)
WriteInt32(f, sepr1)
FilePut(f, vN)
WriteInt32(f, sepr2)
FilePut(f, tCo)
End Sub
Public Function Update() As Integer
Return 40
End Function
End Class
Public Class FACE_LIST
Public nIdx As Integer
Public Idx() As Short
Public Sub ReadHOD(ByVal f As Integer)
ReadInt32(f, nIdx)
ReDim Idx(nIdx - 1)
FileGet(f, Idx)
End Sub
Public Sub WriteHOD(ByVal f As Integer)
WriteInt32(f, nIdx)
FilePut(f, Idx)
End Sub
Public Function Update() As Integer
Return 4 + 2 * nIdx
End Function
End Class
Public Class BMSH_MESH
Public STATtag As Integer ' pointer to a shader (therefor points to a texture group)
Public dwordsPerVtx As Integer ' = 27 {1B 00 00 00} for ship-mesh BMSH chunks,
Public noVtcs As Integer ' number of vertices in this mesh part.
Public Vtx() As BMSH_VT1B
Public noFcLists As Short ' Appears to be 'number of face-lists' of either type '514' or '518' facelists (latter for 'elite').
Public fcListType() As Integer ' Face list type identifier: '514' {02 02 00 00}, or '518' {06 02 00 00} (latter for 'elite').
Public fcLst() As FACE_LIST ' Listing of vertex-indices (starting at zero). Good examples: 'ca_cap.hod', 'fiery_fingers_sphere.hod',
Public Sub ReadHOD(ByVal f As Integer)
ReadInt32(f, STATtag)
ReadInt32(f, dwordsPerVtx)
ReadInt32(f, noVtcs)
ReDim Vtx(noVtcs)
Dim i As Integer
For i = 0 To noVtcs - 1
Vtx(i) = New BMSH_VT1B
Vtx(i).ReadHOD(f)
Next
ReadInt16(f, noFcLists)
ReDim fcListType(noFcLists - 1)
FileGet(f, fcListType)
ReDim fcLst(noFcLists - 1)
For i = 0 To noFcLists - 1
fcLst(i) = New FACE_LIST
fcLst(i).ReadHOD(f)
Next
End Sub
Public Sub WriteHOD(ByVal f As Integer)
WriteInt32(f, STATtag)
WriteInt32(f, dwordsPerVtx)
WriteInt32(f, noVtcs)
Dim i As Integer
For i = 0 To noVtcs - 1
Vtx(i).WriteHOD(f)
Next
WriteInt16(f, noFcLists)
FilePut(f, fcListType)
For i = 0 To noFcLists - 1
fcLst(i).WriteHOD(f)
Next
End Sub
Public Function Update() As Integer
Dim len As Integer = 14 + noVtcs * 40 + noFcLists * 4
Dim i As Integer
For i = 0 To noFcLists - 1
len += fcLst(i).Update()
Next
Return len
End Function
End Class
Public Class BMSH_CHUNK
Public head As FORM_HEADER
Public tID As String ' type ID = 'BMSH'
Public altLf As Integer ' Used alternatively to contain form length (# bytes) if no header is used.
Public LOD As Integer ' LOD number. Contains zero when used in GLOW chunks.
Public noMshs As Integer ' number of meshes in this BMSH chunk.
Public shipmesh() As BMSH_MESH
Public Sub ReadHOD(ByVal f As Integer)
head = New FORM_HEADER
head.ReadHOD(f)
ReadString(f, tID, 4)
ReadRevInt32(f, altLf)
ReadInt32(f, LOD)
ReadInt32(f, noMshs)
Dim i As Integer
ReDim shipmesh(noMshs - 1)
For i = 0 To noMshs - 1
shipmesh(i) = New BMSH_MESH
shipmesh(i).ReadHOD(f)
Next
End Sub
Public Sub WriteHOD(ByVal f As Integer)
head.WriteHOD(f)
WriteString(f, tID, 4)
WriteRevInt32(f, altLf)
WriteInt32(f, LOD)
WriteInt32(f, noMshs)
Dim i As Integer
For i = 0 To noMshs - 1
shipmesh(i).WriteHOD(f)
Next
End Sub
Public Function Update() As Integer
Dim len As Integer = 16
Dim i As Integer
For i = 0 To noMshs - 1
len += shipmesh(i).Update()
Next
Return len
End Function
End Class
Public Class OWNR_CHUNK
Public tid As String
Public rev_len As Integer 'rev(?)
Public lOwner As Integer
Public nOwner As String
Public Sub ReadHOD(ByVal f As Integer)
ReadString(f, tid, 4)
ReadRevInt32(f, rev_len)
ReadHODString(f, lOwner, nOwner)
End Sub
Public Sub WriteHOD(ByVal f As Integer)
WriteString(f, tid, 4)
WriteRevInt32(f, rev_len)
WriteHODString(f, lOwner, nOwner)
End Sub
Public Function Update() As Integer
Return 12 + lOwner
End Function
End Class
Public Class WARN_CHUNK
Public tid As String
Public rev_len As Integer 'rev(?)
Public lWarn As Integer
Public nWarn As String
Public Sub ReadHOD(ByVal f As Integer)
ReadString(f, tid, 4)
ReadRevInt32(f, rev_len)
ReadHODString(f, lWarn, nWarn)
End Sub
Public Sub WriteHOD(ByVal f As Integer)
WriteString(f, tid, 4)
WriteRevInt32(f, rev_len)
WriteHODString(f, lWarn, nWarn)
End Sub
Public Function Update() As Integer
Return 12 + lWarn
End Function
End Class
Public Class ERRR_CHUNK
Public tid As String
Public rev_len As Integer 'rev(?)
Public lErr As Integer
Public nErr As String
Public Sub ReadHOD(ByVal f As Integer)
ReadString(f, tid, 4)
ReadRevInt32(f, rev_len)
ReadHODString(f, lErr, nErr)
End Sub
Public Sub WriteHOD(ByVal f As Integer)
WriteString(f, tid, 4)
WriteRevInt32(f, rev_len)
WriteHODString(f, lErr, nErr)
End Sub
Public Function Update() As Integer
Return 12 + lErr
End Function
End Class
Public Class INFO_CHUNK
Public head As FORM_HEADER
Public tid As String
Public Owner As OWNR_CHUNK
Public Warnings As WARN_CHUNK
Public Errors As ERRR_CHUNK
Public Sub ReadHOD(ByVal f As Integer)
'Assuming always last thing in file.
head = New FORM_HEADER
head.ReadHOD(f)
ReadString(f, tid, 4)
While Not EOF(f)
Select Case PeekHead(f)
Case "OWNR"
Owner = New OWNR_CHUNK
Owner.ReadHOD(f)
Case "WARN"
Warnings = New WARN_CHUNK
Warnings.ReadHOD(f)
Case "ERRR"
Errors = New ERRR_CHUNK
Errors.ReadHOD(f)
Case Else
Return
End Select
End While
End Sub
Public Sub WriteHOD(ByVal f As Integer)
head.WriteHOD(f)
WriteString(f, tid, 4)
If Not Owner Is Nothing Then Owner.WriteHOD(f)
If Not Warnings Is Nothing Then Warnings.WriteHOD(f)
If Not Errors Is Nothing Then Errors.WriteHOD(f)
End Sub
Public Function Update() As Integer
head.rev_len = 4 + Owner.Update()
Return 0 'irrelevent
End Function
End Class
Public Class HIER_OBJECT
Public lName As Integer
Public nName As String
Public lParent As Integer
Public nParent As String
Public Position(2) As Single
Public Orientation(2) As Single
Public Scale(2) As Single
Public Unused(2) As Single
Public Unused2(2) As Byte
Public nChildren As Integer
Public Children() As HIER_OBJECT
Public Function FindObject(ByVal n As String) As HIER_OBJECT
If n = nName Then Return Me
Dim i As Integer
For i = 0 To nChildren - 1
Dim h1 As HIER_OBJECT
h1 = Children(i).FindObject(n)
If Not h1 Is Nothing Then
Return h1
End If
Next
End Function
Public Sub ReadHOD(ByVal f As Integer, ByVal root As HIER_OBJECT)
ReadHODString(f, lName, nName)
ReadHODString(f, lParent, nParent)
FileGet(f, Position)
FileGet(f, Orientation)
FileGet(f, Scale)
FileGet(f, Unused)
FileGet(f, Unused2)
If (lParent > 0) Then
Dim h1 As HIER_OBJECT
h1 = root.FindObject(nParent)
ReDim Preserve h1.Children(h1.nChildren)
h1.Children(h1.nChildren) = Me
h1.nChildren += 1
End If
nChildren = 0
End Sub
Public Sub WriteHOD(ByVal f As Integer)
WriteHODString(f, lName, nName)
WriteHODString(f, lParent, nParent)
FilePut(f, Position)
FilePut(f, Orientation)
FilePut(f, Scale)
FilePut(f, Unused)
FileGet(f, Unused2)
Dim i As Integer
For i = 0 To nChildren - 1
Children(i).WriteHOD(f)
Next
End Sub
Public Function Update() As Integer
Dim len As Integer = 8 + 12 * 4 + 3
Dim i As Integer
For i = 0 To nChildren - 1
len += Children(i).Update()
Next
Return len
End Function
End Class
Public Class HIER_CHUNK
Public tid As String
Public rev_len As Integer 'reversed!
Public nObjects As Integer
Public Object_Root As HIER_OBJECT
Public Sub ReadHOD(ByVal f As Integer)
ReadString(f, tid, 4)
ReadRevInt32(f, rev_len)
ReadInt32(f, nObjects)
Dim i As Integer
Object_Root = New HIER_OBJECT
Object_Root.ReadHOD(f, Nothing)
For i = 1 To nObjects - 1
Dim ctemp As HIER_OBJECT
ctemp = New HIER_OBJECT
ctemp.ReadHOD(f, Object_Root)
Next
End Sub
Public Sub WriteHOD(ByVal f As Integer)
WriteString(f, tid, 4)
WriteRevInt32(f, rev_len)
WriteInt32(f, nObjects)
Object_Root.WriteHOD(f)
End Sub
Public Function Update() As Integer
rev_len = 8
rev_len += Object_Root.Update()
Return rev_len + 8
End Function
End Class
Public Class HOD_POINT
Public val(2) As Single
Public Sub ReadHOD(ByVal f As Integer)
FileGet(f, val)
End Sub
Public Sub WriteHOD(ByVal f As Integer)
FilePut(f, val)
End Sub
Public Function Update() As Integer
Return 12
End Function
End Class
Public Class ETSH_SHAPE
Public nPoints As Integer
Public Points() As HOD_POINT
Public Sub ReadHOD(ByVal f As Integer)
ReadInt32(f, nPoints)
ReDim Points(nPoints - 1)
Dim i As Integer
For i = 0 To nPoints - 1
Points(i) = New HOD_POINT
Points(i).ReadHOD(f)
Next
End Sub
Public Sub WriteHOD(ByVal f As Integer)
WriteInt32(f, nPoints)
Dim i As Integer
For i = 0 To nPoints - 1
Points(i).WriteHOD(f)
Next
End Sub
Public Function Update() As Integer
Return 4 + 12 * nPoints
End Function
End Class
Public Class ETSH_CHUNK
Public tid As String
Public rev_len As Integer 'reversed(?)
Public lName As Integer
Public nName As String
Public lHierObject As Integer
Public nHierObject As String
Public Shapes() As ETSH_SHAPE
Public Sub ReadHOD(ByVal f As Integer)
ReadString(f, tid, 4)
ReadRevInt32(f, rev_len)
Dim bpos As Integer = Seek(f)
ReadHODString(f, lName, nName)
ReadHODString(f, lHierObject, nHierObject)
Dim ns As Integer = 0
While Seek(f) - bpos < rev_len
ReDim Preserve Shapes(ns)
Shapes(ns) = New ETSH_SHAPE
Shapes(ns).ReadHOD(f)
End While
End Sub
Public Sub WriteHOD(ByVal f As Integer)
WriteString(f, tid, 4)
WriteRevInt32(f, rev_len)
WriteHODString(f, lName, nName)
WriteHODString(f, lHierObject, nHierObject)
Dim i As Integer
For i = 0 To Shapes.Length - 1
Shapes(i).WriteHOD(f)
Next
End Sub
Public Function Update() As Integer
rev_len = 8 + lName + lHierObject
Dim i As Integer
For i = 0 To Shapes.Length - 1
rev_len += Shapes(i).Update()
Next
Return rev_len + 8
End Function
End Class
Public Class GLOW_INFO_HEAD
Public head As FORM_HEADER
Public tid As String
Public rev_len As Integer 'reversed(?)
End Class
Public Class GLOW_CHUNK
Public tid As String
Public infohead As GLOW_INFO_HEAD
Public lName As Integer
Public nName As String
Public lHierObject As Integer
Public nHierObject As String
Public LOD As Integer 'Always 0
Public mesh As BMSH_CHUNK
Public Sub ReadHOD(ByVal f As Integer)
ReadString(f, tid, 4)
infohead = New GLOW_INFO_HEAD
infohead.head = New FORM_HEADER
ReadString(f, infohead.head.tid, 4)
ReadRevInt32(f, infohead.head.rev_len)
ReadString(f, infohead.tid, 4)
ReadRevInt32(f, infohead.rev_len)
ReadHODString(f, lName, nName)
ReadHODString(f, lHierObject, nHierObject)
ReadInt32(f, LOD)
mesh.ReadHOD(f)
End Sub
Public Sub WriteHOD(ByVal f As Integer)
WriteString(f, tid, 4)
WriteString(f, infohead.head.tid, 4)
WriteRevInt32(f, infohead.head.rev_len)
WriteString(f, infohead.tid, 4)
WriteRevInt32(f, infohead.rev_len)
WriteHODString(f, lName, nName)
WriteHODString(f, lHierObject, nHierObject)
WriteInt32(f, LOD)
mesh.WriteHOD(f)
End Sub
Public Function Update() As Integer
infohead.rev_len = 8 + lName + lHierObject + mesh.Update()
infohead.head.rev_len = infohead.rev_len + 8
Return infohead.head.rev_len + 8
End Function
End Class
Public Class BURN_CHUNK
Public tid As String
Public lName As Integer
Public nName As String
Public lHierObject As Integer
Public nHierObject As String
Public nPts As Integer 'Always 5(?)
Public unk As Integer ' Always 1(?)
Public pts() As HOD_POINT
Public Sub ReadHOD(ByVal f As Integer)
ReadString(f, tid, 4)
ReadHODString(f, lName, nName)
ReadHODString(f, lHierObject, nHierObject)
ReadInt32(f, nPts)
ReadInt32(f, unk)
Dim i As Integer
ReDim pts(nPts - 1)
For i = 0 To nPts - 1
pts(i) = New HOD_POINT
pts(i).ReadHOD(f)
Next
End Sub
Public Sub WriteHOD(ByVal f As Integer)
WriteString(f, tid, 4)
WriteHODString(f, lName, nName)
WriteHODString(f, lHierObject, nHierObject)
WriteInt32(f, nPts)
WriteInt32(f, unk)
Dim i As Integer
For i = 0 To nPts - 1
pts(i).WriteHOD(f)
Next
End Sub
Public Function Update() As Integer
Dim i, len As Integer
len = 20 + lName + lHierObject
For i = 0 To nPts - 1
len += pts(i).Update()
Next
Return len
End Function
End Class
Public Class NAV_LIGHT
Public lHierObject As Integer
Public nHierObject As String
Public color(3) As Single
Public lType As Integer
Public nType As String
Public o(4) As Single
Public sepr(1) As Byte ' {01} or {00}
Public Sub ReadHOD(ByVal f As Integer)
ReadHODString(f, lHierObject, nHierObject)
FileGet(f, color)
ReadHODString(f, lType, nType)
FileGet(f, o)
FileGet(f, sepr)
End Sub
Public Sub WriteHOD(ByVal f As Integer)
WriteHODString(f, lHierObject, nHierObject)
FilePut(f, color)
WriteHODString(f, lType, nType)
FilePut(f, o)
FilePut(f, sepr)
End Sub
Public Function Update() As Integer
Return 46
End Function
End Class
Public Class NAVL_CHUNK
Public head As FORM_HEADER
Public tid As String
Public rev_len As Integer 'Always 3(?)
Public nLights As Integer
Public NavLights() As NAV_LIGHT
Public Sub ReadHOD(ByVal f As Integer)
head = New FORM_HEADER
ReadString(f, head.tid, 4)
ReadRevInt32(f, head.rev_len)
ReadString(f, tid, 4)
ReadRevInt32(f, rev_len)
ReadInt32(f, nLights)
Dim i As Integer
ReDim NavLights(nLights - 1)
For i = 0 To nLights - 1
NavLights(i) = New NAV_LIGHT
NavLights(i).ReadHOD(f)
Next
End Sub
Public Sub WriteHOD(ByVal f As Integer)
WriteString(f, head.tid, 4)
WriteRevInt32(f, head.rev_len)
WriteString(f, tid, 4)
WriteRevInt32(f, rev_len)
WriteInt32(f, nLights)
Dim i As Integer
For i = 0 To nLights - 1
NavLights(i).WriteHOD(f)
Next
End Sub
Public Function Update() As Integer
rev_len = 4 + 46 * nLights
head.rev_len = rev_len + 8
Return head.rev_len + 8
End Function
End Class
Public Class DOCK_PATH_POINT '64 bytes :)
Public pCo(2) As Single 'position?
Public pOr(2) As Single 'orientation?
'*** Below: probably spline parameters or flags
Public flag0 As Integer ' must be Long!
Public flag1 As Single ' must be Single! (All investigated)
Public flag2 As Integer ' must be Long!
Public flag3 As Single ' must be Single!
Public flag4(5) As Integer ' must be Long! ' Usually there are TEN flags all together except e.g the meg_progenitorpowermodule.hod (others?).
Public Sub ReadHOD(ByVal f As Integer)
FileGet(f, pCo)
FileGet(f, pOr)
ReadInt32(f, flag0)
FileGet(f, flag1)
ReadInt32(f, flag2)
FileGet(f, flag3)
FileGet(f, flag4)
End Sub
Public Sub WriteHOD(ByVal f As Integer)
FilePut(f, pCo)
FilePut(f, pOr)
WriteInt32(f, flag0)
FilePut(f, flag1)
WriteInt32(f, flag2)
FilePut(f, flag3)
FilePut(f, flag4)
End Sub
Public Function Update() As Integer
Return 64 'irrelevent anyways
End Function
End Class
Public Class DOCK_PATH
Public lName As Integer
Public nName As String
Public lHierObject As Integer
Public nHierObject As String
Public unknown As Integer 'Always 6(?)
Public nPars As Integer
Public flags(2) As Integer
Public lAllowed As Integer
Public nAllowed As String
Public flags2 As Integer
Public lAlt As Integer
Public nAlt As String
Public nPoints As Integer
Public Points() As DOCK_PATH_POINT
Public Sub ReadHOD(ByVal f As Integer)
ReadHODString(f, lName, nName)
ReadHODString(f, lHierObject, nHierObject)
ReadInt32(f, unknown)
ReadInt32(f, nPars)
FileGet(f, flags)
ReadHODString(f, lAllowed, nAllowed)
ReadInt32(f, flags2)
ReadHODString(f, lAlt, nAlt)
ReadInt32(f, nPoints)
Dim i As Integer
ReDim Points(nPoints - 1)
For i = 0 To nPoints - 1
Points(i) = New DOCK_PATH_POINT
Points(i).ReadHOD(f)
Next
End Sub
Public Sub WriteHOD(ByVal f As Integer)
WriteHODString(f, lName, nName)
WriteHODString(f, lHierObject, nHierObject)
WriteInt32(f, unknown)
WriteInt32(f, nPars)
FilePut(f, flags)
WriteHODString(f, lAllowed, nAllowed)
WriteInt32(f, flags2)
WriteHODString(f, lAlt, nAlt)
WriteInt32(f, nPoints)
Dim i As Integer
For i = 0 To nPoints - 1
Points(i).WriteHOD(f)
Next
End Sub
Public Function Update() As Integer
Return 44 + lName + lHierObject + lAllowed + lAlt + nPoints * 64
End Function
End Class
Public Class DOCK_CHUNK
Public tid As String
Public rev_len As Integer
Public nPath As Integer
Public Paths() As DOCK_PATH
Public Sub ReadHOD(ByVal f As Integer)
ReadString(f, tid, 4)
ReadRevInt32(f, rev_len)
ReadInt32(f, nPath)
Dim i As Integer
ReDim Paths(nPath - 1)
For i = 0 To nPath - 1
Paths(i) = New DOCK_PATH
Paths(i).ReadHOD(f)
Next
End Sub
Public Sub WriteHOD(ByVal f As Integer)
WriteString(f, tid, 4)
WriteRevInt32(f, rev_len)
WriteInt32(f, nPath)
Dim i As Integer
For i = 0 To nPath - 1
Paths(i).WriteHOD(f)
Next
End Sub
Public Function Update() As Integer
rev_len = 4
Dim i As Integer
For i = 0 To nPath - 1
rev_len += Paths(i).Update()
Next
Return rev_len + 8
End Function
End Class
Public Class ANIM_KEYFRAME
Public kTime As Double ' Time values ( x 1/30th again! ).
'*** These appear not to be like their variable name! (see vgr_infiltratorpod.hod).
Public kPos(2) As Single
Public kRot(2) As Single
Public Sub ReadHOD(ByVal f As Integer)
FileGet(f, kTime)
FileGet(f, kPos)
FileGet(f, kRot)
End Sub
Public Sub WriteHOD(ByVal f As Integer)
FilePut(f, kTime)
FilePut(f, kPos)
FilePut(f, kRot)
End Sub
Public Function Update() As Integer
Return 32
End Function
End Class
Public Class ANIM_CHUNK
Public head As FORM_HEADER
Public tID As String
Public noAnimPars As Integer ' number of animation parameters in this form = always 1 ? (Reversed Long).
Public lPar As Integer ' # bytes in animation parameter name.
Public nPar As String ' animation parameter name.
Public noKeyfs As Integer ' number of keyframes
Public keyframe() As ANIM_KEYFRAME
Public sepr As Double ' or two Longs? It always seems to be zero.
Public Sub ReadHOD(ByVal f As Integer)
head = New FORM_HEADER
ReadString(f, head.tid, 4)
ReadRevInt32(f, head.rev_len)
ReadString(f, tID, 4)
ReadInt32(f, noAnimPars)
ReadHODString(f, lPar, nPar)
ReadInt32(f, noKeyfs)
Dim i As Integer
ReDim keyframe(noKeyfs - 1)
For i = 0 To noKeyfs - 1
keyframe(i) = New ANIM_KEYFRAME
keyframe(i).ReadHOD(f)
Next
End Sub
Public Sub WriteHOD(ByVal f As Integer)
WriteString(f, head.tid, 4)
WriteRevInt32(f, head.rev_len)
WriteString(f, tID, 4)
WriteInt32(f, noAnimPars)
WriteHODString(f, lPar, nPar)
WriteInt32(f, noKeyfs)
Dim i As Integer
For i = 0 To noKeyfs - 1
keyframe(i).WriteHOD(f)
Next
End Sub
Public Function Update() As Integer
head.rev_len = 16 + lPar + noKeyfs * 32
Return head.rev_len + 8
End Function
End Class
Public Class MRKR_CHUNK
Public head As FORM_HEADER
Public tid As String
Public head2 As FORM_HEADER
Public head_tid As String
Public unused As Integer 'reversed
Public lName As Integer
Public nName As String
Public lHierObject As Integer
Public nHierObject As String
Public sepr As Double
Public pos(2) As Double
Public ori(2) As Double
Public KEYF_head As FORM_HEADER
Public k_tid As String
Public Sub ReadHOD(ByVal f As Integer)
head = New FORM_HEADER
ReadString(f, head.tid, 4)
ReadRevInt32(f, head.rev_len)
ReadString(f, tid, 4)
head2 = New FORM_HEADER
head2.ReadHOD(f)
ReadString(f, head_tid, 4)
ReadInt32(f, unused)
ReadHODString(f, lName, nName)
ReadHODString(f, lHierObject, nHierObject)
FileGet(f, sepr)
FileGet(f, pos)
FileGet(f, ori)
KEYF_head = New FORM_HEADER
ReadString(f, KEYF_head.tid, 4)
ReadInt32(f, KEYF_head.rev_len)
ReadString(f, k_tid, 4)
End Sub
Public Sub WriteHOD(ByVal f As Integer)
WriteString(f, head.tid, 4)
WriteRevInt32(f, head.rev_len)
WriteString(f, tid, 4)
head2.WriteHOD(f)
WriteString(f, head_tid, 4)
WriteInt32(f, unused)
WriteHODString(f, lName, nName)
WriteHODString(f, lHierObject, nHierObject)
FilePut(f, sepr)
FilePut(f, pos)
FilePut(f, ori)
WriteString(f, KEYF_head.tid, 4)
WriteInt32(f, KEYF_head.rev_len)
WriteString(f, k_tid, 4)
End Sub
Public Function Update() As Integer
head2.rev_len = 84 + lName + lHierObject
head.rev_len = head2.rev_len + 12
Return head.rev_len + 8
End Function
End Class
Public Class BNDV_CHUNK
' Could be something like: 'camara can't zoom closer than'.
Public tID As String ' type ID = 'BNDV'
Public lF As Integer ' # bytes in form
Public lN As Integer ' # bytes in name to follow (usually 5).
Public nAll As String ' = 'Whole'
Public lO As Integer ' # bytes in object name
Public nO As String ' object name (usually 'Root').
Public noGenPts As Integer ' = always 8 (like: generate EIGHT corners from points below).
Public leftLowerCorner(2) As Single ' checked OK in drawing program.
Public sepr1(14) As Integer ' = always all zero
Public rightUpperCorner(2) As Single ' checked OK in drawing program.
Public sepr2(3) As Integer ' = always all zero
Public Sub ReadHOD(ByVal f As Integer)
ReadString(f, tID, 4)
ReadRevInt32(f, lF)
ReadHODString(f, lN, nAll)
ReadHODString(f, lO, nO)
ReadInt32(f, noGenPts)
FileGet(f, leftLowerCorner)
FileGet(f, sepr1)
FileGet(f, rightUpperCorner)
FileGet(f, sepr2)
End Sub
Public Sub WriteHOD(ByVal f As Integer)
WriteString(f, tID, 4)
WriteRevInt32(f, lF)
WriteHODString(f, lN, nAll)
WriteHODString(f, lO, nO)
WriteInt32(f, noGenPts)
FilePut(f, leftLowerCorner)
FilePut(f, sepr1)
FilePut(f, rightUpperCorner)
FilePut(f, sepr2)
End Sub
Public Function Update() As Integer
lF = 64 + lN + lO
Return lF + 8
End Function
End Class
Public Class COL_BBOX
Public tID As String ' type ID = 'BBOX'
Public rev_len As Integer ' # bytes to follow in this chunk (seen when this chunk is part of a 'COLD' form).
' NB: contains '1000' or {00 00 03 E8} in BSRM form. (Reversed Long).
Public leftLowerCorner(2) As Single ' checked OK in drawing program.
Public edgeSizes(2) As Single ' checked OK in drawing program
Public Sub ReadHOD(ByVal f As Integer)
ReadString(f, tID, 4)
ReadRevInt32(f, rev_len)
FileGet(f, leftLowerCorner)
FileGet(f, edgeSizes)
End Sub
Public Sub WriteHOD(ByVal f As Integer)
WriteString(f, tID, 4)
WriteRevInt32(f, rev_len)
FilePut(f, leftLowerCorner)
FilePut(f, edgeSizes)
End Sub
Public Function Update(ByVal isBSRM As Boolean) As Integer
If (isBSRM = False) Then
rev_len = 24
End If
Return 32
End Function
End Class
Public Class COL_BSPH
Public tID As String ' type ID = 'BSPH'
Public lF As Integer ' # bytes to follow in this chunk (seen when this chunk is part of a 'COLD' form).
' NB: contains '1000' or {00 00 03 E8} in BSRM form. (Reversed Long).
Public center(2) As Single ' checked OK in drawing program.
Public radius As Single ' checked OK in drawing program.
Public Sub ReadHOD(ByVal f As Integer)
ReadString(f, tID, 4)
ReadRevInt32(f, lF)
FileGet(f, center)
FileGet(f, radius)
End Sub
Public Sub WriteHOD(ByVal f As Integer)
WriteString(f, tID, 4)
WriteRevInt32(f, lF)
FilePut(f, center)
FilePut(f, radius)
End Sub
Public Function Update(ByVal isBSRM As Boolean) As Integer
If isBSRM = False Then lF = 16
Return 24
End Function
End Class
Public Class TRIS_TRIS
Public pts(2) As Short
Public Sub ReadHOD(ByVal f As Integer)
FileGet(f, pts)
End Sub
Public Sub WriteHOD(ByVal f As Integer)
FilePut(f, pts)
End Sub
Public Function Update() As Integer
Return 12
End Function
End Class
Public Class COL_TRIS
Public tID As String ' type ID = 'TRIS'
Public lF As Integer ' # bytes to follow in this chunk (seen when this chunk is part of a 'COLD' form).
' NB: contains '1000' or {00 00 03 E8} in BSRM form. (Reversed Long).
Public noVtcs As Integer ' number of vertices
Public vtx() As HOD_POINT ' this time no vertex normals and texture coordinates attached (unlike BMSH vertices).
Public noFcs As Integer ' (number of faces) * 3 (*** No separator used).
Public fc() As TRIS_TRIS
Public Sub ReadHOD(ByVal f As Integer)
ReadString(f, tID, 4)
ReadRevInt32(f, lF)
ReadInt32(f, noVtcs)
Dim i As Integer
ReDim vtx(noVtcs - 1)
For i = 0 To noVtcs - 1
vtx(i) = New HOD_POINT
vtx(i).ReadHOD(f)
Next
ReadInt32(f, noFcs)
noFcs = noFcs / 3
ReDim fc(noFcs - 1)
For i = 0 To noFcs - 1
fc(i) = New TRIS_TRIS
fc(i).ReadHOD(f)
Next
End Sub
Public Sub WriteHOD(ByVal f As Integer)
WriteString(f, tID, 4)
WriteRevInt32(f, lF)
WriteInt32(f, noVtcs)
Dim i As Integer
For i = 0 To noVtcs - 1
vtx(i).WriteHOD(f)
Next
WriteInt32(f, noFcs * 3)
For i = 0 To noFcs - 1
fc(i).WriteHOD(f)
Next
End Sub
Public Function Update(ByVal isBSRM As Boolean) As Integer
If (isBSRM = False) Then
lF = 8 + noVtcs * 12 + noFcs * 6
End If
Return 16 + noVtcs * 12 + noFcs * 6
End Function
End Class
Public Class COLD_CHUNK
Public head As FORM_HEADER
Public tID As String ' type ID = 'COLD' NOTE: COLD chunks don't use an 'altLf' or 'lF' variable!
Public lO As Integer ' # bytes in object name to follow.
Public nO As String ' Hierarchy object name.
Public bbox As COL_BBOX ' occurs once in COLD chunk, without header.
Public bsph As COL_BSPH ' occurs once in COLD chunk, without header.
Public tris As COL_TRIS ' occurs once in COLD chunk, without header.
Public Sub ReadHOD(ByVal f As Integer)
head = New FORM_HEADER
ReadString(f, head.tid, 4)
ReadRevInt32(f, head.rev_len)
ReadString(f, tID, 4)
ReadHODString(f, lO, nO)
bbox = New COL_BBOX
bbox.ReadHOD(f)
bsph = New COL_BSPH
bsph.ReadHOD(f)
tris = New COL_TRIS
tris.ReadHOD(f)
End Sub
Public Sub WriteHOD(ByVal f As Integer)
WriteString(f, head.tid, 4)
WriteRevInt32(f, head.rev_len)
WriteString(f, tID, 4)
WriteHODString(f, lO, nO)
bbox.WriteHOD(f)
bsph.WriteHOD(f)
tris.WriteHOD(f)
End Sub
Public Function Update() As Integer
head.rev_len = 8 + lO + bbox.Update(False) + bsph.Update(False) + tris.Update(False)
Return head.rev_len + 8
End Function
End Class
Public Class BSRM_DESC
Public tID As String ' type ID = 'DESC'
Public altLf As Integer ' # of bytes in form
Public lN As Integer ' # bytes in mesh name
Public nM As String ' mesh name
Public lO As Integer ' # bytes in object name
Public nO As String ' object name
Public nonGoblin As Integer ' Goblin indicator: 0 for goblin, 1 for non-goblin
Public Sub ReadHOD(ByVal f As Integer)
ReadString(f, tID, 4)
ReadRevInt32(f, altLf)
ReadHODString(f, lN, nM)
ReadHODString(f, lO, nO)
ReadInt32(f, nonGoblin)
End Sub
Public Sub WriteHOD(ByVal f As Integer)
WriteString(f, tID, 4)
WriteRevInt32(f, altLf)
WriteHODString(f, lN, nM)
WriteHODString(f, lO, nO)
WriteInt32(f, nonGoblin)
End Sub
Public Function Update() As Integer
Return 20 + lN + lO
End Function
End Class
Public Class COL_NRML
Public tID As String ' type ID = 'VNRM'
Public lF As Integer ' # bytes to follow in this chunk
Public noVtcs As Integer ' number of vertices
Public vtx() As HOD_POINT ' this time no vertex normals and texture coordinates attached (unlike BMSH vertices).
Public noFcs As Integer ' (number of faces) * 3 (*** No separator used).
Public fc() As TRIS_TRIS
Public Sub ReadHOD(ByVal f As Integer)
ReadString(f, tID, 4)
ReadRevInt32(f, lF)
ReadInt32(f, noVtcs)
Dim i As Integer
ReDim vtx(noVtcs - 1)
For i = 0 To noVtcs - 1
vtx(i) = New HOD_POINT
vtx(i).ReadHOD(f)
Next
ReadInt32(f, noFcs)
noFcs = noFcs / 3
ReDim fc(noFcs - 1)
For i = 0 To noFcs - 1
fc(i) = New TRIS_TRIS
fc(i).ReadHOD(f)
Next
End Sub
Public Sub WriteHOD(ByVal f As Integer)
WriteString(f, tID, 4)
WriteRevInt32(f, lF)
WriteInt32(f, noVtcs)
Dim i As Integer
For i = 0 To noVtcs - 1
vtx(i).WriteHOD(f)
Next
WriteInt32(f, noFcs * 3)
For i = 0 To noFcs - 1
fc(i).WriteHOD(f)
Next
End Sub
Public Function Update() As Integer
Return 16 + noVtcs * 12 + noFcs * 6
End Function
End Class
Public Class BSRM_SSUB
Public head As FORM_HEADER ' with 'NMRL'
Public tID As String ' type ID = 'SSUB'
Public rev_len As Integer ' Used alternatively to contain form length (# bytes) if no form header used.
' NB: contains '1000' or {00 00 03 E8} in BSRM form.
'***
Public flag(2) As Integer ' bit-flags (they're always powers of two), indicating the layer priorities per mesh.
' -> (For 'diffuse', 'glow' & '...' (?) layers?).
Public fcLst() As FACE_LIST ' Listing of face-indices (starting at zero) of faces as outlined in the corresponding TRIS chunk.
Public Sub ReadHOD(ByVal f As Integer)
head = New FORM_HEADER
ReadString(f, head.tid, 4)
ReadRevInt32(f, head.rev_len)
Dim bpos As Integer = Seek(f)
ReadString(f, tID, 4)
ReadRevInt32(f, rev_len)
FileGet(f, flag)
Dim nlst As Integer = 0
While Seek(f) - bpos < head.rev_len
ReDim Preserve fcLst(nlst)
fcLst(nlst) = New FACE_LIST
fcLst(nlst).ReadHOD(f)
nlst += 1
End While
End Sub
Public Sub WriteHOD(ByVal f As Integer)
WriteString(f, head.tid, 4)
WriteRevInt32(f, head.rev_len)
WriteString(f, tID, 4)
WriteRevInt32(f, rev_len)
FilePut(f, flag)
Dim i As Integer
For i = 0 To fcLst.Length - 1
fcLst(i).WriteHOD(f)
Next
End Sub
Public Function Update() As Integer
head.rev_len = 20
Dim i As Integer
For i = 0 To fcLst.Length - 1
head.rev_len += fcLst(i).Update()
Next
Return head.rev_len + 8
End Function
End Class
Public Class BSRM_CHUNK
Public head As FORM_HEADER
Public tID As String ' type ID = 'BSRM'
Public descFh As FORM_HEADER ' with 'NRML'
Public desc As BSRM_DESC ' occurs only once in BSRM chunk
Public bboxFh As FORM_HEADER ' with 'NRML'
Public bbox As COL_BBOX ' occurs only once in BSRM chunk
Public bsphFh As FORM_HEADER ' with 'NMRL'
Public bsph As COL_BSPH ' occurs only once in BSRM chunk
Public trisFh As FORM_HEADER ' with 'NMRL'
Public tris As COL_TRIS ' occurs only once in BSRM chunk
Public vnrmFh As FORM_HEADER ' with 'NMRL'
Public vnrm As COL_NRML ' occurs only once in BSRM chunk
Public ssub As BSRM_SSUB ' occurs only once in BSRM chunk
Public Sub ReadHOD(ByVal f As Integer)
head = New FORM_HEADER
head.ReadHOD(f)
ReadString(f, tID, 4)
descFh = New FORM_HEADER
descFh.ReadHOD(f)
desc = New BSRM_DESC
desc.ReadHOD(f)
bboxFh = New FORM_HEADER
bboxFh.ReadHOD(f)
bbox = New COL_BBOX
bbox.ReadHOD(f)
bsphFh = New FORM_HEADER
bsphFh.ReadHOD(f)
bsph = New COL_BSPH
bsph.ReadHOD(f)
trisFh = New FORM_HEADER
trisFh.ReadHOD(f)
tris = New COL_TRIS
tris.ReadHOD(f)
vnrmFh = New FORM_HEADER
vnrmFh.ReadHOD(f)
vnrm = New COL_NRML
vnrm.ReadHOD(f)
ssub = New BSRM_SSUB
ssub.ReadHOD(f)
End Sub
Public Sub WriteHOD(ByVal f As Integer)
head.WriteHOD(f)
WriteString(f, tID, 4)
descFh.WriteHOD(f)
desc.WriteHOD(f)
bboxFh.WriteHOD(f)
bbox.WriteHOD(f)
bsphFh.WriteHOD(f)
bsph.WriteHOD(f)
trisFh.WriteHOD(f)
tris.WriteHOD(f)
vnrmFh.WriteHOD(f)
vnrm.WriteHOD(f)
ssub.WriteHOD(f)
End Sub
Public Function Update() As Integer
descFh.rev_len = desc.Update()
bboxFh.rev_len = bbox.Update(True)
bsphFh.rev_len = bsph.Update(True)
trisFh.rev_len = tris.Update(True)
vnrmFh.rev_len = vnrm.Update()
head.rev_len = 44 + descFh.rev_len + bboxFh.rev_len + bsphFh.rev_len + trisFh.rev_len + vnrmFh.rev_len + ssub.Update()
Return head.rev_len + 8
End Function
End Class
Public Class DTRM_CHUNK
Public head As FORM_HEADER
Public tid As String
Public Hierarchy As HIER_CHUNK
Public EngineTrails() As ETSH_CHUNK
Public Glows() As GLOW_CHUNK
Public Burns() As BURN_CHUNK
Public NavLights() As NAVL_CHUNK
Public DockPaths() As DOCK_CHUNK
Public Anims() As ANIM_CHUNK
Public Markers() As MRKR_CHUNK
Public Boundries() As BNDV_CHUNK
Public CollisionInfo() As COLD_CHUNK
Public BSRMS() As BSRM_CHUNK
Public Sub WriteHOD(ByVal f As Integer)
head.WriteHOD(f)
WriteString(f, tid, 4)
Hierarchy.WriteHOD(f)
If Not (EngineTrails Is Nothing) Then
Dim i As Integer
For i = 0 To EngineTrails.Length - 1
EngineTrails(i).WriteHOD(f)
Next
End If
If Not (Glows Is Nothing) Then
Dim i As Integer
For i = 0 To Glows.Length - 1
Glows(i).WriteHOD(f)
Next
End If
If Not (Burns Is Nothing) Then
Dim i As Integer
For i = 0 To Burns.Length - 1
Burns(i).WriteHOD(f)
Next
End If
If Not (NavLights Is Nothing) Then
Dim i As Integer
For i = 0 To NavLights.Length - 1
NavLights(i).WriteHOD(f)
Next
End If
If Not (DockPaths Is Nothing) Then
Dim i As Integer
For i = 0 To DockPaths.Length - 1
DockPaths(i).WriteHOD(f)
Next
End If
If Not (Anims Is Nothing) Then
Dim i As Integer
For i = 0 To Anims.Length - 1
Anims(i).WriteHOD(f)
Next
End If
If Not (Markers Is Nothing) Then
Dim i As Integer
For i = 0 To Markers.Length - 1
Markers(i).WriteHOD(f)
Next
End If
If Not (Boundries Is Nothing) Then
Dim i As Integer
For i = 0 To Boundries.Length - 1
Boundries(i).WriteHOD(f)
Next
End If
If Not (CollisionInfo Is Nothing) Then
Dim i As Integer
For i = 0 To CollisionInfo.Length - 1
CollisionInfo(i).WriteHOD(f)
Next
End If
If Not (BSRMS Is Nothing) Then
Dim i As Integer
For i = 0 To BSRMS.Length - 1
BSRMS(i).WriteHOD(f)
Next
End If
End Sub
Public Sub ReadHOD(ByVal f As Integer)
head = New FORM_HEADER
head.ReadHOD(f)
Dim bpos As Integer = Seek(f)
ReadString(f, tid, 4)
Dim ne, ng, nb, nn, nd, na, nm, nbv, nc, nbs As Integer
ne = 0
ng = 0
nb = 0
nn = 0
nd = 0
na = 0
nm = 0
nbv = 0
nc = 0
nbs = 0
While Seek(f) - bpos < head.rev_len
Dim ph As String
ph = PeekHead(f)
Select Case ph
Case "HIER"
Hierarchy = New HIER_CHUNK
Hierarchy.ReadHOD(f)
Case "ETSH"
ReDim Preserve EngineTrails(ne)
EngineTrails(ne) = New ETSH_CHUNK
EngineTrails(ne).ReadHOD(f)
ne += 1
Case "BURN"
ReDim Preserve Burns(nb)
Burns(nb) = New BURN_CHUNK
Burns(nb).ReadHOD(f)
nb += 1
Case "BNDV"
ReDim Preserve Boundries(nbv)
Boundries(nbv) = New BNDV_CHUNK
Boundries(nbv).ReadHOD(f)
nb += 1
Case "NRML"
ReDim Preserve NavLights(nn)
NavLights(nn) = New NAVL_CHUNK
NavLights(nn).ReadHOD(f)
nn += 1
Case "DOCK"
ReDim Preserve DockPaths(nd)
DockPaths(nd) = New DOCK_CHUNK
DockPaths(nd).ReadHOD(f)
nd += 1
Case "FORM"
Dim ph2 = PeekHead2(f)
Select Case ph2
Case "GLOW"
ReDim Preserve Glows(ng)
Glows(ng) = New GLOW_CHUNK
Glows(ng).ReadHOD(f)
ng += 1
Case "ANIM"
ReDim Preserve Anims(na)
Anims(na) = New ANIM_CHUNK
Anims(na).ReadHOD(f)
na += 1
Case "MRKR"
ReDim Preserve Markers(nm)
Markers(nm) = New MRKR_CHUNK
Markers(nm).ReadHOD(f)
nm += 1
Case "COLD"
ReDim Preserve CollisionInfo(nc)
CollisionInfo(nc) = New COLD_CHUNK
CollisionInfo(nc).ReadHOD(f)
nc += 1
Case "BSRM"
ReDim Preserve BSRMS(nbs)
BSRMS(nbs) = New BSRM_CHUNK
BSRMS(nbs).ReadHOD(f)
nbs += 1
End Select
End Select
End While
End Sub
Public Function Update() As Integer
head.rev_len = 4
head.rev_len += Hierarchy.Update()
If Not (EngineTrails Is Nothing) Then
Dim i As Integer
For i = 0 To EngineTrails.Length - 1
head.rev_len += EngineTrails(i).Update()
Next
End If
If Not (Glows Is Nothing) Then
Dim i As Integer
For i = 0 To Glows.Length - 1
head.rev_len += Glows(i).Update()
Next
End If
If Not (Burns Is Nothing) Then
Dim i As Integer
For i = 0 To Burns.Length - 1
head.rev_len += Burns(i).Update()
Next
End If
If Not (NavLights Is Nothing) Then
Dim i As Integer
For i = 0 To NavLights.Length - 1
head.rev_len += NavLights(i).Update()
Next
End If
If Not (DockPaths Is Nothing) Then
Dim i As Integer
For i = 0 To DockPaths.Length - 1
head.rev_len += DockPaths(i).Update()
Next
End If
If Not (Anims Is Nothing) Then
Dim i As Integer
For i = 0 To Anims.Length - 1
head.rev_len += Anims(i).Update()
Next
End If
If Not (Markers Is Nothing) Then
Dim i As Integer
For i = 0 To Markers.Length - 1
head.rev_len += Markers(i).Update()
Next
End If
If Not (Boundries Is Nothing) Then
Dim i As Integer
For i = 0 To Boundries.Length - 1
head.rev_len += Boundries(i).Update()
Next
End If
If Not (CollisionInfo Is Nothing) Then
Dim i As Integer
For i = 0 To CollisionInfo.Length - 1
head.rev_len += CollisionInfo(i).Update()
Next
End If
If Not (BSRMS Is Nothing) Then
Dim i As Integer
For i = 0 To BSRMS.Length - 1
head.rev_len += BSRMS(i).Update()
Next
End If
End Function
End Class
Public Class STAT_SHADER
Public five As Integer 'Always 5(?)
Public four As Integer 'Always 4(?)
Public LMIP As Integer
Public lName As Integer
Public nName As String
Public Sub ReadHOD(ByVal f As Integer)
ReadInt32(f, five)
ReadInt32(f, four)
ReadInt32(f, LMIP)
ReadHODString(f, lName, nName)
End Sub
Public Sub WriteHOD(ByVal f As Integer)
WriteInt32(f, five)
WriteInt32(f, four)
WriteInt32(f, LMIP)
WriteHODString(f, lName, nName)
End Sub
Public Function Update() As Integer
Return 16 + lName
End Function
End Class
Public Class STAT_CHUNK
Public head As FORM_HEADER
Public tid As String
Public rev_len As Integer ' Always 1001(?)
Public lTexGroup As Integer
Public nTexGroup As String
Public lType As Integer
Public nType As String
Public nShaders As Integer
Public Shaders() As STAT_SHADER
Public Sub ReadHOD(ByVal f As Integer)
head = New FORM_HEADER
head.ReadHOD(f)
ReadString(f, tid, 4)
ReadRevInt32(f, rev_len)
ReadHODString(f, lTexGroup, nTexGroup)
ReadHODString(f, lType, nType)
ReadInt32(f, nShaders)
Dim i As Integer
ReDim Shaders(nShaders - 1)
For i = 0 To nShaders - 1
Shaders(i) = New STAT_SHADER
Shaders(i).ReadHOD(f)
Next
End Sub
Public Sub WriteHOD(ByVal f As Integer)
head.WriteHOD(f)
WriteString(f, tid, 4)
WriteRevInt32(f, rev_len)
WriteHODString(f, lTexGroup, nTexGroup)
WriteHODString(f, lType, nType)
WriteInt32(f, nShaders)
Dim i As Integer
For i = 0 To nShaders - 1
Shaders(i).WriteHOD(f)
Next
End Sub
Public Function Update() As Integer
head.rev_len = 20 + lTexGroup + lType
Dim i As Integer
For i = 0 To nShaders - 1
head.rev_len += Shaders(i).Update()
Next
Return head.rev_len + 8
End Function
End Class
Public Class LMIP_MIP_LEVEL
Public Wi As Integer
Public Hi As Integer
Public Bdata() As Byte
Public Sub ReadHOD(ByVal f As Integer)
ReadInt32(f, Wi)
ReadInt32(f, Hi)
Dim l1, l2, l3 As Long
l1 = Wi
l2 = Hi
ReDim Bdata(l1 * l2 - 1)
FileGet(f, Bdata)
End Sub
Public Sub WriteHOD(ByVal f As Integer)
WriteInt32(f, Wi)
WriteInt32(f, Hi)
FilePut(f, Bdata)
End Sub
Public Function Update() As Integer
Return 8 + Bdata.Length()
End Function
End Class
Public Class LMIP_CHUNK
Public tid As String 'LMIP
Public rev_len As Integer
Public lFileName As Integer
Public nFileName As String
Public tid1 As String 'DXT5 or 8888(TGA)
Public nMips As Integer
Public mips() As LMIP_MIP_LEVEL
Public Sub ReadHOD(ByVal f As Integer)
ReadString(f, tid, 4)
ReadRevInt32(f, rev_len)
ReadHODString(f, lFileName, nFileName)
ReadString(f, tid1, 4)
ReadInt32(f, nMips)
ReDim mips(nMips - 1)
Dim i As Integer
For i = 0 To nMips - 1
mips(i) = New LMIP_MIP_LEVEL
mips(i).ReadHOD(f)
Next
End Sub
Public Sub WriteHOD(ByVal f As Integer)
WriteString(f, tid, 4)
WriteRevInt32(f, rev_len)
WriteHODString(f, lFileName, nFileName)
WriteString(f, tid1, 4)
WriteInt32(f, nMips)
Dim i As Integer
For i = 0 To nMips - 1
mips(i).WriteHOD(f)
Next
End Sub
Public Function Update() As Integer
rev_len = 12 + lFileName
Dim i As Integer
For i = 0 To nMips - 1
rev_len += mips(i).Update()
Next
Return rev_len + 8
End Function
End Class
Public Class MULT_CHUNK
Public head As FORM_HEADER
Public tID As String ' type ID = 'MULT'
Public rev_len As Integer ' Used alternatively to contain form length (# bytes) if no header is used.
Public lName As Integer ' # bytes in multi-mesh (group) name.
Public nName As String ' multi-mesh name
Public lHierObject As Integer ' # bytes in hierarchy object name.
Public nHierObject As String ' hierarchy object name (for hierarchy).
Public nMeshes As Integer ' number of BMSH chunks in this MULT chunk.
Public Meshes() As BMSH_CHUNK
Public Sub ReadHOD(ByVal f As Integer)
head = New FORM_HEADER
head.ReadHOD(f)
ReadString(f, tID, 4)
ReadRevInt32(f, rev_len)
ReadHODString(f, lName, nName)
ReadHODString(f, lHierObject, nHierObject)
ReadInt32(f, nMeshes)
ReDim Meshes(nMeshes - 1)
Dim i As Integer
For i = 0 To nMeshes - 1
Meshes(i) = New BMSH_CHUNK
Meshes(i).ReadHOD(f)
Next
End Sub
Public Sub WriteHOD(ByVal f As Integer)
head.WriteHOD(f)
WriteString(f, tID, 4)
WriteRevInt32(f, rev_len)
WriteHODString(f, lName, nName)
WriteHODString(f, lHierObject, nHierObject)
WriteInt32(f, nMeshes)
Dim i As Integer
For i = 0 To nMeshes - 1
Meshes(i).WriteHOD(f)
Next
End Sub
Public Function Update() As Integer
head.rev_len = 20 + lName + lHierObject
Dim i As Integer
For i = 0 To nMeshes - 1
head.rev_len += Meshes(i).Update()
Next
Return head.rev_len + 8
End Function
End Class
Public Class GOBG_CHUNK
Public head As FORM_HEADER
Public tID As String ' type ID = 'GOBG'
Public rev_len As Integer ' Used alternatively to contain form length (# bytes) if no header is used.
Public lName As Integer ' # bytes in multi-mesh (group) name.
Public nName As String ' multi-mesh name
Public lHierObject As Integer ' # bytes in hierarchy object name.
Public nHierObject As String ' hierarchy object name (for hierarchy).
Public Mesh As BMSH_CHUNK
Public Sub ReadHOD(ByVal f As Integer)
head = New FORM_HEADER
head.ReadHOD(f)
ReadString(f, tID, 4)
ReadRevInt32(f, rev_len)
ReadHODString(f, lName, nName)
ReadHODString(f, lHierObject, nHierObject)
Mesh = New BMSH_CHUNK
Mesh.ReadHOD(f)
End Sub
Public Sub WriteHOD(ByVal f As Integer)
head.WriteHOD(f)
WriteString(f, tID, 4)
WriteRevInt32(f, rev_len)
WriteHODString(f, lName, nName)
WriteHODString(f, lHierObject, nHierObject)
Mesh.WriteHOD(f)
End Sub
Public Function Update() As Integer
head.rev_len = 16 + lName + lHierObject + Mesh.Update()
Return head.rev_len + 8
End Function
End Class
Public Class HVMD_CHUNK
Public head As FORM_HEADER
Public tid As String
Public stats() As STAT_CHUNK
Public lmips() As LMIP_CHUNK
Public mults() As MULT_CHUNK
Public gobs() As GOBG_CHUNK
Public Sub ReadHOD(ByVal f As Integer)
head = New FORM_HEADER
head.ReadHOD(f)
Dim bpos As Integer = Seek(f)
ReadString(f, tid, 4)
Dim nl, ns, ng, nm As Integer
nl = 0
ns = 0
ng = 0
nm = 0
While Seek(f) - bpos < head.rev_len
Dim ph = PeekHead(f)
Select Case ph
Case "LMIP"
ReDim Preserve lmips(nl)
lmips(nl) = New LMIP_CHUNK
lmips(nl).ReadHOD(f)
nl += 1
Case "NRML"
Dim ph2 As String = PeekHead2(f)
Select Case ph2
Case "MULT"
ReDim Preserve mults(nm)
mults(nm) = New MULT_CHUNK
mults(nm).ReadHOD(f)
nm += 1
Case "GOBG"
ReDim Preserve gobs(ng)
gobs(ng) = New GOBG_CHUNK
gobs(ng).ReadHOD(f)
ng += 1
Case "STAT"
ReDim Preserve stats(ns)
stats(ns) = New STAT_CHUNK
stats(ns).ReadHOD(f)
ns += 1
End Select
End Select
End While
End Sub
Public Sub WriteHOD(ByVal f As Integer)
head.WriteHOD(f)
WriteString(f, tid, 4)
Dim i As Integer
For i = 0 To stats.Length - 1
stats(i).WriteHOD(f)
Next
For i = 0 To lmips.Length - 1
lmips(i).WriteHOD(f)
Next
For i = 0 To mults.Length - 1
mults(i).WriteHOD(f)
Next
For i = 0 To gobs.Length - 1
gobs(i).WriteHOD(f)
Next
End Sub
Public Function Update() As Integer
head.rev_len = 4
Dim i As Integer
For i = 0 To stats.Length - 1
head.rev_len += stats(i).Update()
Next
For i = 0 To lmips.Length - 1
head.rev_len += lmips(i).Update()
Next
For i = 0 To mults.Length - 1
head.rev_len += mults(i).Update()
Next
For i = 0 To gobs.Length - 1
head.rev_len += gobs(i).Update()
Next
End Function
End Class
Public Class NAME_CHUNK
Public head As FORM_HEADER
Public tid As String
Public name As String 'Always "Homeworld2 Multi-Mesh File"
Public Sub ReadHOD(ByVal f As Integer)
head = New FORM_HEADER
head.ReadHOD(f)
ReadString(f, tid, 4)
ReadString(f, name, head.rev_len - 4)
End Sub
Public Sub WriteHOD(ByVal f As Integer)
head.WriteHOD(f)
WriteString(f, tid, 4)
WriteString(f, name, head.rev_len - 4)
End Sub
Public Function Update() As Integer
Return head.rev_len + 8
End Function
End Class
Public Class VERS_CHUNK
Public head As FORM_HEADER
Public tid As String
Public Version As Integer 'Always 512
Public Sub ReadHOD(ByVal f As Integer)
head = New FORM_HEADER
head.ReadHOD(f)
ReadString(f, tid, 4)
ReadInt32(f, Version)
End Sub
Public Sub WriteHOD(ByVal f As Integer)
head.WriteHOD(f)
WriteString(f, tid, 4)
WriteInt32(f, Version)
End Sub
Public Function Update() As Integer
Return 0 'Irrelevent
End Function
End Class
Public Class HODFile
Public Version As VERS_CHUNK
Public Name As NAME_CHUNK
Public MeshInfo As HVMD_CHUNK
Public DTRM As DTRM_CHUNK
Public FileInfo As INFO_CHUNK
Public Sub Read(ByVal f As String)
Dim file As Integer
file = FreeFile()
FileOpen(file, f, OpenMode.Binary)
Version = New VERS_CHUNK
Version.ReadHOD(file)
Name = New NAME_CHUNK
Name.ReadHOD(file)
MeshInfo = New HVMD_CHUNK
MeshInfo.ReadHOD(file)
DTRM = New DTRM_CHUNK
DTRM.ReadHOD(file)
FileInfo = New INFO_CHUNK
FileInfo.ReadHOD(file)
FileClose(file)
End Sub
Public Sub Write(ByVal f As String)
Dim file As Integer
file = FreeFile()
FileOpen(file, f, OpenMode.Binary)
Version.Update()
Version.WriteHOD(file)
Name.Update()
Name.WriteHOD(file)
MeshInfo.Update()
MeshInfo.WriteHOD(file)
DTRM.Update()
DTRM.WriteHOD(file)
FileInfo.Update()
FileInfo.WriteHOD(file)
FileClose(file)
End Sub
End Class
End Module