What's new

Melee Arcive Viewer (MAV) in development project.

Milun

New member
I'm sorry Tcll, but I myself have spent hours upon hours trying to do that in C++, no literally hours. And not a single guide on the net gives me a clear answer on how to go to an offset.

If you've used my GM importer/exporter, you'd see what I did was make the user copy and paste the text from the hex, and then save it in a .txt, so that the code treats the whole hex as a single string. Mine soooort of goes to different offsets, but the way it does that is it travels forward in the string by a few characters, rather than a couple hundred.

I wouldn't recommend this at all, but if you were to treat the hex as a whole as string, then to get the offset you could do something like: Convert the offset number from hex - decimal, then from the very start of the hex, go forward that many characters. If I'm confusing, say so.
 
Last edited:
OP
Tcll

Tcll

Complexity == Fun >:3
I'm sorry Tcll, but I myself have spent hours upon hours trying to do that in C++, no literally hours. And not a single guide on the net gives me a clear answer on how to go to an offset.
amen to that... -_-

If you've used my GM importer/exporter, you'd see what I did was make the user copy and paste the text from the hex, and then save it in a .txt, so that the code treats the whole hex as a single string. Mine soooort of goes to different offsets, but the way it does that is it travels forward in the string by a few characters, rather than a couple hundred.
sry... havn't used it...
but I see where you come from and have to say, it is an idea...
but it still leaves me with the same delema... :p

I wouldn't recommend this at all, but if you were to treat the hex as a whole as string, then to get the offset you could do something like: Convert the offset number from hex - decimal, then from the very start of the hex, go forward that many characters. If I'm confusing, say so.
nah... yur not confusing at all :)

what I'm trying to do is something more like Jahra1n's converter...
I still don't understand how it uses the offsets...
it may be the .frm file instead of the .bas file...
I'll post the code in my next post...
 
OP
Tcll

Tcll

Complexity == Fun >:3
here's the codes:

.bas
Code:
Attribute VB_Name = "Module1"
'******Jahrain's 3d Reverse Engineering Functions********
'The sources of most of this stuff comes from all over the net
'big thanks goes out to Yomamma for the low level Floating point
'from and to hex conversion functions.
'Please Share the source code to any applications using or
'referencing anything from this code
'       _____________    __  __  ____   ___   _____  ____   __
'      /____  ___/   |\ / /\/ /\/ _  \ /   |\/_  _/\/   |\ / /\
'      \___/ /\_/ /| ||/ /_/ / / /\/ |/ /| ||\/ /\\/ /| ||/ / /
'     __  / / // /_| |/ __  / / __¯ </ /_| ||/ / // / | |/ / /
'    |  \/ / // ___  / / / / / /\_| / ___  |/ /_// / /|   / /
'     \___/ //_/\__|/_/ /_/ /_/ //_/_/ __|/____//_/ / |__/ /
'      \__\/ \_\/  [URL="file://\\_\/\_\/\_\/"]\\_\/\_\/\_\/[/URL] \_\_\/  [URL="file://\\____\\_\/"]\\____\\_\/[/URL]  \__\/
'-Word art by Jahrain
'*****Instructions*******
'To use any of these functions, its simple
'just add this module to the project. and use this to open the file into the Global Hex Array.
'    Open "C:\My File.dat" For Binary As #1
'    ReDim ByteArray(0 To LOF(1) - 1) As Byte
'    Get 1, , ByteArray
'    Close #1
'Now any function in this can be used on any array number or offset in the file
'for example, if you want to read a Single Precision floating point number from
'the offset of 32
'just type this
'   text1.text = GetSingle(32)
'and this returns the float value of that offset in the opened file and displays it in the textbox
'Now happy reverse engineering :)
 
Public ByteArray() As Byte 'this is the global array of the
'Hex bytes in a file opened used in this module.
'These are common data types used to store information in models, animations etc...
Type Vector3d 'this is mainly for vertecies, normals etc...
x As Single
y As Single
Z As Single
End Type
Type Vector2d 'this is mainly for texture coords and other 2 dimentional vectors
U As Single
V As Single
End Type
Type Vector4d 'Although rarely used, this is for 4 dimentional data types such as quaternions which are used in bone orientation and animation
i As Single
j As Single
k As Single
W As Single
End Type
Type FaceIndex3d 'These are for storing Triangle Data for models
Av As Long
An As Long
At As Long
Bv As Long
Bn As Long
Bt As Long
Cv As Long
Cn As Long
Ct As Long
End Type
'These are more complex types used to hold lots of model data in groups and what not
Type MESH
'for storing model mesh data and hex offsets
MeshName As String
MeshOffset As Double
VertexCount As Long
INDEXCOUNT As Long
VTXBlock() As Vector3d
INDBlock() As FaceIndex3d
End Type
Type BM8
'you probably wont use this
BMOffset As Double
BMSize As Long
End Type
Type TGA
'or this either
TGAOffset As Double
TGAsize As Long
End Type
 
Public Function GetTag(Offset As Double) As String 'This Function returns a string of 4 Characters at any given offset.
'Certain file types identify blocks by 4 letter 'tags' so this may proove helpful.
    tmp1 = Chr$(ByteArray(Offset))
    tmp2 = Chr$(ByteArray(Offset + 1))
    tmp3 = Chr$(ByteArray(Offset + 2))
    tmp4 = Chr$(ByteArray(Offset + 3))
 
    GetTag = tmp1 & tmp2 & tmp3 & tmp4
 
End Function
Public Function GetLong(Offset As Double) As Double 'Returns a unsigned Long integer value from the specified offset in the global bytearray
    tmp1 = Hex(ByteArray(Offset))
    tmp2 = Hex(ByteArray(Offset + 1))
    tmp3 = Hex(ByteArray(Offset + 2))
    tmp4 = Hex(ByteArray(Offset + 3))
    If Len(tmp1) = 1 Then tmp1 = "0" & tmp1
    If Len(tmp2) = 1 Then tmp2 = "0" & tmp2
    If Len(tmp3) = 1 Then tmp3 = "0" & tmp3
    If Len(tmp4) = 1 Then tmp4 = "0" & tmp4
 
    GetLong = HexToDec(tmp4 & tmp3 & tmp2 & tmp1)
 
End Function
Public Function GetLongS(Offset As Double) As Double 'Returns a Endian Swapped unsigned Long integer value from the specified offset in the global bytearray
If Offset < UBound(ByteArray) Then
    tmp1 = Hex(ByteArray(Offset))
    tmp2 = Hex(ByteArray(Offset + 1))
    tmp3 = Hex(ByteArray(Offset + 2))
    tmp4 = Hex(ByteArray(Offset + 3))
    If Len(tmp1) = 1 Then tmp1 = "0" & tmp1
    If Len(tmp2) = 1 Then tmp2 = "0" & tmp2
    If Len(tmp3) = 1 Then tmp3 = "0" & tmp3
    If Len(tmp4) = 1 Then tmp4 = "0" & tmp4
 
    GetLongS = HexToDec(tmp1 & tmp2 & tmp3 & tmp4)
    Else
    GetLongS = 0
    End If
