Delphi/Pascal Code explanation to PHP

Posts 12 of 2 · Page 1 of 1
Delphi/Pascal Code explanation to PHP
Hey there, i hope there is someone out there who can help me with this. I have a Unit file (i think i can call it class too) with functions to decode a binary file format, that i want to rewrite/transfer to PHP. I completely suck at Delphi/Pascal, so i cannot understand this Code. Im very good at PHP and it would help a lot if someone can translate important parts to PHP or pseudocode. It would help me too if someone tells me what Records are or parts i can skip because of PHP not caring about typesafety.

Code in Delphi:
Code:
unit LtbFile;

interface

uses Contnrs, SysUtils;

const
  LTB_OK = 0;

const
  LTB_FAIL = 1;

const

  //-----------------------------------------------
  //  Offsets.
  //-----------------------------------------------

  LTB_FILEOFFSET_COMLINELENGTH  = 84;      // Command line length description.
  LTB_FILEOFFSET_MESHCOUNT      = 86 + 8;  // Mesh count description.
  LTB_FILEOFFSET_FIRSTMESH      = 86 + 12; // Beginning of the first mesh.

  LTB_MESHOFFSET_VERTEXCOUNT    = 49;      // Vertex count.
  LTB_MESHOFFSET_FACECOUNT      = 53;      // Face count.
  LTB_MESHOFFSET_MESHTYPE_HEAD  = 57;      // Mesh header.
  LTB_MESHOFFSET_MESHTYPE       = 61;      // Mesh type. 1 - not skinned;
                                           //            2 - extra float;
                                           //            4 & 3 - skinned;
                                      
  LTB_MESHOFFSET_FIRSTVERTEX    = 83;      // First vertex in mesh.
  LTB_MESHOFFSET_FIRSTVERTEX_DS = 85;      // First vertex in mesh (not skinned).

  //-----------------------------------------------
  //  Mesh type.
  //-----------------------------------------------

  LTB_MESHTYPE_NOTSKINNED = 1;
  LTB_MESHTYPE_EXTRAFLOAT = 2;
  LTB_MESHTYPE_SKINNED    = 4;
  LTB_MESHTYPE_SKINNEDALT = 3;
  LTB_MESHTYPE_TWOEXTRAFLOAT = 5;

type

  _LtbVector3 = record
    x, y, z: Single;
  end;

  _LtbVertex = record
    Position: _LtbVector3;
    Normal  : _LtbVector3;
    Weights : _LtbVector3;
    U, V    : Single;
  end;

  _LtbVertices = array of _LtbVertex;
  _LtbIndices  = array of Word;

  //-----------------------------------------------
  //  Ltb Mesh class.
  //-----------------------------------------------

  CLtb******sh = class
  private
    VertexCount: Word;
    IndexCount: Word;
    Vertices: _LtbVertices;
    Indices: _LtbIndices;

    MeshName: ShortString;
  public
    constructor Create( const MeshName: ShortString;
      const VertexCount, IndexCount: Word;
      const Vertices: _LtbVertices;
      const Indices: _LtbIndices );
    function GetMeshName( ): ShortString;
    function GetVertices( out Vertices: _LtbVertices ): Word;
    function GetIndices( out Indices: _LtbIndices ): Word;
    destructor Destroy( ); override;
  end;

  //-----------------------------------------------
  //  Ltb File class.
  //-----------------------------------------------

  CLtbFile = class
  private
    MeshList: TObjectList;

    CommandLine: String;
  public
    constructor Create( );
    function GetMeshCount( ): Cardinal;
    function GetMesh( const MeshIndex: Byte ): CLtb******sh;
    function GetCommandLine( ): String;
    function LoadFromFile( const LtbFileName: ShortString ): Byte;
    destructor Destroy( ); override;
  end;

implementation

//-----------------------------------------------
//  Initialize mesh.
//-----------------------------------------------

constructor CLtb******sh.Create( const MeshName: ShortString;
  const VertexCount, IndexCount: Word;
  const Vertices: _LtbVertices;
  const Indices: _LtbIndices );
begin
  Self.MeshName := MeshName;

  // Copy vertices.
  Self.VertexCount := VertexCount;

  SetLength( Self.Vertices, VertexCount );

  Self.Vertices := Copy( Vertices, 0, VertexCount );

  // Copy indices.
  Self.IndexCount := IndexCount;

  SetLength( Self.Vertices, IndexCount );

  Self.Indices := Copy( Indices, 0, IndexCount );
end;

