Index: /oup/current/FileClasses/TXAN.pas
===================================================================
--- /oup/current/FileClasses/TXAN.pas	(revision 235)
+++ /oup/current/FileClasses/TXAN.pas	(revision 236)
@@ -18,38 +18,27 @@
 
 procedure TFile_TXAN.InitDataFields;
-var
-  tempi: Integer;
-  arrargs: TArrayArgs;
 begin
   inherited;
-  FDataFields := TBlock.Create(Self, nil, 0, 'Base', '', nil);
+  FDataFields := TBlock.Create(Self, nil, 'Base', '', []);
   with FDataFields do
   begin
-    AddField(TFileID, $00, 'FileID', '', nil);
+    AddField(TFileID, 'FileID', '', []);
 
-    AddField(TLevelID, $04, 'LevelID', '', nil);
+    AddField(TLevelID, 'LevelID', '', []);
 
-    tempi := 12;
-    AddField(TUnused, $08, 'Unused data', '', @tempi);
+    AddField(TUnused, 'Unused data', '', [12]);
 
-    tempi := 2;
-    AddField(TInt, $14, 'Loop speed', '', @tempi);
+    AddField(TInt, 'Loop speed', '', [2]);
+    AddField(TInt, 'Unknown', '', [2]);
+    AddField(TInt, 'Unknown', '', [2]);
+    AddField(TUnused, 'Unused', '', [2]);
 
-    tempi := 2;
-    AddField(TInt, $16, 'Unknown', '', @tempi);
-
-    tempi := 2;
-    AddField(TInt, $18, 'Unknown', '', @tempi);
-
-    tempi := 2;
-    AddField(TUnused, $1A, 'Unused', '', @tempi);
-
-    arrargs.CounterSize := 2;
-    arrargs.BlockLength := 4;
-    with TArray(AddField(TArray, $1C, 'AnimTextures array', '', @arrargs)) do
+    with TArray(AddField(TArray, 'AnimTextures array', '', [4, 0])) do
     begin
-      AddField(TLinkByID, $00, 'Texture', '', nil);
+      AddField(TLinkByID, 'Texture', '', ['*']);
+      SetCount;
     end;
   end;
+  FDataFields.Update(0, -1);
   FFileStream.Free;
   FFileStream := nil;
Index: /oup/current/FileClasses/TXMP.pas
===================================================================
--- /oup/current/FileClasses/TXMP.pas	(revision 235)
+++ /oup/current/FileClasses/TXMP.pas	(revision 236)
@@ -22,87 +22,42 @@
 
 procedure TFile_TXMP.InitDataFields;
-var
-  tempi: Integer;
-  temps: String;
-  templist: TStringList;
 begin
   inherited;
-  FDataFields := TBlock.Create(Self, nil, 0, 'Base', '', nil);
-  templist := TStringList.Create;
+  FDataFields := TBlock.Create(Self, nil, 'Base', '', []);
   with FDataFields do
   begin
-    AddField(TFileID, $00, 'FileID', '', nil);
+    AddField(TFileID, 'FileID', '', []);
+    AddField(TLevelID, 'LevelID', '', []);
 
-    AddField(TLevelID, $04, 'LevelID', '', nil);
+    AddField(TString, 'FileName', '', [128]);
 
-    tempi := 128;
-    AddField(TString, $08, 'FileName', '', @tempi);
+    AddField(TBitSet, 'Flags1', '',
+        ['MipMapping enabled', 'unknown', 'U wrapping disabled',
+         'V wrapping disabled', 'EnvMapped/EnvMap', 'unused',
+         'Play anim back to back', 'Random anim order + frame time']);
 
-    templist.Add('MipMapping enabled');
-    templist.Add('unknown');
-    templist.Add('U wrapping disabled');
-    templist.Add('V wrapping disabled');
-    templist.Add('EnvMapped/EnvMap');
-    templist.Add('unused');
-    templist.Add('Play anim back to back');
-    templist.Add('Random anim order + frame time');
-    AddField(TBitSet, $88, 'Flags1', '', @templist);
+    AddField(TBitSet, 'Flags2', '',
+        ['Random anim time offset', 'High byte as EnvMap', 'High byte as alpha',
+         'Different alpha formula', 'Data swapping (always set)', 'used at runtime',
+         'TXAN looping on/off', '16 bit blue']);
 
-    templist.Clear;
-    templist.Add('Random anim time offset');
-    templist.Add('High byte as EnvMap');
-    templist.Add('High byte as alpha');
-    templist.Add('Different alpha formula');
-    templist.Add('Data swapping (always set)');
-    templist.Add('used at runtime');
-    templist.Add('TXAN looping on/off');
-    templist.Add('16 bit blue');
-    AddField(TBitSet, $89, 'Flags2', '', @templist);
+    AddField(TBitSet, 'Flags3', '',
+        ['16 bit alpha', '16 bit red', 'unknown', 'unknown',
+         'unknown', 'unknown', 'unknown', 'unknown']);
 
-    templist.Clear;
-    templist.Add('16 bit alpha');
-    templist.Add('16 bit red');
-    templist.Add('unknown');
-    templist.Add('unknown');
-    templist.Add('unknown');
-    templist.Add('unknown');
-    templist.Add('unknown');
-    templist.Add('unknown');
-    AddField(TBitSet, $8A, 'Flags3', '', @templist);
+    AddField(TBitSet, 'Flags4', '',
+        ['unknown', 'unknown', 'unknown', 'unknown',
+         'unknown', 'unknown', 'unknown', 'unknown']);
 