End Function
Public Function GetInt(Offset As Double) As Long 'Returns a unsigned short integer value from the specified offset in the global bytearray
    tmp1 = Hex(ByteArray(Offset))
    tmp2 = Hex(ByteArray(Offset + 1))
    If Len(tmp1) = 1 Then tmp1 = "0" & tmp1
    If Len(tmp2) = 1 Then tmp2 = "0" & tmp2
 
    GetInt = HexToDec(tmp2 & tmp1)
 
End Function
Public Function GetIntS(Offset As Double) As Long 'Returns a endian swapped unsigned short integer value from the specified offset in the global bytearray
If Offset > UBound(ByteArray) - 1 Then
    GetIntS = 0
    GoTo enthisfunc1
End If
    tmp1 = Hex(ByteArray(Offset))
    tmp2 = Hex(ByteArray(Offset + 1))
    If Len(tmp1) = 1 Then tmp1 = "0" & tmp1
    If Len(tmp2) = 1 Then tmp2 = "0" & tmp2
 
    GetIntS = HexToDec(tmp1 & tmp2)
enthisfunc1:
End Function
Public Function GetByte(Offset As Double) As Long 'returns a unsigned Byte value from the specified offset
If Offset < UBound(ByteArray) Then
    tmp1 = Hex(ByteArray(Offset))
 
    If Len(tmp1) = 1 Then tmp1 = "0" & tmp1
 
    GetByte = HexToDec(tmp1)
    Else
     GetByte = 0
     End If
End Function
Public Function GetIntS1(Offset As Double) As Long 'same as GetIntS except it swaps bytes. example: reads A0 1F instead of 0A F1
    tmp1 = Hex(ByteArray(Offset))
    tmp2 = Hex(ByteArray(Offset + 1))
    If Len(tmp1) = 2 Then tmp1 = Mid(tmp1, 2, 1) & Mid(tmp1, 1, 1)
    If Len(tmp2) = 2 Then tmp2 = Mid(tmp2, 2, 1) & Mid(tmp2, 1, 1)
    If Len(tmp1) = 1 Then tmp1 = "0" & tmp1
    If Len(tmp2) = 1 Then tmp2 = "0" & tmp2
    tmp3 = tmp2 & tmp1
 
    GetIntS1 = CLng("&h" & tmp3)
End Function
Public Function IsTag(Offset As Double) As Boolean 'just a boolean to return if an offset is a specified 4 byte tag, add some to the long list of ifs to check ;)
If GetTag(Offset) = "MATE" Or GetTag(Offset) = "OBJM" Or GetTag(Offset) = "CNST" Or GetTag(Offset) = "TEXT" Or GetTag(Offset) = "LIGH" Or GetTag(Offset) = "MESH" Or GetTag(Offset) = "MORP" Or GetTag(Offset) = "MATA" Or GetTag(Offset) = "BLND" Or GetTag(Offset) = "FRAM" Or GetTag(Offset) = "ANIM" Or GetTag(Offset) = "FOG " Or GetTag(Offset) = "ENVL" Then
IsTag = True
Else
IsTag = False
End If
 
End Function
Private Function HexToDec(ByVal HexStr As String) As Double 'Low level hex to decimal conversion
Dim mult As Double
Dim DecNum As Double
Dim ch As String
Dim i As Integer
mult = 1
DecNum = 0
For i = Len(HexStr) To 1 Step -1
    ch = Mid(HexStr, i, 1)
    If (ch >= "0") And (ch <= "9") Then
        DecNum = DecNum + (Val(ch) * mult)
    Else
        If (ch >= "A") And (ch <= "F") Then
            DecNum = DecNum + ((Asc(ch) - Asc("A") + 10) * mult)
        Else
            If (ch >= "a") And (ch <= "f") Then
                DecNum = DecNum + ((Asc(ch) - Asc("a") + 10) * mult)
            Else
                HexToDec = 0
                Exit Function
            End If
        End If
    End If
    mult = mult * 16
Next i
HexToDec = DecNum
End Function
Public Function GetFSingleS(ByRef address As Double, Optional Scalar As Long = 512) As Single 'This reads a 16bit Fixed decimal signed integer and devides it by the scalar to get the floating point value. This is commonly used in GameCube Models
Dim TmpInt As Long
TmpInt = GetIntS(address)
If Scalar = 0 Then Scalar = 512
GetFSingleS = nSigned(TmpInt) / Scalar
End Function
Public Function GetSingle(ByRef address As Double) 'Returns a Single Point Precision Decimal number from the specified offset in the global hex array
tmph = ""
    For i = 0 To 3
        x = CStr(Hex(ByteArray(address + i)))
        If Len(x) = 1 Then x = "0" & x
        tmph = tmph & x
    Next i
 
       GetSingle = CSng(HaloFloat(CStr(tmph)))
End Function
Public Function GetSingleS(ByRef address As Double) 'Returns a Endian Swapped Single Point Precision Decimal number from the specified offset in the global hex array
tmph = ""
    For i = 3 To 0 Step -1
        x = CStr(Hex(ByteArray(address + i)))
        If Len(x) = 1 Then x = "0" & x
        tmph = tmph & x
    Next i
 
       GetSingleS = CDbl(HaloFloat(CStr(tmph)))
End Function
 
 
 
Private Function BinToDec(ByVal num As String) As String 'Converts a Binary string to Decimal
bins = num
tmp1 = InStr(1, bins, ".")
If tmp1 = 0 Then
 unman = bins
 man = ""
Else
 unman = Mid$(bins, 1, tmp1 - 1)
 man = Mid$(bins, tmp1 + 1)
End If
For i = 1 To Len(unman) - 1
 tmp2 = Mid$(unman, Len(unman) - i, 1)
 If tmp2 = 1 Then total = total + 2 ^ i
Next i
For i = 1 To Len(man)
 tmp2 = Mid$(man, i, 1)
 If tmp2 = 1 Then total = total + 2 ^ (i * -1)
Next i
If Right(unman, 1) = "1" Then total = total + 1
BinToDec = Str$(total)
End Function
Private Function HexToBin(ByVal hexy As String) As String
'Converts Hex to binary
For i = 1 To Len(hexy)
 chexy = Mid$(hexy, i, 1)
 
Select Case chexy
 Case "0"
 tmp1 = tmp1 + "0000"
 Case "1"
 tmp1 = tmp1 + "0001"
 Case "2"
 tmp1 = tmp1 + "0010"
 Case "3"
 tmp1 = tmp1 + "0011"
 Case "4"
 tmp1 = tmp1 + "0100"
 Case "5"
 tmp1 = tmp1 + "0101"
 Case "6"
 tmp1 = tmp1 + "0110"
 Case "7"
 tmp1 = tmp1 + "0111"
 Case "8"
 tmp1 = tmp1 + "1000"
 Case "9"
 tmp1 = tmp1 + "1001"
 Case "A"
 tmp1 = tmp1 + "1010"
 Case "B"
 tmp1 = tmp1 + "1011"
 Case "C"
 tmp1 = tmp1 + "1100"
 Case "D"
 tmp1 = tmp1 + "1101"
 Case "E"
 tmp1 = tmp1 + "1110"
 Case "F"
 tmp1 = tmp1 + "1111"