//-----------------------------------------------
//  Get mesh name.
//-----------------------------------------------

function CLtb******sh.GetMeshName( ): ShortString;
begin
  Result := MeshName;
end;

//-----------------------------------------------
//  Get mesh vertices. Returns number of vertices.
//-----------------------------------------------

function CLtb******sh.GetVertices( out Vertices: _LtbVertices ): Word;
begin
  Vertices := Self.Vertices;

  Result := VertexCount;
end;

//-----------------------------------------------
//  Get mesh indices. Returns number of indices.
//-----------------------------------------------

function CLtb******sh.GetIndices( out Indices: _LtbIndices ): Word;
begin
  Indices := Self.Indices;

  Result := IndexCount;
end;

//-----------------------------------------------
//  Destroy mesh.
//-----------------------------------------------

destructor CLtb******sh.Destroy( );
begin
  Vertices := nil;
  Indices  := nil;
end;

//-----------------------------------------------
//  Initialize LTB file.
//-----------------------------------------------

constructor CLtbFile.Create( );
begin
  MeshList := TObjectList.Create( );
end;

//-----------------------------------------------
//  Get mesh count.
//-----------------------------------------------

function CLtbFile.GetMeshCount( ): Cardinal;
begin
  Result := MeshList.Count;
end;

//-----------------------------------------------
//  Get mesh by it's index.
//-----------------------------------------------

function CLtbFile.GetMesh( const MeshIndex: Byte ): CLtb******sh;
begin
  if ( MeshIndex < MeshList.Count ) then
    Result := CLtb******sh( MeshList[MeshIndex] )
  else
    Result := nil;
end;

//-----------------------------------------------
//  Get command line.
//-----------------------------------------------

function CLtbFile.GetCommandLine( ): String;
begin
  Result := CommandLine;
end;

//-----------------------------------------------
//  Load peices (meshes) from a LTB file.
//-----------------------------------------------

function CLtbFile.LoadFromFile( const LtbFileName: ShortString ): Byte;
var
  i, j : Integer;

  _File: File;

  BaseOffset: Cardinal; // Base reading offset.
  GeoOffset : Integer;
  SkipDataSize: Cardinal;
  
  ByteDataA, ByteDataB, ByteDataC, ByteDataD: Byte;
  WordData  : Word;
  CardData  : Cardinal;

  MeshCount : Cardinal;

  MeshName: String;

  VertexCount: Word;
  IndexCount : Word;
  Vertices   : _LtbVertices;
  Indices    : _LtbIndices;

  IncludeWeights: Boolean;
  IncludePostData: Boolean;

  SectionSize: Byte;