-    templist.Clear;
-    templist.Add('unknown');
-    templist.Add('unknown');
-    templist.Add('unknown');
-    templist.Add('unknown');
-    templist.Add('unknown');
-    templist.Add('unknown');
-    templist.Add('unknown');
-    templist.Add('unknown');
-    AddField(TBitSet, $8B, 'Flags4', '', @templist);
-
-    tempi := 2;
-    AddField(TInt, $8C, 'Width', '', @tempi);
-
-    tempi := 2;
-    AddField(TInt, $8E, 'Height', '', @tempi);
-
-    tempi := 4;
-    AddField(TInt, $90, 'StoreType', '', @tempi);
-
-    temps := '*';
-    AddField(TLinkByID, $94, 'TXAN', '', @temps);
-
-    temps := 'TXMP';
-    AddField(TLinkByID, $98, 'TXMP', '', @temps);
-
-    AddField(TRawLink, $9C, 'RawLink', '', nil);
-
-    AddField(TRawLink, $A0, 'SepLink', '', nil);
-
-    tempi := $1C;
-    AddField(TUnused, $A4, 'Unused', '', @tempi);
+    AddField(TInt, 'Width', '', [2]);
+    AddField(TInt, 'Height', '', [2]);
+    AddField(TInt, 'StoreType', '', [4]);
+    AddField(TLinkByID, 'TXAN', '', ['*']);
+    AddField(TLinkByID, 'TXMP', '', ['TXMP']);
+    AddField(TRawLink, 'RawLink', '', []);
+    AddField(TRawLink, 'SepLink', '', []);
+    AddField(TUnused, 'Unused', '', [$1C]);
   end;
-  templist.Free;
+  FDataFields.Update(0, -1);
   FFileStream.Free;
   FFileStream := nil;
Index: /oup/current/FileClasses/_DataTypes.pas
===================================================================
--- /oup/current/FileClasses/_DataTypes.pas	(revision 235)
+++ /oup/current/FileClasses/_DataTypes.pas	(revision 236)
@@ -7,4 +7,6 @@
 
 type
+  TContainer = class;
+  
   TDataField = class(TTreeElement)
       function GetChildCount: Integer; override;
@@ -17,10 +19,10 @@
       FDataLength: Integer;
       FParentFile: TObject;
-      FParentField: TDataField;
+      FParentBlock: TContainer;
       FChanged: Boolean;
-      function GetValueAsString: String; virtual; abstract;
-    public
-      constructor Create(ParentFile: TObject; ParentField: TDataField;
-          Offset: Integer; Name, Description: String; ExtraArgs: Pointer); virtual;
+      function GetValueAsString: String; virtual;
+    public
+      constructor Create(ParentFile: TObject; ParentBlock: TContainer;
+          Name, Description: String; ExtraArgs: array of const); virtual;
 
       procedure Update(Offset, Length: Integer); virtual; abstract;
@@ -35,21 +37,25 @@
   TFieldType = class of TDataField;
 
-
-  TBlock = class(TDataField)
+  TContainer = class(TDataField)
+    public
+      procedure UpdateSize; virtual; abstract;
+  end;
+
+  TBlock = class(TContainer)
     private
       FDataFields: array of TDataField;
-      FBlockLength: Integer;
       function GetChildCount: Integer; override;
       function GetChild(ID: Integer): TTreeElement; override;
       function GetFieldByOffset(Offset: Integer): TDataField;
     public
-      // ExtraArgs: Pointer auf Integer: BlockLength
-      constructor Create(ParentFile: TObject; ParentField: TDataField;
-          Offset: Integer; Name, Description: String; ExtraArgs: Pointer); override;
+      // ExtraArgs: Pointer auf Integer: BlockLength <- no longer
+      constructor Create(ParentFile: TObject; ParentBlock: TContainer;
+          Name, Description: String; ExtraArgs: array of const); override;
       procedure Update(Offset, Length: Integer); override;
       property FieldByOffset[Offset: Integer]: TDataField read GetFieldByOffset;
 
-      function AddField(fieldtype: TFieldType; Offset: Integer;
-          Name, Description: String; ExtraArgs: Pointer): TDataField;
+      function AddField(fieldtype: TFieldType; Name, Description: String;
+          ExtraArgs: array of const): TDataField;
+      procedure UpdateSize; override;
   end;
 
@@ -61,6 +67,6 @@
     public
       // ExtraArgs: Pointer auf Integer: Bytes of TInt
-      constructor Create(ParentFile: TObject; ParentField: TDataField;
-          Offset: Integer; Name, Description: String; ExtraArgs: Pointer); override;
+      constructor Create(ParentFile: TObject; ParentBlock: TContainer;
+          Name, Description: String; ExtraArgs: array of const); override;
       procedure Update(Offset, Length: Integer); override;
   end;
@@ -74,6 +80,6 @@
     public
       // ExtraArgs: Pointer auf TStringList
-      constructor Create(ParentFile: TObject; ParentField: TDataField;
-          Offset: Integer; Name, Description: String; ExtraArgs: Pointer); override;
+      constructor Create(ParentFile: TObject; ParentBlock: TContainer;
+          Name, Description: String; ExtraArgs: array of const); override;
       procedure Update(Offset, Length: Integer); override;
   end;
@@ -86,6 +92,6 @@
     public
       // ExtraArgs: keine
-      constructor Create(ParentFile: TObject; ParentField: TDataField;
-          Offset: Integer; Name, Description: String; ExtraArgs: Pointer); override;
+      constructor Create(ParentFile: TObject; ParentBlock: TContainer;
+          Name, Description: String; ExtraArgs: array of const); override;
       procedure Update(Offset, Length: Integer); override;
   end;
@@ -98,6 +104,6 @@
     public
       // ExtraArgs: keine