End Select
Next i
HexToBin = tmp1
End Function
Private Function HaloFloat(hexs As String) As Double
'Low level function to convert 4 byte hex strings into floats
For i = 1 To Len(hexs)
If Mid$(hexs, i, 1) <> "0" Then GoTo exitthiscrap
Next i
s = 0
GoTo endingskip
exitthiscrap:
For i = 1 To Len(hexs) Step 2
 tmp1 = Mid$(hexs, i, 2) + tmp1
Next i
tmp1 = HexToBin(tmp1)
'Split
sign = Mid$(tmp1, 1, 1)
exponent = Mid$(tmp1, 2, 8)
mantissa = Mid$(tmp1, 10, 23)
'Sign
If sign = "0" Then
 s = 1
Else
 s = -1
End If
'Exponent
e = Val(BinToDec(exponent)) - 127
'Mantissa
m = Val(BinToDec("1." + mantissa))
endingskip:
HaloFloat = s * m * (2 ^ e)
End Function
Private Function DecOfBin(ByVal num As String) As String
'Converts Binary string to decimal values
bins = num
tmp1 = InStr(1, bins, ".")
If tmp1 = 0 Then
 unman = bins
 man = ""
Else
 unman = Mid$(bins, 1, tmp1 - 1)
 man = Mid$(bins, tmp1 + 1)
End If
For i = 1 To Len(unman) - 1
 tmp2 = Mid$(unman, Len(unman) - i, 1)
 If tmp2 = 1 Then total = total + 2 ^ i
Next i
For i = 1 To Len(man)
 tmp2 = Mid$(man, i, 1)
 If tmp2 = 1 Then total = total + 2 ^ (i * -1)
Next i
If Right(unman, 1) = "1" Then total = total + 1
DecOfBin = Str$(total)
End Function
Private Function DecOfFloat(ByVal Float As String) As String
'Converts floating point string to decimal values
Dim sign, mantissa1, mantissa2, exponent As String
'If Left(Float, 1) = 1 Then sign = "-" Else sign = ""
If Left(Float, 1) = 1 Then sign = -1 Else sign = 1
exponent = Mid(Float, 2, 8)
exponent = DecOfBin(exponent)
exponent = (exponent - 127)
'mantissa1 = 1 & Mid(Float, 10, exponent)
'mantissa2 = Mid(Float, (10 + exponent), 32)
'mantissa1 = DecOfBin(mantissa1)
'mantissa2 = DecOfPointBin(mantissa2)
man2 = "1." + Mid$(Float, 10)
man1 = DecOfBin(man2)
DecOfFloat = sign * man1 * 2 ^ exponent
'DecOfFloat = sign & (Val(mantissa1) + Val(mantissa2))
 
End Function
Private Function BinOfDec(ByVal number As String, Optional length As Integer) As String
Dim d, B, L, wk, C
d = number
L = 0
 
If length = Empty Then
    Do
        If d Mod 2 Then B = "1" & B Else B = "0" & B
        d = d \ 2
    Loop Until d = 0
Else
    Do
        If d Mod 2 Then B = "1" & B Else B = "0" & B
        d = d \ 2
        L = L + 1
    Loop Until L = length
End If
If number < 0 And length = 8 Then GoTo TwosCompliment
GoTo BinAns
TwosCompliment:     'the binary is inverted and 1 is added, this is how minus numbers are represented in binary
    L = Len(B)
    d = 0
    C = 1
        For d = L To 1 Step -1
            wk = Mid(B, d, 1)
 
            If wk = 1 Then wk = 0 Else wk = 1   'inverse
 
            If wk = 1 And C = 1 Then            'add 1
                wk = 0
                C = 1
            ElseIf wk = 0 And C = 1 Then
                wk = 1
                C = 0
            ElseIf wk = 1 And C = 0 Then
                wk = 1
                C = 0
            ElseIf wk = 0 And C = 0 Then
                wk = 0
                C = 0
            End If
 
            BinOfDec = BinOfDec & wk
 
        Next d
 
Exit Function
BinAns:
BinOfDec = B
End Function
Private Function DefOfBin(ByVal number As String) As String
    Dim k%
    Dim L%
    Dim d&
    Dim B$
    B = CStr(number)
    L = Len(B)
    For k = 1 To L
        If Mid(B, k, 1) = "1" Then d = d + (2 ^ (L - k))
    Next
    DefOfBin = d
End Function
Public Function GetString(Offset As Double, Lenth As Long) As String
'Returns a string to a specified lenth from a specified offset
    For i = Offset To Offset + Lenth
    If ByteArray(i) = 0 Then GoTo endthisstring
    tmptext = tmptext & Chr$(ByteArray(i))
    Next i
endthisstring:
    GetString = tmptext
End Function
Public Function LoadString(Offset As Double) As String
'Returns a string from the specified offset, the lenth is detemined by when the reading runs into a '00' byte
p = Offset
tmpu = ""
taglenth = 0
r = 0
Dim TmpTxt As String
L = Offset
TmpTxt = ""
 
    Do
      TmpTxt = TmpTxt & Chr$(ByteArray(L))
    r = r + 1
    L = L + 1
 
 
    Loop Until ByteArray(L) = 0
 
LoadString = Left(TmpTxt, r - 1)
End Function
 
 
Public Function OBJVertStr(VertexCoords() As Vector3d, VertexCount As Long) As String
'For logging an array of vertex coords into the format for the .OBJ file format
    Dim TmpTxt() As String
    ReDim TmpTxt(0 To VertexCount - 1)
 
    For i = 0 To VertexCount - 1
        TmpTxt(i) = "v " & VertexCoords(i).x & " " & VertexCoords(i).y & " " & VertexCoords(i).Z
    Next i
    OBJVertStr = Join(TmpTxt, vbCrLf)
End Function
Public Function OBJNormStr(VertexCoords() As Vector3d, NormalCount As Long) As String
'For logging an array of vertex normals into the format for the .OBJ file format
    Dim TmpTxt() As String
    ReDim TmpTxt(0 To NormalCount - 1)
 
    For i = 0 To NormalCount - 1
        TmpTxt(i) = "vn " & VertexCoords(i).x & " " & VertexCoords(i).y & " " & VertexCoords(i).Z
    Next i
    OBJNormStr = Join(TmpTxt, vbCrLf)