begin
  Result := LTB_FAIL;

  if ( not FileExists( LtbFileName ) ) then
    Exit;

  // Assign file.
  AssignFile( _File, LtbFileName );

  // Reset to file's start.
  Reset( _File, 1 );

  // Clear mesh list.
  MeshList.Clear( );

  // Reset base offset.
  BaseOffset := 0;

  // Read command line length.
  Seek( _File, BaseOffset + LTB_FILEOFFSET_COMLINELENGTH );
  BlockRead( _File, WordData, SizeOf( Word ) );

  SetLength( CommandLine, WordData );

  // Read command line.
  BlockRead( _File, CommandLine[1], WordData );

  // Read mesh count.
  Seek( _File, BaseOffset + LTB_FILEOFFSET_MESHCOUNT + WordData );
  BlockRead( _File, MeshCount, SizeOf( Cardinal ) );

  // Seek for first mesh.
  Seek( _File, BaseOffset + LTB_FILEOFFSET_FIRSTMESH + WordData );

  for i := 0 to ( MeshCount - 1 ) do
  begin
    // Read mesh name length.
    BlockRead( _File, WordData, SizeOf( Word ) );

    SetLength( MeshName, WordData );

    // Read mesh name.
    BlockRead( _File, MeshName[1], WordData );

    // Set new base offset.
    BaseOffset := FilePos( _File );

    // Read vertex count.
    Seek( _File, BaseOffset + LTB_MESHOFFSET_VERTEXCOUNT );
    BlockRead( _File, VertexCount, SizeOf( Word ) );

    // Read face count.
    Seek( _File, BaseOffset + LTB_MESHOFFSET_FACECOUNT );
    BlockRead( _File, IndexCount, SizeOf( Word ) );

    // Since LTB models store their face count, instead
    // of index count, we need to multiply it by 3 (Each face - 3 indices).
    IndexCount := IndexCount * 3;

    // Resize vertices and indices arrays.
    SetLength( Vertices, VertexCount );
    SetLength( Indices, IndexCount );

    // Look-up mesh type.
    Seek( _File, BaseOffset + LTB_MESHOFFSET_MESHTYPE_HEAD );
    BlockRead( _File, WordData, SizeOf( Word ) );

    SkipDataSize := 0;

    if ( not ( WordData = LTB_MESHTYPE_SKINNEDALT ) ) then
    begin
      Seek( _File, BaseOffset + LTB_MESHOFFSET_MESHTYPE );
      BlockRead( _File, WordData, SizeOf( Word ) );
    end
    else
      WordData := LTB_MESHTYPE_TWOEXTRAFLOAT;
    
    IncludeWeights := False;
    IncludePostData := False;

    if ( WordData = LTB_MESHTYPE_NOTSKINNED ) then
    begin

      // Mesh type: Not skinned.
      IncludeWeights := False;
      IncludePostData := False;
    end
    else
    if ( WordData = LTB_MESHTYPE_EXTRAFLOAT ) then
    begin

      // Mesh type: Extra float.
      IncludeWeights := False;
      IncludePostData := True;
      SkipDataSize   := SizeOf( Single );
    end
    else
    if ( ( WordData = LTB_MESHTYPE_SKINNED ) or
       ( WordData = LTB_MESHTYPE_SKINNEDALT ) ) then
    begin

      // Mesh type: Skinned.
      IncludeWeights := True;
      IncludePostData := True;
    end
    else
    if ( WordData = LTB_MESHTYPE_TWOEXTRAFLOAT ) then
    begin

      // Mesh type: Double extra float.
      IncludeWeights := False;
      IncludePostData := True;
      SkipDataSize   := SizeOf( Single ) * 2;
    end;

    Seek( _File, BaseOffset + LTB_MESHOFFSET_FIRSTVERTEX );
    BlockRead( _File, ByteDataA, SizeOf( Byte ) );

    Seek( _File, BaseOffset + LTB_MESHOFFSET_FIRSTVERTEX + 1 );
    BlockRead( _File, ByteDataB, SizeOf( Byte ) );

    Seek( _File, BaseOffset + LTB_MESHOFFSET_FIRSTVERTEX + 2 );
    BlockRead( _File, ByteDataC, SizeOf( Byte ) );

    Seek( _File, BaseOffset + LTB_MESHOFFSET_FIRSTVERTEX + 3 );
    BlockRead( _File, ByteDataD, SizeOf( Byte ) );

    if ( ( ByteDataA = 0 ) and ( ByteDataB = 0 ) and ( ByteDataC <> 0 ) and ( ByteDataD <> 0 ) ) then
      GeoOffset := LTB_MESHOFFSET_FIRSTVERTEX_DS
    else
      GeoOffset := LTB_MESHOFFSET_FIRSTVERTEX;

    // Seek to first vertex.
    Seek( _File, BaseOffset + Cardinal( GeoOffset ) );

    // Vertices.
    for j := 0 to ( VertexCount - 1 ) do
    begin
      // Read position.
      BlockRead( _File, Vertices[j].Position, SizeOf( _LtbVector3 ) );

      if ( IncludeWeights ) then
        // Read weights.
        BlockRead( _File, Vertices[j].Weights, SizeOf( _LtbVector3 ) );

      // Read normal.
      BlockRead( _File, Vertices[j].Normal, SizeOf( _LtbVector3 ) );

      Seek( _File, FilePos( _File ) + Integer( SkipDataSize ) );

      // Read u.
      BlockRead( _File, Vertices[j].u, SizeOf( Single ) );

      // Read v.
      BlockRead( _File, Vertices[j].v, SizeOf( Single ) );
    end;

    // Indices.
    for j := 0 to ( IndexCount - 1 ) do
      // Read index.
      BlockRead( _File, Indices[j], SizeOf( Word ) );

    // ** UNKNOWN BEGIN **

    // Post-data.
    if ( IncludePostData ) then
    begin

      // Read section count.
      BlockRead( _File, CardData, SizeOf( Cardinal ) );

      for j := 0 to ( CardData - 1 ) do
        Seek( _File, FilePos( _File ) + 12 );

      // Final section.
      BlockRead( _File, SectionSize, SizeOf( Byte ) );

      Seek( _File, FilePos( _File ) + SectionSize );

    end
    else
      BlockRead( _File, WordData, SizeOf( Word ) );

    // ** UNKNOWN END **

    // Store mesh.
    MeshList.Add( CLtb******sh.Create( MeshName, VertexCount, IndexCount,
      Vertices, Indices ) );
  end;

  Vertices := nil;
  Indices  := nil;

  // Close file, after we're done with it.
  CloseFile( _File );

  Result := LTB_OK;