-      constructor Create(ParentFile: TObject; ParentField: TDataField;
-          Offset: Integer; Name, Description: String; ExtraArgs: Pointer); override;
+      constructor Create(ParentFile: TObject; ParentBlock: TContainer;
+          Name, Description: String; ExtraArgs: array of const); override;
       procedure Update(Offset, Length: Integer); override;
   end;
@@ -113,6 +119,6 @@
     public
       // ExtraArgs: Pointer auf String: Possible Exts
-      constructor Create(ParentFile: TObject; ParentField: TDataField;
-          Offset: Integer; Name, Description: String; ExtraArgs: Pointer); override;
+      constructor Create(ParentFile: TObject; ParentBlock: TContainer;
+          Name, Description: String; ExtraArgs: array of const); override;
       procedure Update(Offset, Length: Integer); override;
   end;
@@ -125,29 +131,30 @@
     public
       // ExtraArgs: Pointer auf Integer: Length
-      constructor Create(ParentFile: TObject; ParentField: TDataField;
-          Offset: Integer; Name, Description: String; ExtraArgs: Pointer); override;
-      procedure Update(Offset, Length: Integer); override;
-  end;
-
-
-  TArrayArgs = packed record
-    CounterSize: Integer;
-    BlockLength: Integer;
-    BlockCount:  Integer;
-  end;
-  TArray = class(TDataField)
+      constructor Create(ParentFile: TObject; ParentBlock: TContainer;
+          Name, Description: String; ExtraArgs: array of const); override;
+      procedure Update(Offset, Length: Integer); override;
+  end;
+
+
+  TArray = class(TContainer)
     private
       FDataFields: array of TBlock;
+      FTemplate: TBlock;
+      FCounterSize: Integer;
+      FBlockCount:  Integer;
       function GetChildCount: Integer; override;
       function GetChild(ID: Integer): TTreeElement; override;
       function GetFieldByOffset(Offset: Integer): TDataField;
     public
-      // ExtraArgs: Pointer auf 3 Integer: CounterSize+Length+Count (packed record...)
-      constructor Create(ParentFile: TObject; ParentField: TDataField;
-          Offset: Integer; Name, Description: String; ExtraArgs: Pointer); override;
-      procedure Update(Offset, Length: Integer); override;
-
-      function AddField(fieldtype: TFieldType; Offset: Integer;
-          Name, Description: String; ExtraArgs: Pointer): TDataField;
+      // ExtraArgs: Pointer auf 2 Integer: CounterSize+Count (packed record...)
+      constructor Create(ParentFile: TObject; ParentBlock: TContainer;
+          Name, Description: String; ExtraArgs: array of const); override;
+      procedure Update(Offset, Length: Integer); override;
+
+      function AddField(fieldtype: TFieldType; Name, Description: String;
+          ExtraArgs: array of const): TDataField;
+      procedure SetCount; overload;
+      procedure SetCount(n: Integer); overload;
+      procedure UpdateSize; override;
   end;
 
@@ -159,6 +166,6 @@
     public
       // ExtraArgs: keine
-      constructor Create(ParentFile: TObject; ParentField: TDataField;
-          Offset: Integer; Name, Description: String; ExtraArgs: Pointer); override;
+      constructor Create(ParentFile: TObject; ParentBlock: TContainer;
+          Name, Description: String; ExtraArgs: array of const); override;
       procedure Update(Offset, Length: Integer); override;
   end;
@@ -170,6 +177,6 @@
     public
       // ExtraArgs: Pointer auf Integer: Length
-      constructor Create(ParentFile: TObject; ParentField: TDataField;
-          Offset: Integer; Name, Description: String; ExtraArgs: Pointer); override;
+      constructor Create(ParentFile: TObject; ParentBlock: TContainer;
+          Name, Description: String; ExtraArgs: array of const); override;
       procedure Update(Offset, Length: Integer); override;
   end;
@@ -188,12 +195,15 @@
 { TDataType }
 
-constructor TDataField.Create(ParentFile: TObject; ParentField: TDataField;
-    Offset: Integer; Name, Description: String; ExtraArgs: Pointer);
-begin
-  FOffset := Offset;
+constructor TDataField.Create(ParentFile: TObject; ParentBlock: TContainer;
+    Name, Description: String; ExtraArgs: array of const);
+begin
+  if Assigned(ParentBlock) then
+    FOffset := ParentBlock.Offset + ParentBlock.DataLength
+  else
+    FOffset := 0;
   FName := Name;
   FDescription := Description;
   FParentFile := ParentFile;
-  FParentField := ParentField;
+  FParentBlock := ParentBlock;
   FConnectionID := TFile(ParentFile).ConnectionID;
 end;
@@ -214,18 +224,30 @@
 end;
 
-
+function TDataField.GetValueAsString: String;
+begin
+  Result := '';
+end;
 
 { TString }
 
-constructor TString.Create(ParentFile: TObject; ParentField: TDataField;
-    Offset: Integer; Name, Description: String; ExtraArgs: Pointer);
-var
-  fstream: TMemoryStream;
-  i: Integer;
-begin
-  inherited Create(ParentFile, ParentField, Offset, Name, Description, ExtraArgs);
-  FDataLength := Integer(ExtraArgs^);
-  fstream := TFile(ParentFile).FileStream;
-  fstream.Seek(Offset, soFromBeginning);
+constructor TString.Create(ParentFile: TObject; ParentBlock: TContainer;
+    Name, Description: String; ExtraArgs: array of const);
+begin
+  inherited Create(ParentFile, ParentBlock, Name, Description, ExtraArgs);
+  FDataLength := ExtraArgs[0].VInteger;
+end;
+
+function TString.GetValueAsString: String;
+begin
+  Result := FString;
+end;
+
+procedure TString.Update(Offset, Length: Integer);
+var
+  fstream: TMemoryStream;
+  i: Integer;
+begin
+  fstream := TFile(FParentFile).FileStream;
+  fstream.Seek(FOffset, soFromBeginning);
   SetLength(FString, FDataLength); 
   fstream.Read(FString[1], FDataLength);