End Function
Public Function OBJUVStr(VertexCoords() As Vector2d, UVCount As Long) As String
'For logging an array of UVs into the format for the .OBJ file format
    Dim TmpTxt() As String
    ReDim TmpTxt(0 To UVCount)
 
    For i = 0 To UVCount - 1
        TmpTxt(i) = "vt " & VertexCoords(i).U & " " & VertexCoords(i).V
    Next i
    OBJUVStr = Join(TmpTxt, vbCrLf)
End Function
Public Function nSigned(ByVal lUnsignedInt As Long) As Integer
'Converts an unsigned Integer into a signed integer
  Dim nReturnVal As Integer   ' Return value from Function
  If lUnsignedInt > 65535 Or lUnsignedInt < 0 Then
    Debug.Print "Error in conversion from Unsigned to nSigned Integer"
    nSigned = 0
    Exit Function
  End If
  If lUnsignedInt > 32767 Then
    nReturnVal = lUnsignedInt - 65536
  Else
    nReturnVal = lUnsignedInt
  End If
  nSigned = nReturnVal
End Function
Public Function IsSingle(address As Double, Optional UpperBound As Double = 100000000, Optional LowerBound As Double = 0.00000001) As Boolean
  'a very usefull function to test for possible floating point digits
    If GetSingle(address) ^ 2 < UpperBound And GetSingle(address) ^ 2 > LowerBound Then
    IsSingle = True
    Else
    IsSingle = False
    End If
 
End Function
Public Function IsSingleS(address As Double, Optional UpperBound As Double = 100000000, Optional LowerBound As Double = 0.00000001) As Boolean
  'a very usefull function to test for endian swapped possible floating point digits
    If GetSingleS(address) ^ 2 < UpperBound And GetSingleS(address) ^ 2 > LowerBound Then
    IsSingleS = True
    Else
    IsSingleS = False
    End If
End Function

.frm
Code:
VERSION 5.00
Object = "{F9043C88-F6F2-101A-A3C9-08002B2F49FB}#1.2#0"; "comdlg32.ocx"
Object = "{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}#2.0#0"; "Mscomctl.ocx"
Begin VB.Form frmMain 
   BorderStyle     =   1  'Fixed Single
   Caption         =   "SSBM_Model_Converter"
   ClientHeight    =   1020
   ClientLeft      =   150
   ClientTop       =   840
   ClientWidth     =   4560
   LinkTopic       =   "Form1"
   MaxButton       =   0   'False
   MinButton       =   0   'False
   ScaleHeight     =   68
   ScaleMode       =   3  'Pixel
   ScaleWidth      =   304
   StartUpPosition =   3  'Windows Default
   Begin VB.TextBox Text2 
      Height          =   285
      Left            =   1920
      TabIndex        =   2
      Text            =   "295000"
      Top             =   120
      Width           =   1095
   End
   Begin MSComctlLib.ProgressBar loadbar 
      Align           =   2  'Align Bottom
      Height          =   255
      Left            =   0
      TabIndex        =   0
      Top             =   495
      Width           =   4560
      _ExtentX        =   8043
      _ExtentY        =   450
      _Version        =   393216
      Appearance      =   1
   End
   Begin MSComDlg.CommonDialog dlgCommonDialog 
      Left            =   9120
      Top             =   5640
      _ExtentX        =   847
      _ExtentY        =   847
      _Version        =   393216
   End
   Begin MSComctlLib.StatusBar StatusBar 
      Align           =   2  'Align Bottom
      Height          =   270
      Left            =   0
      TabIndex        =   1
      Top             =   750
      Width           =   4560
      _ExtentX        =   8043
      _ExtentY        =   476
      Style           =   1
      _Version        =   393216
      BeginProperty Panels {8E3867A5-8586-11D1-B16A-00C0F0283628} 
         NumPanels       =   3
         BeginProperty Panel1 {8E3867AB-8586-11D1-B16A-00C0F0283628} 
            AutoSize        =   1
            Object.Width           =   2858
            Text            =   "Status"
            TextSave        =   "Status"
         EndProperty
         BeginProperty Panel2 {8E3867AB-8586-11D1-B16A-00C0F0283628} 
            Style           =   6
            AutoSize        =   2
            TextSave        =   "7/29/2006"
         EndProperty
         BeginProperty Panel3 {8E3867AB-8586-11D1-B16A-00C0F0283628} 
            Style           =   5
            AutoSize        =   2
            TextSave        =   "12:40 AM"
         EndProperty
      EndProperty
   End
   Begin VB.Label Label2 
      Caption         =   "bytes"
      Height          =   255
      Left            =   3240
      TabIndex        =   4
      Top             =   120
      Width           =   1095
   End
   Begin VB.Label Label1 
      Caption         =   "Skip Index Search After:"
      Height          =   255
      Left            =   120
      TabIndex        =   3
      Top             =   120
      Width           =   1935
   End
   Begin VB.Menu mnuFile 
      Caption         =   "&File"
      Begin VB.Menu mnuFileOpen 
         Caption         =   "&Open..."
      End
      Begin VB.Menu mnuFileExit 
         Caption         =   "E&xit"
      End
   End
End
Attribute VB_Name = "frmMain"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Dim IndexOffset As Double
Dim Vertecies() As Vector3d
Dim Normals() As Vector3d
Dim UVs() As Vector2d
Dim VertexCount As Long
Dim NormalCount As Long
Dim UVCount As Long
Dim GroupCount As Long
Dim OutputFile As String
 
Private Sub Form_Load()
    Me.Left = GetSetting(App.Title, "Settings", "MainLeft", 1000)
    Me.Top = GetSetting(App.Title, "Settings", "MainTop", 1000)
    Me.Width = GetSetting(App.Title, "Settings", "MainWidth", 6500)
    Me.Height = GetSetting(App.Title, "Settings", "MainHeight", 6500)
End Sub
 
Private Sub Form_Unload(Cancel As Integer)
    Dim i As Integer
 
    'close all sub forms
    For i = Forms.Count - 1 To 1 Step -1
        Unload Forms(i)
    Next
    If Me.WindowState <> vbMinimized Then
        SaveSetting App.Title, "Settings", "MainLeft", Me.Left
        SaveSetting App.Title, "Settings", "MainTop", Me.Top
        SaveSetting App.Title, "Settings", "MainWidth", Me.Width
        SaveSetting App.Title, "Settings", "MainHeight", Me.Height
    End If
End Sub
Private Sub mnuFileExit_Click()
    'unload the form
    Unload Me
End Sub
Private Sub mnuFileOpen_Click()
    Dim sFile As String
StatusBar.SimpleText = "Loading File"
    With dlgCommonDialog
        .DialogTitle = "Open"
        .CancelError = False
        'ToDo: set the flags and attributes of the common dialog control
        .Filter = "Ty SSBM cache files (*.dat*)|*.dat*"
        .ShowOpen
        If Len(.FileName) = 0 Then
            Exit Sub
        End If
        sFile = .FileName
    End With
    Open sFile For Binary As #1
    ReDim ByteArray(0 To LOF(1) - 1) As Byte
    Get 1, , ByteArray
    Close 1