end;

//-----------------------------------------------
//  Destroy LTB file.
//-----------------------------------------------

destructor CLtbFile.Destroy( );
begin
  MeshList.Free( );
end;

end.
Damn censoring fail
There is the full code:
http://pastebin.com/JGJXE1jP
So what i have done so far:
Code:
<?php

error_reporting(E_ALL);
function LoadFromFile($LtbFileName) {
  $LTB_FILEOFFSET_COMLINELENGTH  = 84;      // Command line length description.
  $LTB_FILEOFFSET_MESHCOUNT      = 86 + 8;  // Mesh count description.
  $LTB_FILEOFFSET_FIRSTMESH      = 86 + 12; // Beginning of the first mesh.
  $LTB_MESHOFFSET_VERTEXCOUNT    = 49;      // Vertex count.
  $LTB_MESHOFFSET_FACECOUNT      = 53;      // Face count.
  $LTB_MESHOFFSET_MESHTYPE_HEAD  = 57;      // Mesh header.
  $LTB_MESHOFFSET_MESHTYPE       = 61;      // Mesh type. 1 - not skinned;
                                            //            2 - extra float;
                                            //            4 & 3 - skinned;                                  
  $LTB_MESHOFFSET_FIRSTVERTEX    = 83;      // First vertex in mesh.
  $LTB_MESHOFFSET_FIRSTVERTEX_DS = 85;      // First vertex in mesh (not skinned).
  $LTB_MESHTYPE_NOTSKINNED = 1;
  $LTB_MESHTYPE_EXTRAFLOAT = 2;
  $LTB_MESHTYPE_SKINNED    = 4;
  $LTB_MESHTYPE_SKINNEDALT = 3;
  $LTB_MESHTYPE_TWOEXTRAFLOAT = 5;
  
  $MeshList = array();
   
  // Assign file.
  $_File = fopen($LtbFileName,"rb");

  // Reset to file's start.
  rewind($_File);


  // Reset base offset.
  $BaseOffset = 0;

  // Read command line length.
  fseek($_File, $BaseOffset + $LTB_FILEOFFSET_COMLINELENGTH );
  $WordData = fread($_File, 2); //sizeof word = 2
  
  echo $WordData."\n";
  
                                                    //fseek($_File,(ftell($_File) - 2),SEEK_SET);
  // Read command line.
  $CommandLine = fread($_File, (int)$WordData);
echo $CommandLine."\n";
  // Read mesh count.
  fseek($_File, $BaseOffset + $LTB_FILEOFFSET_MESHCOUNT + $WordData );
  $MeshCount = fread($_File, 4);//sizeof cardinal = 4
echo $MeshCount."\n";
  // Seek for first mesh.
  fseek( $_File, $BaseOffset + $LTB_FILEOFFSET_FIRSTMESH + $WordData );

  /*
  for ($i=0;$i= $MeshCount;$i++) {
    // Read mesh name length.
    $WordData = fread($_File, 2);//sizeof word = 2
    $MeshName ="";

    // Read mesh name.
    $MeshName = fread($_File,(int)$WordData);

    // Set new base offset.
    $BaseOffset = ftell($_File);

    // Read vertex count.
    fseek( $_File, $BaseOffset + $LTB_MESHOFFSET_VERTEXCOUNT );
    $VertexCount = fread( $_File, 2);

    // Read face count.
    fseek( $_File, $BaseOffset + $LTB_MESHOFFSET_FACECOUNT );
    $IndexCount = fread($_File, 2 );//sizeof word = 2

    // Since LTB models store their face count, instead
    // of index count, we need to multiply it by 3 (Each face - 3 indices).
    $IndexCount = $IndexCount * 3;

    // Resize vertices and indices arrays.
    // SetLength( Vertices, VertexCount );
    // SetLength( Indices, IndexCount );

    // Look-up mesh type.
    fseek( $_File, $BaseOffset + $LTB_MESHOFFSET_MESHTYPE_HEAD );
    $WordData = fread($_File, 2);

    $SkipDataSize = 0;

    if($WordData != $LTB_MESHTYPE_SKINNEDALT) {
      fseek($_File, $BaseOffset + $LTB_MESHOFFSET_MESHTYPE);
      $WordData = fread($_File, 2);//sizeof word = 2
    }
    else {
      $WordData = $LTB_MESHTYPE_TWOEXTRAFLOAT;
    }
    
    $IncludeWeights = false;
    $IncludePostData = false;

    if($WordData == $LTB_MESHTYPE_NOTSKINNED) {
      // Mesh type: Not skinned.
      $IncludeWeights = false;
      $IncludePostData = False;
    }
    elseif( $WordData = $LTB_MESHTYPE_EXTRAFLOAT) {
      // Mesh type: Extra float.
      $IncludeWeights = false;
      $IncludePostData = true;
      $SkipDataSize   = 4; //size of single = 4
    }
    elseif(($WordData = $LTB_MESHTYPE_SKINNED) OR ($WordData = $LTB_MESHTYPE_SKINNEDALT)) {
      // Mesh type: Skinned.
      $IncludeWeights = true;
      $IncludePostData = true;
    }
    elseif($WordData = $LTB_MESHTYPE_TWOEXTRAFLOAT) {
      // Mesh type: Double extra float.
      $IncludeWeights = False;
      $IncludePostData = True;
      $SkipDataSize = 4 * 2; //Sizeof single * 2
    }

    fseek($_File, $BaseOffset + $LTB_MESHOFFSET_FIRSTVERTEX);
    $ByteDataA = fread( $_File, 1 );

    fseek($_File, $BaseOffset + $LTB_MESHOFFSET_FIRSTVERTEX + 1);
    $ByteDataB = fread( $_File, 1 );

    fseek($_File, $BaseOffset + $LTB_MESHOFFSET_FIRSTVERTEX + 2);
    $ByteDataC = fread( $_File, 1 );

    fseek($_File, $BaseOffset + $LTB_MESHOFFSET_FIRSTVERTEX + 3);
    $ByteDataD = fread( $_File, 1);

    if(($ByteDataA == 0) and ($ByteDataB == 0) and ($ByteDataC != 0) and ($ByteDataD != 0)) {
      $GeoOffset = $LTB_MESHOFFSET_FIRSTVERTEX_DS;
    } else {
      $GeoOffset = $LTB_MESHOFFSET_FIRSTVERTEX;
    }

    // Seek to first vertex.
    fseek($_File, $BaseOffset + $GeoOffset);

    // Vertices.
    $Vertices = array();
    for($j=0;$i<=$VertexCount;$j++) {
      $Vertices[$j] = array();
      
 
 
      
      // Read position.

      $x = fread($_File,4);
      $y = fread($_File,4);
      $z = fread($_File,4);
      $Vertices[$j]['Position'] = array($x,$y,$z);
      
      // Read weights.
      if($IncludeWeights) {
          $x = fread($_File,4);
          $y = fread($_File,4);
          $z = fread($_File,4);
          $Vertices[$j]['Weights'] = array($x,$y,$z);
      }
      // Read normal.
      $x = fread($_File,4);
      $y = fread($_File,4);
      $z = fread($_File,4);
      $Vertices[$j]['Normal'] = array($x,$y,$z);

      fseek($_File, ftell($_File) + $SkipDataSize);

      // Read u.
      $Vertices[$j]['U'] = fread($_File, 4);

      // Read v.
      $Vertices[$j]['V'] = fread($_File, 4);
    }

    // Indices.
    $Indices = array();
    
    for($j=0;$j<=$IndexCount;$j++)  // Read index.
      $Indices[$j] = fread( $_File,2);

    // ** UNKNOWN BEGIN **

    // Post-data.
    if($IncludePostData) {
      // Read section count.
      $CardData = fread($_File,4);

      for($j=0;$j<=$CardData;$j++)
        fseek($_File, ftell($_File) + 12);

      // Final section.
      $SectionSize = fread($_File,1);
      fseek($_File, ftell($_File ) + $SectionSize);

    }
    else
      $WordData = fread($_File,2);

    // ** UNKNOWN END **

    // Store mesh.
    $MeshList[] = array($MeshName, $VertexCount, $IndexCount, $Vertices, $Indices );
  }//END Foreach Mesh
  */
  return $MeshList;
  fclose($_File);
}


LoadFromFile("C:/test****b");
sleep(20000);
?>
The problem is, when reading data , ex. Commandline the result is a smiley like when viewing with notepad++, not a number. Somebody knows how to read them correctly? And a second issue might be that Blockread in Pascal doesnt moves the Filepointer, i dont know if it does, can somebody help me?
Posts 12 of 2 · Page 1 of 1

Post a Reply

Similar Threads

Tags for this Thread

None

Need help?