Index: oup/rewrite/Tools/BinEdit.dfm
===================================================================
--- oup/rewrite/Tools/BinEdit.dfm	(revision 104)
+++ oup/rewrite/Tools/BinEdit.dfm	(revision 104)
@@ -0,0 +1,227 @@
+inherited Form_BinEdit: TForm_BinEdit
+  Caption = 'BinEdit'
+  KeyPreview = True
+  OnCloseQuery = FormCloseQuery
+  OnKeyUp = FormKeyUp
+  ExplicitWidth = 500
+  ExplicitHeight = 450
+  PixelsPerInch = 96
+  TextHeight = 13
+  inherited content: TPanel
+    object Splitter2: TSplitter
+      Left = 0
+      Top = 209
+      Width = 283
+      Height = 9
+      Cursor = crVSplit
+      Align = alTop
+      AutoSnap = False
+      Beveled = True
+      MinSize = 40
+      ExplicitWidth = 425
+    end
+    object Splitter3: TSplitter
+      Left = 0
+      Top = 318
+      Width = 283
+      Height = 8
+      Cursor = crVSplit
+      Align = alBottom
+      AutoSnap = False
+      Beveled = True
+      MinSize = 40
+      ExplicitLeft = -9
+      ExplicitTop = 430
+      ExplicitWidth = 425
+    end
+    object hex: TMPHexEditor
+      Left = 0
+      Top = 0
+      Width = 283
+      Height = 209
+      Cursor = crIBeam
+      Align = alTop
+      Font.Charset = DEFAULT_CHARSET
+      Font.Color = clWindowText
+      Font.Height = -16
+      Font.Name = 'Courier'
+      Font.Style = []
+      OnKeyUp = hexKeyUp
+      ParentFont = False
+      TabOrder = 0
+      BytesPerRow = 16
+      Translation = tkASCII
+      OffsetFormat = '6!10:0x|'
+      Colors.Background = clWindow
+      Colors.ChangedBackground = clWindow
+      Colors.ChangedText = clRed
+      Colors.CursorFrame = clNavy
+      Colors.Offset = clBlack
+      Colors.OddColumn = clBlue
+      Colors.EvenColumn = clNavy
+      Colors.CurrentOffsetBackground = clBtnShadow
+      Colors.OffsetBackGround = clBtnFace
+      Colors.CurrentOffset = clBtnHighlight
+      Colors.Grid = clBtnFace
+      Colors.NonFocusCursorFrame = clAqua
+      Colors.ActiveFieldBackground = clWindow
+      FocusFrame = True
+      NoSizeChange = True
+      AllowInsertMode = False
+      DrawGridLines = False
+      Version = 'May 23, 2005; '#169' markus stephany, vcl[at]mirkes[dot]de'
+      OnChange = hexChange
+      ShowPositionIfNotFocused = True
+      OnSelectionChanged = hexSelectionChanged
+    end
+    object value_viewer: TWrapGrid
+      Left = 0
+      Top = 218
+      Width = 283
+      Height = 100
+      Align = alClient
+      ColCount = 1
+      DefaultColWidth = 80
+      DefaultRowHeight = 18
+      FixedCols = 0
+      RowCount = 8
+      FixedRows = 0
+      Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goColSizing]
+      PopupMenu = value_viewer_context
+      ScrollBars = ssVertical
+      TabOrder = 1
+      OnDblClick = value_viewerDblClick
+      OnMouseDown = value_viewerMouseDown
+    end
+    object VST: TVirtualStringTree
+      Left = 0
+      Top = 326
+      Width = 283
+      Height = 97
+      Align = alBottom
+      AnimationDuration = 0
+      AutoExpandDelay = 300
+      BiDiMode = bdLeftToRight
+      Colors.UnfocusedSelectionColor = clGradientActiveCaption
+      Colors.UnfocusedSelectionBorderColor = clGradientActiveCaption
+      Ctl3D = True
+      DragOperations = []
+      DrawSelectionMode = smBlendedRectangle
+      EditDelay = 200
+      Font.Charset = DEFAULT_CHARSET
+      Font.Color = clWindowText
+      Font.Height = -11
+      Font.Name = 'Tahoma'
+      Font.Style = []
+      Header.AutoSizeIndex = 0
+      Header.Font.Charset = DEFAULT_CHARSET
+      Header.Font.Color = clWindowText
+      Header.Font.Height = -11
+      Header.Font.Name = 'Tahoma'
+      Header.Font.Style = []
+      Header.Options = [hoColumnResize, hoDblClickResize, hoDrag, hoVisible]
+      Header.PopupMenu = VTHPopup
+      Header.Style = hsFlatButtons
+      HintAnimation = hatNone
+      HintMode = hmTooltip
+      Indent = 14
+      ParentBiDiMode = False
+      ParentCtl3D = False
+      ParentFont = False
+      ParentShowHint = False
+      ShowHint = True
+      TabOrder = 2
+      TreeOptions.MiscOptions = [toAcceptOLEDrop, toCheckSupport, toFullRepaintOnResize, toInitOnSave, toToggleOnDblClick, toWheelPanning]
+      TreeOptions.PaintOptions = [toShowButtons, toShowDropmark, toShowHorzGridLines, toShowRoot, toShowTreeLines, toShowVertGridLines, toUseBlendedImages]
+      TreeOptions.SelectionOptions = [toExtendedFocus, toFullRowSelect, toRightClickSelect]
+      OnDblClick = VSTDblClick
+      OnFocusChanged = VSTFocusChanged
+      OnGetText = VSTGetText
+      OnHeaderDragged = VSTHeaderDragged
+      Columns = <
+        item
+          MaxWidth = 300
+          MinWidth = 100
+          Options = [coEnabled, coParentBidiMode, coParentColor, coResizable, coShowDropMark, coVisible]
+          Position = 0
+          Spacing = 20
+          Width = 150
+          WideText = 'Name'
+          WideHint = 'Name of the item.'
+        end
+        item
+          MaxWidth = 110
+          MinWidth = 80
+          Options = [coDraggable, coEnabled, coParentBidiMode, coParentColor, coResizable, coShowDropMark, coVisible]
+          Position = 1
+          Spacing = 20
+          Width = 85
+          WideText = 'Offset'
+          WideHint = 'Offset of the data-item.'
+        end
+        item
+          MaxWidth = 110
+          MinWidth = 75
+          Options = [coDraggable, coEnabled, coParentBidiMode, coParentColor, coResizable, coShowDropMark, coVisible]
+          Position = 2
+          Width = 75
+          WideText = 'Type'
+          WideHint = 'Data type of the item.'
+        end
+        item
+          MaxWidth = 250
+          MinWidth = 80
+          Options = [coDraggable, coEnabled, coParentBidiMode, coParentColor, coResizable, coShowDropMark, coVisible]
+          Position = 3
+          Width = 100
+          WideText = 'Value'
+          WideHint = 'Value of the item.'
+        end
+        item
+          MaxWidth = 400
+          MinWidth = 80
+          Options = [coDraggable, coEnabled, coParentBidiMode, coParentColor, coResizable, coShowDropMark, coVisible]
+          Position = 4
+          Width = 400
+          WideText = 'Description'
+        end>
+      WideDefaultText = ''
+    end
+  end
+  object value_viewer_context: TPopupMenu [3]
+    AutoHotkeys = maManual
+    AutoLineReduction = maManual
+    OnPopup = value_viewer_contextPopup
+    Left = 280
+    Top = 232
+    object value_viewer_context_copy: TMenuItem
+      Caption = 'Copy to &clipboard'
+      OnClick = value_viewer_context_copyClick
+    end
+    object value_viewer_context_copyasdec: TMenuItem
+      Caption = 'Copy to clipboard (as &dec)'
+      OnClick = value_viewer_context_copyClick
+    end
+    object value_viewer_context_copyasfloat: TMenuItem
+      Caption = 'Copy to clipboard (as &float)'
+      OnClick = value_viewer_context_copyClick
+    end
+    object value_viewer_context_copyasbitset: TMenuItem
+      Caption = 'Copy to clipboard (as &bitset)'
+      OnClick = value_viewer_context_copyClick
+    end
+    object value_viewer_context_copyasstring: TMenuItem
+      Caption = 'Copy to clipboard (as &string)'
+      OnClick = value_viewer_context_copyClick
+    end
+    object value_viewer_context_copyashex: TMenuItem
+      Caption = 'Copy to clipboard (as &hex)'
+      OnClick = value_viewer_context_copyClick
+    end
+  end
+  object VTHPopup: TVTHeaderPopupMenu [4]
+    OnColumnChange = VTHPopupColumnChange
+    Left = 272
+    Top = 376
+  end
+end
Index: oup/rewrite/Tools/BinEdit.pas
===================================================================
--- oup/rewrite/Tools/BinEdit.pas	(revision 104)
+++ oup/rewrite/Tools/BinEdit.pas	(revision 104)
@@ -0,0 +1,985 @@
+unit BinEdit;
+interface
+uses
+  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
+  Dialogs, Template, StdCtrls, ExtCtrls, VirtualTrees, Grids, Wrapgrid,
+  MPHexEditor, VTHeaderPopup, Menus, StrUtils, Clipbrd,
+  Data, TypeDefs, ConnectionManager, Buttons;
+
+type
+  TForm_BinEdit = class(TForm_ToolTemplate)
+    hex: TMPHexEditor;
+    Splitter2: TSplitter;
+    value_viewer: TWrapGrid;
+    VST: TVirtualStringTree;
+    Splitter3: TSplitter;
+    value_viewer_context: TPopupMenu;
+    value_viewer_context_copy: TMenuItem;
+    value_viewer_context_copyasdec: TMenuItem;
+    value_viewer_context_copyasfloat: TMenuItem;
+    value_viewer_context_copyasbitset: TMenuItem;
+    value_viewer_context_copyasstring: TMenuItem;
+    value_viewer_context_copyashex: TMenuItem;
+    VTHPopup: TVTHeaderPopupMenu;
+    procedure FormCreate(Sender: TObject);
+    procedure NewFile(fileinfo: TFileInfo);
+
+    procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
+    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
+
+    procedure hexKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
+    procedure hexSelectionChanged(Sender: TObject);
+    procedure hexChange(Sender: TObject);
+
+    procedure LoadDat(_fileid: Integer);
+    function Save: Boolean;
+    function GetValue(datatype: Word; offset: LongWord): String;
+    procedure SetNewValue(datatype: Word; offset: LongWord; Value: String);
+
+    procedure WriteStructureInfos;
+    procedure ClearStructViewer;
+    procedure VSTDblClick(Sender: TObject);
+    procedure VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode;
+      Column: TColumnIndex);
+    procedure VTHPopupColumnChange(const Sender: TBaseVirtualTree;
+      const Column: TColumnIndex; Visible: Boolean);
+    procedure VSTHeaderDragged(Sender: TVTHeader; Column: TColumnIndex;
+      OldPosition: Integer);
+    procedure VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
+      Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
+
+    procedure ClearValues;
+    procedure WriteValues;
+    procedure value_viewerDblClick(Sender: TObject);
+    procedure value_viewer_context_copyClick(Sender: TObject);
+    procedure value_viewerMouseDown(Sender: TObject; Button: TMouseButton;
+      Shift: TShiftState; X, Y: Integer);
+    procedure value_viewer_contextPopup(Sender: TObject);
+  private
+    fileid: Integer;
+    ConID: Integer;
+  public
+  end;
+
+var
+  Form_BinEdit: TForm_BinEdit;
+
+implementation
+
+uses ValueEdit, Main, Functions, DatStructureLoader{, RawEdit};
+{$R *.dfm}
+
+type
+  PNodeData = ^TNodeData;
+
+  TNodeData = record
+    Caption:  String;
+    Offset:   LongInt;
+    DataType: Word;
+    Value:    String;
+    Description: String;
+  end;
+
+
+
+procedure TForm_BinEdit.FormCreate(Sender: TObject);
+begin
+  inherited;
+  Self.OnNewFileSelected := NewFile;
+
+  Self.Caption := '';
+  fileid     := 0;
+  VST.NodeDataSize := SizeOf(TNodeData);
+  value_viewer.ColCount := 2;
+  value_viewer.RowCount := 8;
+  value_viewer.FixedRows := 1;
+  value_viewer.FixedCols := 1;
+  value_viewer.Cells[0, 0] := 'Type';
+  value_viewer.Cells[1, 0] := 'Value';
+  value_viewer.Cells[0, 1] := '1 byte, unsigned';
+  value_viewer.Cells[0, 2] := '2 bytes, unsigned';
+  value_viewer.Cells[0, 3] := '4 bytes, unsigned';
+  value_viewer.Cells[0, 4] := 'Bitset';
+  value_viewer.Cells[0, 5] := 'Float';
+  value_viewer.Cells[0, 6] := 'String';
+  value_viewer.Cells[0, 7] := 'Selected length';
+  value_viewer.ColWidths[0] := 120;
+  value_viewer.ColWidths[1] := 1000;
+//  hex.Height := content.Height - 215;
+  //
+  value_viewer.Font.Charset := AppSettings.CharSet;
+  VST.Font.Charset := AppSettings.CharSet;
+  hex.Translation := tkAsIs;
+  hex.Font.Charset := AppSettings.CharSet;
+  //
+end;
+
+procedure TForm_BinEdit.NewFile(fileinfo: TFileInfo);
+begin
+  LoadDat(fileinfo.ID);
+end;
+
+
+
+
+function AddVSTEntry(AVST: TCustomVirtualStringTree; ANode: PVirtualNode;
+  ARecord: TNodeData): PVirtualNode;
+var
+  Data: PNodeData;
+begin
+  Result := AVST.AddChild(ANode);
+  Data   := AVST.GetNodeData(Result);
+  AVST.ValidateNode(Result, False);
+  Data^ := ARecord;
+end;
+
+
+
+
+procedure TForm_BinEdit.LoadDat(_fileid: Integer);
+var
+  mem:  TMemoryStream;
+  Data: TByteData;
+begin
+  if ConID <> -1 then
+  begin
+    if hex.Modified then
+    begin
+      if not Save then
+      begin
+        Self.SelectFileID(ConnectionID, FileID);
+        Exit;
+      end;
+    end;
+  end;
+  if _fileid >= 0 then
+  begin
+    fileid := _fileid;
+    ConID := ConnectionID;
+    if ConManager.Connection[ConID].ExtractFileIDOfName(filelist.Items.Strings[filelist.ItemIndex]) <> fileid then
+      Self.SelectFileID(ConnectionID, fileid);
+    Self.ClearStructViewer;
+    mem := nil;
+    ConManager.Connection[ConID].LoadDatFile(fileid, TStream(mem));
+    hex.LoadFromStream(mem);
+    mem.Free;
+    ClearValues;
+    WriteStructureInfos;
+  end
+  else
+  begin
+    fileid := _fileid;
+    ConID := -1;
+    Self.ClearStructViewer;
+    ClearValues;
+    hex.DataSize := 0;
+  end;
+end;
+
+
+
+
+function IntToBin(Value: Byte): String;
+var
+  i: Byte;
+begin
+  Result := '';
+  for i := 7 downto 0 do
+    Result := Result + IntToStr((Value shr i) and $01);
+end;
+
+
+
+
+function TForm_BinEdit.GetValue(datatype: Word; offset: LongWord): String;
+var
+  Data: TByteData;
+  i:    Word;
+  floatformat: TFormatSettings;
+begin
+  floatformat.DecimalSeparator := '.';
+  case datatype of
+    1:
+      Result := IntToStr(hex.Data[offset]);
+    2:
+      Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256);
+    3:
+      Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256 + hex.Data[offset + 2] * 256 * 256);
+    4:
+      Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256 + hex.Data[offset + 2] *
+        256 * 256 + hex.Data[offset + 3] * 256 * 256 * 256);
+    5:
+      Result := '0x' + IntToHex(hex.Data[offset], 2);
+    6:
+      Result := '0x' + IntToHex(hex.Data[offset] + hex.Data[offset + 1] * 256, 4);
+    7:
+      Result := '0x' + IntToHex(hex.Data[offset] + hex.Data[offset + 1] * 256 +
+        hex.Data[offset + 2] * 256 * 256, 6);
+    8:
+      Result := '0x' + IntToHex(hex.Data[offset] + hex.Data[offset + 1] * 256 +
+        hex.Data[offset + 2] * 256 * 256 + hex.Data[offset + 3] * 256 * 256 * 256, 8);
+    9:
+    begin
+      SetLength(Data, 4);
+      Data[0] := hex.Data[offset];
+      Data[1] := hex.Data[offset + 1];
+      Data[2] := hex.Data[offset + 2];
+      Data[3] := hex.Data[offset + 3];
+      Result  := FloatToStr(Decode_Float(Data), floatformat);
+    end;
+    10:
+      Result := IntToBin(hex.Data[offset]);
+    11:
+      Result := '0x' + IntToHex(ConManager.Connection[ConID].GetRawInfo(fileid, offset).RawAddr, 8);
+    12:
+      Result := FormatNumber(hex.Data[offset + 1] + hex.Data[offset + 2] * 256 +
+        hex.Data[offset + 3] * 256 * 256, 5, '0');
+    13:
+      Result := IntToStr(hex.Data[offset]);
+    14:
+      Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256);
+    15:
+      Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256 + hex.Data[offset + 2] * 256 * 256);
+    16:
+      Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256 + hex.Data[offset + 2] *
+        256 * 256 + hex.Data[offset + 3] * 256 * 256 * 256);
+    17:
+      Result := IntToStr((hex.Data[offset + 3]) div 2);
+    100..300:
+    begin
+      Result := '';
+      for i := 1 to datatype - 100 do
+      begin
+        if hex.Data[offset + i - 1] >= 32 then
+          Result := Result + Chr(hex.Data[offset + i - 1])
+        else
+          Break;
+      end;
+    end;
+    1000..9999:
+    begin
+      Result := '';
+      for i := 1 to datatype - 1000 do
+      begin
+        if hex.Data[offset + i - 1] >= 32 then
+          Result := Result + Chr(hex.Data[offset + i - 1])
+        else
+          Result := Result + '.';
+      end;
+    end;
+    10000..65535:
+    begin
+      Result := '';
+      for i := 1 to datatype - 10000 do
+      begin
+        if hex.Data[offset + i - 1] >= 32 then
+          Result := Result + Chr(hex.Data[offset + i - 1])
+        else
+          Result := Result + '.';
+      end;
+    end;
+  end;
+end;
+
+
+
+
+procedure TForm_BinEdit.WriteStructureInfos;
+var
+  i, j:    LongWord;
+  pdata:   PNodeData;
+  Data:    TNodeData;
+  node:    PVirtualNode;
+  structs: TStructDef;
+begin
+  VST.BeginUpdate;
+  if VST.RootNodeCount = 0 then
+  begin
+    structs := LoadStructureDefinition(ConID, fileid);
+    if structs.Data then
+    begin
+      if Length(structs.Global) > 0 then
+      begin
+        for i := 0 to High(structs.Global) do
+        begin
+          Data.Caption  := structs.Global[i].Name;
+          Data.Offset   := structs.Global[i].offset;
+          Data.DataType := structs.Global[i].datatype;
+          Data.Value    := GetValue(structs.Global[i].datatype, structs.Global[i].offset);
+          Data.Description := structs.Global[i].description;
+          AddVSTEntry(VST, nil, Data);
+        end;
+      end;
+      if Length(structs.Subs) > 0 then
+      begin
+        for i := 0 to High(structs.Subs) do
+        begin
+          with structs.Subs[i] do
+          begin
+            if Length(Entries) > 0 then
+            begin
+              if Pos('#', SubName) > 0 then
+              begin
+                Data.Offset  := HexToLong(MidStr(SubName, Pos('#', SubName) + 1, 8));
+                Data.Value   :=
+                  MidStr(SubName, PosEx('#', SubName, Pos('#', SubName) + 1) + 1, 8);
+                Data.Caption := MidStr(SubName, 1, Pos('#', SubName) - 1);
+                Data.Description := SubDesc;
+              end
+              else
+              begin
+                Data.Caption := SubName;
+                Data.Description := SubDesc;
+                Data.Offset := 0;
+                Data.Value := '';
+              end;
+              Data.DataType := 0;
+              node := AddVSTEntry(VST, nil, Data);
+              Data.Description := '';
+              for j := 0 to High(Entries) do
+              begin
+                Data.Caption  := Entries[j].Name;
+                Data.Offset   := Entries[j].offset;
+                Data.DataType := Entries[j].datatype;
+                Data.Value    := GetValue(Entries[j].datatype, Entries[j].offset);
+                Data.Description := Entries[j].description;
+                AddVSTEntry(VST, node, Data);
+              end;
+            end;
+          end;
+        end;
+      end;
+    end;
+    if VST.RootNodeCount > 0 then
+      VST.FocusedNode := VST.GetFirst;
+  end
+  else
+  begin
+    Node := VST.GetFirst;
+    while Assigned(Node) do
+    begin
+      pdata := VST.GetNodeData(Node);
+      if pdata.DataType > 0 then
+        pdata.Value := GetValue(pdata.Datatype, pdata.Offset);
+      Node := VST.GetNext(Node);
+    end;
+  end;
+  VST.EndUpdate;
+end;
+
+
+
+
+procedure TForm_BinEdit.ClearValues;
+var
+  i: Byte;
+begin
+  for i := 1 to value_viewer.RowCount - 1 do
+  begin
+    value_viewer.Cells[1, i] := '';
+  end;
+end;
+
+
+
+
+procedure TForm_BinEdit.WriteValues;
+var
+  i, j:  Integer;
+  Data:  TByteData;
+  str:   String;
+  Value: LongWord;
+  floatformat: TFormatSettings;
+begin
+  floatformat.DecimalSeparator := '.';
+  for i := 1 to value_viewer.RowCount - 1 do
+  begin
+    if value_viewer.Cells[0, i] = '1 byte, unsigned' then
+    begin
+      if ((hex.SelCount = 1) or (hex.SelCount = 0)) and not
+        ((hex.SelStart + 1) > hex.DataSize) then
+      begin
+        Value := hex.Data[hex.SelStart];
+        value_viewer.Cells[1, i] := IntToStr(Value) + ' / 0x' + IntToHex(Value, 2);
+      end
+      else
+        value_viewer.Cells[1, i] := '';
+    end;
+    if value_viewer.Cells[0, i] = '2 bytes, unsigned' then
+    begin
+      if ((hex.SelCount = 2) or (hex.SelCount = 0)) and not
+        ((hex.SelStart + 2) > hex.DataSize) then
+      begin
+        Value := hex.Data[hex.SelStart] + hex.Data[hex.SelStart + 1] * 256;
+        value_viewer.Cells[1, i] := IntToStr(Value) + ' / 0x' + IntToHex(Value, 4);
+      end
+      else
+        value_viewer.Cells[1, i] := '';
+    end;
+    if value_viewer.Cells[0, i] = '4 bytes, unsigned' then
+    begin
+      if ((hex.SelCount = 4) or (hex.SelCount = 0)) and not
+        ((hex.SelStart + 4) > hex.DataSize) then
+      begin
+        Value := hex.Data[hex.SelStart] + hex.Data[hex.SelStart + 1] * 256 +
+          hex.Data[hex.SelStart + 2] * 256 * 256 + hex.Data[hex.SelStart + 3] * 256 * 256 * 256;
+        value_viewer.Cells[1, i] := IntToStr(Value) + ' / 0x' + IntToHex(Value, 8);
+      end
+      else
+        value_viewer.Cells[1, i] := '';
+    end;
+    if value_viewer.Cells[0, i] = 'Bitset' then
+    begin
+      if (hex.SelCount <= 8) then
+      begin
+        if hex.SelCount = 0 then
+        begin
+          SetLength(Data, 1);
+          Data[0] := hex.Data[hex.SelStart];
+        end
+        else
+        begin
+          SetLength(Data, hex.SelCount);
+          for j := 0 to hex.SelCount - 1 do
+            Data[j] := hex.Data[hex.SelStart + j];
+        end;
+        value_viewer.Cells[1, i] := DataToBin(Data);
+      end
+      else
+        value_viewer.Cells[1, i] := '';
+    end;
+    if value_viewer.Cells[0, i] = 'Float' then
+    begin
+      if ((hex.SelCount = 4) or (hex.SelCount = 0)) and not
+        ((hex.SelStart + 4) > hex.DataSize) then
+      begin
+        SetLength(Data, 4);
+        for j := 0 to 3 do
+          Data[j] := hex.Data[hex.SelStart + j];
+        value_viewer.Cells[1, i] := FloatToStr(Decode_Float(Data), floatformat);
+      end
+      else
+        value_viewer.Cells[1, i] := '';
+    end;
+    if value_viewer.Cells[0, i] = 'Selected length' then
+    begin
+      value_viewer.Cells[1, i] := IntToStr(hex.SelCount) + ' bytes';
+    end;
+    if value_viewer.Cells[0, i] = 'String' then
+    begin
+      j   := 0;
+      str := '';
+      if hex.SelCount = 0 then
+      begin
+        while (hex.Data[hex.SelStart + j] > 0) and ((hex.SelStart + j) < hex.DataSize) do
+        begin
+          if hex.Data[hex.selstart + j] >= 32 then
+            str := str + Char(hex.Data[hex.SelStart + j])
+          else
+            str := str + '.';
+          Inc(j);
+        end;
+      end
+      else
+      begin
+        for j := 0 to hex.SelCount - 1 do
+          if hex.Data[hex.selstart + j] >= 32 then
+            str := str + Char(hex.Data[hex.SelStart + j])
+          else if hex.Data[hex.selstart + j] > 0 then
+            str := str + '.'
+          else
+            Break;
+      end;
+      value_viewer.Cells[1, i] := str;
+    end;
+  end;
+end;
+
+
+
+
+function TForm_BinEdit.Save: Boolean;
+var
+  mem:  TMemoryStream;
+  i:    LongWord;
+begin
+  case MessageBox(Self.Handle, PChar('Save changes to file ' +
+      ConManager.Connection[ConID].GetFileInfo(fileid).Name + '?'), PChar('Data changed...'),
+      MB_YESNOCANCEL + MB_ICONQUESTION) of
+    idYes:
+    begin
+      mem := TMemoryStream.Create;
+      hex.SaveToStream(mem);
+      mem.Seek(0, soFromBeginning);
+      ConManager.Connection[ConID].UpdateDatFile(fileid, mem);
+      mem.Free;
+      hex.Modified := False;
+      for i := 0 to hex.Datasize - 1 do
+        hex.ByteChanged[i] := False;
+      Result := True;
+    end;
+    idNo:
+      Result := True;
+    idCancel:
+    begin
+      Result := False;
+    end;
+  end;
+end;
+
+
+
+
+procedure TForm_BinEdit.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
+begin
+  if hex.Modified then
+  begin
+    if not Save then
+      CanClose := False;
+  end;
+end;
+
+
+
+
+procedure TForm_BinEdit.ClearStructViewer;
+begin
+  VST.Clear;
+end;
+
+
+
+
+
+
+procedure TForm_BinEdit.hexChange(Sender: TObject);
+begin
+  ClearValues;
+  if hex.DataSize > 0 then
+  begin
+    WriteStructureInfos;
+    WriteValues;
+  end;
+end;
+
+
+
+
+procedure TForm_BinEdit.hexKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
+//var
+//  temps: String;
+begin
+  if (Shift = [ssCtrl]) and (Key = Ord('C')) then
+  begin
+    if hex.SelCount > 0 then
+    begin
+      if hex.InCharField then
+        Clipboard.AsText := hex.SelectionAsText
+      else
+        Clipboard.AsText := hex.SelectionAsHex;
+    end;
+  end;
+  if (Shift = [ssCtrl]) and (Key = Ord('V')) then
+  begin
+{      temps:=Clipboard.AsText;
+      IF hex.SelStart+Length(temps)>hex.DataSize THEN
+        SetLength(temps, hex.DataSize-hex.SelStart);
+      hex.Sel
+      hex.SelCount:=Length(temps);
+      hex.ReplaceSelection(temps,Length(temps));
+}    end;
+end;
+
+
+
+
+procedure TForm_BinEdit.hexSelectionChanged(Sender: TObject);
+var
+  selstart: Integer;
+  node:     PVirtualNode;
+  pdata:    PNodeData;
+begin
+  if hex.DataSize > 0 then
+  begin
+    WriteValues;
+    selstart := hex.SelStart;
+    if VST.RootNodeCount > 0 then
+    begin
+      Node := VST.GetFirst;
+      while Assigned(Node) do
+      begin
+        pdata := VST.GetNodeData(Node);
+        if pdata.DataType > 0 then
+        begin
+          if ((selstart - pdata.Offset) < GetDataTypeLength(pdata.DataType)) and
+            ((selstart - pdata.Offset) >= 0) then
+          begin
+            VST.FocusedNode    := Node;
+            VST.Selected[Node] := True;
+            Break;
+          end;
+        end;
+        Node := VST.GetNext(Node);
+      end;
+    end;
+  end;
+end;
+
+
+
+
+procedure TForm_BinEdit.value_viewer_contextPopup(Sender: TObject);
+var
+  i: Byte;
+begin
+  for i := 0 to value_viewer_context.Items.Count - 1 do
+    value_viewer_context.Items.Items[i].Visible := False;
+  with value_viewer do
+  begin
+    if (Col = 1) and (Row > 0) and (Length(Cells[Col, Row]) > 0) then
+    begin
+      if Pos(' byte', Cells[0, Row]) = 2 then
+      begin
+        value_viewer_context.Items.Find('Copy to &clipboard').Visible := True;
+        value_viewer_context.Items.Find('Copy to clipboard (as &dec)').Visible := True;
+        value_viewer_context.Items.Find('Copy to clipboard (as &hex)').Visible := True;
+      end;
+      if Pos('Float', Cells[0, Row]) = 1 then
+        value_viewer_context.Items.Find('Copy to clipboard (as &float)').Visible := True;
+      if Pos('Bitset', Cells[0, Row]) = 1 then
+        value_viewer_context.Items.Find(
+          'Copy to clipboard (as &bitset)').Visible := True;
+      if Pos('String', Cells[0, Row]) = 1 then
+        value_viewer_context.Items.Find(
+          'Copy to clipboard (as &string)').Visible := True;
+      if Pos('Selected length', Cells[0, Row]) = 1 then
+        value_viewer_context.Items.Find('Copy to &clipboard').Visible := True;
+    end;
+  end;
+end;
+
+
+
+
+procedure TForm_BinEdit.value_viewerMouseDown(Sender: TObject; Button: TMouseButton;
+  Shift: TShiftState; X, Y: Integer);
+var
+  ACol, ARow: Integer;
+begin
+  if Button = mbRight then
+  begin
+    value_viewer.MouseToCell(x, y, ACol, ARow);
+    if ARow > 0 then
+    begin
+      value_viewer.Col := ACol;
+      value_viewer.Row := ARow;
+    end;
+  end;
+end;
+
+
+
+
+procedure TForm_BinEdit.value_viewer_context_copyClick(Sender: TObject);
+var
+  Name:  String;
+  Value: LongWord;
+begin
+  Name := TMenuItem(Sender).Name;
+  if Pos('asstring', Name) > 0 then
+  begin
+    Clipboard.AsText := value_viewer.Cells[value_viewer.Col, value_viewer.Row];
+  end
+  else if Pos('asfloat', Name) > 0 then
+  begin
+    Clipboard.AsText := value_viewer.Cells[value_viewer.Col, value_viewer.Row];
+  end
+  else if Pos('asbitset', Name) > 0 then
+  begin
+    Clipboard.AsText := value_viewer.Cells[value_viewer.Col, value_viewer.Row];
+  end
+  else if (Pos('ashex', Name) > 0) or (Pos('asdec', Name) > 0) then
+  begin
+    if value_viewer.Cells[0, value_viewer.Row] = '1 byte, unsigned' then
+    begin
+      if ((hex.SelCount = 1) or (hex.SelCount = 0)) and not
+        ((hex.SelStart + 1) > hex.DataSize) then
+        Value := hex.Data[hex.SelStart];
+    end;
+    if value_viewer.Cells[0, value_viewer.Row] = '2 bytes, unsigned' then
+    begin
+      if ((hex.SelCount = 2) or (hex.SelCount = 0)) and not
+        ((hex.SelStart + 2) > hex.DataSize) then
+        Value := hex.Data[hex.SelStart] + hex.Data[hex.SelStart + 1] * 256;
+    end;
+    if value_viewer.Cells[0, value_viewer.Row] = '4 bytes, unsigned' then
+    begin
+      if ((hex.SelCount = 4) or (hex.SelCount = 0)) and not
+        ((hex.SelStart + 4) > hex.DataSize) then
+        Value := hex.Data[hex.SelStart] + hex.Data[hex.SelStart + 1] * 256 +
+          hex.Data[hex.SelStart + 2] * 256 * 256 + hex.Data[hex.SelStart + 3] * 256 * 256 * 256;
+    end;
+    if Pos('asdec', Name) > 0 then
+    begin
+      Clipboard.AsText := IntToStr(Value);
+    end
+    else
+    begin
+      if value_viewer.Cells[0, value_viewer.Row] = '1 byte, unsigned' then
+        Clipboard.AsText := '0x' + IntToHex(Value, 2);
+      if value_viewer.Cells[0, value_viewer.Row] = '2 bytes, unsigned' then
+        Clipboard.AsText := '0x' + IntToHex(Value, 4);
+      if value_viewer.Cells[0, value_viewer.Row] = '4 bytes, unsigned' then
+        Clipboard.AsText := '0x' + IntToHex(Value, 8);
+    end;
+  end
+  else
+  begin
+    Clipboard.AsText := value_viewer.Cells[value_viewer.Col, value_viewer.Row];
+  end;
+end;
+
+
+
+
+procedure TForm_BinEdit.VSTDblClick(Sender: TObject);
+var
+  node: PVirtualNode;
+  nodedata: PNodeData;
+  form: TForm_ToolTemplate;
+begin
+  if VST.FocusedColumn = 3 then
+  begin
+    node     := VST.FocusedNode;
+    nodedata := VST.GetNodeData(node);
+
+    if not (nodedata.datatype in [11, 12]) and
+      ((nodedata.DataType < 100) or (nodedata.DataType > 300)) then
+    begin
+      Form_ValueEdit.MakeVarInput(nodedata.Caption, nodedata.offset,
+        nodedata.datatype, nodedata.Value, Self);
+    end
+    else
+    begin
+      if nodedata.DataType = 11 then
+      begin
+        if ConManager.Connection[ConID].GetRawInfo(fileid, nodedata.offset).RawSize > 0 then
+          Form_Main.open_child('rawedit', ConID, fileid);
+      end;
+      if nodedata.DataType = 12 then
+      begin
+        if (StrToInt(nodedata.Value) < ConManager.Connection[ConID].GetFileCount) and
+          (StrToInt(nodedata.Value) > 0) and
+          (StrToInt(nodedata.Value) <> fileid) then
+        begin
+          if ConManager.Connection[ConID].GetFileInfo(StrToInt(nodedata.Value)).Size > 0 then
+            Form_Main.open_child('binedit', ConID, StrToInt(nodedata.Value))
+          else
+            ShowMessage('Linked filed is a zero-byte-file');
+        end;
+      end;
+      if (nodedata.DataType >= 100) and (nodedata.DataType <= 300) then
+      begin
+        form := Form_Main.open_child('binedit', ConID, -1);
+        if Assigned(form) then
+          form.SetFileFilters(nodedata.Value, '', False);
+      end;
+    end;
+
+  end;
+end;
+
+
+
+
+procedure TForm_BinEdit.VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode;
+  Column: TColumnIndex);
+var
+  Data: PNodeData;
+begin
+  Data := VST.GetNodeData(node);
+  if Data.DataType > 0 then
+  begin
+    hex.SelStart := Data.Offset;
+    hex.SelEnd   := Data.Offset + GetDataTypeLength(Data.DataType) - 1;
+  end
+  else
+  begin
+    hex.SelStart := Data.Offset;
+    hex.SelEnd   := Data.Offset + HexToLong(Data.Value) - 1;
+  end;
+end;
+
+
+
+
+procedure TForm_BinEdit.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
+  Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
+var
+  Data: PNodeData;
+begin
+  Data     := Sender.GetNodeData(Node);
+  CellText := '';
+  if TextType = ttNormal then
+  begin
+    case Column of
+      0:
+        CellText := Data.Caption;
+      1:
+        if Data.DataType > 0 then
+          CellText := '0x' + IntToHex(Data.Offset, 8)
+        else if Data.Offset > 0 then
+          CellText := '0x' + IntToHex(Data.Offset, 8);
+      2:
+        if Data.DataType > 0 then
+          CellText := GetDataType(Data.DataType);
+      3:
+        if Data.DataType > 0 then
+          CellText := Data.Value //GetValue(data.DataType, data.Offset)
+        else if Length(Data.Value) > 0 then
+          CellText := IntToStr(HexToLong(Data.Value)) + ' Bytes';
+      4:
+        CellText := Data.Description;
+    end;
+  end;
+end;
+
+
+
+
+procedure TForm_BinEdit.VSTHeaderDragged(Sender: TVTHeader; Column: TColumnIndex;
+  OldPosition: Integer);
+begin
+  if Sender.Columns.Items[column].Position < 1 then
+    Sender.Columns.Items[column].Position := OldPosition;
+end;
+
+
+
+
+procedure TForm_BinEdit.VTHPopupColumnChange(const Sender: TBaseVirtualTree;
+  const Column: TColumnIndex; Visible: Boolean);
+begin
+  if column = 0 then
+    TVirtualStringTree(Sender).Header.Columns.Items[column].Options :=
+      TVirtualStringTree(Sender).Header.Columns.Items[column].Options + [coVisible];
+end;
+
+
+
+
+procedure TForm_BinEdit.SetNewValue(datatype: Word; offset: LongWord; Value: String);
+var
+  Data: TByteData;
+  value_int: LongWord;
+  value_float: Single;
+  i: Word;
+begin
+  case datatype of
+    1..4:
+    begin
+      value_int := StrToInt(Value);
+      SetLength(Data, datatype);
+      for i := 0 to datatype - 1 do
+      begin
+        Data[i]   := value_int mod 256;
+        value_int := value_int div 256;
+      end;
+    end;
+    5..8:
+    begin
+      value_int := StrToInt('$' + Value);
+      SetLength(Data, datatype - 4);
+      for i := 0 to datatype - 5 do
+      begin
+        Data[i]   := value_int mod 256;
+        value_int := value_int div 256;
+      end;
+    end;
+    9:
+    begin
+      value_float := StrToFloat(Value);
+      Data := Encode_Float(value_float);
+    end;
+    10:
+    begin
+      value_int := BinToInt(Value);
+      SetLength(Data, 1);
+      Data[0] := value_int;
+    end;
+    10000..65535:
+    begin
+      SetLength(Data, datatype - 10000);
+      for i := 1 to datatype - 10000 do
+      begin
+        if i <= Length(Value) then
+          Data[i - 1] := Ord(Value[i])
+        else
+          Data[i - 1] := 0;
+      end;
+    end;
+  end;
+  for i := 0 to High(Data) do
+  begin
+    if hex.Data[offset + i] <> Data[i] then
+      hex.ByteChanged[offset + i] := True;
+    hex.Data[offset + i] := Data[i];
+  end;
+  hex.Modified := True;
+  hexChange(Self);
+  hex.Repaint;
+end;
+
+
+
+
+procedure TForm_BinEdit.value_viewerDblClick(Sender: TObject);
+var
+  offset:     LongWord;
+  datatype:   Word;
+  objectname: String;
+  Value:      String;
+begin
+  if (value_viewer.Col = 1) and (Length(value_viewer.Cells[1, value_viewer.Row]) > 0) then
+  begin
+    offset := hex.SelStart;
+    if value_viewer.Cells[0, value_viewer.Row] = '1 byte, unsigned' then
+      datatype := 1;
+    if value_viewer.Cells[0, value_viewer.Row] = '2 bytes, unsigned' then
+      datatype := 2;
+    if value_viewer.Cells[0, value_viewer.Row] = '4 bytes, unsigned' then
+      datatype := 4;
+    if value_viewer.Cells[0, value_viewer.Row] = 'Bitset' then
+      datatype := 10;
+    if value_viewer.Cells[0, value_viewer.Row] = 'Float' then
+      datatype := 9;
+    if value_viewer.Cells[0, value_viewer.Row] = 'Selected length' then
+      Exit;
+    if value_viewer.Cells[0, value_viewer.Row] = 'String' then
+    begin
+      if hex.SelCount > 0 then
+        datatype := 10000 + hex.SelCount
+      else
+        datatype := 10000 + Length(value_viewer.Cells[1, value_viewer.Row]);
+    end;
+    objectname := '';
+    Value      := GetValue(datatype, offset);
+    Form_ValueEdit.MakeVarInput(objectname, offset, datatype, Value, Self);
+  end;
+end;
+
+
+
+
+procedure TForm_BinEdit.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
+begin
+  if (Shift = [ssCtrl]) and (Key = 83) then
+    if hex.Modified then
+      if not Save then
+        Exit;
+end;
+
+
+begin
+  AddToolListEntry('binedit', 'Binary .dat-Editor', '');
+end.
Index: oup/rewrite/Tools/RawEdit.dfm
===================================================================
--- oup/rewrite/Tools/RawEdit.dfm	(revision 104)
+++ oup/rewrite/Tools/RawEdit.dfm	(revision 104)
@@ -0,0 +1,199 @@
+inherited Form_RawEdit: TForm_RawEdit
+  Caption = 'RawEdit'
+  KeyPreview = True
+  OnCloseQuery = FormCloseQuery
+  OnKeyUp = FormKeyUp
+  ExplicitWidth = 500
+  ExplicitHeight = 450
+  PixelsPerInch = 96
+  TextHeight = 13
+  inherited panel_files: TPanel
+    object Splitter4: TSplitter [0]
+      Left = 0
+      Top = 205
+      Width = 200
+      Height = 8
+      Cursor = crVSplit
+      Align = alBottom
+      AutoSnap = False
+      Beveled = True
+      MinSize = 150
+      ExplicitLeft = 3
+      ExplicitTop = 89
+    end
+    inherited filelist: TListBox
+      Height = 52
+      ExplicitHeight = 52
+    end
+    object panel_imexport: TPanel
+      Left = 0
+      Top = 363
+      Width = 200
+      Height = 60
+      Align = alBottom
+      BevelOuter = bvNone
+      TabOrder = 3
+      DesignSize = (
+        200
+        60)
+      object btn_export: TButton
+        Left = 4
+        Top = 4
+        Width = 190
+        Height = 25
+        Anchors = [akLeft, akTop, akRight]
+        Caption = 'Export to file...'
+        TabOrder = 0
+        OnClick = btn_exportClick
+      end
+      object btn_import: TButton
+        Left = 4
+        Top = 32
+        Width = 190
+        Height = 25
+        Anchors = [akLeft, akTop, akRight]
+        Caption = 'Import from file...'
+        TabOrder = 1
+        OnClick = btn_importClick
+      end
+    end
+    object GroupBox1: TGroupBox
+      Left = 0
+      Top = 213
+      Width = 200
+      Height = 150
+      Align = alBottom
+      Caption = '2. Select .dat-link-offset'
+      TabOrder = 2
+      object list_offset: TListBox
+        Left = 2
+        Top = 15
+        Width = 196
+        Height = 133
+        Align = alClient
+        ItemHeight = 13
+        TabOrder = 0
+        OnClick = list_offsetClick
+      end
+    end
+  end
+  inherited content: TPanel
+    object Splitter2: TSplitter
+      Left = 0
+      Top = 300
+      Width = 283
+      Height = 9
+      Cursor = crVSplit
+      Align = alTop
+      AutoSnap = False
+      Beveled = True
+      MinSize = 40
+      ExplicitTop = 414
+    end
+    object hex: TMPHexEditor
+      Left = 0
+      Top = 0
+      Width = 283
+      Height = 300
+      Cursor = crIBeam
+      Align = alTop
+      Font.Charset = DEFAULT_CHARSET
+      Font.Color = clWindowText
+      Font.Height = -16
+      Font.Name = 'Courier'
+      Font.Style = []
+      OnKeyUp = hexKeyUp
+      ParentFont = False
+      TabOrder = 0
+      BytesPerRow = 16
+      Translation = tkAsIs
+      OffsetFormat = '6!10:0x|'
+      Colors.Background = clWindow
+      Colors.ChangedBackground = clWindow
+      Colors.ChangedText = clRed
+      Colors.CursorFrame = clNavy
+      Colors.Offset = clBlack
+      Colors.OddColumn = clBlue
+      Colors.EvenColumn = clNavy
+      Colors.CurrentOffsetBackground = clBtnShadow
+      Colors.OffsetBackGround = clBtnFace
+      Colors.CurrentOffset = clBtnHighlight
+      Colors.Grid = clBtnFace
+      Colors.NonFocusCursorFrame = clAqua
+      Colors.ActiveFieldBackground = clWindow
+      FocusFrame = True
+      NoSizeChange = True
+      AllowInsertMode = False
+      DrawGridLines = False
+      Version = 'May 23, 2005; '#169' markus stephany, vcl[at]mirkes[dot]de'
+      OnChange = hexChange
+      ShowPositionIfNotFocused = True
+      OnSelectionChanged = hexSelectionChanged
+    end
+    object value_viewer: TWrapGrid
+      Left = 0
+      Top = 309
+      Width = 283
+      Height = 114
+      Align = alClient
+      ColCount = 2
+      DefaultColWidth = 80
+      DefaultRowHeight = 18
+      FixedCols = 0
+      RowCount = 8
+      FixedRows = 0
+      Font.Charset = DEFAULT_CHARSET
+      Font.Color = clWindowText
+      Font.Height = -11
+      Font.Name = 'Tahoma'
+      Font.Style = []
+      Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goColSizing]
+      ParentFont = False
+      PopupMenu = value_viewer_context
+      ScrollBars = ssVertical
+      TabOrder = 1
+      OnDblClick = value_viewerDblClick
+      OnMouseDown = value_viewerMouseDown
+    end
+  end
+  object value_viewer_context: TPopupMenu [3]
+    AutoHotkeys = maManual
+    OnPopup = value_viewer_contextPopup
+    Left = 368
+    Top = 264
+    object value_viewer_context_copy: TMenuItem
+      Caption = 'Copy to &clipboard'
+      OnClick = value_viewer_context_copyClick
+    end
+    object value_viewer_context_copyasdec: TMenuItem
+      Caption = 'Copy to clipboard (as &dec)'
+      OnClick = value_viewer_context_copyClick
+    end
+    object value_viewer_context_copyasfloat: TMenuItem
+      Caption = 'Copy to clipboard (as &float)'
+      OnClick = value_viewer_context_copyClick
+    end
+    object value_viewer_context_copyasbitset: TMenuItem
+      Caption = 'Copy to clipboard (as &bitset)'
+      OnClick = value_viewer_context_copyClick
+    end
+    object value_viewer_context_copyasstring: TMenuItem
+      Caption = 'Copy to clipboard (as &string)'
+      OnClick = value_viewer_context_copyClick
+    end
+    object value_viewer_context_copyashex: TMenuItem
+      Caption = 'Copy to clipboard (as &hex)'
+      OnClick = value_viewer_context_copyClick
+    end
+  end
+  object opend: TOpenDialog [4]
+    Options = [ofPathMustExist, ofFileMustExist, ofEnableSizing]
+    Left = 128
+    Top = 256
+  end
+  object saved: TSaveDialog [5]
+    Options = [ofOverwritePrompt, ofPathMustExist, ofEnableSizing]
+    Left = 128
+    Top = 280
+  end
+end
Index: oup/rewrite/Tools/RawEdit.pas
===================================================================
--- oup/rewrite/Tools/RawEdit.pas	(revision 104)
+++ oup/rewrite/Tools/RawEdit.pas	(revision 104)
@@ -0,0 +1,804 @@
+unit RawEdit;
+interface
+uses
+  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
+  Dialogs, Template, StdCtrls, ExtCtrls, Menus, Grids, Wrapgrid,
+  MPHexEditor, Clipbrd, StrUtils, TypeDefs,
+  Data, Functions, DatStructureLoader, ConnectionManager, Buttons;
+
+type
+  TForm_RawEdit = class(TForm_ToolTemplate)
+    Splitter4: TSplitter;
+    panel_imexport: TPanel;
+    btn_export: TButton;
+    btn_import: TButton;
+    GroupBox1: TGroupBox;
+    list_offset: TListBox;
+    hex: TMPHexEditor;
+    Splitter2: TSplitter;
+    value_viewer: TWrapGrid;
+    value_viewer_context: TPopupMenu;
+    value_viewer_context_copy: TMenuItem;
+    value_viewer_context_copyasdec: TMenuItem;
+    value_viewer_context_copyasfloat: TMenuItem;
+    value_viewer_context_copyasbitset: TMenuItem;
+    value_viewer_context_copyasstring: TMenuItem;
+    value_viewer_context_copyashex: TMenuItem;
+    opend: TOpenDialog;
+    saved: TSaveDialog;
+    procedure list_offsetClick(Sender: TObject);
+    procedure NewFile(fileinfo: TFileInfo);
+    procedure LoadRaw(raw_info: TRawDataInfo);
+    function Save: Boolean;
+
+    procedure btn_importClick(Sender: TObject);
+    procedure btn_exportClick(Sender: TObject);
+
+    procedure FormCreate(Sender: TObject);
+    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
+    procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
+
+    function GetValue(datatype: Word; offset: LongWord): String;
+    procedure ClearValues;
+    procedure WriteValues;
+    procedure SetNewValue(datatype: Word; offset: LongWord; Value: String);
+
+    procedure value_viewerDblClick(Sender: TObject);
+    procedure value_viewer_context_copyClick(Sender: TObject);
+    procedure value_viewerMouseDown(Sender: TObject; Button: TMouseButton;
+      Shift: TShiftState; X, Y: Integer);
+    procedure value_viewer_contextPopup(Sender: TObject);
+
+    procedure hexKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
+    procedure hexSelectionChanged(Sender: TObject);
+    procedure hexChange(Sender: TObject);
+  private
+    ConID, fileid, datoffset: Integer;
+  public
+  end;
+
+var
+  Form_RawEdit: TForm_RawEdit;
+
+implementation
+{$R *.dfm}
+uses Main, ValueEdit;
+
+procedure TForm_RawEdit.NewFile(fileinfo: TFileInfo);
+var
+  offsets: TRawDataList;
+  i: Integer;
+begin
+  if fileinfo.ID >= 0 then
+  begin
+    if hex.Modified then
+      if not Save then
+        Exit;
+    ClearValues;
+    hex.DataSize := 0;
+    fileid := fileinfo.ID;
+    list_offset.Enabled := False;
+    if fileinfo.size > 0 then
+    begin
+      offsets := ConManager.Connection[ConnectionID].GetRawList(fileid);
+      list_offset.Items.Clear;
+      if Length(offsets) > 0 then
+        for i := 0 to High(offsets) do
+          list_offset.Items.Add('0x' + IntToHex(offsets[i].SrcOffset, 8) +
+                ', ' + IntToStr(offsets[i].RawSize) + ' Bytes');
+      list_offset.Enabled := True;
+    end;
+  end
+  else
+  begin
+    ClearValues;
+    hex.DataSize := 0;
+    fileid := -1;
+    list_offset.Items.Clear;
+  end;
+end;
+
+procedure TForm_RawEdit.LoadRaw(raw_info: TRawDataInfo);
+var
+  i:    LongWord;
+  mem: TMemoryStream;
+begin
+  if hex.Modified then
+  begin
+    if not Save then
+    begin
+      Exit;
+    end;
+  end;
+  if list_offset.Count = 0 then
+  begin
+    for i := 0 to filelist.Count - 1 do
+    begin
+      if ConManager.Connection[ConID].ExtractFileIDOfName(filelist.Items.Strings[i]) = RawInfo.SrcID then
+      begin
+        filelist.ItemIndex := i;
+        listClick(Self);
+        Break;
+      end;
+    end;
+    for i := 0 to list_offset.Count - 1 do
+    begin
+      if MidStr(list_offset.Items.Strings[i], 3, 8) = IntToHex(raw_info.SrcOffset, 8) then
+      begin
+        list_offset.ItemIndex := i;
+        Break;
+      end;
+    end;
+  end;
+  mem := nil;
+  ConManager.Connection[ConID].LoadRawFile(raw_info.SrcID, raw_info.SrcOffset, mem);
+  hex.LoadFromStream(mem);
+  ClearValues;
+  hexSelectionChanged(Self);
+end;
+
+
+
+
+
+
+procedure TForm_RawEdit.list_offsetClick(Sender: TObject);
+begin
+  ClearValues;
+  dat_offset := StrToInt('$' + MidStr(
+    list_offset.Items.Strings[list_offset.ItemIndex], 3, 8));
+  LoadRaw(Connection.GetRawInfo(fileid, dat_offset));
+end;
+
+
+
+
+function IntToBin(Value: Byte): String;
+var
+  i: Byte;
+begin
+  Result := '';
+  for i := 7 downto 0 do
+  begin
+    Result := Result + IntToStr((Value shr i) and $01);
+  end;
+end;
+
+
+
+
+function TForm_RawEdit.GetValue(datatype: Word; offset: LongWord): String;
+var
+  Data: Tdata;
+  i:    Word;
+  floatformat: TFormatSettings;
+begin
+  floatformat.DecimalSeparator := '.';
+  case datatype of
+    1:
+      Result := IntToStr(hex.Data[offset]);
+    2:
+      Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256);
+    3:
+      Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256 + hex.Data[offset + 2] * 256 * 256);
+    4:
+      Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256 + hex.Data[offset + 2] *
+        256 * 256 + hex.Data[offset + 3] * 256 * 256 * 256);
+    5:
+      Result := '0x' + IntToHex(hex.Data[offset], 2);
+    6:
+      Result := '0x' + IntToHex(hex.Data[offset] + hex.Data[offset + 1] * 256, 4);
+    7:
+      Result := '0x' + IntToHex(hex.Data[offset] + hex.Data[offset + 1] * 256 +
+        hex.Data[offset + 2] * 256 * 256, 6);
+    8:
+      Result := '0x' + IntToHex(hex.Data[offset] + hex.Data[offset + 1] * 256 +
+        hex.Data[offset + 2] * 256 * 256 + hex.Data[offset + 3] * 256 * 256 * 256, 8);
+    9:
+    begin
+      SetLength(Data, 4);
+      Data[0] := hex.Data[offset];
+      Data[1] := hex.Data[offset + 1];
+      Data[2] := hex.Data[offset + 2];
+      Data[3] := hex.Data[offset + 3];
+      Result  := FloatToStr(Decode_Float(Data), floatformat);
+    end;
+    10:
+      Result := IntToBin(hex.Data[offset]);
+    11:
+      Result := '0x' + IntToHex(hex.Data[offset] + hex.Data[offset + 1] * 256 +
+        hex.Data[offset + 2] * 256 * 256 + hex.Data[offset + 3] * 256 * 256 * 256, 8);
+    10000..65535:
+    begin
+      Result := '';
+      for i := 1 to datatype - 10000 do
+      begin
+        if hex.Data[offset + i - 1] >= 32 then
+          Result := Result + Chr(hex.Data[offset + i - 1])
+        else
+          Result := Result + '.';
+      end;
+    end;
+  end;
+end;
+
+
+
+
+procedure TForm_RawEdit.ClearValues;
+var
+  i: Byte;
+begin
+  for i := 1 to value_viewer.RowCount - 1 do
+  begin
+    value_viewer.Cells[1, i] := '';
+  end;
+end;
+
+
+
+
+procedure TForm_RawEdit.WriteValues;
+var
+  i, j:  Integer;
+  Data:  Tdata;
+  str:   String;
+  Value: LongWord;
+  floatformat: TFormatSettings;
+begin
+  floatformat.DecimalSeparator := '.';
+  for i := 1 to value_viewer.RowCount - 1 do
+  begin
+    if value_viewer.Cells[0, i] = '1 byte, unsigned' then
+    begin
+      if ((hex.SelCount = 1) or (hex.SelCount = 0)) and not
+        ((hex.SelStart + 1) > hex.DataSize) then
+      begin
+        Value := hex.Data[hex.SelStart];
+        value_viewer.Cells[1, i] := IntToStr(Value) + ' / 0x' + IntToHex(Value, 2);
+      end
+      else
+        value_viewer.Cells[1, i] := '';
+    end;
+    if value_viewer.Cells[0, i] = '2 bytes, unsigned' then
+    begin
+      if ((hex.SelCount = 2) or (hex.SelCount = 0)) and not
+        ((hex.SelStart + 2) > hex.DataSize) then
+      begin
+        Value := hex.Data[hex.SelStart] + hex.Data[hex.SelStart + 1] * 256;
+        value_viewer.Cells[1, i] := IntToStr(Value) + ' / 0x' + IntToHex(Value, 4);
+      end
+      else
+        value_viewer.Cells[1, i] := '';
+    end;
+    if value_viewer.Cells[0, i] = '4 bytes, unsigned' then
+    begin
+      if ((hex.SelCount = 4) or (hex.SelCount = 0)) and not
+        ((hex.SelStart + 4) > hex.DataSize) then
+      begin
+        Value := hex.Data[hex.SelStart] + hex.Data[hex.SelStart + 1] * 256 +
+          hex.Data[hex.SelStart + 2] * 256 * 256 + hex.Data[hex.SelStart + 3] * 256 * 256 * 256;
+        value_viewer.Cells[1, i] := IntToStr(Value) + ' / 0x' + IntToHex(Value, 8);
+      end
+      else
+        value_viewer.Cells[1, i] := '';
+    end;
+    if value_viewer.Cells[0, i] = 'Bitset' then
+    begin
+      if (hex.SelCount <= 8) then
+      begin
+        if hex.SelCount = 0 then
+        begin
+          SetLength(Data, 1);
+          Data[0] := hex.Data[hex.SelStart];
+        end
+        else
+        begin
+          SetLength(Data, hex.SelCount);
+          for j := 0 to hex.SelCount - 1 do
+            Data[j] := hex.Data[hex.SelStart + j];
+        end;
+        value_viewer.Cells[1, i] := DataToBin(Data);
+      end
+      else
+        value_viewer.Cells[1, i] := '';
+    end;
+    if value_viewer.Cells[0, i] = 'Float' then
+    begin
+      if ((hex.SelCount = 4) or (hex.SelCount = 0)) and not
+        ((hex.SelStart + 4) > hex.DataSize) then
+      begin
+        SetLength(Data, 4);
+        for j := 0 to 3 do
+          Data[j] := hex.Data[hex.SelStart + j];
+        value_viewer.Cells[1, i] := FloatToStr(Decode_Float(Data), floatformat);
+      end
+      else
+        value_viewer.Cells[1, i] := '';
+    end;
+    if value_viewer.Cells[0, i] = 'Selected length' then
+    begin
+      value_viewer.Cells[1, i] := IntToStr(hex.SelCount) + ' bytes';
+    end;
+    if value_viewer.Cells[0, i] = 'String' then
+    begin
+      j   := 0;
+      str := '';
+      if hex.SelCount = 0 then
+      begin
+        while (hex.Data[hex.SelStart + j] > 0) and ((hex.SelStart + j) < hex.DataSize) do
+        begin
+          if hex.Data[hex.selstart + j] >= 32 then
+            str := str + Char(hex.Data[hex.SelStart + j])
+          else
+            str := str + '.';
+          Inc(j);
+        end;
+      end
+      else
+      begin
+        for j := 0 to hex.SelCount - 1 do
+          if hex.Data[hex.selstart + j] >= 32 then
+            str := str + Char(hex.Data[hex.SelStart + j])
+          else if hex.Data[hex.selstart + j] > 0 then
+            str := str + '.'
+          else
+            Break;
+      end;
+      value_viewer.Cells[1, i] := str;
+    end;
+  end;
+end;
+
+
+
+
+procedure TForm_RawEdit.FormCreate(Sender: TObject);
+var
+  i:     LongWord;
+  exts: String;
+begin
+  inherited;
+  Self.OnNewFileSelected := Self.NewFile;
+
+  exts := '';
+  if Length(RawListHandlers) > 0 then
+  begin
+    for i := 0 to High(RawListHandlers) do
+      if Length(exts) > 0 then
+        exts := exts + ',' + RawListHandlers[i].Ext
+      else
+        exts := RawListHandlers[i].Ext;
+  end;
+  Self.AllowedExts := exts;
+
+  Self.Caption := '';
+  fileid     := -1;
+
+{
+  value_viewer.ColCount := 2;
+  value_viewer.RowCount := 8;
+}
+  value_viewer.FixedRows := 1;
+  value_viewer.FixedCols := 1;
+  value_viewer.Cells[0, 0] := 'Type';
+  value_viewer.Cells[1, 0] := 'Value';
+  value_viewer.Cells[0, 1] := '1 byte, unsigned';
+  value_viewer.Cells[0, 2] := '2 bytes, unsigned';
+  value_viewer.Cells[0, 3] := '4 bytes, unsigned';
+  value_viewer.Cells[0, 4] := 'Bitset';
+  value_viewer.Cells[0, 5] := 'Float';
+  value_viewer.Cells[0, 6] := 'String';
+  value_viewer.Cells[0, 7] := 'Selected length';
+  value_viewer.ColWidths[0] := 125;
+  value_viewer.ColWidths[1] := 1000;
+  //
+  value_viewer.Font.Charset := AppSettings.CharSet;
+  //
+end;
+
+
+
+
+function TForm_RawEdit.Save: Boolean;
+var
+  mem:  TMemoryStream;
+  Data: Tdata;
+  i:    LongWord;
+begin
+  case MessageBox(Self.Handle, PChar('Save changes to .raw-part of file ' +
+      Connection.GetFileInfo(fileid).FileName + '?'), PChar('Data changed...'),
+      MB_YESNOCANCEL) of
+    idYes:
+    begin
+      mem := TMemoryStream.Create;
+      hex.SaveToStream(mem);
+      mem.Seek(0, soFromBeginning);
+      SetLength(Data, mem.Size);
+      mem.Read(Data[0], mem.Size);
+      mem.Free;
+      Connection.UpdateRawFile(fileid_opened, dat_offset_opened,
+        Length(Data), @Data[0]);
+      hex.Modified := False;
+      for i := 0 to hex.Datasize - 1 do
+        hex.ByteChanged[i] := False;
+      Result := True;
+    end;
+    idNo:
+      Result := True;
+    idCancel:
+    begin
+      Result := False;
+    end;
+  end;
+end;
+
+
+
+
+procedure TForm_RawEdit.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
+begin
+  if hex.Modified then
+  begin
+    if not Save then
+      CanClose := False;
+  end;
+end;
+
+
+
+
+procedure TForm_RawEdit.hexChange(Sender: TObject);
+begin
+  ClearValues;
+  if hex.DataSize > 0 then
+  begin
+{      WriteStructureInfos(GetStructureInfoId(GetFileInfo(fileid).Extension));
+      WriteValues;
+}    end;
+end;
+
+
+
+
+procedure TForm_RawEdit.hexKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
+//var
+//  temps: String;
+begin
+  if (Shift = [ssCtrl]) and (Key = Ord('C')) then
+  begin
+    if hex.SelCount > 0 then
+    begin
+      if hex.InCharField then
+        Clipboard.AsText := hex.SelectionAsText
+      else
+        Clipboard.AsText := hex.SelectionAsHex;
+    end;
+  end;
+  if (Shift = [ssCtrl]) and (Key = Ord('V')) then
+  begin
+{      temps:=Clipboard.AsText;
+      IF hex.SelStart+Length(temps)>hex.DataSize THEN
+        SetLength(temps, hex.DataSize-hex.SelStart);
+      hex.Sel
+      hex.SelCount:=Length(temps);
+      hex.ReplaceSelection(temps,Length(temps));
+}    end;
+end;
+
+
+
+
+procedure TForm_RawEdit.hexSelectionChanged(Sender: TObject);
+//var
+//  selstart: Integer;
+//  i, j:     Word;
+begin
+{    FOR i:=1 TO structs.RowCount-1 DO BEGIN
+      FOR j:=0 TO structs.ColCount-1 DO BEGIN
+        structs.CellColors[j,i]:=clWhite;
+        structs.CellFontColors[j,i]:=clBlack;
+      END;
+    END;
+}    if hex.DataSize > 0 then
+  begin
+{      selstart:=hex.SelStart;
+      IF GetStructureInfoId(GetFileInfo(fileid).Extension)>=0 THEN BEGIN
+        WITH structure_infos[GetStructureInfoId(GetFileInfo(fileid).Extension)] DO BEGIN
+          FOR i:=0 TO High(entries) DO BEGIN
+            IF ((selstart-entries[i].offset)<GetTypeDataLength(entries[i].datatype)) AND ((selstart-entries[i].offset)>=0) THEN BEGIN
+              FOR j:=0 TO structs.ColCount-1 DO BEGIN
+                structs.CellColors[j,i+1]:=clBlue;
+                structs.CellFontColors[j,i+1]:=clWhite;
+              END;
+              structs.Row:=i+1;
+            END;
+          END;
+        END;
+      END;
+}      WriteValues;
+  end;
+end;
+
+
+
+
+
+procedure TForm_RawEdit.btn_exportClick(Sender: TObject);
+var
+  fs: TFileStream;
+begin
+  saved.Filter     := 'Files of matching extension (*.' + Connection.GetFileInfo(
+    fileid).Extension + ')|*.' + Connection.GetFileInfo(fileid).Extension +
+    '|All files|*.*';
+  saved.DefaultExt := Connection.GetFileInfo(fileid).Extension;
+  if saved.Execute then
+  begin
+    fs := TFileStream.Create(saved.FileName, fmCreate);
+    hex.SaveToStream(fs);
+    fs.Free;
+  end;
+end;
+
+
+
+
+procedure TForm_RawEdit.btn_importClick(Sender: TObject);
+var
+//  Data: Tdata;
+  fs:   TFileStream;
+begin
+  opend.Filter := 'Files of matching extension (*.' + Connection.GetFileInfo(
+    fileid).Extension + ')|*.' + Connection.GetFileInfo(fileid).Extension +
+    '|All files|*.*';
+  if opend.Execute then
+  begin
+    fs := TFileStream.Create(opend.FileName, fmOpenRead);
+    if fs.Size <> hex.DataSize then
+    begin
+      ShowMessage('Can''t import ' + ExtractFilename(opend.FileName) +
+        ', file has to have same size as file in .dat.' + CrLf +
+        'Size of file in .dat: ' + FormatFileSize(hex.datasize) + CrLf +
+        'Size of chosen file: ' + FormatFileSize(fs.Size));
+    end
+    else
+    begin
+      hex.LoadFromStream(fs);
+      hex.Modified := True;
+    end;
+    fs.Free;
+  end;
+end;
+
+
+
+
+procedure TForm_RawEdit.value_viewer_contextPopup(Sender: TObject);
+var
+  i: Byte;
+begin
+  for i := 0 to value_viewer_context.Items.Count - 1 do
+    value_viewer_context.Items.Items[i].Visible := False;
+  with value_viewer do
+  begin
+    if (Col = 1) and (Row > 0) and (Length(Cells[Col, Row]) > 0) then
+    begin
+      if Pos(' byte', Cells[0, Row]) = 2 then
+      begin
+        value_viewer_context.Items.Find('Copy to &clipboard').Visible := True;
+        value_viewer_context.Items.Find('Copy to clipboard (as &dec)').Visible := True;
+        value_viewer_context.Items.Find('Copy to clipboard (as &hex)').Visible := True;
+      end;
+      if Pos('Float', Cells[0, Row]) = 1 then
+        value_viewer_context.Items.Find('Copy to clipboard (as &float)').Visible := True;
+      if Pos('Bitset', Cells[0, Row]) = 1 then
+        value_viewer_context.Items.Find(
+          'Copy to clipboard (as &bitset)').Visible := True;
+      if Pos('String', Cells[0, Row]) = 1 then
+        value_viewer_context.Items.Find(
+          'Copy to clipboard (as &string)').Visible := True;
+      if Pos('Selected length', Cells[0, Row]) = 1 then
+        value_viewer_context.Items.Find('Copy to &clipboard').Visible := True;
+    end;
+  end;
+end;
+
+
+
+
+procedure TForm_RawEdit.value_viewerMouseDown(Sender: TObject; Button: TMouseButton;
+  Shift: TShiftState; X, Y: Integer);
+var
+  ACol, ARow: Integer;
+begin
+  if Button = mbRight then
+  begin
+    value_viewer.MouseToCell(x, y, ACol, ARow);
+    if ARow > 0 then
+    begin
+      value_viewer.Col := ACol;
+      value_viewer.Row := ARow;
+    end;
+  end;
+end;
+
+
+
+
+procedure TForm_RawEdit.value_viewer_context_copyClick(Sender: TObject);
+var
+//  i:     Byte;
+  Name:  String;
+  Value: LongWord;
+begin
+  Name := TMenuItem(Sender).Name;
+  if Pos('asstring', Name) > 0 then
+  begin
+    Clipboard.AsText := value_viewer.Cells[value_viewer.Col, value_viewer.Row];
+  end
+  else if Pos('asfloat', Name) > 0 then
+  begin
+    Clipboard.AsText := value_viewer.Cells[value_viewer.Col, value_viewer.Row];
+  end
+  else if Pos('asbitset', Name) > 0 then
+  begin
+    Clipboard.AsText := value_viewer.Cells[value_viewer.Col, value_viewer.Row];
+  end
+  else if (Pos('ashex', Name) > 0) or (Pos('asdec', Name) > 0) then
+  begin
+    if value_viewer.Cells[0, value_viewer.Row] = '1 byte, unsigned' then
+    begin
+      if ((hex.SelCount = 1) or (hex.SelCount = 0)) and not
+        ((hex.SelStart + 1) > hex.DataSize) then
+        Value := hex.Data[hex.SelStart];
+    end;
+    if value_viewer.Cells[0, value_viewer.Row] = '2 bytes, unsigned' then
+    begin
+      if ((hex.SelCount = 2) or (hex.SelCount = 0)) and not
+        ((hex.SelStart + 2) > hex.DataSize) then
+        Value := hex.Data[hex.SelStart] + hex.Data[hex.SelStart + 1] * 256;
+    end;
+    if value_viewer.Cells[0, value_viewer.Row] = '4 bytes, unsigned' then
+    begin
+      if ((hex.SelCount = 4) or (hex.SelCount = 0)) and not
+        ((hex.SelStart + 4) > hex.DataSize) then
+        Value := hex.Data[hex.SelStart] + hex.Data[hex.SelStart + 1] * 256 +
+          hex.Data[hex.SelStart + 2] * 256 * 256 + hex.Data[hex.SelStart + 3] * 256 * 256 * 256;
+    end;
+    if Pos('asdec', Name) > 0 then
+    begin
+      Clipboard.AsText := IntToStr(Value);
+    end
+    else
+    begin
+      if value_viewer.Cells[0, value_viewer.Row] = '1 byte, unsigned' then
+        Clipboard.AsText := '0x' + IntToHex(Value, 2);
+      if value_viewer.Cells[0, value_viewer.Row] = '2 bytes, unsigned' then
+        Clipboard.AsText := '0x' + IntToHex(Value, 4);
+      if value_viewer.Cells[0, value_viewer.Row] = '4 bytes, unsigned' then
+        Clipboard.AsText := '0x' + IntToHex(Value, 8);
+    end;
+  end
+  else
+  begin
+    Clipboard.AsText := value_viewer.Cells[value_viewer.Col, value_viewer.Row];
+  end;
+end;
+
+
+
+
+procedure TForm_RawEdit.SetNewValue(datatype: Word; offset: LongWord; Value: String);
+var
+  Data: Tdata;
+  value_int: LongWord;
+  value_float: Single;
+  i: Word;
+begin
+  case datatype of
+    1..4:
+    begin
+      value_int := StrToInt(Value);
+      SetLength(Data, datatype);
+      for i := 0 to datatype - 1 do
+      begin
+        Data[i]   := value_int mod 256;
+        value_int := value_int div 256;
+      end;
+    end;
+    5..8:
+    begin
+      value_int := StrToInt('$' + Value);
+      SetLength(Data, datatype - 4);
+      for i := 0 to datatype - 5 do
+      begin
+        Data[i]   := value_int mod 256;
+        value_int := value_int div 256;
+      end;
+    end;
+    9:
+    begin
+      value_float := StrToFloat(Value);
+      Data := Encode_Float(value_float);
+    end;
+    10:
+    begin
+      value_int := BinToInt(Value);
+      SetLength(Data, 1);
+      Data[0] := value_int;
+    end;
+    10000..65535:
+    begin
+      SetLength(Data, datatype - 10000);
+      for i := 1 to datatype - 10000 do
+      begin
+        if i <= Length(Value) then
+          Data[i - 1] := Ord(Value[i])
+        else
+          Data[i - 1] := 0;
+      end;
+    end;
+  end;
+  for i := 0 to High(Data) do
+  begin
+    if hex.Data[offset + i] <> Data[i] then
+      hex.ByteChanged[offset + i] := True;
+    hex.Data[offset + i] := Data[i];
+  end;
+  hex.Modified := True;
+  hexChange(Self);
+  hex.Repaint;
+end;
+
+
+
+
+procedure TForm_RawEdit.value_viewerDblClick(Sender: TObject);
+var
+  offset:     LongWord;
+  datatype:   Word;
+  objectname: String;
+  Value:      String;
+begin
+  if (value_viewer.Col = 1) and (Length(value_viewer.Cells[1, value_viewer.Row]) > 0) then
+  begin
+    offset := hex.SelStart;
+    if value_viewer.Cells[0, value_viewer.Row] = '1 byte, unsigned' then
+      datatype := 1;
+    if value_viewer.Cells[0, value_viewer.Row] = '2 bytes, unsigned' then
+      datatype := 2;
+    if value_viewer.Cells[0, value_viewer.Row] = '4 bytes, unsigned' then
+      datatype := 4;
+    if value_viewer.Cells[0, value_viewer.Row] = 'Bitset' then
+      datatype := 10;
+    if value_viewer.Cells[0, value_viewer.Row] = 'Float' then
+      datatype := 9;
+    if value_viewer.Cells[0, value_viewer.Row] = 'Selected length' then
+      Exit;
+    if value_viewer.Cells[0, value_viewer.Row] = 'String' then
+    begin
+      if hex.SelCount > 0 then
+        datatype := 10000 + hex.SelCount
+      else
+        datatype := 10000 + Length(value_viewer.Cells[1, value_viewer.Row]);
+    end;
+    objectname := '';
+    Value      := GetValue(datatype, offset);
+    Form_ValueEdit.MakeVarInput(objectname, offset, datatype, Value, Self);
+  end;
+end;
+
+
+
+
+procedure TForm_RawEdit.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
+begin
+  if (Shift = [ssCtrl]) and (Key = 83) then
+    if hex.Modified then
+      if not Save then
+        Exit;
+end;
+
+begin
+  AddToolListEntry('rawedit', 'Binary .raw-Editor', '');
+end.