StatusBar.SimpleText = "Loading Please Wait: Processing Vertecies..."
Refresh
Dim i As Double
Dim j As Double
Dim k As Double
Dim FileIsFloat As Boolean
VertexCount = 0
NormalCount = 0
j = 0
IndexOffset = GetLongS(4) + 32
i = 32
loadbar.Max = IndexOffset
If IsSingleS(32) = True And IsSingleS(36) = True And IsSingleS(40) = True Then
            FileIsFloat = True
        Else
            FileIsFloat = False
End If
ReDim Vertecies(CLng(65535)) As Vector3d
Do Until GetLongS(i) + GetLongS(i + 4) + GetLongS(i + 8) + GetLongS(i + 12) = 0
'On Error GoTo skipthisvert
loadbar.Value = i
If FileIsFloat = True Then
    Vertecies(j).x = GetSingleS(i)
    Vertecies(j).Z = GetSingleS(i + 4)
    Vertecies(j).y = GetSingleS(i + 8)
    VertexCount = VertexCount + 1
    i = i + 12
Else
    Vertecies(j).x = GetFSingleS(i)
    Vertecies(j).Z = GetFSingleS(i + 2)
    Vertecies(j).y = GetFSingleS(i + 4)
    VertexCount = VertexCount + 1
    i = i + 6
End If
    j = j + 1
skipthisvert:
Loop
 
StatusBar.SimpleText = "Loading Please Wait: Processing Normals..."
i = i + 16
j = 0
If IsSingleS(i + 4) = True And IsSingleS(i) = True And IsSingleS(i + 8) = True Then
            NormIsFloat = True
        Else
            NormIsFloat = False
End If
If NormIsFloat = False Then
    Dim NormalScalar As Long
    Dim t As Long
    t = 2
    s = 2
 
    Do Until t >= 65535
        If Round((GetFSingleS(i, t) ^ 2) + (GetFSingleS(i + 2, t) ^ 2) + (GetFSingleS(i + 4, t) ^ 2), 0) = 1 Then
            NormalScalar = t
            t = 65536
        End If
        t = 2 ^ s
        s = s + 1
   Loop
End If
ReDim Normals(CLng(65535)) As Vector3d
Refresh
k = 0
Do Until GetLongS(i) + GetLongS(i + 4) + GetLongS(i + 8) + GetLongS(i + 12) = 0
On Error GoTo skipthisnorm
loadbar.Value = i
If IsSingleS(i + 4) = True And IsSingleS(i) = True And IsSingleS(i + 8) = True Then
    'If NormIsFloat = True Then
       Normals(k).x = GetSingleS(i)
        Normals(k).Z = GetSingleS(i + 4)
        Normals(k).y = GetSingleS(i + 8)
        NormalCount = NormalCount + 1
        i = i + 12
    Else
        Normals(k).x = GetFSingleS(i, NormalScalar)
        Normals(k).Z = GetFSingleS(i + 2, NormalScalar)
       Normals(k).y = GetFSingleS(i + 4, NormalScalar)
        NormalCount = NormalCount + 1
        i = i + 6
End If
    k = k + 1
skipthisnorm:
Loop
i = i + 16
k = 0
ReDim UVs(CLng(65535)) As Vector2d
StatusBar.SimpleText = "Loading Please Wait: Processing UVs..."
Refresh
Do Until i >= GetLongS(IndexOffset)
If FileIsFloat = True Then
loadbar.Value = i
    UVs(k).U = GetSingleS(i)
    UVs(k).V = GetSingleS(i + 4)
    UVCount = UVCount + 1
    i = i + 12
    k = k + 1
    Else
    UVs(k).U = GetFSingleS(i, NormalScalar)
    UVs(k).V = GetFSingleS(i + 2, NormalScalar)
    UVCount = UVCount + 1
    i = i + 12
    k = k + 1
End If
Loop
StatusBar.SimpleText = "Loading Please Wait: Scanning For Primitive Groups"
Refresh
OutputFile = OBJVertStr(Vertecies, VertexCount) & vbCrLf
'outputfile = outputfile & OBJNormStr(Normals, NormalCount) & vbCrLf
OutputFile = OutputFile & OBJUVStr(UVs, UVCount) & vbCrLf
tmpcount = VertexCount
tmpcount1 = NormalCount
tmpOffset = 91936
Dim TriGroupOffset(32767) As Double
Dim TriGroupType(32767) As Byte
Dim o As Long
o = 0
loadbar.Max = IndexOffset
Do Until i >= IndexOffset
'On Error GoTo tryagain
loadbar.Value = i
    If GetByte(i) = CByte(&H98) And GetIntS(i + 3) <= tmpcount And GetIntS(i + 3) > 0 And GetIntS(i + 5) > 0 And GetIntS(i + 7) > 0 And GetIntS(i + 5) <= tmpcount1 And GetIntS(i + 1) > 0 Then
            If GetByte(3 + i + (GetIntS(i + 1) * 6)) = CByte(&H98) Or GetLongS(3 + i + (GetIntS(i + 1) * 6)) + GetLongS(3 + i + (GetIntS(i + 1) * 6) + 4) = 0 Then
                TriGroupType(o) = 3
                TriGroupOffset(o) = i
                o = o + 1
                i = i + GetIntS(i + 1) * 6
                i = i - 2
                y = 0
            ElseIf GetByte(3 + i + (GetIntS(i + 1) * 8)) = CByte(&H98) Or GetLongS(3 + i + (GetIntS(i + 1) * 8)) + GetLongS(3 + i + (GetIntS(i + 1) * 8) + 4) = 0 Then
                TriGroupType(o) = 4
                TriGroupOffset(o) = i
                o = o + 1
                i = i + GetIntS(i + 1) * 8
                i = i - 2
                y = 0
            ElseIf GetByte(3 + i + (GetIntS(i + 1) * 4)) = CByte(&H98) Or GetLongS(3 + i + (GetIntS(i + 1) * 4)) + GetLongS(3 + i + (GetIntS(i + 1) * 4) + 4) = 0 Then
                TriGroupType(o) = 2
                TriGroupOffset(o) = i
                o = o + 1
                i = i + GetIntS(i + 1) * 4
                i = i - 2
                y = 0
            ElseIf GetByte(3 + i + (GetIntS(i + 1) * 10)) = CByte(&H98) Or GetLongS(3 + i + (GetIntS(i + 1) * 10)) + GetLongS(3 + i + (GetIntS(i + 1) * 4) + 10) = 0 Then
                TriGroupType(o) = 5
                TriGroupOffset(o) = i
                o = o + 1
                i = i + GetIntS(i + 1) * 10
                i = i - 2
                y = 0
            ElseIf GetByte(3 + i + (GetIntS(i + 1) * 12)) = CByte(&H98) Or GetLongS(3 + i + (GetIntS(i + 1) * 12)) + GetLongS(3 + i + (GetIntS(i + 1) * 4) + 12) = 0 Then
                TriGroupType(o) = 6
                TriGroupOffset(o) = i
                o = o + 1
                i = i + GetIntS(i + 1) * 12
                i = i - 2
                y = 0
            Else
            i = i + 1
        End If
            Else