@@ -238,114 +260,144 @@
 end;
 
-function TString.GetValueAsString: String;
-begin
-  Result := FString;
-end;
-
-procedure TString.Update(Offset, Length: Integer);
-begin
-  Exit;
-end;
-
 
 
 { TInt }
 
-constructor TInt.Create(ParentFile: TObject; ParentField: TDataField;
-    Offset: Integer; Name, Description: String; ExtraArgs: Pointer);
-var
-  fstream: TMemoryStream;
-begin
-  inherited Create(ParentFile, ParentField, Offset, Name, Description, ExtraArgs);
-  FDataLength := Integer(ExtraArgs^);
+constructor TInt.Create(ParentFile: TObject; ParentBlock: TContainer;
+    Name, Description: String; ExtraArgs: array of const);
+begin
+  inherited Create(ParentFile, ParentBlock, Name, Description, ExtraArgs);
+  FDataLength := ExtraArgs[0].VInteger;
   FInt := 0;
-  fstream := TFile(ParentFile).FileStream;
-  fstream.Seek(Offset, soFromBeginning);
+end;
+
+function TInt.GetValueAsString: String;
+begin
+  Result := IntToStr(FInt);
+end;
+
+procedure TInt.Update(Offset, Length: Integer);
+var
+  fstream: TMemoryStream;
+begin
+  fstream := TFile(FParentFile).FileStream;
+  fstream.Seek(FOffset, soFromBeginning);
   fstream.Read(FInt, FDataLength);
 end;
 
-function TInt.GetValueAsString: String;
-begin
-  Result := IntToStr(FInt);
-end;
-
-procedure TInt.Update(Offset, Length: Integer);
-begin
-  Exit;
-end;
-
 
 
 { TArray }
 
-function TArray.AddField(fieldtype: TFieldType; Offset: Integer;
-    Name, Description: String; ExtraArgs: Pointer): TDataField;
-var
-  i: Integer;
-begin
-(*
-  if Length(FDataFields) > 0 then
-  begin
-    for i := 0 to High(FDataFields) do
-      if FDataFields[i].FOffset = Offset then
-        Break;
-    if i < Length(FDataFields) then
-    begin
-      ShowMessage('Field already exists');
-      Exit;
-    end;
-  end;
-  SetLength(FDataFields, Length(FDataFields) + 1);
-  FDataFields[High(FDataFields)] := TFieldType(fieldtype).Create(
-      FParentFile, Self, Offset, Name, Description, ExtraArgs);
-  Result := FDataFields[High(FDataFields)];
-*)
-end;
-
-constructor TArray.Create(ParentFile: TObject; ParentField: TDataField;
-    Offset: Integer; Name, Description: String; ExtraArgs: Pointer);
-var
-  i: Integer;
-  args: TArrayArgs;
-  fstream: TMemoryStream;
-begin
-  inherited Create(ParentFile, ParentField, Offset, Name, Description, ExtraArgs);
-  args := TArrayArgs(ExtraArgs^);
-  if args.CounterSize > 0 then
+function TArray.AddField(fieldtype: TFieldType;
+    Name, Description: String; ExtraArgs: array of const): TDataField;
+var
+  i: Integer;
+begin
+  Result := FTemplate.AddField(fieldtype, Name, Description, ExtraArgs);
+end;
+
+constructor TArray.Create(ParentFile: TObject; ParentBlock: TContainer;
+    Name, Description: String; ExtraArgs: array of const);
+var
+  i: Integer;
+  fstream: TMemoryStream;
+begin
+  inherited Create(ParentFile, ParentBlock, Name, Description, ExtraArgs);
+  FCounterSize := ExtraArgs[0].VInteger;
+  FBlockCount  := ExtraArgs[1].VInteger;
+  if FCounterSize > 0 then
   begin
     fstream := TFile(ParentFile).FileStream;
     fstream.Seek(Offset, soFromBeginning);
-    args.BlockCount := 0;
-    fstream.Read(args.BlockCount, args.CounterSize);
-  end;
-  SetLength(FDataFields, args.BlockCount);
+    FBlockCount := 0;
+    fstream.Read(FBlockCount, FCounterSize);
+  end;
+  FTemplate := TBlock.Create(ParentFile, Self, '', '', []);
+end;
+
+function TArray.GetChildCount: Integer;
+begin
+  Result := Length(FDataFields);
+end;
+
+function TArray.GetChild(ID: Integer): TTreeElement;
+begin
+  Result := FDataFields[ID];
+end;
+
+function TArray.GetFieldByOffset(Offset: Integer): TDataField;
+begin
+  Exit;
+end;
+
+procedure TArray.SetCount;
+var
+  fid: Integer;
+  arr_index: Integer;
+  field: TDataField;
+begin
+  FDataLength := FCounterSize;
+  if FBlockCount > 0 then
+  begin
+    for arr_index := 0 to FBlockCount - 1 do
+    begin
+      SetLength(FDataFields, arr_index + 1);
+      FDataFields[arr_index] := TBlock.Create(FParentFile, Self,
+          FName + '[' + IntToStr(arr_index) + ']', '', []);
+      if Length(FTemplate.FDataFields) > 0 then
+      begin
+        for fid := 0 to High(FTemplate.FDataFields) do
+        begin
+          field := FTemplate.FDataFields[fid];
+          FDataFields[arr_index].AddField(TFieldType(field.ClassType), field.Name, field.Description, []);
+        end;
+      end;
+    end;
+  end;
+  FName := FName + '[' + IntToStr(FBlockCount) + ']';
+  FParentBlock.UpdateSize;
+end;
+
+procedure TArray.SetCount(n: Integer);
+begin
+  FParentBlock.UpdateSize;
+end;
+
+procedure TArray.Update(Offset, Length: Integer);
+var
+  i: Integer;
+  field: TDataField;
+begin
+  if System.Length(FDataFields) > 0 then
+  begin
+    if Length > 0 then
+    begin
+      for i := 0 to High(FDataFields) do
+      begin
+        field := FDataFields[i];
+        if ((field.Offset < Offset) and (field.Offset + field.DataLength > Offset + Length)) or
+          ((field.Offset > Offset) and (field.Offset < Offset + Length)) or
+          ((field.Offset + field.DataLength > Offset) and (field.Offset+field.DataLength < Offset + Length)) then
+          field.Update(Offset, Length);
+      end;
+    end else begin
+      for i := 0 to High(FDataFields) do
+      begin
+        FDataFields[i].Update(Offset, Length);
+      end;
+    end;
+  end;
+end;
+
+procedure TArray.UpdateSize;
+var
+  i: Integer;
+begin
+  FDataLength := FCounterSize;
   if Length(FDataFields) > 0 then