tryagain:
            y = y + 1
            i = i + 1
    End If
If y > CLng(Text2) Then i = IndexOffset
Loop
p = 0
GroupCount = o
loadbar.Max = GroupCount + 1
StatusBar.SimpleText = "Loading Please Wait: Building Index"
Refresh
Dim tmpText2(30000) As String
Dim Indx As FaceIndex3d
W = 1
g = 1
For i = 0 To GroupCount - 1
 '   On Error Resume Next
loadbar.Value = i
'If GetLongS((TriGroupOffset(i) + ((TriGroupType(i) * 2) * GetIntS(TriGroupOffset(i) + 1)))) = 0 Then
tmpText2(p) = tmpText2(p) & vbCrLf & "g object_" & g & vbCrLf
g = g + 1
'ElseIf GetLongS((TriGroupOffset(i) + ((TriGroupType(i) * 2) * GetIntS(TriGroupOffset(i) + 1))) + 4) = 0 Then
'tmpText2(p) = tmpText2(p) & vbCrLf & "g object_" & g & vbCrLf
'g = g + 1
'ElseIf GetLongS((TriGroupOffset(i) + ((TriGroupType(i) * 2) * GetIntS(TriGroupOffset(i) + 1))) + 8) = 0 Then
'tmpText2(p) = tmpText2(p) & vbCrLf & "g object_" & g & vbCrLf
'g = g + 1
'ElseIf GetLongS((TriGroupOffset(i) + ((TriGroupType(i) * 2) * GetIntS(TriGroupOffset(i) + 1))) + 12) = 0 Then
'tmpText2(p) = tmpText2(p) & vbCrLf & "g object_" & g & vbCrLf
'g = g + 1
'End If
For j = TriGroupOffset(i) + 3 To (TriGroupOffset(i) + ((TriGroupType(i) * 2) * GetIntS(TriGroupOffset(i) + 1))) Step TriGroupType(i) * 2
'    On Error Resume Next
    If GetIntS(j) > tmpcount Then GoTo skipthisone
    If GetIntS(j + (TriGroupType(i) * 2)) > tmpcount Then GoTo skipthisone
    If GetIntS(j + (TriGroupType(i) * 2) + (TriGroupType(i) * 2)) > tmpcount Then GoTo skipthisone
    Indx.Av = GetIntS(j) + 1
    Indx.An = GetIntS(j + 2) + 1
    Indx.At = GetIntS(j + 4) + 1
 
    Indx.Bv = GetIntS(j + (TriGroupType(i) * 2)) + 1
    Indx.Bn = GetIntS(j + (TriGroupType(i) * 2) + 2) + 1
    Indx.Bt = GetIntS(j + (TriGroupType(i) * 2) + 4) + 1
 
    Indx.Cv = GetIntS(j + (TriGroupType(i) * 2) + (TriGroupType(i) * 2)) + 1
    Indx.Cn = GetIntS(j + (TriGroupType(i) * 2) + (TriGroupType(i) * 2) + 2) + 1
    Indx.Ct = GetIntS(j + (TriGroupType(i) * 2) + (TriGroupType(i) * 2) + 4) + 1
If Indx.Av = Indx.Bv Then GoTo skipthisone
If Indx.Av = Indx.Cv Then GoTo skipthisone
If Indx.Cv = Indx.Bv Then GoTo skipthisone
    If W = 1 Then
    tmpText2(p) = tmpText2(p) & "f " & Indx.Av & "/" & Indx.An & "/" & Indx.At & " " & Indx.Bv & "/" & Indx.Bn & "/" & Indx.Bt & " " & Indx.Cv & "/" & Indx.Cn & "/" & Indx.Ct & vbCrLf
    W = 0
    Else
    tmpText2(p) = tmpText2(p) & "f " & Indx.Cv & "/" & Indx.Cn & "/" & Indx.Ct & " " & Indx.Bv & "/" & Indx.Bn & "/" & Indx.Bt & " " & Indx.Av & "/" & Indx.An & "/" & Indx.At & vbCrLf
    W = 1
    End If
p = p + 1
skipthisone:
Next j
Next i
StatusBar.SimpleText = "Loading Done!!!"
Refresh
OutputFile = OutputFile & vbCrLf & "g object_0" & vbCrLf & Join(tmpText2)
x = 1
   With dlgCommonDialog
        .DialogTitle = "Save OBJ"
        .CancelError = False
        .Filter = "OBJ Files (*.obj*)|*.obj*"
        .ShowSave
        If Len(.FileName) = 0 Then
            Exit Sub
        End If
        sFile = .FileName
    End With
    Open (sFile & ".obj") For Output As #2
Print #2, OutputFile
Close 2
 
End Sub
Private Sub ProgressBar1_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
End Sub
Private Sub sbStatusBar_PanelClick(ByVal Panel As MSComctlLib.Panel)
End Sub

EDIT:
the bas file is the functions
the frm file is the code

at least I understand this a little better
finally some progress
 
Last edited:
OP
Tcll

Tcll

Complexity == Fun >:3
KK... that kinda surprises me... o_O
it's VB of all things...
I don't even program in it and I can still somewhat understand it...
 
OP
Tcll

Tcll

Complexity == Fun >:3
I did manage to find out how he converted verticies...
take a look at this:
Code:
Dim i As Double
Dim j As Double
Dim k As Double
Dim FileIsFloat As Boolean
VertexCount = 0
NormalCount = 0
j = 0
IndexOffset = GetLongS(4) + 32
i = 32
loadbar.Max = IndexOffset
If IsSingleS(32) = True And IsSingleS(36) = True And IsSingleS(40) = True Then
            FileIsFloat = True
        Else
            FileIsFloat = False
End If
ReDim Vertecies(CLng(65535)) As Vector3d
Do Until GetLongS(i) + GetLongS(i + 4) + GetLongS(i + 8) + GetLongS(i + 12) = 0
'On Error GoTo skipthisvert
loadbar.Value = i
If FileIsFloat = True Then
    Vertecies(j).x = GetSingleS(i)
    Vertecies(j).Z = GetSingleS(i + 4)
    Vertecies(j).y = GetSingleS(i + 8)
    VertexCount = VertexCount + 1
    i = i + 12
Else
    Vertecies(j).x = GetFSingleS(i)
    Vertecies(j).Z = GetFSingleS(i + 2)
    Vertecies(j).y = GetFSingleS(i + 4)
    VertexCount = VertexCount + 1
    i = i + 6
End If
    j = j + 1
skipthisvert:
Loop
 
OP
Tcll

Tcll

Complexity == Fun >:3
I've got an idea...
not sure hoe to carry it out though...

but after finding the value in the data from the relocation table,
run a series of tests on the data, and whatever the tests return,
use that info for a listed conversion method...