-  begin
     for i := 0 to High(FDataFields) do
-    begin
-      FDataFields[i] := TBlock.Create(ParentFile, Self,
-          Offset + args.CounterSize + i * args.BlockLength, Name+'['+IntToStr(i)+']', '', @args.BlockLength);
-    end;
-  end;
-end;
-
-function TArray.GetChildCount: Integer;
-begin
-  Result := Length(FDataFields);
-end;
-
-function TArray.GetChild(ID: Integer): TTreeElement;
-begin
-  Result := FDataFields[ID];
-end;
-
-function TArray.GetFieldByOffset(Offset: Integer): TDataField;
-begin
-  Exit;
-end;
-
-procedure TArray.Update(Offset, Length: Integer);
-begin
-  Exit;
+      FDataLength := FDataLength + FDataFields[i].DataLength;
+  FParentBlock.UpdateSize;
 end;
 
@@ -354,34 +406,20 @@
 { TBlock }
 
-function TBlock.AddField(fieldtype: TFieldType; Offset: Integer; Name,
-    Description: String; ExtraArgs: Pointer): TDataField;
-var
-  i: Integer;
-begin
-  if Length(FDataFields) > 0 then
-  begin
-    for i := 0 to High(FDataFields) do
-      if FDataFields[i].FOffset = Offset then
-        Break;
-    if i < Length(FDataFields) then
-    begin
-      ShowMessage('Field already exists');
-      Exit;
-    end;
-  end;
+function TBlock.AddField(fieldtype: TFieldType; Name,
+    Description: String; ExtraArgs: array of const): TDataField;
+begin
   SetLength(FDataFields, Length(FDataFields) + 1);
   FDataFields[High(FDataFields)] := TFieldType(fieldtype).Create(
-      FParentFile, Self, Offset, Name, Description, ExtraArgs);
+      FParentFile, Self, Name, Description, ExtraArgs);
   Result := FDataFields[High(FDataFields)];
-end;
-
-constructor TBlock.Create(ParentFile: TObject; ParentField: TDataField;
-    Offset: Integer; Name, Description: String; ExtraArgs: Pointer);
-begin
-  inherited Create(ParentFile, ParentField, Offset, Name, Description, ExtraArgs);
-  if ExtraArgs <> nil then
-    FBlockLength := Integer(ExtraArgs^)
-  else
-    FBlockLength := -1;
+  FDataLength := FDataLength + Result.DataLength;
+  if Assigned(FParentBlock) then
+    FParentBlock.UpdateSize;
+end;
+
+constructor TBlock.Create(ParentFile: TObject; ParentBlock: TContainer;
+    Name, Description: String; ExtraArgs: array of const);
+begin
+  inherited Create(ParentFile, ParentBlock, Name, Description, ExtraArgs);
 end;
 
@@ -402,6 +440,39 @@
 
 procedure TBlock.Update(Offset, Length: Integer);
-begin
-  Exit;
+var
+  i: Integer;
+  field: TDataField;
+begin
+  if System.Length(FDataFields) > 0 then
+  begin
+    if Length > 0 then
+    begin
+      for i := 0 to High(FDataFields) do
+      begin
+        field := FDataFields[i];
+        if ((field.Offset < Offset) and (field.Offset + field.DataLength > Offset + Length)) or
+          ((field.Offset > Offset) and (field.Offset < Offset + Length)) or
+          ((field.Offset + field.DataLength > Offset) and (field.Offset+field.DataLength < Offset + Length)) then
+          field.Update(Offset, Length);
+      end;
+    end else begin
+      for i := 0 to High(FDataFields) do
+      begin
+        FDataFields[i].Update(Offset, Length);
+      end;
+    end;
+  end;
+end;
+
+procedure TBlock.UpdateSize;
+var
+  i: Integer;
+begin
+  FDataLength := 0;
+  if Length(FDataFields) > 0 then
+    for i := 0 to High(FDataFields) do
+      FDataLength := FDataLength + FDataFields[i].FDataLength;
+  if Assigned(FParentBlock) then
+    FParentBlock.UpdateSize;
 end;
 
@@ -410,40 +481,50 @@
 { TLevelID }
 
-constructor TLevelID.Create(ParentFile: TObject; ParentField: TDataField;
-    Offset: Integer; Name, Description: String; ExtraArgs: Pointer);
-var
-  fstream: TMemoryStream;
-begin
-  inherited Create(ParentFile, ParentField, Offset, Name, Description, ExtraArgs);
+constructor TLevelID.Create(ParentFile: TObject; ParentBlock: TContainer;
+    Name, Description: String; ExtraArgs: array of const);
+begin
+  inherited Create(ParentFile, ParentBlock, Name, Description, ExtraArgs);
   FDataLength := 4;