it should work if one knows how to carry it out...
 

Milun

New member
Help has arrived:

Here's the C++ code I've made to export (only) the Hex vertices to .obj, for now, let's say it's reading a .txt with this text in it:


FD A0 FE E0 FE 40 FF C0 FD E0 FC E0 03 40 FD 00
FB C0 07 00 FC E0 FB A0 05 20 FD 40 FC 20 07 E0
FD C0 FC E0 0A 40 FE 60 FD A0 0B C0 FF 20 FE C0
FD A0 FE 40 FF 40 FF C0 FC 80 FE C0 03 40 FB 40
FE 40 07 00 FB 00 FE 40 05 20 FB A0 FE 60 07 E0


Code:
#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
#include <iterator>
using namespace std;

char *CHAR;

string Input;
string Output;

///All this does is convert Decimal values to Hex///
string fn_DecToHex (unsigned int value) {
	char conHex[256];
	int rawDec = value; //this is variable
	sprintf(conHex,"%x",rawDec);
	return conHex;
}

///It's name is self explanitory///
int fn_HexToDec (char rawHex[]) {
	int conDec; 
	sscanf(rawHex, "%x", &conDec);
	return conDec;
}

///////////////////////
string fn_IntToString(int intValue) {
  char *myBuff;
  string strRetVal;
  myBuff = new char[100];
  memset(myBuff,'\0',100);
  itoa(intValue,myBuff,10);
  strRetVal = myBuff;
  delete[] myBuff;
  return(strRetVal);
}

////////////////////////
int fn_StringToInt(string strConvert) {
  int intReturn;
  intReturn = atoi(strConvert.c_str());
  return(intReturn);
}

/////////////////////////
void fn_StringToChar(string STR) {
     int TempNumOne=STR.size();
     for (int a=0;a<=TempNumOne;a++)
     {
         CHAR[a]=STR[a];
     }
}



int main() {

  string line;///Makes a new variable called 'line', the 'line' in this case being the entire hex contained copy-pasted within the .txt, so it's large.
  cout << "Opening files." << endl;///This just shows text in command prompt, and makes a new line.
  
  cout << "Input file: ";
  cin >> Input;///This asks for the complete filename.
  cout << endl;///New line.
  
  ifstream myfile (Input.c_str());///Makes a filename out of 'Input'.
  
  cout << "Output file: ";
  cin >> Output;
  cout << endl;
  
  ofstream outfile (Output.c_str()); ///Makes a filename out of 'Output'.
  
  cout << "Writing vertice data to file." << endl;
  
  if (myfile.is_open() && outfile.is_open())///If both files are allowed.
  {
    while (! myfile.eof() )
    {   
      getline (myfile,line);///Reads the text in the file and assigns it to 'line'.
      CHAR  = new char[100];///Makes a new character variable.
      unsigned int Offset = 0;///Starts the offset at 0.
      unsigned int MaxOffset = line.length();///MaxOffset is the size of the text (character ammount), and tells the code when to stop.
      
      Convert:///We'll have a loop going here.
      
      /////////
      /// X ///
      /////////
      
      fn_StringToChar(line.substr(Offset,2));
      ///Converts the first two characters from 'Offset' into characters, if 'Offset' = 0, it would be converting the 'FD' in my example.
      
      double DecX = fn_HexToDec(CHAR);
      ///This then converts the characters to their decimal values and assigns the hex value of 'FD' to DecX (assuming Offset = 0).
      
      if (DecX > 127) {DecX -= 256;}
      ///This does the whole unscrambling process.
      
      fn_StringToChar(line.substr(Offset+3,2));
      ///Now, we take the next Hex value, but leave the Offset as is. Notice it copies the string at 'Offset + 3', because in a .txt, space (' ') is a character. So, it would copy 'A0'. 
      
      int Decimal = fn_HexToDec(CHAR);
      ///Etc.
      
      double FracX = 0.00390625*Decimal;
      ///Now, I don't know how yours works, but to avoid guargantuan models, mine treats the secondary value as decimal. What you see is that Hex value being multiplied by 1/256th.
      
      Offset += 6;
      ///Now, we add to the offset, so it reaches the start of the Y values.
      
      /////////
      /// Y ///
      /////////
      
      ///And again...
      
      fn_StringToChar(line.substr(Offset,2));
      double DecY = fn_HexToDec(CHAR);
      if (DecY > 127) {DecY -= 256;}
      
      fn_StringToChar(line.substr(Offset+3,2));
      Decimal = fn_HexToDec(CHAR);
      double FracY = 0.00390625*Decimal;
      Offset += 6;
      
      /////////
      /// Z ///
      /////////
      
      ///And again...
      
      fn_StringToChar(line.substr(Offset,2));
      double DecZ = fn_HexToDec(CHAR);
      if (DecZ > 127) {DecZ -= 256;}
      
      fn_StringToChar(line.substr(Offset+3,2));
      Decimal = fn_HexToDec(CHAR);
      double FracZ = 0.00390625*Decimal;
      Offset += 6;
      
      ///Now, we add the X decimal value to the X whole value, etc.
      DecX += FracX;
      DecY += FracY;
      DecZ += FracZ;
      
      ///Write it to my output file, and make a new line.
      outfile << "v " << DecX << " " << DecY << " " << DecZ << endl;
      
      ///Check to see if we've reached the end of the file yet...
      if (Offset < MaxOffset){goto Convert;}///If not, go back and repeat...
      else
      {cout << "Done!" << endl;}///Otherwise, display that it finished.
    }
    myfile.close();///Close the file when done.
    outfile.close();///Ditto that.
  }

  else cout << "Unable to open file";///If the file doesn't exist, show an error.


	system ("pause");///Don't close, let the user see that everything worked first.
	return 0;
}
 

GameWatching

New member
Help has arrived:

Here's the C++ code I've made to export (only) the Hex vertices to .obj, for now, let's say it's reading a .txt with this text in it:


FD A0 FE E0 FE 40 FF C0 FD E0 FC E0 03 40 FD 00
FB C0 07 00 FC E0 FB A0 05 20 FD 40 FC 20 07 E0
FD C0 FC E0 0A 40 FE 60 FD A0 0B C0 FF 20 FE C0
FD A0 FE 40 FF 40 FF C0 FC 80 FE C0 03 40 FB 40
FE 40 07 00 FB 00 FE 40 05 20 FB A0 FE 60 07 E0


Code:
stuffz that actually i can't read

do you need a program to execute this script ?

and the hex values !
are they for characters ?
because i searched for levels and i found nothing !
 

Milun

New member
Uh... whoops, shoulda explained that. What the code does, is export the vertices of any file to a .obj. It's in C++, you don't need a program, you just need to compile it. Here's the .exe, just copy and paste the complete vertice code into a .txt (copy and paste works only through HxD hex editor).

http://www.megaupload.com/?d=TSSZW1PP
 
OP
Tcll

Tcll

Complexity == Fun >:3
how can i find the vertices code >< ?
as milun explained...

you need HxD to get the data and put it into a txt file...
that's how his program works...
reading hex data from a txt file, and converting that to obj...

my code for the blender importer will only import verts...
(same results you get with miluns converter)
 
OP
Tcll

Tcll

Complexity == Fun >:3
Help has arrived:

Here's the C++ code I've made to export (only) the Hex vertices to .obj, for now, let's say it's reading a .txt with this text in it:


FD A0 FE E0 FE 40 FF C0 FD E0 FC E0 03 40 FD 00
FB C0 07 00 FC E0 FB A0 05 20 FD 40 FC 20 07 E0
FD C0 FC E0 0A 40 FE 60 FD A0 0B C0 FF 20 FE C0
FD A0 FE 40 FF 40 FF C0 FC 80 FE C0 03 40 FB 40
FE 40 07 00 FB 00 FE 40 05 20 FB A0 FE 60 07 E0

Code:
#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
#include <iterator>
using namespace std;
 
char *CHAR;
 
string Input;
string Output;
 
///All this does is convert Decimal values to Hex///
string fn_DecToHex (unsigned int value) {
    char conHex[256];
    int rawDec = value; //this is variable
    sprintf(conHex,"%x",rawDec);
    return conHex;
}
 
///It's name is self explanitory///
int fn_HexToDec (char rawHex[]) {
    int conDec; 
    sscanf(rawHex, "%x", &conDec);
    return conDec;
}
 
///////////////////////
string fn_IntToString(int intValue) {
  char *myBuff;
  string strRetVal;
  myBuff = new char[100];
  memset(myBuff,'\0',100);
  itoa(intValue,myBuff,10);
  strRetVal = myBuff;
  delete[] myBuff;
  return(strRetVal);
}
 
////////////////////////
int fn_StringToInt(string strConvert) {
  int intReturn;
  intReturn = atoi(strConvert.c_str());
  return(intReturn);
}
 
/////////////////////////
void fn_StringToChar(string STR) {
     int TempNumOne=STR.size();
     for (int a=0;a<=TempNumOne;a++)
     {
         CHAR[a]=STR[a];
     }
}
 
 
 
int main() {
 
  string line;///Makes a new variable called 'line', the 'line' in this case being the entire hex contained copy-pasted within the .txt, so it's large.
  cout << "Opening files." << endl;///This just shows text in command prompt, and makes a new line.
 
  cout << "Input file: ";
  cin >> Input;///This asks for the complete filename.
  cout << endl;///New line.
 
  ifstream myfile (Input.c_str());///Makes a filename out of 'Input'.
 
  cout << "Output file: ";
  cin >> Output;
  cout << endl;
 
  ofstream outfile (Output.c_str()); ///Makes a filename out of 'Output'.
 
  cout << "Writing vertice data to file." << endl;
 
  if (myfile.is_open() && outfile.is_open())///If both files are allowed.
  {
    while (! myfile.eof() )
    {   
      getline (myfile,line);///Reads the text in the file and assigns it to 'line'.
      CHAR  = new char[100];///Makes a new character variable.
      unsigned int Offset = 0;///Starts the offset at 0.
      unsigned int MaxOffset = line.length();///MaxOffset is the size of the text (character ammount), and tells the code when to stop.
 
      Convert:///We'll have a loop going here.
 
      /////////
      /// X ///
      /////////
 
      fn_StringToChar(line.substr(Offset,2));
      ///Converts the first two characters from 'Offset' into characters, if 'Offset' = 0, it would be converting the 'FD' in my example.
 
      double DecX = fn_HexToDec(CHAR);
      ///This then converts the characters to their decimal values and assigns the hex value of 'FD' to DecX (assuming Offset = 0).
 
      if (DecX > 127) {DecX -= 256;}
      ///This does the whole unscrambling process.
 
      fn_StringToChar(line.substr(Offset+3,2));
      ///Now, we take the next Hex value, but leave the Offset as is. Notice it copies the string at 'Offset + 3', because in a .txt, space (' ') is a character. So, it would copy 'A0'. 
 
      int Decimal = fn_HexToDec(CHAR);
      ///Etc.
 
      double FracX = 0.00390625*Decimal;
      ///Now, I don't know how yours works, but to avoid guargantuan models, mine treats the secondary value as decimal. What you see is that Hex value being multiplied by 1/256th.
 
      Offset += 6;
      ///Now, we add to the offset, so it reaches the start of the Y values.
 
      /////////
      /// Y ///
      /////////
 
      ///And again...
 
      fn_StringToChar(line.substr(Offset,2));
      double DecY = fn_HexToDec(CHAR);
      if (DecY > 127) {DecY -= 256;}
 
      fn_StringToChar(line.substr(Offset+3,2));
      Decimal = fn_HexToDec(CHAR);
      double FracY = 0.00390625*Decimal;
      Offset += 6;
 
      /////////
      /// Z ///
      /////////
 
      ///And again...
 
      fn_StringToChar(line.substr(Offset,2));
      double DecZ = fn_HexToDec(CHAR);
      if (DecZ > 127) {DecZ -= 256;}
 
      fn_StringToChar(line.substr(Offset+3,2));
      Decimal = fn_HexToDec(CHAR);
      double FracZ = 0.00390625*Decimal;
      Offset += 6;
 
      ///Now, we add the X decimal value to the X whole value, etc.
      DecX += FracX;
      DecY += FracY;
      DecZ += FracZ;
 
      ///Write it to my output file, and make a new line.
      outfile << "v " << DecX << " " << DecY << " " << DecZ << endl;
 
      ///Check to see if we've reached the end of the file yet...
      if (Offset < MaxOffset){goto Convert;}///If not, go back and repeat...
      else
      {cout << "Done!" << endl;}///Otherwise, display that it finished.
    }
    myfile.close();///Close the file when done.
    outfile.close();///Ditto that.
  }
 
  else cout << "Unable to open file";///If the file doesn't exist, show an error.
 
 
    system ("pause");///Don't close, let the user see that everything worked first.
    return 0;
}

yep... still up to yur old ideas as usual XDD

but this is moar improved :D
nice job
at least yur gifted to actually get a working program out of it...
it's more friendly with you than it is with me D:

eh...
but it doesn't really help me out as it only does verts
if it's vert data you copied instead of all the data, then it doesn't really work...
but still... reading verts from all the data is easy...

if you want it to work...
you have to go through the relocation table...
 
OP
Tcll

Tcll

Complexity == Fun >:3
KK... from the start of the dat file you will find the header...
(will not look exactly like this in the file)
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
(32 bytes)

start copying data from the first value after the header until you reach the first group of:

'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'

that's the vert data
 

GameWatching

New member
i tried with fox and i got this oO :
weirdlm.png


what i did wrong ?
 

GameWatching

New member
it's fox (character)

i found 00 00 00 ...
i started after it ends then i stopped when i seen the other 00 00 00

normally that should work
 

Top