-  fstream := TFile(ParentFile).FileStream;
-  fstream.Seek(Offset, soFromBeginning);
+  FLevelID := 0;
+end;
+
+function TLevelID.GetValueAsString: String;
+begin
+  Result := IntToStr(FLevelID);
+end;
+
+procedure TLevelID.Update(Offset, Length: Integer);
+var
+  fstream: TMemoryStream;
+begin
+  fstream := TFile(FParentFile).FileStream;
+  fstream.Seek(FOffset, soFromBeginning);
   fstream.Read(FLevelID, 4);
   FLevelID := FLevelID div 256 div 256 div 256 div 2;
 end;
 
-function TLevelID.GetValueAsString: String;
-begin
-  Result := IntToStr(FLevelID);
-end;
-
-procedure TLevelID.Update(Offset, Length: Integer);
-begin
-  Exit;
-end;
-
 
 
 { TFileID }
 
-constructor TFileID.Create(ParentFile: TObject; ParentField: TDataField;
-    Offset: Integer; Name, Description: String; ExtraArgs: Pointer);
-var
-  fstream: TMemoryStream;
-begin
-  inherited Create(ParentFile, ParentField, Offset, Name, Description, ExtraArgs);
+constructor TFileID.Create(ParentFile: TObject; ParentBlock: TContainer;
+    Name, Description: String; ExtraArgs: array of const);
+begin
+  inherited Create(ParentFile, ParentBlock, Name, Description, ExtraArgs);
   FDataLength := 4;
-  fstream := TFile(ParentFile).FileStream;
-  fstream.Seek(Offset, soFromBeginning);
+  FFileID := -1;
+end;
+
+function TFileID.GetValueAsString: String;
+begin
+  Result := IntToStr(FFileID);
+end;
+
+procedure TFileID.Update(Offset, Length: Integer);
+var
+  fstream: TMemoryStream;
+begin
+  fstream := TFile(FParentFile).FileStream;
+  fstream.Seek(FOffset, soFromBeginning);
   fstream.Read(FFileID, 4);
   if FFileID > 0 then
@@ -453,28 +534,50 @@
 end;
 
-function TFileID.GetValueAsString: String;
-begin
-  Result := IntToStr(FFileID);
-end;
-
-procedure TFileID.Update(Offset, Length: Integer);
-begin
-  Exit;
-end;
-
 
 
 { TLinkByID }
 
-constructor TLinkByID.Create(ParentFile: TObject; ParentField: TDataField;
-    Offset: Integer; Name, Description: String; ExtraArgs: Pointer);
-var
-  fstream: TMemoryStream;
-begin
-  inherited Create(ParentFile, ParentField, Offset, Name, Description, ExtraArgs);
+constructor TLinkByID.Create(ParentFile: TObject; ParentBlock: TContainer;
+    Name, Description: String; ExtraArgs: array of const);
+begin
+  inherited Create(ParentFile, ParentBlock, Name, Description, ExtraArgs);
   FDataLength := 4;
-  FPosExts := String(ExtraArgs^);
-  fstream := TFile(ParentFile).FileStream;
-  fstream.Seek(Offset, soFromBeginning);
+  case ExtraArgs[0].VType of
+    vtChar: FPosExts := ExtraArgs[0].VChar;
+    vtAnsiString: FPosExts := String(ExtraArgs[0].VAnsiString);
+  end;
+  FFileID := -1;
+end;
+
+function TLinkByID.GetChild(ID: Integer): TTreeElement;
+begin
+  if FFileID > 0 then
+    Result := ConManager.Connection[FConnectionID].MetaData.FileById[FFileID].Child[ID]
+  else
+    Result := nil;
+end;
+
+function TLinkByID.GetChildCount: Integer;
+begin
+  if FFileID > 0 then
+    Result := ConManager.Connection[FConnectionID].MetaData.FileById[FFileID].ChildCount
+  else
+    Result := 0;
+end;
+
+function TLinkByID.GetValueAsString: String;
+begin
+  if FFileID >= 0 then
+    Result := IntToStr(FFileID)
+  else
+    Result := 'unused';
+end;
+
+procedure TLinkByID.Update(Offset, Length: Integer);
+var
+  fstream: TMemoryStream;
+begin
+  fstream := TFile(FParentFile).FileStream;
+  fstream.Seek(FOffset, soFromBeginning);
   fstream.Read(FFileID, 4);
   if FFileID > 0 then
@@ -484,26 +587,49 @@
 end;
 
-function TLinkByID.GetChild(ID: Integer): TTreeElement;
-begin
-  if FFileID > 0 then
-    Result := ConManager.Connection[FConnectionID].MetaData.FileById[FFileID].Child[ID]
+
+
+{ TRawLink }
+
+constructor TRawLink.Create(ParentFile: TObject; ParentBlock: TContainer;
+    Name, Description: String; ExtraArgs: array of const);
+begin
+  inherited Create(ParentFile, ParentBlock, Name, Description, ExtraArgs);
+  FDataLength := 4;
+end;
+
+function TRawLink.GetValueAsString: String;
+begin
+  if FRawAddress > 0 then
+    Result := '0x' + IntToHex(FRawAddress, 8)
   else
-    Result := nil;
-end;
-
-function TLinkByID.GetChildCount: Integer;
-begin
-  if FFileID > 0 then
-    Result := ConManager.Connection[FConnectionID].MetaData.FileById[FFileID].ChildCount
-  else
-    Result := 0;
-end;
-
-function TLinkByID.GetValueAsString: String;
-begin
-  Result := IntToStr(FFileID);
-end;
-
-procedure TLinkByID.Update(Offset, Length: Integer);
+    Result := 'unused';
+end;
+
+procedure TRawLink.Update(Offset, Length: Integer);
+var
+  fstream: TMemoryStream;
+begin
+  fstream := TFile(FParentFile).FileStream;
+  fstream.Seek(FOffset, soFromBeginning);
+  fstream.Read(FRawAddress, 4);
+end;
+
+
+
+{ TUnused }
+
+constructor TUnused.Create(ParentFile: TObject; ParentBlock: TContainer;
+    Name, Description: String; ExtraArgs: array of const);
+begin
+  inherited Create(ParentFile, ParentBlock, Name, Description, ExtraArgs);
+  FDataLength := ExtraArgs[0].VInteger;
+end;
+
+function TUnused.GetValueAsString: String;
+begin
+  Result := '';
+end;
+
+procedure TUnused.Update(Offset, Length: Integer);
 begin
   Exit;
@@ -512,77 +638,45 @@
 
 
-{ TRawLink }
-
-constructor TRawLink.Create(ParentFile: TObject; ParentField: TDataField;
-    Offset: Integer; Name, Description: String; ExtraArgs: Pointer);
-var
-  fstream: TMemoryStream;
-begin
-  inherited Create(ParentFile, ParentField, Offset, Name, Description, ExtraArgs);
-  FDataLength := 4;
-  fstream := TFile(ParentFile).FileStream;
-  fstream.Seek(Offset, soFromBeginning);
-  fstream.Read(FRawAddress, 4);
-end;
-
-function TRawLink.GetValueAsString: String;
-begin
-  Result := IntToStr(FRawAddress);
-end;
-
-procedure TRawLink.Update(Offset, Length: Integer);
-begin
-  Exit;
-end;
-
-
-
-{ TUnused }
-
-constructor TUnused.Create(ParentFile: TObject; ParentField: TDataField;
-    Offset: Integer; Name, Description: String; ExtraArgs: Pointer);
-begin
-  inherited Create(ParentFile, ParentField, Offset, Name, Description, ExtraArgs);
-  FDataLength := Integer(ExtraArgs^);
-end;
-
-function TUnused.GetValueAsString: String;
-begin
-  Result := '';
-end;
-
-procedure TUnused.Update(Offset, Length: Integer);
-begin
-  Exit;
-end;
-
-
-
 { TBitSet }
 
-constructor TBitSet.Create(ParentFile: TObject; ParentField: TDataField;
-    Offset: Integer; Name, Description: String; ExtraArgs: Pointer);
-var
-  fstream: TMemoryStream;
-begin
-  inherited Create(ParentFile, ParentField, Offset, Name, Description, ExtraArgs);
+constructor TBitSet.Create(ParentFile: TObject; ParentBlock: TContainer;
+    Name, Description: String; ExtraArgs: array of const);
+var
+  i: Integer;
+begin
+  inherited Create(ParentFile, ParentBlock, Name, Description, ExtraArgs);
   FNames := TStringList.Create;
-  FNames.AddStrings(TStringList(ExtraArgs^));
+  for i := 0 to High(ExtraArgs) do
+    case ExtraArgs[i].VType of
+      vtChar: FNames.Add(ExtraArgs[0].VChar);
+      vtAnsiString: FNames.Add(String(ExtraArgs[0].VAnsiString));
+    end;
   FDataLength := 1;
   FBits := 0;
-  fstream := TFile(ParentFile).FileStream;
-  fstream.Seek(Offset, soFromBeginning);
+end;
+
+function TBitSet.GetValueAsString: String;
+  function IntToBits(Int: Integer): String;
+  var
+    i: Integer;
+  begin
+    Result := '';
+    for i := 0 to 7 do
+    begin
+      Result := IntToStr(FBits and (1 shl i) shr i) + Result;
+    end;
+  end;
+begin
+  Result := IntToBits(FBits);
+end;
+
+procedure TBitSet.Update(Offset, Length: Integer);
+var
+  fstream: TMemoryStream;
+begin
+  fstream := TFile(FParentFile).FileStream;
+  fstream.Seek(FOffset, soFromBeginning);
   fstream.Read(FBits, FDataLength);
 end;
 
-function TBitSet.GetValueAsString: String;
-begin
-  Result := IntToStr(FBits);
-end;
-
-procedure TBitSet.Update(Offset, Length: Integer);
-begin
-  Exit;
-end;
-
 end.
Index: /oup/current/FileClasses/_EmptyFile.pas
===================================================================
--- /oup/current/FileClasses/_EmptyFile.pas	(revision 235)
+++ /oup/current/FileClasses/_EmptyFile.pas	(revision 236)
@@ -20,5 +20,5 @@
 begin
   inherited;
-  FDataFields := TBlock.Create(Self, nil, 0, 'Base', '', nil);
+  FDataFields := TBlock.Create(Self, nil, 'Base', '', []);
 end;
 
Index: /oup/current/FileClasses/_MetaTypes.pas
===================================================================
--- /oup/current/FileClasses/_MetaTypes.pas	(revision 235)
+++ /oup/current/FileClasses/_MetaTypes.pas	(revision 236)
@@ -5,13 +5,14 @@
 uses
   _FileTypes, _EmptyFile, _Unlinked, _DataTypes, _Extensions, _TreeElement,
-  ABNA, AGDB, AGQC, AGQG, AGQM, AGQR, AISA, AITR, AIWA, AKAA, AKBA, AKBP, AKDA,
-  AKEV, AKOT, AKVA, BINA, CBPI, CBPM, CONS, CRSA, DOOR, DPge, EDIA, ENVP, FILM,
-  FXLR, GMAN, HPge, IDXA, IGHH, IGPA, IGPG, IGSA, IGSt, Impt, IPge, KeyI, M3GA,
-  M3GM, M3TA, Mtrl, NMSA, OBAN, OBDC, OBLS, OBOA, OFGA, ONCC, ONCP, ONCV, ONFA,
-  ONGS, ONIA, ONLD, ONLV, ONMA, ONOA, ONSA, ONSK, ONTA, ONVL, ONWC, OPge, OSBD,
-  OTIT, OTLF, PLEA, PNTA, PSpc, PSpL, PSUI, QTNA, QUDA, SNDD, StNA, SUBT, TMFA,
-  TMRA, TRAC, TRAM, TRAS, TRBS, TRCM, TRFT, TRGA, TRGE, TRIA, TRIG, TRMA, TRSC,
-  TRTA, TSFF, TSFL, TSFT, TSGA, TStr, TURR, TXAN, TXCA, TXMA, TXMB, TXMP, TXPC,
-  TxtC, UUEA, UVDL, VCRA, WMCL, WMDD, WMM_, WMMB, WPge;
+  TXAN, TXMP;
+//  ABNA, AGDB, AGQC, AGQG, AGQM, AGQR, AISA, AITR, AIWA, AKAA, AKBA, AKBP, AKDA,
+//  AKEV, AKOT, AKVA, BINA, CBPI, CBPM, CONS, CRSA, DOOR, DPge, EDIA, ENVP, FILM,
+//  FXLR, GMAN, HPge, IDXA, IGHH, IGPA, IGPG, IGSA, IGSt, Impt, IPge, KeyI, M3GA,
+//  M3GM, M3TA, Mtrl, NMSA, OBAN, OBDC, OBLS, OBOA, OFGA, ONCC, ONCP, ONCV, ONFA,
+//  ONGS, ONIA, ONLD, ONLV, ONMA, ONOA, ONSA, ONSK, ONTA, ONVL, ONWC, OPge, OSBD,
+//  OTIT, OTLF, PLEA, PNTA, PSpc, PSpL, PSUI, QTNA, QUDA, SNDD, StNA, SUBT, TMFA,
+//  TMRA, TRAC, TRAM, TRAS, TRBS, TRCM, TRFT, TRGA, TRGE, TRIA, TRIG, TRMA, TRSC,
+//  TRTA, TSFF, TSFL, TSFT, TSGA, TStr, TURR, TXAN, TXCA, TXMA, TXMB, TXMP, TXPC,
+//  TxtC, UUEA, UVDL, VCRA, WMCL, WMDD, WMM_, WMMB, WPge;
 
 type
@@ -22,4 +23,5 @@
   TExtension = _Extensions.TExtension;
   TExtensions = _Extensions.TExtensions;
+  TDataField = _DataTypes.TDataField;
 
   TFileClass = class of TFile;
@@ -30,4 +32,10 @@
 
 const
+  FileDescs: array[0..1] of TFileDesc = (
+    (ext: 'TXAN'; ftype: TFile_TXAN),
+    (ext: 'TXMP'; ftype: TFile_TXMP)
+  );
+
+{
   FileDescs: array[0..112] of TFileDesc = (
     (ext: 'ABNA'; ftype: TFile_ABNA),
@@ -145,5 +153,5 @@
     (ext: 'WPge'; ftype: TFile_WPge)
   );
-
+}
 
 implementation
Index: /oup/current/OniUnPacker.bdsproj
===================================================================
--- /oup/current/OniUnPacker.bdsproj	(revision 235)
+++ /oup/current/OniUnPacker.bdsproj	(revision 236)
@@ -176,5 +176,6 @@
 			<Language Name="ProjectLang">$00000000</Language>
 			<Language Name="RootDir"></Language>
-		</Language>  <Excluded_Packages>
+		</Language>  
+    <Excluded_Packages>
       <Excluded_Packages Name="d:\programme\borland\bds\3.0\Bin\dbwebxprt.bpl">Borland Web Wizard Package</Excluded_Packages>
     </Excluded_Packages>
Index: /oup/current/OniUnPacker.dpr
===================================================================
--- /oup/current/OniUnPacker.dpr	(revision 235)
+++ /oup/current/OniUnPacker.dpr	(revision 236)
@@ -26,8 +26,9 @@
   LevelDB in 'Helper\LevelDB.pas' {Form_LevelDB},
   Img_DDSTypes in 'Global\Img_DDSTypes.pas',
-  TXMP in 'FileClasses\TXMP.pas',
   _MetaManager in 'FileClasses\_MetaManager.pas',
   _EmptyFile in 'FileClasses\_EmptyFile.pas',
+  TXMP in 'FileClasses\TXMP.pas',
   TXAN in 'FileClasses\TXAN.pas',
+{
   SUBT in 'FileClasses\SUBT.pas',
   ABNA in 'FileClasses\ABNA.pas',
@@ -141,4 +142,5 @@
   WMMB in 'FileClasses\WMMB.pas',
   WPge in 'FileClasses\WPge.pas',
+}
   _BaseTemplate in 'Tools\_BaseTemplate.pas' {Form_BaseTemplate},
   _TemplateFile in 'Tools\_TemplateFile.pas' {Form_TemplateFile},
Index: /oup/current/Tools/MetaEditor.pas
===================================================================
--- /oup/current/Tools/MetaEditor.pas	(revision 235)
+++ /oup/current/Tools/MetaEditor.pas	(revision 236)
@@ -205,4 +205,9 @@
             CellText := IntToStr(TFile(Data.Field).FileInfo.ID);
         end;
+      3:
+        begin
+          if Data.Field is TDataField then
+            CellText := TDataField(Data.Field).ValueAsString;
+        end;
     end;
   end;
