Index: oup/current/Code/DataStructures.pas
===================================================================
--- oup/current/Code/DataStructures.pas	(revision 46)
+++ oup/current/Code/DataStructures.pas	(revision 46)
@@ -0,0 +1,605 @@
+unit DataStructures;
+
+interface
+
+uses SysUtils, Classes, Data, Dialogs, StrUtils;
+
+type
+  Tstructure_entry = record
+    Name:     String;
+    offset:   LongWord;
+    datatype: Word;  // 1..4  : Integer[1..4] dec
+    // 5..8  : Integer[1..4] hex
+    // 9     : float
+    // 10    : bitset
+    // 11    : raw-addr
+    // 12    : dat-file-ID
+    // 13..16: Signed Integer[1..4]
+    // 17    : level-ID
+    // 100..300: dat-file-name[0..200]
+    // 1000..9999: Unused data[0-8999]
+    // 10000+: string[0+]
+    description: String;
+  end;
+
+  TStructDefSub = record
+    SubName: String;
+    SubDesc: String;
+    Entries: array of TStructure_entry;
+  end;
+
+  TStructDef = record
+    Data:   Boolean;
+    Global: array of TStructure_entry;
+    Subs:   array of TStructDefSub;
+  end;
+  THandler = function(fileid: LongWord): TRawList;
+
+  TRawListHandlers = record
+    Ext:     String[4];
+    needed:  Boolean;
+    Handler: THandler;
+  end;
+
+var
+  RawListHandlers: array of TRawListHandlers;
+  Raws: String;
+
+
+function LoadStructureDefinition(fileid: LongWord): TStructDef;
+function GetDataType(typeid: Word): String;
+function GetTypeDataLength(datatype: Word): Word;
+
+implementation
+
+uses Functions, OniDataClass, Forms, Template;
+
+
+
+
+function GetTypeDataLength(datatype: Word): Word;
+begin
+  case datatype of
+    1..4:
+      Result := datatype;
+    5..8:
+      Result := datatype - 4;
+    9:
+      Result := 4;
+    10:
+      Result := 1;
+    11:
+      Result := 4;
+    12:
+      Result := 4;
+    13..16:
+      Result := datatype - 12;
+    17:
+      Result := 4;
+    100..300:
+      Result := datatype - 100;
+    1000..9999:
+      Result := datatype - 1000;
+    10000..65535:
+      Result := datatype - 10000;
+  end;
+end;
+
+
+
+
+function GetDataType(typeid: Word): String;
+begin
+  case typeid of
+    1..4:
+      Result := 'Int' + IntToStr(typeid * 8);
+    5..8:
+      Result := 'Int' + IntToStr((typeid - 4) * 8);
+    9:
+      Result := 'Float';
+    10:
+      Result := 'BitSet';
+    11:
+      Result := 'Raw-Address';
+    12:
+      Result := '.dat-file-ID';
+    13..16:
+      Result := 'SignedInt' + IntToStr((typeid - 12) * 8);
+    17:
+      Result := 'LevelID';
+    100..300:
+      Result := '.dat-file-name(' + IntToStr(typeid - 100) + ')';
+    1000..9999:
+      Result := 'Unused(' + IntToStr(typeid - 1000) + ')';
+    10000..65535:
+      Result := 'String(' + IntToStr(typeid - 10000) + ')';
+  end;
+end;
+
+
+
+
+function AGDB(fileid: LongWord): TRawList;
+var
+  link:  LongWord;
+  links: LongWord;
+  i:     LongWord;
+begin
+  if not OniDataConnection.OSisMac then
+  begin
+    OniDataConnection.LoadDatFilePart(fileid, $1C, 4, @links);
+    links := links * 2;
+    SetLength(Result, links);
+    for i := 0 to links - 1 do
+    begin
+      Result[i].src_offset := $20 + i * 4;
+      OniDataConnection.LoadDatFilePart(fileid, $20 + i * 4, 4, @link);
+      Result[i].raw_addr := link;
+      Result[i].raw_size := 0{????????????????????????????????};
+      Result[i].loc_sep  := False;
+    end;
+  end;
+end;
+
+
+
+
+function AKVA(fileid: LongWord): TRawList;
+var
+  link:  LongWord;
+  links: LongWord;
+  i:     LongWord;
+begin
+  if not OniDataConnection.OSisMac then
+  begin
+    OniDataConnection.LoadDatFilePart(fileid, $1C, 4, @links);
+    SetLength(Result, links);
+    for i := 0 to links - 1 do
+    begin
+      Result[i].src_offset := $20 + i * $74 + $24;
+      OniDataConnection.LoadDatFilePart(fileid, $20 + i * $74 + $24, 4, @link);
+      Result[i].raw_addr := link;
+      OniDataConnection.LoadDatFilePart(fileid, $20 + i * $74 + $28, 4, @link);
+      Result[i].raw_size := link;
+      Result[i].loc_sep  := False;
+    end;
+  end;
+end;
+
+
+
+
+function BINA(fileid: LongWord): TRawList;
+var
+  link:     LongWord;
+  datasize: LongWord;
+begin
+  OniDataConnection.LoadDatFilePart(fileid, $0C, 4, @link);
+  OniDataConnection.LoadDatFilePart(fileid, $08, 4, @datasize);
+  SetLength(Result, 1);
+  Result[0].src_offset := $0C;
+  Result[0].raw_addr   := link;
+  Result[0].raw_size   := datasize;
+  Result[0].loc_sep    := OniDataConnection.OSisMac;
+end;
+
+
+
+
+function OSBD(fileid: LongWord): TRawList;
+var
+  link:     LongWord;
+  datasize: LongWord;
+begin
+  OniDataConnection.LoadDatFilePart(fileid, $08, 4, @datasize);
+  OniDataConnection.LoadDatFilePart(fileid, $0C, 4, @link);
+  SetLength(Result, 1);
+  Result[0].src_offset := $0C;
+  Result[0].raw_addr   := link;
+  Result[0].raw_size   := datasize;
+  Result[0].loc_sep    := OniDataConnection.OSisMac;
+end;
+
+
+
+
+function SNDD(fileid: LongWord): TRawList;
+var
+  link:     LongWord;
+  datasize: LongWord;
+begin
+  SetLength(Result, 1);
+  if not OniDataConnection.OSisMac then
+  begin
+    OniDataConnection.LoadDatFilePart(fileid, $40, 4, @datasize);
+    OniDataConnection.LoadDatFilePart(fileid, $44, 4, @link);
+    Result[0].src_offset := $44;
+  end
+  else
+  begin
+    OniDataConnection.LoadDatFilePart(fileid, $10, 4, @datasize);
+    OniDataConnection.LoadDatFilePart(fileid, $14, 4, @link);
+    Result[0].src_offset := $14;
+  end;
+  Result[0].raw_addr := link;
+  Result[0].raw_size := datasize;
+  Result[0].loc_sep  := False;
+end;
+
+
+
+
+function SUBT(fileid: LongWord): TRawList;
+var
+  baselink, lastlink: LongWord;
+  links: LongWord;
+  j, k:  LongWord;
+  Data:  Tdata;
+begin
+  OniDataConnection.LoadDatFilePart(fileid, $18, 4, @baselink);
+  OniDataConnection.LoadDatFilePart(fileid, $1C, 4, @links);
+  if links > 0 then
+  begin
+    OniDataConnection.LoadDatFilePart(fileid, $20 + (links - 1) * 4, 4, @lastlink);
+    SetLength(Data, lastlink + 1024);
+    TOniDataDat(OniDataConnection).LoadRawOffset(False,
+      baselink, lastlink + 1024, Data);
+    //      OniDataConnection.LoadRawFile(fileid,$1C,baselink,lastlink+1024,False,@data[0]);
+    k := 0;
+    for j := 0 to 1024 do
+    begin
+      if (Data[lastlink + j] = $00) or (j = 1024) then
+      begin
+        if j < 1024 then
+        begin
+          if k = 0 then
+          begin
+            k := 1;
+          end
+          else
+          begin
+            SetLength(Result, 1);
+            Result[0].src_offset := $18;
+            Result[0].raw_addr   := baselink;
+            Result[0].raw_size   := lastlink + j;
+            Break;
+          end;
+        end;
+      end;
+    end;
+  end;
+end;
+
+
+
+
+function TRAM(fileid: LongWord): TRawList;
+var
+  i:      Integer;
+  link:   LongWord;
+  frames: Word;
+  tempb:  Byte;
+  tempw:  Word;
+  templ:  LongWord;
+  Data:   Tdata;
+  offset: Word;
+  frame_count: Byte;
+begin
+  SetLength(Result, 13);
+  OniDataConnection.LoadDatFilePart(fileid, $16C, 2, @frames);
+  {y-pos}
+  OniDataConnection.LoadDatFilePart(fileid, $0C, 4, @link);
+  Result[0].src_offset := $0C;
+  Result[0].raw_addr   := link;
+  Result[0].raw_size   := frames * 4;
+  {x-z-pos}
+  OniDataConnection.LoadDatFilePart(fileid, $10, 4, @link);
+  Result[1].src_offset := $10;
+  Result[1].raw_addr   := link;
+  Result[1].raw_size   := frames * 8;
+  {attacks}
+  OniDataConnection.LoadDatFilePart(fileid, $182, 1, @tempb);
+  OniDataConnection.LoadDatFilePart(fileid, $14, 4, @link);
+  Result[2].src_offset := $14;
+  Result[2].raw_addr   := link;
+  Result[2].raw_size   := tempb * 32;
+  {damage}
+  OniDataConnection.LoadDatFilePart(fileid, $183, 1, @tempb);
+  OniDataConnection.LoadDatFilePart(fileid, $18, 4, @link);
+  Result[3].src_offset := $18;
+  Result[3].raw_addr   := link;
+  Result[3].raw_size   := tempb * 8;
+  {motionblur}
+  OniDataConnection.LoadDatFilePart(fileid, $184, 1, @tempb);
+  OniDataConnection.LoadDatFilePart(fileid, $1C, 4, @link);
+  Result[4].src_offset := $1C;
+  Result[4].raw_addr   := link;
+  Result[4].raw_size   := tempb * 8;
+  {shortcut}
+  OniDataConnection.LoadDatFilePart(fileid, $185, 1, @tempb);
+  OniDataConnection.LoadDatFilePart(fileid, $20, 4, @link);
+  Result[5].src_offset := $20;
+  Result[5].raw_addr   := link;
+  Result[5].raw_size   := tempb * 8;
+  {throw}
+  OniDataConnection.LoadDatFilePart(fileid, $24, 4, @link);
+  Result[6].src_offset := $24;
+  Result[6].raw_addr   := link;
+  if link > 0 then
+    Result[6].raw_size := 24
+  else
+    Result[6].raw_size := 0;
+  {footstep}
+  OniDataConnection.LoadDatFilePart(fileid, $186, 1, @tempb);
+  OniDataConnection.LoadDatFilePart(fileid, $28, 4, @link);
+  Result[7].src_offset := $28;
+  Result[7].raw_addr   := link;
+  Result[7].raw_size   := tempb * 4;
+  {particle}
+  OniDataConnection.LoadDatFilePart(fileid, $187, 1, @tempb);
+  OniDataConnection.LoadDatFilePart(fileid, $2C, 4, @link);
+  Result[8].src_offset := $2C;
+  Result[8].raw_addr   := link;
+  Result[8].raw_size   := tempb * 24;
+  {position}
+  OniDataConnection.LoadDatFilePart(fileid, $30, 4, @link);
+  Result[9].src_offset := $30;
+  Result[9].raw_addr   := link;
+  Result[9].raw_size   := frames * 8;
+  {particle}
+  OniDataConnection.LoadDatFilePart(fileid, $154, 2, @tempw);
+  OniDataConnection.LoadDatFilePart(fileid, $38, 4, @link);
+  Result[11].src_offset := $38;
+  Result[11].raw_addr   := link;
+  Result[11].raw_size   := tempw * 34;
+  {extent}
+  OniDataConnection.LoadDatFilePart(fileid, $138, 4, @templ);
+  OniDataConnection.LoadDatFilePart(fileid, $13C, 4, @link);
+  Result[12].src_offset := $13C;
+  Result[12].raw_addr   := link;
+  Result[12].raw_size   := templ * 12;
+
+  OniDataConnection.LoadDatFilePart(fileid, $34, 4, @link);
+  if link > 0 then
+  begin
+    OniDataConnection.LoadDatFilePart(fileid, $160, 2, @tempw);
+    frame_count := 0;
+    i := 0;
+    SetLength(Data, $FFFF);
+    TOniDataDat(OniDataConnection).LoadRawOffset(False, link, $FFFF, Data);
+    offset := Data[$24] + Data[$25] * 256;
+    while (offset + i < Length(Data)) and (frame_count < frames - 1) do
+    begin
+      Inc(i, tempw);
+      frame_count := frame_count + Data[offset + i];
+      Inc(i);
+    end;
+    if offset + i < Length(Data) then
+    begin
+      Inc(i, tempw);
+      Result[10].raw_size := offset + i;
+    end
+    else
+    begin
+      Result[10].raw_size := 0;
+    end;
+  end;
+  Result[10].src_offset := $34;
+  Result[10].raw_addr   := link;
+end;
+
+
+
+
+function TXMP(fileid: LongWord): TRawList;
+var
+  link_pc:   LongWord;
+  link_mac:  LongWord;
+  x, y:      Word;
+  storetype: Byte;
+  datasize:  LongWord;
+begin
+  OniDataConnection.LoadDatFilePart(fileid, $8C, SizeOf(x), @x);
+  OniDataConnection.LoadDatFilePart(fileid, $8E, SizeOf(y), @y);
+  OniDataConnection.LoadDatFilePart(fileid, $90, SizeOf(storetype), @storetype);
+  OniDataConnection.LoadDatFilePart(fileid, $9C, 4, @link_pc);
+  OniDataConnection.LoadDatFilePart(fileid, $A0, 4, @link_mac);
+  case storetype of
+    0, 1, 2:
+      datasize := x * y * 2;
+    8:
+      datasize := x * y * 4;
+    9:
+      datasize := x * y div 2;
+  end;
+  SetLength(Result, 1);
+  if not OniDataConnection.OSisMac then
+  begin
+    Result[0].src_offset := $9C;
+    Result[0].raw_addr   := link_pc;
+  end
+  else
+  begin
+    Result[0].src_offset := $A0;
+    Result[0].raw_addr   := link_mac;
+  end;
+  Result[0].raw_size := datasize;
+  Result[0].loc_sep  := OniDataConnection.OSisMac;
+end;
+
+
+
+
+procedure InsertRawListHandler(ext: String; needed: Boolean; handler: THandler);
+begin
+  SetLength(RawListHandlers, Length(RawListHandlers) + 1);
+  RawListHandlers[High(RawListHandlers)].Ext := ext;
+  RawListHandlers[High(RawListHandlers)].needed := needed;
+  RawListHandlers[High(RawListHandlers)].handler := handler;
+  Raws := Raws + ext;
+  AddToolListEntry('rawedit', '', ext);
+end;
+
+
+
+
+function LoadStructureDefinition(fileid: LongWord): TStructDef;
+var
+  i:      LongWord;
+  current_type: Byte; //0: Global, 1: Undynamic, 2: Dynamic
+  current_base, current_package, current_package_size: LongWord;
+  packages: LongWord;
+  deffile: Text;
+  structentry: TStructure_Entry;
+  fields: TStringArray;
+  filename: String;
+  ext:    String[4];
+  temps:  String;
+  Data:   TData;
+begin
+  SetLength(Result.Global, 0);
+  SetLength(Result.Subs, 0);
+  Result.Data := False;
+  ext      := OniDataConnection.GetFileInfo(fileid).Extension;
+  filename := ExtractFilePath(Application.ExeName) + '\StructDefs\' + ext + '.txt';
+  if FileExists(filename) then
+  begin
+    Data := OniDataConnection.LoadDatFile(fileid);
+    AssignFile(deffile, filename);
+    Reset(deffile);
+    current_type := 0;
+    Result.Data  := True;
+    if not EOF(deffile) then
+    begin
+      ReadLn(deffile, temps);
+      while not EOF(deffile) do
+      begin
+        ReadLn(deffile, temps);
+        if (Length(temps) > 0) and (temps[1] <> '#') then
+        begin
+          if temps[1] = '*' then
+          begin
+            fields := Explode(temps, #9);
+            case Length(fields) of
+              1..2:
+              begin
+                current_type := 1;
+                current_base := 0;
+                SetLength(Result.Subs, Length(Result.Subs) + 1);
+                Result.Subs[High(Result.Subs)].SubName :=
+                  MidStr(fields[0], 2, Length(fields[0]) - 1);
+                if Length(fields) = 2 then
+                  Result.Subs[High(Result.Subs)].SubDesc := fields[1];
+              end;
+              3:
+              begin
+                current_type := 1;
+                current_base := HexToLong(fields[2]);
+                SetLength(Result.Subs, Length(Result.Subs) + 1);
+                Result.Subs[High(Result.Subs)].SubName :=
+                  MidStr(fields[0], 2, Length(fields[0]) - 1);
+                Result.Subs[High(Result.Subs)].SubDesc := fields[1];
+              end;
+              6:
+              begin
+                current_type    := 2;
+                current_base    := HexToLong(fields[2]);
+                current_package := 0;
+                current_package_size := StrToInt(fields[5]);
+                if fields[4][1] <> '$' then
+                begin
+                  case StrToInt(fields[4]) of
+                    1:
+                      packages := Data[HexToLong(fields[3])];
+                    2:
+                      packages := Data[HexToLong(fields[3])] + Data[HexToLong(fields[3]) + 1] * 256;
+                    4:
+                      packages := Data[HexToLong(fields[3])] + Data[HexToLong(fields[3]) + 1] *
+                        256 + Data[HexToLong(fields[3]) + 2] * 256 * 256 + Data[HexToLong(fields[3]) + 3] * 256 * 256 * 256;
+                  end;
+                end
+                else
+                begin
+                  packages := HexToLong(fields[4]);
+                end;
+                SetLength(Result.Subs, Length(Result.Subs) + packages);
+                for current_package := 0 to packages - 1 do
+                begin
+                  Result.Subs[High(Result.Subs) - packages +
+                    current_package + 1].SubName :=
+                    MidStr(fields[0], 2, Length(fields[0]) - 1) +
+                    '[' + IntToStr(current_package) + ']' + '#' +
+                    IntToHex(current_base + current_package * current_package_size, 8) +
+                    '#' + IntToHex(current_package_size, 8);
+                  Result.Subs[High(Result.Subs) - packages +
+                    current_package + 1].SubDesc :=
+                    fields[1];
+                end;
+              end;
+            end;
+          end
+          else
+          begin
+            fields := Explode(temps, #9);
+            if (Length(fields) = 3) or (Length(fields) = 4) then
+            begin
+              if not AppSettings.HideUnusedData or
+                ((StrToInt(fields[2]) < 1000) or (StrToInt(fields[2]) > 9999)) then
+              begin
+                structentry.Name     := fields[0];
+                structentry.datatype := StrToInt(fields[2]);
+                if Length(fields) = 4 then
+                  structentry.description := fields[3]
+                else
+                  structentry.description := '';
+                if current_type in [0, 1] then
+                begin
+                  structentry.offset := HexToLong(fields[1]) + current_base;
+                  if Length(Result.Subs) = 0 then
+                  begin
+                    SetLength(Result.Global, Length(Result.Global) + 1);
+                    Result.Global[High(Result.Global)] := structentry;
+                  end
+                  else
+                  begin
+                    SetLength(Result.Subs[High(Result.Subs)].Entries,
+                      Length(Result.Subs[High(Result.Subs)].Entries) + 1);
+                    Result.Subs[High(Result.Subs)].Entries[High(
+                      Result.Subs[High(Result.Subs)].Entries)] := structentry;
+                  end;
+                end
+                else
+                begin
+                  for current_package := 0 to packages - 1 do
+                  begin
+                    structentry.offset :=
+                      current_base + current_package * current_package_size + HexToLong(fields[1]);
+                    with Result.Subs[High(Result.Subs) - packages + current_package + 1] do
+                    begin
+                      SetLength(Entries, Length(Entries) + 1);
+                      Entries[High(Entries)] := structentry;
+                    end;
+                  end;
+                end;
+              end;
+            end;
+          end;
+        end;
+      end;
+    end;
+    CloseFile(deffile);
+  end;
+end;
+
+
+begin
+  Raws := '';
+  //  InsertRawListHandler('AGDB',True,AGDB);
+  InsertRawListHandler('AKVA', True, AKVA);
+  InsertRawListHandler('BINA', True, BINA);
+  InsertRawListHandler('OSBD', True, OSBD);
+  InsertRawListHandler('SNDD', True, SNDD);
+  InsertRawListHandler('SUBT', True, SUBT);
+  InsertRawListHandler('TRAM', True, TRAM);
+  InsertRawListHandler('TXMP', True, TXMP);
+end.
Index: oup/current/Code/Exporters.pas
===================================================================
--- oup/current/Code/Exporters.pas	(revision 46)
+++ oup/current/Code/Exporters.pas	(revision 46)
@@ -0,0 +1,256 @@
+unit Exporters;
+
+interface
+
+uses Classes, Dialogs, StrUtils, SysUtils, Math, Data, OniImgClass;
+
+procedure ExportDatFile(fileid: LongWord; filename: String);
+procedure ExportRawFile(fileid: LongWord; dat_offset: LongWord; filename: String);
+
+function ExportSNDD(fileid: LongWord; filename: String; convert: Boolean): Integer;
+function ExportTRAC(fileid: LongWord; filename: String; convert: Boolean): Integer;
+function ExportTXAN(fileid: LongWord; filename: String; convert: Boolean): Integer;
+function ExportTXMB(fileid: LongWord; filename: String; convert: Boolean): Integer;
+function ExportTXMP(fileid: LongWord; filename: String; convert: Boolean): Integer;
+
+var
+  ExportHandlers: array[1..1] of TExportHandlers = (
+    //    (Ext:'ABNA'; needed:False),
+    //(Ext:'AGDB'; needed:False),
+    (Ext: 'SNDD'; needed: True; Handler: ExportSNDD)
+{    (Ext:'TRAC'; needed:True; Handler:ExportTRAC),
+    (Ext:'TXAN'; needed:True; Handler:ExportTXAN),
+    (Ext:'TXMB'; needed:True; Handler:ExportTXMB),
+    (Ext:'TXMP'; needed:True; Handler:ExportTXMP)
+});
+
+
+
+implementation
+
+uses Functions, DataStructures, OniDataClass;
+
+
+
+
+procedure ExportDatFile(fileid: LongWord; filename: String);
+var
+  filestream: TFileStream;
+  Data: Tdata;
+begin
+  Data := OniDataConnection.LoadDatFile(fileid);
+  if FileExists(filename) then
+  begin
+    filestream := TFileStream.Create(filename, fmOpenReadWrite);
+    filestream.Seek(0, soFromEnd);
+  end
+  else
+  begin
+    filestream := TFileStream.Create(filename, fmCreate);
+  end;
+  filestream.Write(Data[0], Length(Data));
+  filestream.Free;
+end;
+
+
+
+
+procedure ExportRawFile(fileid: LongWord; dat_offset: LongWord; filename: String);
+var
+  filestream: TFileStream;
+  Data: Tdata;
+begin
+  SetLength(Data, OniDataConnection.GetRawInfo(fileid, dat_offset).raw_size);
+  OniDataConnection.LoadRawFile(fileid, dat_offset, @Data[0]);
+  if FileExists(filename + '.raw0x' + IntToHex(dat_offset, 8)) then
+  begin
+    filestream := TFileStream.Create(filename + '.raw0x' + IntToHex(
+      dat_offset, 8), fmOpenReadWrite);
+    filestream.Seek(0, soFromEnd);
+  end
+  else
+  begin
+    filestream := TFileStream.Create(filename + '.raw0x' + IntToHex(dat_offset, 8), fmCreate);
+  end;
+  filestream.Write(Data[0], Length(Data));
+  filestream.Free;
+end;
+
+
+
+
+function ExportSNDD;
+{  CONST
+    WAVheader:Array[0..0] OF Byte=(
+        Ord('R'),Ord('I'),Ord('F'),Ord('F'),0,0,0,0,Ord('W'),Ord('A'),Ord('V'),Ord('E'),
+        Ord('f'),Ord('m'),Ord('t'),Ord(' '),24,0,0,0,
+      );
+}  type
+  TDatData = record
+    {0x00}
+    _fileid:   LongWord;
+    level:     LongWord;
+    Flag:      LongWord;
+    FormatTag: Word;
+    ChanNo:    Word;
+    {0x10}
+    SampleRate: LongWord;
+    BytesPSec: LongWord;
+    BPSample:  LongWord;
+    BitsPS:    LongWord;
+    {0x20}
+    Unknown:   array[1..7] of LongWord;
+    Unknown2:  Word;
+    {0x40}
+    RawSize:   LongWord;
+    RawPos:    LongWord;
+  end;
+var
+  filestream: TFileStream;
+
+  DatData:     TDatData;
+  //Wave Header Stuff
+  ASCII_Group: LongWord; //"RIFF"
+  WAV_Len:     LongWord;
+  ASCII_WAV:   LongWord; //"WAVE"
+  ASCII_FMT:   LongWord; //"fmt "
+  WAV_FMT_Len: LongWord;
+  ASCII_DATA:  LongWord; //"data"
+  WAV_FolLen:  LongWord;
+
+  Data: Tdata;
+begin
+  Result := export_noerror;
+  OniDataConnection.LoadDatFilePart(fileid, 0, SizeOf(DatData), @DatData);
+  with DatData do
+  begin
+    //Initializing Header vars
+    ASCII_Group := 1179011410; // 'RIFF'
+    WAV_Len     := RAWSize + 70;
+    ASCII_WAV   := 1163280727;  // 'WAVE'
+    ASCII_FMT   := 544501094;   // 'fmt '
+    WAV_FMT_Len := 50;          // 50 bytes
+    ASCII_DATA  := 1635017060;  // 'data'
+    WAV_FolLen  := RAWSize;
+    SetLength(Data, RAWSize);
+    OniDataConnection.LoadRawFile(fileid, $44, Data);
+
+    filestream := TFileStream.Create(filename + '.raw', fmCreate);
+    filestream.Write(Data[0], Length(Data));
+    filestream.Free;
+
+    if convert then
+    begin
+      //Now start packing this into a neat wave...
+      filestream := TFileStream.Create(filename + '.wav', fmCreate);
+      filestream.Write(ASCII_Group, SizeOf(ASCII_Group));
+      filestream.Write(WAV_Len, SizeOf(WAV_Len));
+      filestream.Write(ASCII_WAV, SizeOf(ASCII_WAV));
+      filestream.Write(ASCII_FMT, SizeOf(ASCII_FMT));
+      filestream.Write(WAV_FMT_Len, SizeOf(WAV_FMT_Len));
+      filestream.Write(ChanNo, SizeOf(ChanNo));
+      filestream.Write(Samplerate, SizeOf(Samplerate));
+      filestream.Write(BytesPSec, SizeOf(BytesPSec));
+      filestream.Write(BPSample, SizeOf(BPSample));
+      filestream.Write(BitsPS, SizeOf(BitsPS));
+      filestream.Write(Unknown[1], SizeOf(Unknown));
+      filestream.Write(Unknown2, SizeOf(Unknown2));
+      filestream.Write(ASCII_DATA, SizeOf(ASCII_DATA));
+      filestream.Write(WAV_FolLen, SizeOf(WAV_FolLen));
+      filestream.Write(Data[0], Length(Data));
+      filestream.Free;
+    end;
+  end;
+end;
+
+
+
+
+function ExportTRAC;
+var
+  link: LongWord;
+  linkcount: Word;
+  i: LongWord;
+begin
+  Result := export_noerror;
+
+  OniDataConnection.LoadDatFilePart(fileid, $18, SizeOf(link), @link);
+  link := link div 256;
+
+  OniDataConnection.LoadDatFilePart(fileid, $1E, SizeOf(linkcount), @linkcount);
+  for i := 1 to linkcount do
+  begin
+    OniDataConnection.LoadDatFilePart(fileid, $20 + (i - 1) * 12 + 8, SizeOf(link), @link);
+    link := link div 256;
+  end;
+end;
+
+
+
+
+function ExportTXAN;
+var
+  loop_speed, unknown: Word;
+  linkcount: LongWord;
+  link: LongWord;
+  i: Byte;
+begin
+  Result := export_noerror;
+
+  OniDataConnection.LoadDatFilePart(fileid, $14, SizeOf(loop_speed), @loop_speed);
+  OniDataConnection.LoadDatFilePart(fileid, $16, SizeOf(unknown), @unknown);
+
+  OniDataConnection.LoadDatFilePart(fileid, $1C, SizeOf(linkcount), @linkcount);
+  for i := 0 to linkcount - 1 do
+  begin
+    OniDataConnection.LoadDatFilePart(fileid, $20 + i * 4, SizeOf(link), @link);
+    link := link div 256;
+    if link = 0 then
+      link := fileid - 1;
+  end;
+end;
+
+
+
+
+function ExportTXMB;
+var
+  filestream: TFileStream;
+  //    img:TImgPackage;
+  Data: Tdata;
+begin
+  Result := export_noerror;
+  if convert then
+  begin
+{      img:=LoadTXMBconnected(fileid);
+      data:=ImgdataToBmp(img.imgx,img.imgy,img.imgdepth,img.storetype,img.imgdata);
+      filestream:=TFileStream.Create(filename+'.bmp',fmCreate);
+      filestream.Write(data[0],Length(data));
+      filestream.Free;
+}    end;
+end;
+
+
+
+
+function ExportTXMP;
+var
+  filestream: TFileStream;
+  //    img:TImgPackage;
+begin
+  Result := export_noerror;
+{    img:=LoadImgData(fileid);
+
+    filestream:=TFileStream.Create(filename+'.raw',fmCreate);
+    filestream.Write(img.imgdata[0],Length(img.imgdata));
+    filestream.Free;
+
+    IF convert THEN BEGIN
+      img.imgdata:=ImgdataToBMP(img.imgx,img.imgy,img.imgdepth,img.storetype,img.imgdata);
+      filestream:=TFileStream.Create(filename+'.bmp',fmCreate);
+      filestream.Write(img.imgdata[0],Length(img.imgdata));
+      filestream.Free;
+    END;
+}  end;
+
+end.
Index: oup/current/Code/Functions.pas
===================================================================
--- oup/current/Code/Functions.pas	(revision 46)
+++ oup/current/Code/Functions.pas	(revision 46)
@@ -0,0 +1,401 @@
+unit Functions;
+
+interface
+
+uses Classes, Dialogs, SysUtils, StrUtils, Math, Data;
+
+type
+  TExportSet = set of (DO_dat, DO_raw, DO_convert, DO_toone);
+
+function BoolToStr(bool: Boolean): String;
+function HexToLong(hex: String): LongWord;
+function Decode_Int(buffer: Tdata): LongWord;
+function Encode_Int(input: LongWord): Tdata;
+function Decode_Float(buffer: Tdata): Single;
+function Encode_Float(input: Single): Tdata;
+function DataToBin(Data: Tdata): String;
+function BinToInt(bin: String): Byte;
+
+function ExportFile(fileid: LongWord; filename: String; settings: TExportSet;
+  path: String): Integer;
+
+function StringSmaller(string1, string2: String): Boolean;
+
+function FormatNumber(Value: LongWord; Width: Byte; leadingzeros: Char): String;
+function FormatFileSize(size: LongWord): String;
+function CreateHexString(Data: Tdata; HexOnly: Boolean): String;
+function DecodeHexString(hex: String): Tdata;
+function GetWinFileName(Name: String): String;
+function GetExtractPath: String;
+
+function Explode(_string: String; delimiter: Char): TStringArray;
+
+
+implementation
+
+uses Exporters, OniDataClass;
+
+type
+  TValueSwitcher = record
+    case IsFloat: Boolean of
+      True: (ValueFloat: Single);
+      False: (ValueInt: LongWord);
+  end;
+
+
+
+
+function BoolToStr(bool: Boolean): String;
+begin
+  if bool then
+    Result := 'true'
+  else
+    Result := 'false';
+end;
+
+
+
+
+function HexToLong(hex: String): LongWord;
+
+
+
+
+  function NormalizeHexString(var hex: String): Boolean;
+  var
+    i: Byte;
+  begin
+    if hex[1] = '$' then
+    begin
+      for i := 1 to Length(hex) - 1 do
+      begin
+        hex[i] := hex[i + 1];
+      end;
+      SetLength(hex, Length(hex) - 1);
+    end;
+    if (hex[1] = '0') and (UpCase(hex[2]) = 'X') then
+    begin
+      for i := 1 to Length(hex) - 2 do
+      begin
+        hex[i] := hex[i + 2];
+      end;
+      SetLength(hex, Length(hex) - 2);
+    end;
+    if Length(hex) = 0 then
+      Result := False
+    else
+      Result := True;
+  end;
+
+var
+  i: Byte;
+begin
+  if NormalizeHexString(hex) then
+  begin
+    hex    := UpperCase(hex);
+    Result := 0;
+    for i := 1 to Length(hex) do
+    begin
+      Result := Result shl 4;
+      case hex[i] of
+        '0'..'9':
+          Result := Result + Ord(hex[i]) - 48;
+        'A'..'F':
+          Result := Result + Ord(hex[i]) - 55;
+        else
+          Result := 0;
+          Exit;
+      end;
+    end;
+  end
+  else
+  begin
+    Result := 0;
+  end;
+end;
+
+
+
+
+function Decode_Int(buffer: Tdata): LongWord;
+begin
+  Result := buffer[0] + buffer[1] * 256 + buffer[2] * 256 * 256 + buffer[3] * 256 * 256 * 256;
+end;
+
+
+
+
+function Encode_Int(input: LongWord): Tdata;
+begin
+  SetLength(Result, 4);
+  Result[0] := input mod 256;
+  input     := input div 256;
+  Result[1] := input mod 256;
+  input     := input div 256;
+  Result[2] := input mod 256;
+  input     := input div 256;
+  Result[3] := input mod 256;
+end;
+
+
+
+
+function Decode_Float(buffer: Tdata): Single;
+var
+  _valueswitcher: TValueSwitcher;
+begin
+  _valueswitcher.ValueInt := Decode_Int(buffer);
+  Result := _valueswitcher.ValueFloat;
+  if IsNAN(Result) then
+    Result := 0.0;
+end;
+
+
+
+
+function Encode_Float(input: Single): Tdata;
+var
+  _valueswitcher: TValueSwitcher;
+begin
+  _valueswitcher.ValueFloat := input;
+  Result := Encode_Int(_valueswitcher.ValueInt);
+end;
+
+
+
+
+function DataToBin(Data: Tdata): String;
+var
+  i, j:     Byte;
+  singlebyte: Byte;
+  bytepart: String;
+begin
+  SetLength(bytepart, 8);
+  Result := '';
+  for i := 0 to High(Data) do
+  begin
+    singlebyte := Data[i];
+    for j := 7 downto 0 do
+    begin
+      bytepart[j + 1] := Char((singlebyte and $01) + 48);
+      singlebyte      := singlebyte shr 1;
+    end;
+    Result := Result + bytepart + ' ';
+  end;
+end;
+
+
+
+
+function BinToInt(bin: String): Byte;
+var
+  Add: Integer;
+  i:   Byte;
+begin
+  Result := 0;
+  if Length(bin) <> 8 then
+    Exit;
+  Add := 1;
+  for i := 8 downto 1 do
+  begin
+    if not (bin[i] in ['0', '1']) then
+      Exit;
+    if bin[i] = '1' then
+      Inc(Result, Add);
+    Add := Add shl 1;
+  end;
+end;
+
+
+
+
+function FormatNumber(Value: LongWord; Width: Byte; leadingzeros: Char): String;
+begin
+  Result := AnsiReplaceStr(Format('%' + IntToStr(Width) + 'u', [Value]), ' ', leadingzeros);
+end;
+
+
+
+
+function FormatFileSize(size: LongWord): String;
+begin
+  if size >= 1000 * 1024 * 1024 then
+  begin
+    Result := FloatToStrF(size / 1024 / 1024 / 1024, ffFixed, 5, 1) + ' GB';
+  end
+  else
+  begin
+    if size >= 1000 * 1024 then
+    begin
+      Result := FloatToStrF(size / 1024 / 1024, ffFixed, 5, 1) + ' MB';
+    end
+    else
+    begin
+      if size >= 1000 then
+      begin
+        Result := FloatToStrF(size / 1024, ffFixed, 5, 1) + ' KB';
+      end
+      else
+      begin
+        Result := IntToStr(size) + ' B';
+      end;
+    end;
+  end;
+end;
+
+
+
+
+function CreateHexString(Data: Tdata; HexOnly: Boolean): String;
+var
+  string_build, ascii_version: String;
+  i: LongWord;
+begin
+  string_build  := '';
+  ascii_version := '';
+  for i := 0 to High(Data) do
+  begin
+    if not HexOnly then
+      if (i mod 16) = 0 then
+        string_build := string_build + '0x' + IntToHex(i, 6) + '  ';
+    string_build := string_build + IntToHex(Data[i], 2);
+    if not HexOnly then
+    begin
+      if Data[i] >= 32 then
+        ascii_version := ascii_version + Chr(Data[i])
+      else
+        ascii_version := ascii_version + '.';
+      if ((i + 1) mod 2) = 0 then
+        string_build := string_build + #32;
+      if ((i + 1) mod 16) = 0 then
+      begin
+        string_build  := string_build + #32 + ascii_version + CrLf;
+        ascii_version := '';
+      end;
+    end;
+  end;
+  Result := string_build;
+end;
+
+
+
+
+function DecodeHexString(hex: String): Tdata;
+var
+  i: LongWord;
+begin
+  SetLength(Result, Length(hex) div 2);
+  for i := 0 to Length(Result) do
+  begin
+    Result[i] := 0;
+    case UpCase(hex[1 + i * 2]) of
+      '0'..'9':
+        Result[i] := (Ord(UpCase(hex[1 + i * 2])) - 48) * 16;
+      'A'..'F':
+        Result[i] := (Ord(UpCase(hex[1 + i * 2])) - 55) * 16;
+    end;
+    case UpCase(hex[1 + i * 2 + 1]) of
+      '0'..'9':
+        Result[i] := Result[i] + (Ord(UpCase(hex[1 + i * 2 + 1])) - 48);
+      'A'..'F':
+        Result[i] := Result[i] + (Ord(UpCase(hex[1 + i * 2 + 1])) - 55);
+    end;
+  end;
+end;
+
+
+
+
+function StringSmaller(string1, string2: String): Boolean;
+var
+  i:   Integer;
+  len: Integer;
+begin
+  len := Min(Length(string1), Length(string2));
+  for i := 1 to len do
+    if Ord(string1[i]) <> Ord(string2[i]) then
+    begin
+      Result := Ord(string1[i]) < Ord(string2[i]);
+      Exit;
+    end;
+  Result := Length(string1) < Length(string2);
+end;
+
+
+
+
+function ExportFile(fileid: LongWord; filename: String; settings: TExportSet;
+  path: String): Integer;
+var
+  i: Byte;
+  extension: String;
+  rawlist: TRawList;
+begin
+  Result    := export_noerror;
+  extension := RightStr(filename, 4);
+  if DO_toone in settings then
+  begin
+    ExportDatFile(fileid, path + '\' + GetWinFileName(filename));
+  end
+  else
+  begin
+    if DO_dat in settings then
+      ExportDatFile(fileid, path + '\' + GetWinFileName(filename));
+    if DO_raw in settings then
+    begin
+      rawlist := OniDataConnection.GetRawList(fileid);
+      if Length(rawlist) > 0 then
+      begin
+        for i := 0 to High(rawlist) do
+        begin
+          ExportRawFile(fileid, rawlist[i].src_offset, path + '\' +
+            GetWinFileName(filename));
+        end;
+      end;
+    end;
+  end;
+end;
+
+
+
+
+function Explode(_string: String; delimiter: Char): TStringArray;
+var
+  start, len: Word;
+begin
+  SetLength(Result, 0);
+  start := 1;
+  while PosEx(delimiter, _string, start) > 0 do
+  begin
+    len := PosEx(delimiter, _string, start) - start;
+    SetLength(Result, Length(Result) + 1);
+    Result[High(Result)] := MidStr(_string, start, len);
+    start := start + len + 1;
+  end;
+  SetLength(Result, Length(Result) + 1);
+  Result[High(Result)] := MidStr(_string, start, Length(_string) - start + 1);
+end;
+
+
+
+
+function GetWinFileName(Name: String): String;
+begin
+  Result := Name;
+  Result := AnsiReplaceStr(Result, '\', '__');
+  Result := AnsiReplaceStr(Result, '/', '__');
+  Result := AnsiReplaceStr(Result, '>', '__');
+  Result := AnsiReplaceStr(Result, '<', '__');
+end;
+
+
+
+
+function GetExtractPath: String;
+begin
+  Result := ExtractFilePath(OniDataConnection.FileName) + '\extracted_' +
+    ExtractFileName(OniDataConnection.Filename);
+end;
+
+
+end.
Index: oup/current/Code/OniDataClass.pas
===================================================================
--- oup/current/Code/OniDataClass.pas	(revision 46)
+++ oup/current/Code/OniDataClass.pas	(revision 46)
@@ -0,0 +1,1379 @@
+unit OniDataClass;
+interface
+uses Data, DataStructures, Classes, SysUtils, StrUtils,
+  Dialogs, ABSDecUtil, ABSMain, DB;
+
+type
+  TOniData = class
+  private
+    FFileName:  String;
+    FLevelInfo: TLevelInfo;
+    FBackend:   Integer;
+    Fos_mac:    Boolean;
+  protected
+  public
+    property FileName: String Read FFileName Write FFileName;
+    property Backend: Integer Read FBackend Write FBackend;
+    property OSisMac: Boolean Read Fos_mac Write Fos_mac;
+    property LevelInfo: TLevelinfo Read FLevelInfo Write FLevelInfo;
+
+    constructor Create(filename: String; var Result: Boolean); virtual; abstract;
+    procedure Close; virtual; abstract;
+
+    function GetFileInfo(fileid: LongWord): TFileInfo; virtual; abstract;
+    function GetFilesList(ext: String; pattern: String;
+      NoEmptyFiles: Boolean; sort: TSortType): TStringArray; virtual; abstract;
+    function GetFilesCount: LongWord; virtual; abstract;
+    function GetExtensionsList: TStringArray; virtual; abstract;
+    function GetExtendedExtensionsList: TExtensionsMap; virtual; abstract;
+    function ExtractFileID(Name: String): Integer;
+    function GetFileIDByName(Name: String): Integer;
+
+    function LoadDatFile(fileid: LongWord): Tdata; virtual; abstract;
+    procedure UpdateDatFile(fileid: LongWord; Data: Tdata); virtual; abstract;
+    procedure LoadDatFilePart(fileid, offset, size: LongWord; target: Pointer);
+      virtual; abstract;
+    procedure UpdateDatFilePart(fileid, offset, size: LongWord; target: Pointer);
+      virtual; abstract;
+
+    function GetRawList(fileid: LongWord): TRawList; virtual; abstract;
+    function GetRawInfo(fileid, dat_offset: LongWord): TRawInfo;
+    procedure LoadRawFile(fileid, dat_offset: LongWord; target: Pointer);
+      virtual; abstract;
+    procedure UpdateRawFile(fileid, dat_offset: LongWord; size: LongWord; target: Pointer);
+      virtual; abstract;
+    procedure LoadRawFilePart(fileid, dat_offset: LongWord;
+      offset, size: LongWord; target: Pointer); virtual; abstract;
+    procedure UpdateRawFilePart(fileid, dat_offset: LongWord;
+      offset, size: LongWord; target: Pointer); virtual; abstract;
+    function AppendRawFile(loc_sep: Boolean; size: LongWord; target: Pointer): LongWord;
+      virtual; abstract;//Returns new Address
+  published
+  end;
+
+  TOniDataDat = class(TOniData)
+  private
+    Fdat_file:     TFileStream;
+    Fraw_file:     TFileStream;
+    Fsep_file:     TFileStream;
+    Fdat_header:   THeader;
+    Fdat_filesmap: TFilesMap;
+    Fdat_files:    TFiles;
+    Fdat_namedfilesmap: TNamedFilesMap;
+    Fdat_extensionsmap: TExtensionsMap;
+    FUnloadWhenUnused: Boolean;
+    FDatOpened:    Boolean;
+    FRawOpened:    Boolean;
+    FSepOpened:    Boolean;
+  protected
+  public
+    property UnloadWhenUnused: Boolean Read FUnloadWhenUnused Write FUnloadWhenUnused;
+
+    constructor Create(DatFilename: String; var Result: Boolean); override;
+    procedure Close; override;
+
+    function GetFileInfo(fileid: LongWord): TFileInfo; override;
+    function GetFilesList(ext: String; pattern: String;
+      NoEmptyFiles: Boolean; sort: TSortType): TStringArray; override;
+    function GetFilesCount: LongWord; override;
+    function GetExtensionsList: TStringArray; override;
+    function GetExtendedExtensionsList: TExtensionsMap; override;
+
+    function LoadDatFile(fileid: LongWord): Tdata; override;
+    procedure UpdateDatFile(fileid: LongWord; Data: Tdata); override;
+    procedure LoadDatFilePart(fileid, offset, size: LongWord; target: Pointer); override;
+    procedure UpdateDatFilePart(fileid, offset, size: LongWord; target: Pointer); override;
+
+    procedure LoadRawOffset(loc_sep: Boolean; raw_addr, size: LongWord; target: Pointer);
+    function GetRawList(fileid: LongWord): TRawList; override;
+    procedure LoadRawFile(fileid, dat_offset: LongWord; target: Pointer); override;
+    procedure UpdateRawFile(fileid, dat_offset: LongWord; size: LongWord;
+      target: Pointer); override;
+    procedure LoadRawFilePart(fileid, dat_offset: LongWord;
+      offset, size: LongWord; target: Pointer); override;
+    procedure UpdateRawFilePart(fileid, dat_offset: LongWord;
+      offset, size: LongWord; target: Pointer); override;
+    function AppendRawFile(loc_sep: Boolean; size: LongWord; target: Pointer): LongWord;
+      override;//Returns new Address
+  published
+  end;
+
+  TOniDataADB = class(TOniData)
+  private
+    FDatabase: TABSDatabase;
+    FQuery:    TABSQuery;
+  protected
+  public
+    constructor Create(OLDBFilename: String; var Result: Boolean); override;
+    procedure Close; override;
+
+    //      function GetDatLinks(srcid:LongWord):TDatLinks;
+    function GetFileInfo(fileid: LongWord): TFileInfo; override;
+    function GetFilesList(ext: String; pattern: String;
+      NoEmptyFiles: Boolean; sort: TSortType): TStringArray; override;
+    function GetFilesCount: LongWord; override;
+    function GetExtensionsList: TStringArray; override;
+    function GetExtendedExtensionsList: TExtensionsMap; override;
+    function GetNamedFilesMap: TNamedFilesMap;
+
+    function LoadDatFile(fileid: LongWord): Tdata; override;
+    procedure UpdateDatFile(fileid: LongWord; Data: Tdata); override;
+    procedure LoadDatFilePart(fileid, offset, size: LongWord; target: Pointer); override;
+    procedure UpdateDatFilePart(fileid, offset, size: LongWord; target: Pointer); override;
+
+    function GetRawList(fileid: LongWord): TRawList; override;
+    procedure LoadRawFile(fileid, dat_offset: LongWord; target: Pointer); override;
+    procedure UpdateRawFile(fileid, dat_offset: LongWord; size: LongWord;
+      target: Pointer); override;
+    procedure LoadRawFilePart(fileid, dat_offset: LongWord;
+      offset, size: LongWord; target: Pointer); override;
+    procedure UpdateRawFilePart(fileid, dat_offset: LongWord;
+      offset, size: LongWord; target: Pointer); override;
+  published
+  end;
+
+
+const
+  ODB_None = -1;
+  ODB_Dat  = 0;
+  ODB_ADB  = 1;
+
+var
+  OniDataConnection: TOniData;
+
+function CreateDataConnection(filename: String; backend: Integer): Boolean;
+procedure CloseDataConnection;
+
+
+
+
+implementation
+uses Functions;
+
+
+
+(*
+  Implementation of  TOniData
+*)
+
+function TOniData.GetFileIDByName(Name: String): Integer;
+var
+  files: TStringArray;
+  i:     Integer;
+begin
+  Result := -1;
+  files  := Self.GetFilesList('', Name, False, stIDAsc);
+  if Length(files) > 0 then
+    for i := 0 to High(files) do
+      if Pos(Name, files[i]) = Pos('-', files[i]) + 1 then
+      begin
+        //        if MidStr(files[i],Pos('-',files[i])+1,Length(files[i])-Pos('-',files[i])-5)=name then begin
+        Result := Self.ExtractFileID(files[i]);
+        Break;
+      end;
+end;
+
+
+
+
+function TOniData.ExtractFileID(Name: String): Integer;
+begin
+  if Name[5] = '-' then
+    Result := HexToLong(MidStr(Name, 1, 4))
+  else
+    Result := StrToInt(MidStr(Name, 1, 5));
+end;
+
+
+
+
+function TOniData.GetRawInfo(fileid, dat_offset: LongWord): TRawInfo;
+var
+  i: LongWord;
+  raw_list: TRawList;
+begin
+  raw_list      := Self.GetRawList(fileid);
+  Result.src_id := 0;
+  Result.src_offset := 0;
+  Result.raw_addr := 0;
+  Result.raw_size := 0;
+  for i := 0 to High(raw_list) do
+  begin
+    if raw_list[i].src_offset = dat_offset then
+    begin
+      Result.src_id     := fileid;
+      Result.src_offset := raw_list[i].src_offset;
+      Result.raw_addr   := raw_list[i].raw_addr;
+      Result.raw_size   := raw_list[i].raw_size;
+      Result.loc_sep    := raw_list[i].loc_sep;
+      Break;
+    end;
+  end;
+end;
+
+
+
+
+
+
+
+(*
+================================================================================
+                      Implementation of  TOniDataDat
+*)
+
+constructor TOniDataDat.Create(DatFilename: String; var Result: Boolean);
+const
+  header_ident1_pc: array[0..$13] of Byte =
+    ($1F, $27, $DC, $33, $DF, $BC, $03, $00, $31, $33, $52, $56, $40, $00,
+    $14, $00, $10, $00, $08, $00);
+  header_ident1_mac: array[0..$13] of Byte =
+    ($61, $30, $C1, $23, $DF, $BC, $03, $00, $31, $33, $52, $56, $40, $00,
+    $14, $00, $10, $00, $08, $00);
+  header_ident1_macbeta: array[0..$13] of Byte =
+    ($81, $11, $8D, $23, $DF, $BC, $03, $00, $31, $33, $52, $56, $40, $00,
+    $14, $00, $10, $00, $08, $00);
+  header_ident2: array[0..$F] of Byte =
+    ($99, $CF, $40, $00, $90, $4F, $63, $00, $F4, $55, $5F, $00, $90, $4F, $63, $00);
+var
+  i: LongWord;
+  header_pc, header_mac: Boolean;
+begin
+  FUnloadWhenUnused := True;
+  FDatOpened := False;
+  FRawOpened := False;
+  if not FileExists(DatFilename) then
+  begin
+    ShowMessage('File doesn''t exist!!!');
+    Result := False;
+    Exit;
+  end;
+  FFileName := DatFilename;
+  Fdat_file := TFileStream.Create(FFileName, fmOpenRead);
+  Fdat_file.Read(Fdat_header, SizeOf(Fdat_header));
+  header_pc  := True;
+  header_mac := True;
+  for i := 0 to High(Fdat_header.Ident) do
+  begin
+    FLevelInfo.Ident[i] := Fdat_header.Ident[i];
+    if Fdat_header.Ident[i] <> header_ident1_pc[i] then
+      header_pc := False;
+    if Fdat_header.Ident[i] <> header_ident1_mac[i] then
+      header_mac := False;
+  end;
+  if not (header_pc xor header_mac) then
+  begin
+    Result := False;
+    Exit;
+  end
+  else
+  begin
+    if (header_pc and not header_mac) then
+      Fos_mac := False
+    else
+      Fos_mac := True;
+  end;
+  SetLength(Fdat_filesmap, Fdat_header.Files);
+  SetLength(Fdat_files, Fdat_header.Files);
+  for i := 0 to Fdat_header.Files - 1 do
+    Fdat_file.Read(Fdat_filesmap[i], SizeOf(Fdat_filesmap[i]));
+  for i := 0 to Fdat_header.Files - 1 do
+  begin
+    Fdat_files[i].ID := i;
+    Fdat_files[i].Extension := Fdat_filesmap[i].Extension;
+    Fdat_files[i].Extension := ReverseString(Fdat_files[i].Extension);
+    Fdat_files[i].Size      := Fdat_filesmap[i].FileSize;
+    Fdat_files[i].FileType  := Fdat_filesmap[i].FileType;
+    Fdat_files[i].DatAddr   := Fdat_filesmap[i].DataAddr - 8 + Fdat_header.DataAddr;
+    if (Fdat_filesmap[i].FileType and $01) = 0 then
+    begin
+      Fdat_file.Seek(Fdat_filesmap[i].NameAddr + Fdat_header.NamesAddr, soFromBeginning);
+      SetLength(Fdat_files[i].Name, 100);
+      Fdat_file.Read(Fdat_files[i].Name[1], 100);
+      Fdat_files[i].Name := MidStr(Fdat_files[i].Name, 1 + 4, Pos(
+        #0, Fdat_files[i].Name) - 1 - 4);
+    end
+    else
+    begin
+      Fdat_files[i].Name := '';
+    end;
+    Fdat_files[i].FileName    :=
+      FormatNumber(i, 5, '0') + '-' + Fdat_files[i].Name + '.' + Fdat_files[i].Extension;
+    Fdat_files[i].FileNameHex :=
+      IntToHex(i, 4) + '-' + Fdat_files[i].Name + '.' + Fdat_files[i].Extension;
+  end;
+  Fdat_file.Seek($40 + Fdat_header.Files * $14, soFromBeginning);
+  SetLength(Fdat_namedfilesmap, Fdat_header.NamedFiles);
+  for i := 0 to Fdat_header.NamedFiles - 1 do
+    Fdat_file.Read(Fdat_namedfilesmap[i], SizeOf(Fdat_namedfilesmap[i]));
+
+  Fdat_file.Seek($40 + Fdat_header.Files * $14 + Fdat_header.NamedFiles * $8, soFromBeginning);
+  SetLength(Fdat_extensionsmap, Fdat_header.Extensions);
+  for i := 0 to Fdat_header.Extensions - 1 do
+    Fdat_file.Read(Fdat_extensionsmap[i], SizeOf(Fdat_extensionsmap[i]));
+
+  Fdat_file.Seek(Fdat_files[0].DatAddr + 7, soFromBeginning);
+  Fdat_file.Read(FLevelInfo.LevelNumber, 1);
+  FLevelInfo.LevelNumber := FLevelInfo.LevelNumber div 2;
+
+  Fdat_file.Free;
+
+  Result   := True;
+  FBackend := ODB_Dat;
+end;
+
+
+
+
+procedure TOniDataDat.Close;
+begin
+  if not FUnloadWhenUnused and FDatOpened then
+    Fdat_file.Free;
+  if not FUnloadWhenUnused and FRawOpened then
+    Fraw_file.Free;
+  if not FUnloadWhenUnused and FSepOpened then
+    Fsep_file.Free;
+  Self.Free;
+end;
+
+
+
+
+function TOniDataDat.GetFileInfo(fileid: LongWord): TFileInfo;
+begin
+  if fileid < Self.GetFilesCount then
+    Result    := Fdat_files[fileid]
+  else
+    Result.ID := -1;
+end;
+
+
+
+
+function TOniDataDat.GetFilesList(ext: String; pattern: String;
+  NoEmptyFiles: Boolean; sort: TSortType): TStringArray;
+var
+  i: LongWord;
+  list: TStringList;
+  id, name, extension: String;
+  fields: TStrings;
+
+  procedure getfields;
+  begin
+     fields.CommaText := StringReplace(AnsiQuotedStr(list.Strings[i], '"'), ';', '","', [rfReplaceAll]);
+    if sort in [stIDAsc, stIDDesc] then
+    begin
+      id := fields.Strings[0];
+      name := fields.Strings[1];
+      extension := fields.Strings[2];
+    end;
+    if sort in [stNameAsc, stNameDesc] then
+    begin
+      id := fields.Strings[1];
+      name := fields.Strings[0];
+      extension := fields.Strings[2];
+    end;
+    if sort in [stExtAsc, stExtDesc] then
+    begin
+      id := fields.Strings[1];
+      name := fields.Strings[2];
+      extension := fields.Strings[0];
+    end;
+  end;
+
+begin
+  list := TStringList.Create;
+  list.Sorted := True;
+  for i := 0 to Fdat_header.Files - 1 do
+  begin
+    if ((Length(ext) = 0) or (Pos(Fdat_files[i].Extension, ext) > 0)) and
+      ((Length(pattern) = 0) or
+      (Pos(UpperCase(pattern), UpperCase(Fdat_files[i].Name)) > 0)) then
+    begin
+      if (NoEmptyFiles = False) or ((Fdat_files[i].FileType and $02) = 0) then
+      begin
+        if AppSettings.FilenumbersAsHex then
+          id := IntToHex(Fdat_files[i].ID, 4)
+        else
+          id := FormatNumber(Fdat_files[i].ID, 5, '0');
+        name := Fdat_files[i].Name;
+        extension := Fdat_files[i].Extension;
+
+        case sort of
+          stIDAsc, stIDDesc:     list.Add(id + ';' + name + ';' + extension);
+          stNameAsc, stNameDesc: list.Add(name + ';' + id + ';' + extension);
+          stExtAsc, stExtDesc:   list.Add(extension + ';' + id + ';' + name);
+        end;
+      end;
+    end;
+  end;
+  SetLength(Result, list.Count);
+  fields := TStringList.Create;
+  if sort in [stIDAsc, stNameAsc, stExtAsc] then
+    for i := 0 to list.Count - 1 do
+    begin
+      getfields;
+      Result[i] := id + '-' + name + '.' + extension;
+    end
+  else
+    for i := list.Count - 1 downto 0 do
+    begin
+      getfields;
+      Result[list.Count - i - 1] := id + '-' + name + '.' + extension;
+    end;
+  list.Free;
+  fields.Free;
+end;
+
+
+
+
+function TOniDataDat.GetFilesCount: LongWord;
+begin
+  Result := Fdat_header.Files;
+end;
+
+
+
+
+function TOniDataDat.GetExtensionsList: TStringArray;
+var
+  i: LongWord;
+begin
+  SetLength(Result, Fdat_header.Extensions);
+  for i := 0 to Fdat_header.Extensions - 1 do
+  begin
+    with Fdat_extensionsmap[i] do
+    begin
+      Result[i] := Extension[3] + Extension[2] + Extension[1] + Extension[0] +
+        ' (' + IntToStr(ExtCount) + ')';
+    end;
+  end;
+end;
+
+
+
+
+function TOniDataDat.GetExtendedExtensionsList: TExtensionsMap;
+var
+  i: LongWord;
+begin
+  SetLength(Result, Fdat_header.Extensions);
+  for i := 0 to Fdat_header.Extensions - 1 do
+  begin
+    Result[i] := Fdat_extensionsmap[i];
+  end;
+end;
+
+
+
+
+function TOniDataDat.LoadDatFile(fileid: LongWord): Tdata;
+begin
+  if fileid < Self.GetFilesCount then
+  begin
+    if FUnloadWhenUnused or not FDatOpened then
+      Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
+    Fdat_file.Seek(Fdat_files[fileid].DatAddr, soFromBeginning);
+    SetLength(Result, Fdat_files[fileid].Size);
+    Fdat_file.Read(Result[0], Fdat_files[fileid].Size);
+    if UnloadWhenUnused then
+      Fdat_file.Free
+    else
+      FDatOpened := True;
+  end;
+end;
+
+
+
+
+procedure TOniDataDat.UpdateDatFile(fileid: LongWord; Data: Tdata);
+begin
+  if fileid < Self.GetFilesCount then
+  begin
+    if FUnloadWhenUnused or not FDatOpened then
+      Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
+    Fdat_file.Seek(Fdat_files[fileid].DatAddr, soFromBeginning);
+    Fdat_file.Write(Data[0], Length(Data));
+    if UnloadWhenUnused then
+      Fdat_file.Free
+    else
+      FDatOpened := True;
+  end;
+end;
+
+
+
+
+procedure TOniDataDat.LoadDatFilePart(fileid, offset, size: LongWord; target: Pointer);
+begin
+  if fileid < Self.GetFilesCount then
+  begin
+    if FUnloadWhenUnused or not FDatOpened then
+      Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
+    Fdat_file.Seek(Fdat_files[fileid].DatAddr + offset, soFromBeginning);
+    Fdat_file.Read(target^, size);
+    if UnloadWhenUnused then
+      Fdat_file.Free
+    else
+      FDatOpened := True;
+  end;
+end;
+
+
+
+
+procedure TOniDataDat.UpdateDatFilePart(fileid, offset, size: LongWord; target: Pointer);
+begin
+  if fileid < Self.GetFilesCount then
+  begin
+    if FUnloadWhenUnused or not FDatOpened then
+      Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
+    Fdat_file.Seek(Fdat_files[fileid].DatAddr + offset, soFromBeginning);
+    Fdat_file.Write(target^, size);
+    if UnloadWhenUnused then
+      Fdat_file.Free
+    else
+      FDatOpened := True;
+  end;
+end;
+
+
+
+
+function TOniDataDat.GetRawList(fileid: LongWord): TRawList;
+var
+  i: LongWord;
+begin
+  SetLength(Result, 0);
+  for i := 0 to High(RawListHandlers) do
+    if UpperCase(RawListHandlers[i].Ext) = UpperCase(Fdat_files[fileid].extension) then
+      if RawListHandlers[i].needed then
+      begin
+        Result := RawListHandlers[i].Handler(fileid);
+        Break;
+      end
+      else
+        Break;
+end;
+
+
+
+
+procedure TOniDataDat.LoadRawOffset(loc_sep: Boolean; raw_addr, size: LongWord;
+  target: Pointer);
+begin
+  if not loc_sep then
+  begin
+    if FUnloadWhenUnused or not FRawOpened then
+      Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
+        fmOpenReadWrite);
+    if raw_addr <= Fraw_file.Size then
+    begin
+      Fraw_file.Seek(raw_addr, soFromBeginning);
+      Fraw_file.Read(target^, size);
+    end;
+    if UnloadWhenUnused then
+      Fraw_file.Free
+    else
+      FRawOpened := True;
+  end
+  else
+  begin
+    if FUnloadWhenUnused or not FSepOpened then
+      Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
+        fmOpenReadWrite);
+    if raw_addr <= Fsep_file.Size then
+    begin
+      Fsep_file.Seek(raw_addr, soFromBeginning);
+      Fsep_file.Read(target^, size);
+    end;
+    if UnloadWhenUnused then
+      Fsep_file.Free
+    else
+      FSepOpened := True;
+  end;
+end;
+
+
+
+
+procedure TOniDataDat.LoadRawFile(fileid, dat_offset: LongWord; target: Pointer);
+var
+  raw_info: TRawInfo;
+begin
+  if fileid < Self.GetFilesCount then
+  begin
+    raw_info := Self.GetRawInfo(fileid, dat_offset);
+    if not raw_info.loc_sep then
+    begin
+      if FUnloadWhenUnused or not FRawOpened then
+        Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
+          fmOpenReadWrite);
+      Fraw_file.Seek(raw_info.raw_addr, soFromBeginning);
+      Fraw_file.Read(target^, raw_info.raw_size);
+      if UnloadWhenUnused then
+        Fraw_file.Free
+      else
+        FRawOpened := True;
+    end
+    else
+    begin
+      if FUnloadWhenUnused or not FSepOpened then
+        Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
+          fmOpenReadWrite);
+      Fsep_file.Seek(raw_info.raw_addr, soFromBeginning);
+      Fsep_file.Read(target^, raw_info.raw_size);
+      if UnloadWhenUnused then
+        Fsep_file.Free
+      else
+        FSepOpened := True;
+    end;
+  end;
+end;
+
+
+
+
+procedure TOniDataDat.UpdateRawFile(fileid, dat_offset: LongWord;
+  size: LongWord; target: Pointer);
+var
+  raw_info: TRawInfo;
+begin
+  if fileid < Self.GetFilesCount then
+  begin
+    raw_info := Self.GetRawInfo(fileid, dat_offset);
+    if not raw_info.loc_sep then
+    begin
+      if FUnloadWhenUnused or not FRawOpened then
+        Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
+          fmOpenReadWrite);
+      Fraw_file.Seek(raw_info.raw_addr, soFromBeginning);
+      Fraw_file.Write(target^, raw_info.raw_size);
+      if UnloadWhenUnused then
+        Fraw_file.Free
+      else
+        FRawOpened := True;
+    end
+    else
+    begin
+      if FUnloadWhenUnused or not FSepOpened then
+        Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
+          fmOpenReadWrite);
+      Fsep_file.Seek(raw_info.raw_addr, soFromBeginning);
+      Fsep_file.Write(target^, raw_info.raw_size);
+      if UnloadWhenUnused then
+        Fsep_file.Free
+      else
+        FSepOpened := True;
+    end;
+  end;
+end;
+
+
+
+
+procedure TOniDataDat.LoadRawFilePart(fileid, dat_offset: LongWord;
+  offset, size: LongWord; target: Pointer);
+var
+  raw_info: TRawInfo;
+  Data:     Tdata;
+  mem:      TMemoryStream;
+begin
+  if fileid < Self.GetFilesCount then
+  begin
+    raw_info := Self.GetRawInfo(fileid, dat_offset);
+    SetLength(Data, raw_info.raw_size);
+    Self.LoadRawFile(fileid, dat_offset, @Data[0]);
+    mem := TMemoryStream.Create;
+    mem.Write(Data[offset], size);
+    mem.Read(target^, size);
+    mem.Free;
+  end;
+end;
+
+
+
+
+procedure TOniDataDat.UpdateRawFilePart(fileid, dat_offset: LongWord;
+  offset, size: LongWord; target: Pointer);
+var
+  raw_info: TRawInfo;
+begin
+  if fileid < Self.GetFilesCount then
+  begin
+    raw_info := Self.GetRawInfo(fileid, dat_offset);
+    if not raw_info.loc_sep then
+    begin
+      if FUnloadWhenUnused or not FRawOpened then
+        Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
+          fmOpenReadWrite);
+      Fraw_file.Seek(raw_info.raw_addr + offset, soFromBeginning);
+      Fraw_file.Write(target^, raw_info.raw_size);
+      if UnloadWhenUnused then
+        Fraw_file.Free
+      else
+        FRawOpened := True;
+    end
+    else
+    begin
+      if FUnloadWhenUnused or not FSepOpened then
+        Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
+          fmOpenReadWrite);
+      Fsep_file.Seek(raw_info.raw_addr + offset, soFromBeginning);
+      Fsep_file.Write(target^, raw_info.raw_size);
+      if UnloadWhenUnused then
+        Fsep_file.Free
+      else
+        FSepOpened := True;
+    end;
+  end;
+end;
+
+
+
+
+function TOniDataDat.AppendRawFile(loc_sep: Boolean; size: LongWord;
+  target: Pointer): LongWord; //Returns new Address
+begin
+  if not loc_sep then
+  begin
+    if FUnloadWhenUnused or not FRawOpened then
+      Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
+        fmOpenReadWrite);
+    Result := Fraw_file.Size;
+    Fraw_file.Seek(0, soFromEnd);
+    Fraw_file.Write(target^, size);
+    if UnloadWhenUnused then
+      Fraw_file.Free
+    else
+      FRawOpened := True;
+  end
+  else
+  begin
+    if FUnloadWhenUnused or not FSepOpened then
+      Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
+        fmOpenReadWrite);
+    Result := Fsep_file.Size;
+    Fsep_file.Seek(0, soFromEnd);
+    Fsep_file.Write(target^, size);
+    if UnloadWhenUnused then
+      Fsep_file.Free
+    else
+      FSepOpened := True;
+  end;
+end;
+
+
+
+
+
+
+
+
+
+
+
+(*
+================================================================================
+                     Implementation of  TOniDataADB
+*)
+
+constructor TOniDataADB.Create(OLDBFilename: String; var Result: Boolean);
+var
+  i, j:  Byte;
+  temps: String;
+begin
+  if not FileExists(OLDBFilename) then
+  begin
+    ShowMessage('File doesn''t exist!!!');
+    Result := False;
+    Exit;
+  end;
+  FFileName := OLDBFilename;
+  FDatabase := TABSDatabase.Create(nil);
+  FDatabase.DatabaseName := 'OLDBcon';
+  FDatabase.DatabaseFileName := OLDBFilename;
+  FDatabase.Open;
+  FQuery := TABSQuery.Create(FDatabase);
+  FQuery.DatabaseName := 'OLDBcon';
+  FQuery.SQL.Text := 'SELECT [name],[value] FROM globals ORDER BY [name] ASC';
+  FQuery.Open;
+  FQuery.First;
+  repeat
+    if FQuery.FieldByName('name').AsString = 'dbversion' then
+    begin
+      if FQuery.FieldByName('value').AsString <> DBversion then
+      begin
+        ShowMessage('Database-file ' + #13 + #10 +
+          '"' + OLDBFilename + '"' + #13 + #10 +
+          'has wrong version. (Required: ' + DBversion + '; found: ' +
+          FQuery.FieldByName('value').AsString + ')');
+        FQuery.Close;
+        Result := False;
+        Exit;
+      end;
+    end;
+    if FQuery.FieldByName('name').AsString = 'lvl' then
+    begin
+      FLevelInfo.LevelNumber := StrToInt(FQuery.FieldByName('value').AsString);
+    end;
+    if FQuery.FieldByName('name').AsString = 'ident' then
+    begin
+      temps := FQuery.FieldByName('value').AsString;
+      for i := 0 to High(FLevelInfo.Ident) do
+      begin
+        j := i * 2 + 1;
+        case temps[j] of
+          '0'..'9':
+            FLevelInfo.Ident[i] := Ord(temps[j]) - 48;
+          'A'..'F':
+            FLevelInfo.Ident[i] := Ord(temps[j]) - 55;
+        end;
+        FLevelInfo.Ident[i] := FLevelInfo.Ident[i] * 16;
+        case temps[j + 1] of
+          '0'..'9':
+            FLevelInfo.Ident[i] := FLevelInfo.Ident[i] + Ord(temps[j + 1]) - 48;
+          'A'..'F':
+            FLevelInfo.Ident[i] := FLevelInfo.Ident[i] + Ord(temps[j + 1]) - 55;
+        end;
+      end;
+    end;
+    if FQuery.FieldByName('name').AsString = 'ident' then
+    begin
+      temps   := FQuery.FieldByName('value').AsString;
+      Fos_mac := temps = 'MAC';
+    end;
+    FQuery.Next;
+  until FQuery.EOF;
+  FQuery.Close;
+
+  Result   := True;
+  FBackend := ODB_ADB;
+end;
+
+
+
+
+procedure TOniDataADB.Close;
+begin
+  FDatabase.Close;
+  FDatabase.Free;
+  Self.Free;
+end;
+
+
+
+
+function TOniDataADB.GetFileInfo(fileid: LongWord): TFileInfo;
+begin
+  if fileid < Self.GetFilesCount then
+  begin
+    FQuery.SQL.Text := 'SELECT * FROM datfiles WHERE id=' + IntToStr(
+      fileid) + ' ORDER BY id ASC;';
+    FQuery.Open;
+    if FQuery.RecordCount = 1 then
+    begin
+      FQuery.First;
+      Result.ID      := FQuery.FieldByName('id').AsInteger;
+      Result.Name    := FQuery.FieldByName('name').AsString;
+      Result.Extension := FQuery.FieldByName('extension').AsString;
+      Result.FileName := FormatNumber(Result.ID, 5, '0') + '-' + Result.Name + '.' +
+        Result.Extension;
+      Result.Size    := FQuery.FieldByName('size').AsInteger;
+      Result.FileType := HexToLong(FQuery.FieldByName('contenttype').AsString);
+      Result.DatAddr := 0;
+      Result.opened  := False;
+    end;
+    FQuery.Close;
+  end
+  else
+  begin
+    Result.ID := -1;
+  end;
+end;
+
+
+
+
+function TOniDataADB.GetFilesList(ext: String; pattern: String;
+  NoEmptyFiles: Boolean; sort: TSortType): TStringArray;
+var
+  i:     LongWord;
+  where: String;
+  where_ext: String;
+  order: String;
+begin
+  where := '';
+  if Length(ext) > 0 then
+  begin
+    if Length(where) > 0 then
+      where := where + ' AND ';
+    if Pos(',', ext) > 0 then
+    begin
+      i := 1;
+      where_ext := '';
+      while i < Length(ext) do
+      begin
+        if Length(where_ext) > 0 then
+          where_ext := where_ext + ' OR ';
+        where_ext := where_ext + '(extension="' + MidStr(ext, i, 4) + '")';
+        i := i + 5;
+      end;
+      where := where + '(' + where_ext + ')';
+    end
+    else
+    begin
+      where := where + '(extension="' + ext + '")';
+    end;
+  end;
+  if Length(pattern) > 0 then
+  begin
+    if Length(where) > 0 then
+      where := where + ' AND ';
+    where := where + '(name LIKE "%' + pattern + '%")';
+  end;
+  if NoEmptyFiles then
+  begin
+    if Length(where) > 0 then
+      where := where + ' AND ';
+    where := where + '(contenttype<>2)';
+  end;
+  if Length(where) > 0 then
+    where := ' WHERE ' + where;
+  case sort of
+    stIDAsc:    order := ' ORDER BY id ASC';
+    stIDDesc:   order := ' ORDER BY id DESC';
+    stNameAsc:  order := ' ORDER BY name ASC, id ASC';
+    stNameDesc: order := ' ORDER BY name DESC, id ASC';
+    stExtAsc:   order := ' ORDER BY extension ASC, id ASC';
+    stExtDesc:  order := ' ORDER BY extension DESC, id ASC';
+  end;
+  FQuery.SQL.Text := 'SELECT id,name,extension FROM datfiles' + where + order + ';';
+  FQuery.Open;
+  if FQuery.RecordCount > 0 then
+  begin
+    FQuery.First;
+    SetLength(Result, FQuery.RecordCount);
+    i := 0;
+    repeat
+      Result[i] := FormatNumber(FQuery.FieldByName('id').AsInteger, 5, '0') + '-' +
+        FQuery.FieldByName('name').AsString + '.' + FQuery.FieldByName('extension').AsString;
+      Inc(i);
+      FQuery.Next;
+    until FQuery.EOF;
+  end;
+  FQuery.Close;
+end;
+
+
+
+
+function TOniDataADB.GetFilesCount: LongWord;
+begin
+  FQuery.SQL.Text := 'SELECT Count(*) AS cnumber FROM datfiles;';
+  FQuery.Open;
+  if FQuery.RecordCount > 0 then
+  begin
+    FQuery.First;
+    Result := FQuery.FieldByName('cnumber').AsInteger;
+  end
+  else
+    Result := 0;
+  FQuery.Close;
+end;
+
+
+
+
+function TOniDataADB.GetExtensionsList: TStringArray;
+var
+  i: LongWord;
+begin
+  SetLength(Result, 0);
+  FQuery.SQL.Text :=
+    'SELECT extension,count(extension) AS x FROM datfiles GROUP BY extension ORDER BY extension ASC;';
+  FQuery.Open;
+  if FQuery.RecordCount > 0 then
+  begin
+    SetLength(Result, FQuery.RecordCount);
+    i := 0;
+    repeat
+      Result[i] := FQuery.FieldByName('extension').AsString + ' (' +
+        IntToStr(FQuery.FieldByName('x').AsInteger) + ')';
+      Inc(i);
+      FQuery.Next;
+    until FQuery.EOF;
+  end;
+  FQuery.Close;
+end;
+
+
+
+
+function TOniDataADB.GetExtendedExtensionsList: TExtensionsMap;
+var
+  i, j:  LongWord;
+  temps: String;
+  Data:  Tdata;
+begin
+  SetLength(Result, 0);
+  FQuery.SQL.Text := 'SELECT ext,ident FROM extlist ORDER BY ext ASC;';
+  FQuery.Open;
+  if FQuery.RecordCount > 0 then
+  begin
+    SetLength(Result, FQuery.RecordCount);
+    i := 0;
+    repeat
+      temps := FQuery.FieldByName('ext').AsString;
+      for j := 0 to 3 do
+        Result[i].Extension[j] := temps[4 - j];
+      Data := DecodeHexString(FQuery.FieldByName('ident').AsString);
+      for j := 0 to 7 do
+        Result[i].Ident[j] := Data[j];
+      Inc(i);
+      FQuery.Next;
+    until FQuery.EOF;
+  end;
+  FQuery.Close;
+end;
+
+
+
+
+function TOniDataADB.GetNamedFilesMap: TNamedFilesMap;
+var
+  i:     LongWord;
+  temp:  Integer;
+  temps: String;
+  temparray: array of record
+    id: Integer;
+    fullname: String[50];
+  end;
+begin
+  SetLength(temparray, 0);
+  FQuery.SQL.Text :=
+    'SELECT id,(extension+name) AS xname FROM datfiles WHERE Length(name)>0 ORDER BY extension,name ASC;';
+  FQuery.Open;
+  if FQuery.RecordCount > 0 then
+  begin
+    repeat
+      temp  := FQuery.FieldByName('id').AsInteger;
+      temps := FQuery.FieldByName('xname').AsString;
+
+      SetLength(temparray, Length(temparray) + 1);
+      if Length(temparray) > 1 then
+      begin
+        for i := High(temparray) - 1 downto 0 do
+        begin
+          if StringSmaller(temps, temparray[i].fullname) then
+          begin
+            temparray[i + 1] := temparray[i];
+            if i = 0 then
+            begin
+              temparray[i].id := temp;
+              temparray[i].fullname := temps;
+            end;
+          end
+          else
+          begin
+            temparray[i + 1].id := temp;
+            temparray[i + 1].fullname := temps;
+            Break;
+          end;
+        end;
+      end
+      else
+      begin
+        temparray[0].id := temp;
+        temparray[0].fullname := temps;
+      end;
+      FQuery.Next;
+    until FQuery.EOF;
+  end;
+  FQuery.Close;
+  SetLength(Result, Length(temparray));
+  for i := 0 to High(temparray) do
+  begin
+    Result[i].FileNumber := temparray[i].id;
+    Result[i].blubb      := 0;
+  end;
+end;
+
+
+
+
+function TOniDataADB.LoadDatFile(fileid: LongWord): Tdata;
+var
+  mem: TStream;
+begin
+  if fileid < Self.GetFilesCount then
+  begin
+    FQuery.SQL.Text := 'SELECT data FROM datfiles WHERE id=' + IntToStr(fileid) + ';';
+    FQuery.Open;
+    if FQuery.RecordCount > 0 then
+    begin
+      mem := FQuery.CreateBlobStream(FQuery.FieldByName('data'), bmRead);
+      SetLength(Result, mem.Size);
+      mem.Seek(0, soFromBeginning);
+      mem.Read(Result[0], mem.Size);
+      mem.Free;
+    end;
+    FQuery.Close;
+  end;
+end;
+
+
+
+
+procedure TOniDataADB.UpdateDatFile(fileid: LongWord; Data: Tdata);
+var
+  MimeCoder: TStringFormat_MIME64;
+  mem: TMemoryStream;
+begin
+  if fileid < Self.GetFilesCount then
+  begin
+    mimecoder := TStringFormat_MIME64.Create;
+    mem := TMemoryStream.Create;
+    mem.Write(Data[0], Length(Data));
+    mem.Seek(0, soFromBeginning);
+    FQuery.SQL.Text := 'UPDATE datfiles SET data=MimeToBin("' +
+      MimeCoder.StrTo(mem.Memory, mem.Size) + '") WHERE id=' + IntToStr(fileid) + ';';
+    FQuery.ExecSQL;
+    mem.Free;
+    mimecoder.Free;
+  end;
+end;
+
+
+
+
+procedure TOniDataADB.LoadDatFilePart(fileid, offset, size: LongWord; target: Pointer);
+var
+  mem: TStream;
+begin
+  if fileid < Self.GetFilesCount then
+  begin
+    FQuery.SQL.Text := 'SELECT data FROM datfiles WHERE id=' + IntToStr(fileid) + ';';
+    FQuery.Open;
+    if FQuery.RecordCount > 0 then
+    begin
+      mem := FQuery.CreateBlobStream(FQuery.FieldByName('data'), bmRead);
+      mem.Seek(offset, soFromBeginning);
+      mem.Read(target^, size);
+      mem.Free;
+    end;
+    FQuery.Close;
+  end;
+end;
+
+
+
+
+procedure TOniDataADB.UpdateDatFilePart(fileid, offset, size: LongWord; target: Pointer);
+var
+  MimeCoder: TStringFormat_MIME64;
+  mem:  TMemoryStream;
+  Data: Tdata;
+begin
+  if fileid < Self.GetFilesCount then
+  begin
+    Data := Self.LoadDatFile(fileid);
+    mimecoder := TStringFormat_MIME64.Create;
+    mem := TMemoryStream.Create;
+    mem.Write(Data[0], Length(Data));
+    mem.Seek(offset, soFromBeginning);
+    mem.Write(target^, size);
+    mem.Seek(0, soFromBeginning);
+    FQuery.SQL.Text := 'UPDATE datfiles SET data=MimeToBin("' +
+      MimeCoder.StrTo(mem.Memory, mem.Size) + '") WHERE id=' + IntToStr(fileid) + ';';
+    FQuery.ExecSQL;
+    mem.Free;
+    mimecoder.Free;
+  end;
+end;
+
+
+
+
+function TOniDataADB.GetRawList(fileid: LongWord): TRawList;
+var
+  i: LongWord;
+begin
+  SetLength(Result, 0);
+  FQuery.SQL.Text := 'SELECT [src_link_offset],[size],[sep] FROM rawmap WHERE [src_id]=' +
+    IntToStr(fileid) + ' ORDER BY src_link_offset ASC;';
+  FQuery.Open;
+  if FQuery.RecordCount > 0 then
+  begin
+    FQuery.First;
+    SetLength(Result, FQuery.RecordCount);
+    i := 0;
+    repeat
+      Result[i].src_id     := fileid;
+      Result[i].src_offset := FQuery.FieldByName('src_link_offset').AsInteger;
+      Result[i].raw_addr   := 0;
+      Result[i].raw_size   := FQuery.FieldByName('size').AsInteger;
+      Result[i].loc_sep    := FQuery.FieldByName('sep').AsBoolean;
+      Inc(i);
+      FQuery.Next;
+    until FQuery.EOF;
+  end;
+  FQuery.Close;
+end;
+
+
+
+
+procedure TOniDataADB.LoadRawFile(fileid, dat_offset: LongWord; target: Pointer);
+var
+  mem: TStream;
+begin
+  if fileid < Self.GetFilesCount then
+  begin
+    FQuery.SQL.Text := 'SELECT data FROM rawmap WHERE (src_id=' +
+      IntToStr(fileid) + ') AND (src_link_offset=' + IntToStr(dat_offset) + ');';
+    FQuery.Open;
+    if FQuery.RecordCount > 0 then
+    begin
+      mem := FQuery.CreateBlobStream(FQuery.FieldByName('data'), bmRead);
+      mem.Seek(0, soFromBeginning);
+      mem.Read(target^, mem.size);
+      mem.Free;
+    end;
+    FQuery.Close;
+  end;
+end;
+
+
+
+
+procedure TOniDataADB.UpdateRawFile(fileid, dat_offset: LongWord;
+  size: LongWord; target: Pointer);
+var
+  MimeCoder: TStringFormat_MIME64;
+  mem: TMemoryStream;
+begin
+  if fileid < Self.GetFilesCount then
+  begin
+    mimecoder := TStringFormat_MIME64.Create;
+    mem := TMemoryStream.Create;
+    mem.Write(target^, size);
+    mem.Seek(0, soFromBeginning);
+    FQuery.SQL.Text := 'UPDATE rawmap SET data=MimeToBin("' + MimeCoder.StrTo(
+      mem.Memory, mem.Size) + '") WHERE (src_id=' + IntToStr(fileid) +
+      ') AND (src_link_offset=' + IntToStr(dat_offset) + ');';
+    FQuery.ExecSQL;
+    mem.Free;
+    mimecoder.Free;
+  end;
+end;
+
+
+
+
+procedure TOniDataADB.LoadRawFilePart(fileid, dat_offset: LongWord;
+  offset, size: LongWord; target: Pointer);
+var
+  Data: Tdata;
+  mem:  TMemoryStream;
+begin
+  if fileid < Self.GetFilesCount then
+  begin
+    SetLength(Data, Self.GetRawInfo(fileid, dat_offset).raw_size);
+    Self.LoadRawFile(fileid, dat_offset, @Data[0]);
+    mem := TMemoryStream.Create;
+    mem.Write(Data[offset], size);
+    mem.Read(target^, size);
+    mem.Free;
+  end;
+end;
+
+
+
+
+procedure TOniDataADB.UpdateRawFilePart(fileid, dat_offset: LongWord;
+  offset, size: LongWord; target: Pointer);
+var
+  MimeCoder: TStringFormat_MIME64;
+  mem:  TMemoryStream;
+  Data: Tdata;
+begin
+  if fileid < Self.GetFilesCount then
+  begin
+    SetLength(Data, Self.GetRawInfo(fileid, offset).raw_size);
+    Self.LoadRawFile(fileid, offset, @Data[0]);
+    mimecoder := TStringFormat_MIME64.Create;
+    mem := TMemoryStream.Create;
+    mem.Write(Data[0], Length(Data));
+    mem.Seek(offset, soFromBeginning);
+    mem.Write(target^, size);
+    mem.Seek(0, soFromBeginning);
+    FQuery.SQL.Text := 'UPDATE rawmap SET data=MimeToBin("' + MimeCoder.StrTo(
+      mem.Memory, mem.Size) + '") WHERE (src_id=' + IntToStr(fileid) +
+      ') AND (src_link_offset=' + IntToStr(dat_offset) + ');';
+    FQuery.ExecSQL;
+    mem.Free;
+    mimecoder.Free;
+  end;
+end;
+
+
+
+
+
+
+
+
+
+
+
+function CreateDataConnection(filename: String; backend: Integer): Boolean;
+var
+  answer: Boolean;
+begin
+  if Assigned(OniDataConnection) then
+  begin
+    OniDataConnection.Close;
+    OniDataConnection.Free;
+    OniDataConnection := nil;
+  end;
+  case backend of
+    ODB_Dat:
+      OniDataConnection := TOniDataDat.Create(filename, answer);
+    ODB_ADB:
+      OniDataConnection := TOniDataADB.Create(filename, answer);
+    else
+      ShowMessage('Unknown Backend');
+      Result := False;
+      Exit;
+  end;
+
+  if answer then
+  begin
+    //      ShowMessage('file loaded');
+    //      ShowMessage('Files: '+IntToStr(OniDataConnection.GetFilesCount));
+    Result := True;
+  end
+  else
+  begin
+    ShowMessage('File not loaded');
+    OniDataConnection.Close;
+    OniDataConnection.Free;
+    Result := False;
+  end;
+end;
+
+
+
+
+procedure CloseDataConnection;
+begin
+  if Assigned(OniDataConnection) then
+  begin
+    OniDataConnection.Close;
+    OniDataConnection := nil;
+  end;
+end;
+
+end.
Index: oup/current/Code/OniImgClass.pas
===================================================================
--- oup/current/Code/OniImgClass.pas	(revision 46)
+++ oup/current/Code/OniImgClass.pas	(revision 46)
@@ -0,0 +1,827 @@
+unit OniImgClass;
+
+interface
+
+uses Math, Dialogs, Types, SysUtils, Classes, Data, OniDataClass;
+
+type
+  TImgDataType = set of (DT_OniReverted, DT_Oni, DT_Decoded32);
+
+type
+  TOniImage = class
+  private
+    FLoaded:    Boolean;
+    FDataType:  TImgDataType;
+    FData:      Tdata;
+    FWidth, FHeight: Word;
+    FDepth:     Byte;
+    FStoreType: Byte;
+
+    function ResizeImage(oldx, oldy: LongWord; img: Tdata): Tdata;
+    procedure RevertImage;
+    procedure DecodeImage;
+    procedure DecompressImage;
+  protected
+  public
+    property Loaded: Boolean Read FLoaded Write FLoaded;
+    property DataType: TImgDataType Read FDataType Write FDataType;
+    property Width: Word Read FWidth Write FWidth;
+    property Height: Word Read FHeight Write FHeight;
+    property Depth: Byte Read FDepth Write FDepth;
+    property StoreType: Byte Read FStoreType Write FStoreType;
+    property Data: Tdata Read FData Write FData;
+
+    constructor Create;
+    function Load(fileid: LongWord): Boolean;
+    function LoadFromPSpc(fileid: LongWord): Boolean;
+    function LoadFromTXMP(fileid: LongWord): Boolean;
+    function LoadFromTXMB(fileid: LongWord): Boolean;
+    function GetImageDataSize(fading: Boolean): LongWord;
+
+    function GetAsData: Tdata;
+    function GetAs32bit: Tdata;
+    function GetAsBMP: Tdata;
+    function LoadFromBMP(filename: String): Boolean;
+    function WriteToBMP(filename: String): Boolean;
+    function GetMipMappedImage(var faded: Tdata): Boolean;
+  published
+  end;
+
+
+implementation
+
+uses Functions;
+
+
+
+
+constructor TOniImage.Create;
+begin
+  Self.FLoaded   := False;
+  Self.FDataType := [];
+  SetLength(Self.FData, 0);
+  Self.FWidth     := 0;
+  Self.FHeight    := 0;
+  Self.FDepth     := 0;
+  Self.FStoreType := 0;
+end;
+
+
+
+
+function TOniImage.ResizeImage(oldx, oldy: LongWord; img: Tdata): Tdata;
+var
+  i, j: LongWord;
+  col, row, row_orig: LongWord;
+begin
+  SetLength(Result, (oldx div 2) * (oldy div 2) * (Self.FDepth div 8));
+  row_orig := 0;
+  row      := 0;
+  col      := 0;
+  for i := 0 to (oldx * oldy) - 1 do
+  begin
+    if ((i mod oldx) = 0) and (i > 0) then
+    begin
+      Inc(row_orig);
+      if (row_orig mod 2) = 0 then
+      begin
+        Inc(row);
+        col := 0;
+      end;
+    end;
+    if (row_orig mod 2) = 0 then
+    begin
+      if (i mod 2) = 0 then
+      begin
+        for j := 0 to (Self.FDepth div 8) - 1 do
+          Result[((row * (oldx div 2)) + col) * (Self.FDepth div 8) + j] :=
+            img[(i * (Self.FDepth div 8)) + j];
+        Inc(col);
+      end;
+    end;
+  end;
+end;
+
+
+
+
+procedure TOniImage.RevertImage;
+var
+  x, y, i: LongWord;
+  tempd:   Tdata;
+begin
+  SetLength(tempd, Self.FWidth * Self.FHeight * (Self.FDepth div 8));
+  for y := 0 to Self.FHeight - 1 do
+    for x := 0 to Self.FWidth - 1 do
+      for i := 0 to (Self.FDepth div 8) - 1 do
+        tempd[((Self.FWidth * (Self.FHeight - 1 - y) + x) * (Self.FDepth div 8)) + i] :=
+          Self.FData[(Self.FWidth * y + x) * (Self.FDepth div 8) + i];
+  for x := 0 to High(tempd) do
+    Self.FData[x] := tempd[x];
+  if DT_OniReverted in Self.FDataType then
+    Self.FDataType := Self.FDataType - [DT_OniReverted]
+  else
+    Self.FDataType := Self.FDataType + [DT_OniReverted];
+end;
+
+
+
+
+procedure TOniImage.DecodeImage;
+var
+  x, y:  LongWord;
+  tempd: Tdata;
+begin
+  if not (DT_Decoded32 in Self.FDataType) then
+  begin
+    SetLength(tempd, Self.FWidth * Self.FHeight * 4);
+    case Self.FStoreType of
+      0:
+      begin
+        for y := 0 to Self.FHeight - 1 do
+        begin
+          for x := 0 to Self.FWidth - 1 do
+          begin
+            tempd[((Self.FWidth * y + x) * 4) + 0] :=
+              Round(((Self.FData[(Self.FWidth * y + x) * 2] + Self.FData[(Self.FWidth * y + x) * 2 + 1] * 256) and
+              $000F) / $000F * 255);
+            tempd[((Self.FWidth * y + x) * 4) + 1] :=
+              Round(((Self.FData[(Self.FWidth * y + x) * 2] + Self.FData[(Self.FWidth * y + x) * 2 + 1] * 256) and
+              $00F0) / $00F0 * 255);
+            tempd[((Self.FWidth * y + x) * 4) + 2] :=
+              Round(((Self.FData[(Self.FWidth * y + x) * 2] + Self.FData[(Self.FWidth * y + x) * 2 + 1] * 256) and
+              $0F00) / $0F00 * 255);
+            tempd[((Self.FWidth * y + x) * 4) + 3] := 0;
+          end;
+        end;
+      end;
+      1, 2:
+      begin
+        for y := 0 to Self.FHeight - 1 do
+        begin
+          for x := 0 to Self.FWidth - 1 do
+          begin
+            tempd[((Self.FWidth * y + x) * 4) + 0] :=
+              Round(((Self.FData[(Self.FWidth * y + x) * 2] + Self.FData[(Self.FWidth * y + x) * 2 + 1] * 256) and
+              $001F) / $001F * 255);
+            tempd[((Self.FWidth * y + x) * 4) + 1] :=
+              Round(((Self.FData[(Self.FWidth * y + x) * 2] + Self.FData[(Self.FWidth * y + x) * 2 + 1] * 256) and
+              $03E0) / $03E0 * 255);
+            tempd[((Self.FWidth * y + x) * 4) + 2] :=
+              Round(((Self.FData[(Self.FWidth * y + x) * 2] + Self.FData[(Self.FWidth * y + x) * 2 + 1] * 256) and
+              $7C00) / $7C00 * 255);
+            tempd[((Self.FWidth * y + x) * 4) + 3] := 0;
+          end;
+        end;
+      end;
+      9:
+      begin
+        DecompressImage;
+      end;
+    end;
+    Self.FDepth := 32;
+    if (Self.FStoreType <> 9) and (Self.FStoreType <> 8) then
+    begin
+      SetLength(Self.FData, Length(tempd));
+      for x := 0 to High(tempd) do
+        Self.FData[x] := tempd[x];
+    end;
+    Self.FStoreType := 8;
+    if DT_Oni in Self.FDataType then
+      Self.FDataType := Self.FDataType - [DT_Oni];
+    Self.FDataType := Self.FDataType + [DT_Decoded32];
+  end;
+  if DT_OniReverted in Self.FDataType then
+    Self.RevertImage;
+end;
+
+
+
+
+procedure TOniImage.DecompressImage;
+type
+  Tcolor = record
+    RGBb: Byte;
+    RGBg: Byte;
+    RGBr: Byte;
+    RGBa: Byte;
+  end;
+var
+  i, j, x, y: LongWord;
+  color:      array[1..4] of Tcolor;
+  pixel:      array[1..16] of Byte;
+  tempd:      Tdata;
+begin
+  x := 0;
+  y := 0;
+  SetLength(tempd, Self.FWidth * Self.FHeight * 4);
+  for i := 0 to ((Self.FWidth * Self.FHeight) div 16) - 1 do
+  begin
+    Color[1].RGBb := Round(((Self.FData[(i * 8) + 0] + Self.FData[(i * 8) + 1] * 256) and $001F) /
+      $001F * 255);
+    Color[1].RGBg := Round(((Self.FData[(i * 8) + 0] + Self.FData[(i * 8) + 1] * 256) and $07E0) /
+      $07E0 * 255);
+    Color[1].RGBr := Round(((Self.FData[(i * 8) + 0] + Self.FData[(i * 8) + 1] * 256) and $F800) /
+      $F800 * 255);
+    Color[1].RGBa := 255;
+    Color[2].RGBb := Round(((Self.FData[(i * 8) + 2] + Self.FData[(i * 8) + 3] * 256) and $001F) /
+      $001F * 255);
+    Color[2].RGBg := Round(((Self.FData[(i * 8) + 2] + Self.FData[(i * 8) + 3] * 256) and $07E0) /
+      $07E0 * 255);
+    Color[2].RGBr := Round(((Self.FData[(i * 8) + 2] + Self.FData[(i * 8) + 3] * 256) and $F800) /
+      $F800 * 255);
+    Color[2].RGBa := 255;
+    Color[3].RGBb := Round(Color[1].RGBb / 3 * 2 + Color[2].RGBb / 3);
+    Color[3].RGBg := Round(Color[1].RGBg / 3 * 2 + Color[2].RGBg / 3);
+    Color[3].RGBr := Round(Color[1].RGBr / 3 * 2 + Color[2].RGBr / 3);
+    Color[3].RGBa := 255;
+    Color[4].RGBb := Round(Color[1].RGBb / 3 + Color[2].RGBb / 3 * 2);
+    Color[4].RGBg := Round(Color[1].RGBg / 3 + Color[2].RGBg / 3 * 2);
+    Color[4].RGBr := Round(Color[1].RGBr / 3 + Color[2].RGBr / 3 * 2);
+    Color[4].RGBa := 255;
+    Pixel[1]      := Round((Self.FData[(i * 8) + 4] and $C0) / $40 + 1);
+    Pixel[2]      := Round((Self.FData[(i * 8) + 4] and $30) / $10 + 1);
+    Pixel[3]      := Round((Self.FData[(i * 8) + 4] and $0C) / $04 + 1);
+    Pixel[4]      := Round((Self.FData[(i * 8) + 4] and $03) + 1);
+    Pixel[5]      := Round((Self.FData[(i * 8) + 5] and $C0) / $40 + 1);
+    Pixel[6]      := Round((Self.FData[(i * 8) + 5] and $30) / $10 + 1);
+    Pixel[7]      := Round((Self.FData[(i * 8) + 5] and $0C) / $04 + 1);
+    Pixel[8]      := Round((Self.FData[(i * 8) + 5] and $03) + 1);
+    Pixel[9]      := Round((Self.FData[(i * 8) + 6] and $C0) / $40 + 1);
+    Pixel[10]     := Round((Self.FData[(i * 8) + 6] and $30) / $10 + 1);
+    Pixel[11]     := Round((Self.FData[(i * 8) + 6] and $0C) / $04 + 1);
+    Pixel[12]     := Round((Self.FData[(i * 8) + 6] and $03) + 1);
+    Pixel[13]     := Round((Self.FData[(i * 8) + 7] and $C0) / $40 + 1);
+    Pixel[14]     := Round((Self.FData[(i * 8) + 7] and $30) / $10 + 1);
+    Pixel[15]     := Round((Self.FData[(i * 8) + 7] and $0C) / $04 + 1);
+    Pixel[16]     := Round((Self.FData[(i * 8) + 7] and $03) + 1);
+    for j := 0 to 3 do
+    begin
+      tempd[((y + 3) * Self.FWidth + x + j) * 4 + 0] := Color[Pixel[16 - j]].RGBb;
+      tempd[((y + 3) * Self.FWidth + x + j) * 4 + 1] := Color[Pixel[16 - j]].RGBg;
+      tempd[((y + 3) * Self.FWidth + x + j) * 4 + 2] := Color[Pixel[16 - j]].RGBr;
+      tempd[((y + 3) * Self.FWidth + x + j) * 4 + 3] := 0;
+    end;
+    for j := 0 to 3 do
+    begin
+      tempd[((y + 2) * Self.FWidth + x + j) * 4 + 0] := Color[Pixel[12 - j]].RGBb;
+      tempd[((y + 2) * Self.FWidth + x + j) * 4 + 1] := Color[Pixel[12 - j]].RGBg;
+      tempd[((y + 2) * Self.FWidth + x + j) * 4 + 2] := Color[Pixel[12 - j]].RGBr;
+      tempd[((y + 2) * Self.FWidth + x + j) * 4 + 3] := 0;
+    end;
+    for j := 0 to 3 do
+    begin
+      tempd[((y + 1) * Self.FWidth + x + j) * 4 + 0] := Color[Pixel[8 - j]].RGBb;
+      tempd[((y + 1) * Self.FWidth + x + j) * 4 + 1] := Color[Pixel[8 - j]].RGBg;
+      tempd[((y + 1) * Self.FWidth + x + j) * 4 + 2] := Color[Pixel[8 - j]].RGBr;
+      tempd[((y + 1) * Self.FWidth + x + j) * 4 + 3] := 0;
+    end;
+    for j := 0 to 3 do
+    begin
+      tempd[((y + 0) * Self.FWidth + x + j) * 4 + 0] := Color[Pixel[4 - j]].RGBb;
+      tempd[((y + 0) * Self.FWidth + x + j) * 4 + 1] := Color[Pixel[4 - j]].RGBg;
+      tempd[((y + 0) * Self.FWidth + x + j) * 4 + 2] := Color[Pixel[4 - j]].RGBr;
+      tempd[((y + 0) * Self.FWidth + x + j) * 4 + 3] := 0;
+    end;
+    x := x + 4;
+    if x = Self.FWidth then
+    begin
+      y := y + 4;
+      x := 0;
+    end;
+  end;
+  SetLength(Self.FData, Length(tempd));
+  for i := 0 to High(tempd) do
+    Self.FData[i] := tempd[i];
+  Self.FStoreType := 8;
+  Self.FDepth    := 32;
+  Self.FDataType := Self.FDataType - [DT_Oni] + [DT_Decoded32];
+end;
+
+
+
+
+
+function TOniImage.Load(fileid: LongWord): Boolean;
+var
+  FileInfo: TFileInfo;
+  ext:      String;
+begin
+  FileInfo := OniDataConnection.GetFileInfo(fileid);
+  if FileInfo.Extension = 'PSpc' then
+    Result := LoadFromPSpc(fileid)
+  else if FileInfo.Extension = 'TXMB' then
+    Result := LoadFromTXMB(fileid)
+  else if FileInfo.Extension = 'TXMP' then
+    Result := LoadFromTXMP(fileid)
+  else
+    Result := False;
+end;
+
+
+
+
+function TOniImage.LoadFromPSpc(fileid: LongWord): Boolean;
+type
+  TPoint = packed record
+    X, Y: Word;
+  end;
+
+  TPSpc = packed record
+    p1:   array[0..8] of TPoint;
+    p2:   array[0..8] of TPoint;
+    TXMP: LongWord;
+  end;
+
+  TPart = packed record
+    x_txmp, y_txmp: Word;
+    x_pspc, y_pspc: Word;
+    w, h:    Word;
+    imgdata: Tdata;
+    used:    Boolean;
+  end;
+const
+  PartMatch: array[0..8] of Byte = (0, 3, 6, 1, 4, 7, 2, 5, 8);
+var
+  x, y, pixel: Word;
+  i: Integer;
+
+  PSpc:     TPSpc;
+  txmpimg:  TOniImage;
+  txmpdata: Tdata;
+
+  parts:    array[0..8] of TPart;
+  part:     Byte;
+  cols:     array[0..2] of Word;
+  rows:     array[0..2] of Word;
+  col, row: Byte;
+begin
+  OniDataConnection.LoadDatFilePart(fileid, $08, SizeOf(PSpc), @PSpc);
+  PSpc.TXMP := PSpc.TXMP div 256;
+  if PSpc.TXMP = 0 then
+  begin
+    Result := False;
+    Exit;
+  end;
+  txmpimg := TOniImage.Create;
+  txmpimg.LoadFromTXMP(PSpc.TXMP);
+  txmpimg.DecodeImage;
+  txmpimg.WriteToBMP('C:\file.bmp');
+  txmpdata := txmpimg.GetAs32bit;
+{    ShowMessage(IntToStr(txmpimg.Width)+'x'+IntToStr(txmpimg.Height));
+    for i:=0 to High(txmpdata) do
+      txmpimg.Data[i]:=txmpdata[i];
+    txmpimg.WriteToBMP('D:\file2.bmp');
+}
+  with PSpc do
+  begin
+    for i := 0 to 2 do
+    begin
+      cols[i] := 0;
+      rows[i] := 0;
+    end;
+    for i := 0 to 8 do
+    begin
+      part := PartMatch[i];
+      col  := i div 3;
+      row  := i mod 3;
+      if (p2[i].X > 0) or (p2[i].Y > 0) then
+      begin
+        parts[part].x_txmp := p1[i].X - 1;
+        parts[part].y_txmp := p1[i].Y - 1;
+        parts[part].x_pspc := 0;
+        if col > 0 then
+          for x := 0 to col - 1 do
+            Inc(parts[part].x_pspc, cols[x]);
+        parts[part].y_pspc := 0;
+        if row > 0 then
+          for y := 0 to row - 1 do
+            Inc(parts[part].y_pspc, rows[y]);
+        parts[part].w := p2[i].X - p1[i].X + 1;
+        parts[part].h := p2[i].Y - p1[i].Y + 1;
+        parts[part].used := True;
+        cols[col] := parts[part].w;
+        rows[row] := parts[part].h;
+        SetLength(parts[part].imgdata, parts[part].w * parts[part].h * 4);
+        for y := 0 to parts[part].h - 1 do
+        begin
+          for x := 0 to parts[part].w - 1 do
+          begin
+            for pixel := 0 to 3 do
+            begin
+              parts[part].imgdata[(y * parts[part].w + x) * 4 + pixel] :=
+                txmpdata[((parts[part].y_txmp + y) * txmpimg.Width +
+                parts[part].x_txmp + x) * 4 + pixel];
+            end;
+          end;
+        end;
+      end
+      else
+      begin
+        parts[part].used := False;
+      end;
+    end;
+
+  end;
+
+  txmpimg.Free;
+  txmpimg := TOniImage.Create;
+  for i := 0 to 8 do
+  begin
+    if parts[i].used then
+    begin
+      SetLength(txmpimg.FData, Length(parts[i].imgdata));
+      for pixel := 0 to High(parts[i].imgdata) do
+        txmpimg.Data[pixel] := parts[i].imgdata[pixel];
+      txmpimg.Width := parts[i].w;
+      txmpimg.Height    := parts[i].h;
+      txmpimg.StoreType := 8;
+      txmpimg.DataType  := [DT_Decoded32];
+      txmpimg.Depth     := 32;
+      txmpimg.WriteToBMP('D:\' + IntToStr(i) + '.bmp');
+    end;
+  end;
+  txmpimg.Free;
+
+  Self.FWidth  := 0;
+  Self.FHeight := 0;
+  for i := 0 to 2 do
+  begin
+    Inc(Self.FWidth, cols[i]);
+    Inc(Self.FHeight, rows[i]);
+  end;
+  SetLength(Self.FData, Self.FWidth * Self.FHeight * 4);
+
+  //Combine data parts
+
+  Self.FDepth     := 32;
+  Self.FStoreType := 8;
+  Self.FDataType  := [DT_Decoded32];
+  //    Self.RevertImage;
+end;
+
+
+
+
+function TOniImage.LoadFromTXMP(fileid: LongWord): Boolean;
+var
+  img_addr: LongWord;
+begin
+  Result := True;
+  OniDataConnection.LoadDatFilePart(fileid, $8C, SizeOf(Self.FWidth), @Self.FWidth);
+  OniDataConnection.LoadDatFilePart(fileid, $8E, SizeOf(Self.FHeight), @Self.FHeight);
+  OniDataConnection.LoadDatFilePart(fileid, $90, SizeOf(Self.FStoreType),
+    @Self.FStoreType);
+  if not OniDataConnection.OSisMac then
+    OniDataConnection.LoadDatFilePart(fileid, $9C, SizeOf(img_addr), @img_addr)
+  else
+    OniDataConnection.LoadDatFilePart(fileid, $A0, SizeOf(img_addr), @img_addr);
+
+  case Self.FStoreType of
+    0, 1, 2:
+    begin
+      SetLength(Self.FData, Self.FWidth * Self.FHeight * 2);
+      Self.FDepth := 16;
+    end;
+    8:
+    begin
+      SetLength(Self.FData, Self.FWidth * Self.FHeight * 4);
+      Self.FDepth := 32;
+    end;
+    9:
+    begin
+      SetLength(Self.FData, Self.FWidth * Self.FHeight div 2);
+      Self.FDepth := 16;
+    end;
+    else
+      Result := False;
+      Exit;
+  end;
+
+  if not OniDataConnection.OSisMac then
+    OniDataConnection.LoadRawFile(fileid, $9C, @Self.FData[0])
+  else
+    OniDataConnection.LoadRawFile(fileid, $A0, @Self.FData[0]);
+
+  Self.FDataType := [DT_OniReverted, DT_Oni];
+end;
+
+
+
+
+function TOniImage.LoadFromTXMB(fileid: LongWord): Boolean;
+var
+  i, x, y, x2, y2, pixelid, imgid: LongWord;
+  rows, cols: Word;
+  linkcount: LongWord;
+  link: LongWord;
+  images_decoded: array of TOniImage;
+  x_start, y_start: LongWord;
+begin
+  OniDataConnection.LoadDatFilePart(fileid, $10, SizeOf(Self.FWidth), @Self.FWidth);
+  OniDataConnection.LoadDatFilePart(fileid, $12, SizeOf(Self.FHeight), @Self.FHeight);
+  OniDataConnection.LoadDatFilePart(fileid, $18, SizeOf(cols), @cols);
+  OniDataConnection.LoadDatFilePart(fileid, $1A, SizeOf(rows), @rows);
+  OniDataConnection.LoadDatFilePart(fileid, $1C, SizeOf(linkcount), @linkcount);
+  SetLength(images_decoded, linkcount);
+  for i := 0 to linkcount - 1 do
+  begin
+    OniDataConnection.LoadDatFilePart(fileid, $20 + i * 4, SizeOf(link), @link);
+    link := link div 256;
+    images_decoded[i] := TOniImage.Create;
+    images_decoded[i].LoadFromTXMP(link);
+    images_decoded[i].DecodeImage;
+    images_decoded[i].RevertImage;
+  end;
+  SetLength(Self.FData, Self.FWidth * Self.FHeight * 4);
+  for y := 0 to rows - 1 do
+  begin
+    for x := 0 to cols - 1 do
+    begin
+      imgid   := y * cols + x;
+      x_start := 0;
+      y_start := 0;
+      for i := 0 to x do
+        if i < x then
+          x_start := x_start + images_decoded[i].Width;
+      for i := 0 to y do
+        if i < y then
+          y_start := y_start + images_decoded[i].Height;
+      for y2 := 0 to images_decoded[imgid].Height - 1 do
+      begin
+        for x2 := 0 to images_decoded[imgid].Width - 1 do
+        begin
+          if ((x_start + x2) < Self.FWidth) and ((y_start + y2) < Self.FHeight) then
+          begin
+            pixelid := y_start * Self.FWidth + x_start + y2 * Self.FWidth + x2;
+            Self.FData[pixelid * 4 + 0] :=
+              images_decoded[imgid].Data[(y2 * images_decoded[imgid].Width + x2) * 4 + 0];
+            Self.FData[pixelid * 4 + 1] :=
+              images_decoded[imgid].Data[(y2 * images_decoded[imgid].Width + x2) * 4 + 1];
+            Self.FData[pixelid * 4 + 2] :=
+              images_decoded[imgid].Data[(y2 * images_decoded[imgid].Width + x2) * 4 + 2];
+            Self.FData[pixelid * 4 + 3] :=
+              images_decoded[imgid].Data[(y2 * images_decoded[imgid].Width + x2) * 4 + 3];
+          end;
+        end;
+      end;
+    end;
+  end;
+  for i := 0 to linkcount - 1 do
+    images_decoded[i].Free;
+  Self.FDepth     := 32;
+  Self.FStoreType := 8;
+  Self.FDataType  := [DT_Decoded32];
+  Self.RevertImage;
+end;
+
+
+
+
+function TOniImage.GetImageDataSize(fading: Boolean): LongWord;
+var
+  size: LongWord;
+  x, y: Word;
+  bpp:  Byte;
+begin
+  case Self.FStoreType of
+    9:
+      bpp := 8;
+    0, 1, 2:
+      bpp := 16;
+    8:
+      bpp := 32;
+    else
+      Result := 0;
+      Exit;
+  end;
+
+  x    := Self.FWidth;
+  y    := Self.FHeight;
+  size := x * y * bpp div 8;
+  if fading then
+  begin
+    repeat
+      x    := x div 2;
+      y    := y div 2;
+      size := size + x * y * bpp div 8;
+    until (x = 1) or (y = 1);
+  end;
+  Result := size;
+end;
+
+
+
+
+function TOniImage.GetAsData: Tdata;
+var
+  i:      Integer;
+  revert: Boolean;
+begin
+  //    if not (DT_Decoded32 in Self.FDataType) then
+  //      Self.DecodeImage;
+  if not (DT_OniReverted in Self.FDataType) then
+  begin
+    revert := True;
+    Self.RevertImage;
+  end
+  else
+    revert := False;
+  SetLength(Result, Length(Self.FData));
+  for i := 0 to High(Result) do
+    Result[i] := Self.FData[i];
+  if revert then
+    Self.RevertImage;
+end;
+
+
+
+
+function TOniImage.GetAs32bit: Tdata;
+var
+  i: Integer;
+begin
+  if not (DT_Decoded32 in Self.FDataType) then
+    Self.DecodeImage;
+  SetLength(Result, Length(Self.FData));
+  for i := 0 to High(Result) do
+    Result[i] := Self.FData[i];
+end;
+
+
+
+
+function TOniImage.GetAsBMP: Tdata;
+const
+  BMPheader: array[0..53] of Byte =
+    ($42, $4D, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0,
+    40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, $18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+var
+  i, x, y: LongWord;
+begin
+  if not (DT_Decoded32 in Self.FDataType) then
+    Self.DecodeImage;
+
+  SetLength(Result, Self.FWidth * Self.FHeight * 3 + 54);
+  for y := 0 to Self.FHeight - 1 do
+  begin
+    for x := 0 to Self.FWidth - 1 do
+    begin
+      Result[((Self.FWidth * y + x) * 3) + 0 + 54] := Self.FData[(Self.FWidth * y + x) * 4 + 0];
+      Result[((Self.FWidth * y + x) * 3) + 1 + 54] := Self.FData[(Self.FWidth * y + x) * 4 + 1];
+      Result[((Self.FWidth * y + x) * 3) + 2 + 54] := Self.FData[(Self.FWidth * y + x) * 4 + 2];
+    end;
+  end;
+
+  for i := 0 to High(BMPheader) do
+    Result[i] := BMPheader[i];
+  Result[2] := ((Self.FWidth * Self.FHeight * 3 + 54) and $000000FF) div $1;
+  Result[3]  := ((Self.FWidth * Self.FHeight * 3 + 54) and $0000FF00) div $100;
+  Result[4]  := ((Self.FWidth * Self.FHeight * 3 + 54) and $00FF0000) div $10000;
+  Result[5]  := ((Self.FWidth * Self.FHeight * 3 + 54) and $FF000000) div $1000000;
+  Result[18] := (Self.FWidth and $000000FF) div $1;
+  Result[19] := (Self.FWidth and $0000FF00) div $100;
+  Result[20] := (Self.FWidth and $00FF0000) div $10000;
+  Result[21] := (Self.FWidth and $FF000000) div $1000000;
+  Result[22] := (Self.FHeight and $000000FF) div $1;
+  Result[23] := (Self.FHeight and $0000FF00) div $100;
+  Result[24] := (Self.FHeight and $00FF0000) div $10000;
+  Result[25] := (Self.FHeight and $FF000000) div $1000000;
+  Result[34] := ((Self.FWidth * Self.FHeight * 3) and $000000FF) div $1;
+  Result[35] := ((Self.FWidth * Self.FHeight * 3) and $0000FF00) div $100;
+  Result[36] := ((Self.FWidth * Self.FHeight * 3) and $00FF0000) div $10000;
+  Result[37] := ((Self.FWidth * Self.FHeight * 3) and $FF000000) div $1000000;
+end;
+
+
+
+
+function TOniImage.LoadFromBMP(filename: String): Boolean;
+var
+  filestream: TFileStream;
+  tempd:      Tdata;
+
+  x, y: LongWord;
+begin
+  filestream := TFileStream.Create(filename, fmOpenRead);
+  SetLength(tempd, filestream.Size);
+  filestream.Read(tempd[0], filestream.Size);
+  filestream.Free;
+
+  if not ((tempd[00] = $42) and (tempd[01] = $4D)) then
+  begin
+    Result := False;
+    ShowMessage('Not a standard 24bit bitmap');
+    Exit;
+  end;
+  if not (tempd[10] = 54) then
+  begin
+    Result := False;
+    ShowMessage('Imagedata has to start at 0x54');
+    Exit;
+  end;
+  if not (tempd[14] = 40) then
+  begin
+    Result := False;
+    ShowMessage('Second bitmap header has to have 40 bytes');
+    Exit;
+  end;
+  if not (tempd[28] = 24) then
+  begin
+    Result := False;
+    ShowMessage('Bitmap has to have 24bits');
+    Exit;
+  end;
+  if not (tempd[30] = 0) then
+  begin
+    Result := False;
+    ShowMessage('Bitmap has to be uncompressed');
+    Exit;
+  end;
+
+  Self.FWidth     := tempd[18] + tempd[19] * 256 + tempd[20] * 256 * 256 + tempd[21] * 256 * 256 * 256;
+  Self.FHeight    := tempd[22] + tempd[23] * 256 + tempd[24] * 256 * 256 + tempd[25] * 256 * 256 * 256;
+  Self.FDepth     := 32;
+  Self.FStoreType := 8;
+
+  SetLength(Self.FData, Self.FWidth * Self.FHeight * Self.FDepth div 8);
+  for y := 0 to Self.FHeight - 1 do
+  begin
+    for x := 0 to Self.FWidth - 1 do
+    begin
+      Self.FData[((Self.FWidth * y + x) * 4) + 0] := tempd[54 + (Self.FWidth * y + x) * 3 + 0];
+      Self.FData[((Self.FWidth * y + x) * 4) + 1] := tempd[54 + (Self.FWidth * y + x) * 3 + 1];
+      Self.FData[((Self.FWidth * y + x) * 4) + 2] := tempd[54 + (Self.FWidth * y + x) * 3 + 2];
+      Self.FData[((Self.FWidth * y + x) * 4) + 3] := 0;
+    end;
+  end;
+
+  Self.FDataType := [DT_Decoded32];
+end;
+
+
+
+
+function TOniImage.WriteToBMP(filename: String): Boolean;
+var
+  filestream: TFileStream;
+  tempd:      Tdata;
+begin
+  tempd      := Self.GetAsBMP;
+  filestream := TFileStream.Create(filename, fmCreate);
+  filestream.Write(tempd[0], Length(tempd));
+  filestream.Free;
+end;
+
+
+
+
+function TOniImage.GetMipMappedImage(var faded: Tdata): Boolean;
+var
+  i:      LongWord;
+  x, y:   Word;
+  fadelvldata: Tdata;
+  revert: Boolean;
+begin
+  Result := False;
+
+  //    if not (DT_Decoded32 in Self.FDataType) then
+  //      Self.DecodeImage;
+  if Self.FStoreType = 9 then
+    Self.DecompressImage;
+  if not (DT_OniReverted in Self.FDataType) then
+  begin
+    revert := True;
+    Self.RevertImage;
+  end
+  else
+    revert := False;
+
+  x := Self.FWidth;
+  y := Self.FHeight;
+  SetLength(faded, x * y * Self.FDepth div 8);
+  SetLength(fadelvldata, x * y * Self.FDepth div 8);
+  for i := 0 to Length(faded) - 1 do
+  begin
+    faded[i] := Self.FData[i];
+    fadelvldata[i] := Self.FData[i];
+  end;
+  repeat
+    fadelvldata := Self.ResizeImage(x, y, fadelvldata);
+    x := x div 2;
+    y := y div 2;
+    SetLength(faded, Length(faded) + x * y * Self.FDepth div 8);
+    for i := 0 to Length(fadelvldata) - 1 do
+      faded[Length(faded) - x * y * Self.FDepth div 8 + i] := fadelvldata[i];
+  until (x = 1) or (y = 1) or ((x mod 2) = 1) or ((y mod 2) = 1);
+  if (x > 1) and (y > 1) then
+    Exit;
+  Result := True;
+
+  if revert then
+    Self.RevertImage;
+end;
+
+
+end.
Index: oup/current/Code_DataStructures.pas
===================================================================
--- oup/current/Code_DataStructures.pas	(revision 45)
+++ 	(revision )
@@ -1,605 +1,0 @@
-unit Code_DataStructures;
-
-interface
-
-uses SysUtils, Classes, Data, Dialogs, StrUtils;
-
-type
-  Tstructure_entry = record
-    Name:     String;
-    offset:   LongWord;
-    datatype: Word;  // 1..4  : Integer[1..4] dec
-    // 5..8  : Integer[1..4] hex
-    // 9     : float
-    // 10    : bitset
-    // 11    : raw-addr
-    // 12    : dat-file-ID
-    // 13..16: Signed Integer[1..4]
-    // 17    : level-ID
-    // 100..300: dat-file-name[0..200]
-    // 1000..9999: Unused data[0-8999]
-    // 10000+: string[0+]
-    description: String;
-  end;
-
-  TStructDefSub = record
-    SubName: String;
-    SubDesc: String;
-    Entries: array of TStructure_entry;
-  end;
-
-  TStructDef = record
-    Data:   Boolean;
-    Global: array of TStructure_entry;
-    Subs:   array of TStructDefSub;
-  end;
-  THandler = function(fileid: LongWord): TRawList;
-
-  TRawListHandlers = record
-    Ext:     String[4];
-    needed:  Boolean;
-    Handler: THandler;
-  end;
-
-var
-  RawListHandlers: array of TRawListHandlers;
-  Raws: String;
-
-
-function LoadStructureDefinition(fileid: LongWord): TStructDef;
-function GetDataType(typeid: Word): String;
-function GetTypeDataLength(datatype: Word): Word;
-
-implementation
-
-uses Code_Functions, Code_OniDataClass, Forms, Tool_Template;
-
-
-
-
-function GetTypeDataLength(datatype: Word): Word;
-begin
-  case datatype of
-    1..4:
-      Result := datatype;
-    5..8:
-      Result := datatype - 4;
-    9:
-      Result := 4;
-    10:
-      Result := 1;
-    11:
-      Result := 4;
-    12:
-      Result := 4;
-    13..16:
-      Result := datatype - 12;
-    17:
-      Result := 4;
-    100..300:
-      Result := datatype - 100;
-    1000..9999:
-      Result := datatype - 1000;
-    10000..65535:
-      Result := datatype - 10000;
-  end;
-end;
-
-
-
-
-function GetDataType(typeid: Word): String;
-begin
-  case typeid of
-    1..4:
-      Result := 'Int' + IntToStr(typeid * 8);
-    5..8:
-      Result := 'Int' + IntToStr((typeid - 4) * 8);
-    9:
-      Result := 'Float';
-    10:
-      Result := 'BitSet';
-    11:
-      Result := 'Raw-Address';
-    12:
-      Result := '.dat-file-ID';
-    13..16:
-      Result := 'SignedInt' + IntToStr((typeid - 12) * 8);
-    17:
-      Result := 'LevelID';
-    100..300:
-      Result := '.dat-file-name(' + IntToStr(typeid - 100) + ')';
-    1000..9999:
-      Result := 'Unused(' + IntToStr(typeid - 1000) + ')';
-    10000..65535:
-      Result := 'String(' + IntToStr(typeid - 10000) + ')';
-  end;
-end;
-
-
-
-
-function AGDB(fileid: LongWord): TRawList;
-var
-  link:  LongWord;
-  links: LongWord;
-  i:     LongWord;
-begin
-  if not OniDataConnection.OSisMac then
-  begin
-    OniDataConnection.LoadDatFilePart(fileid, $1C, 4, @links);
-    links := links * 2;
-    SetLength(Result, links);
-    for i := 0 to links - 1 do
-    begin
-      Result[i].src_offset := $20 + i * 4;
-      OniDataConnection.LoadDatFilePart(fileid, $20 + i * 4, 4, @link);
-      Result[i].raw_addr := link;
-      Result[i].raw_size := 0{????????????????????????????????};
-      Result[i].loc_sep  := False;
-    end;
-  end;
-end;
-
-
-
-
-function AKVA(fileid: LongWord): TRawList;
-var
-  link:  LongWord;
-  links: LongWord;
-  i:     LongWord;
-begin
-  if not OniDataConnection.OSisMac then
-  begin
-    OniDataConnection.LoadDatFilePart(fileid, $1C, 4, @links);
-    SetLength(Result, links);
-    for i := 0 to links - 1 do
-    begin
-      Result[i].src_offset := $20 + i * $74 + $24;
-      OniDataConnection.LoadDatFilePart(fileid, $20 + i * $74 + $24, 4, @link);
-      Result[i].raw_addr := link;
-      OniDataConnection.LoadDatFilePart(fileid, $20 + i * $74 + $28, 4, @link);
-      Result[i].raw_size := link;
-      Result[i].loc_sep  := False;
-    end;
-  end;
-end;
-
-
-
-
-function BINA(fileid: LongWord): TRawList;
-var
-  link:     LongWord;
-  datasize: LongWord;
-begin
-  OniDataConnection.LoadDatFilePart(fileid, $0C, 4, @link);
-  OniDataConnection.LoadDatFilePart(fileid, $08, 4, @datasize);
-  SetLength(Result, 1);
-  Result[0].src_offset := $0C;
-  Result[0].raw_addr   := link;
-  Result[0].raw_size   := datasize;
-  Result[0].loc_sep    := OniDataConnection.OSisMac;
-end;
-
-
-
-
-function OSBD(fileid: LongWord): TRawList;
-var
-  link:     LongWord;
-  datasize: LongWord;
-begin
-  OniDataConnection.LoadDatFilePart(fileid, $08, 4, @datasize);
-  OniDataConnection.LoadDatFilePart(fileid, $0C, 4, @link);
-  SetLength(Result, 1);
-  Result[0].src_offset := $0C;
-  Result[0].raw_addr   := link;
-  Result[0].raw_size   := datasize;
-  Result[0].loc_sep    := OniDataConnection.OSisMac;
-end;
-
-
-
-
-function SNDD(fileid: LongWord): TRawList;
-var
-  link:     LongWord;
-  datasize: LongWord;
-begin
-  SetLength(Result, 1);
-  if not OniDataConnection.OSisMac then
-  begin
-    OniDataConnection.LoadDatFilePart(fileid, $40, 4, @datasize);
-    OniDataConnection.LoadDatFilePart(fileid, $44, 4, @link);
-    Result[0].src_offset := $44;
-  end
-  else
-  begin
-    OniDataConnection.LoadDatFilePart(fileid, $10, 4, @datasize);
-    OniDataConnection.LoadDatFilePart(fileid, $14, 4, @link);
-    Result[0].src_offset := $14;
-  end;
-  Result[0].raw_addr := link;
-  Result[0].raw_size := datasize;
-  Result[0].loc_sep  := False;
-end;
-
-
-
-
-function SUBT(fileid: LongWord): TRawList;
-var
-  baselink, lastlink: LongWord;
-  links: LongWord;
-  j, k:  LongWord;
-  Data:  Tdata;
-begin
-  OniDataConnection.LoadDatFilePart(fileid, $18, 4, @baselink);
-  OniDataConnection.LoadDatFilePart(fileid, $1C, 4, @links);
-  if links > 0 then
-  begin
-    OniDataConnection.LoadDatFilePart(fileid, $20 + (links - 1) * 4, 4, @lastlink);
-    SetLength(Data, lastlink + 1024);
-    TOniDataDat(OniDataConnection).LoadRawOffset(False,
-      baselink, lastlink + 1024, Data);
-    //      OniDataConnection.LoadRawFile(fileid,$1C,baselink,lastlink+1024,False,@data[0]);
-    k := 0;
-    for j := 0 to 1024 do
-    begin
-      if (Data[lastlink + j] = $00) or (j = 1024) then
-      begin
-        if j < 1024 then
-        begin
-          if k = 0 then
-          begin
-            k := 1;
-          end
-          else
-          begin
-            SetLength(Result, 1);
-            Result[0].src_offset := $18;
-            Result[0].raw_addr   := baselink;
-            Result[0].raw_size   := lastlink + j;
-            Break;
-          end;
-        end;
-      end;
-    end;
-  end;
-end;
-
-
-
-
-function TRAM(fileid: LongWord): TRawList;
-var
-  i:      Integer;
-  link:   LongWord;
-  frames: Word;
-  tempb:  Byte;
-  tempw:  Word;
-  templ:  LongWord;
-  Data:   Tdata;
-  offset: Word;
-  frame_count: Byte;
-begin
-  SetLength(Result, 13);
-  OniDataConnection.LoadDatFilePart(fileid, $16C, 2, @frames);
-  {y-pos}
-  OniDataConnection.LoadDatFilePart(fileid, $0C, 4, @link);
-  Result[0].src_offset := $0C;
-  Result[0].raw_addr   := link;
-  Result[0].raw_size   := frames * 4;
-  {x-z-pos}
-  OniDataConnection.LoadDatFilePart(fileid, $10, 4, @link);
-  Result[1].src_offset := $10;
-  Result[1].raw_addr   := link;
-  Result[1].raw_size   := frames * 8;
-  {attacks}
-  OniDataConnection.LoadDatFilePart(fileid, $182, 1, @tempb);
-  OniDataConnection.LoadDatFilePart(fileid, $14, 4, @link);
-  Result[2].src_offset := $14;
-  Result[2].raw_addr   := link;
-  Result[2].raw_size   := tempb * 32;
-  {damage}
-  OniDataConnection.LoadDatFilePart(fileid, $183, 1, @tempb);
-  OniDataConnection.LoadDatFilePart(fileid, $18, 4, @link);
-  Result[3].src_offset := $18;
-  Result[3].raw_addr   := link;
-  Result[3].raw_size   := tempb * 8;
-  {motionblur}
-  OniDataConnection.LoadDatFilePart(fileid, $184, 1, @tempb);
-  OniDataConnection.LoadDatFilePart(fileid, $1C, 4, @link);
-  Result[4].src_offset := $1C;
-  Result[4].raw_addr   := link;
-  Result[4].raw_size   := tempb * 8;
-  {shortcut}
-  OniDataConnection.LoadDatFilePart(fileid, $185, 1, @tempb);
-  OniDataConnection.LoadDatFilePart(fileid, $20, 4, @link);
-  Result[5].src_offset := $20;
-  Result[5].raw_addr   := link;
-  Result[5].raw_size   := tempb * 8;
-  {throw}
-  OniDataConnection.LoadDatFilePart(fileid, $24, 4, @link);
-  Result[6].src_offset := $24;
-  Result[6].raw_addr   := link;
-  if link > 0 then
-    Result[6].raw_size := 24
-  else
-    Result[6].raw_size := 0;
-  {footstep}
-  OniDataConnection.LoadDatFilePart(fileid, $186, 1, @tempb);
-  OniDataConnection.LoadDatFilePart(fileid, $28, 4, @link);
-  Result[7].src_offset := $28;
-  Result[7].raw_addr   := link;
-  Result[7].raw_size   := tempb * 4;
-  {particle}
-  OniDataConnection.LoadDatFilePart(fileid, $187, 1, @tempb);
-  OniDataConnection.LoadDatFilePart(fileid, $2C, 4, @link);
-  Result[8].src_offset := $2C;
-  Result[8].raw_addr   := link;
-  Result[8].raw_size   := tempb * 24;
-  {position}
-  OniDataConnection.LoadDatFilePart(fileid, $30, 4, @link);
-  Result[9].src_offset := $30;
-  Result[9].raw_addr   := link;
-  Result[9].raw_size   := frames * 8;
-  {particle}
-  OniDataConnection.LoadDatFilePart(fileid, $154, 2, @tempw);
-  OniDataConnection.LoadDatFilePart(fileid, $38, 4, @link);
-  Result[11].src_offset := $38;
-  Result[11].raw_addr   := link;
-  Result[11].raw_size   := tempw * 34;
-  {extent}
-  OniDataConnection.LoadDatFilePart(fileid, $138, 4, @templ);
-  OniDataConnection.LoadDatFilePart(fileid, $13C, 4, @link);
-  Result[12].src_offset := $13C;
-  Result[12].raw_addr   := link;
-  Result[12].raw_size   := templ * 12;
-
-  OniDataConnection.LoadDatFilePart(fileid, $34, 4, @link);
-  if link > 0 then
-  begin
-    OniDataConnection.LoadDatFilePart(fileid, $160, 2, @tempw);
-    frame_count := 0;
-    i := 0;
-    SetLength(Data, $FFFF);
-    TOniDataDat(OniDataConnection).LoadRawOffset(False, link, $FFFF, Data);
-    offset := Data[$24] + Data[$25] * 256;
-    while (offset + i < Length(Data)) and (frame_count < frames - 1) do
-    begin
-      Inc(i, tempw);
-      frame_count := frame_count + Data[offset + i];
-      Inc(i);
-    end;
-    if offset + i < Length(Data) then
-    begin
-      Inc(i, tempw);
-      Result[10].raw_size := offset + i;
-    end
-    else
-    begin
-      Result[10].raw_size := 0;
-    end;
-  end;
-  Result[10].src_offset := $34;
-  Result[10].raw_addr   := link;
-end;
-
-
-
-
-function TXMP(fileid: LongWord): TRawList;
-var
-  link_pc:   LongWord;
-  link_mac:  LongWord;
-  x, y:      Word;
-  storetype: Byte;
-  datasize:  LongWord;
-begin
-  OniDataConnection.LoadDatFilePart(fileid, $8C, SizeOf(x), @x);
-  OniDataConnection.LoadDatFilePart(fileid, $8E, SizeOf(y), @y);
-  OniDataConnection.LoadDatFilePart(fileid, $90, SizeOf(storetype), @storetype);
-  OniDataConnection.LoadDatFilePart(fileid, $9C, 4, @link_pc);
-  OniDataConnection.LoadDatFilePart(fileid, $A0, 4, @link_mac);
-  case storetype of
-    0, 1, 2:
-      datasize := x * y * 2;
-    8:
-      datasize := x * y * 4;
-    9:
-      datasize := x * y div 2;
-  end;
-  SetLength(Result, 1);
-  if not OniDataConnection.OSisMac then
-  begin
-    Result[0].src_offset := $9C;
-    Result[0].raw_addr   := link_pc;
-  end
-  else
-  begin
-    Result[0].src_offset := $A0;
-    Result[0].raw_addr   := link_mac;
-  end;
-  Result[0].raw_size := datasize;
-  Result[0].loc_sep  := OniDataConnection.OSisMac;
-end;
-
-
-
-
-procedure InsertRawListHandler(ext: String; needed: Boolean; handler: THandler);
-begin
-  SetLength(RawListHandlers, Length(RawListHandlers) + 1);
-  RawListHandlers[High(RawListHandlers)].Ext := ext;
-  RawListHandlers[High(RawListHandlers)].needed := needed;
-  RawListHandlers[High(RawListHandlers)].handler := handler;
-  Raws := Raws + ext;
-  AddToolListEntry('rawedit', '', ext);
-end;
-
-
-
-
-function LoadStructureDefinition(fileid: LongWord): TStructDef;
-var
-  i:      LongWord;
-  current_type: Byte; //0: Global, 1: Undynamic, 2: Dynamic
-  current_base, current_package, current_package_size: LongWord;
-  packages: LongWord;
-  deffile: Text;
-  structentry: TStructure_Entry;
-  fields: TStringArray;
-  filename: String;
-  ext:    String[4];
-  temps:  String;
-  Data:   TData;
-begin
-  SetLength(Result.Global, 0);
-  SetLength(Result.Subs, 0);
-  Result.Data := False;
-  ext      := OniDataConnection.GetFileInfo(fileid).Extension;
-  filename := ExtractFilePath(Application.ExeName) + '\StructDefs\' + ext + '.txt';
-  if FileExists(filename) then
-  begin
-    Data := OniDataConnection.LoadDatFile(fileid);
-    AssignFile(deffile, filename);
-    Reset(deffile);
-    current_type := 0;
-    Result.Data  := True;
-    if not EOF(deffile) then
-    begin
-      ReadLn(deffile, temps);
-      while not EOF(deffile) do
-      begin
-        ReadLn(deffile, temps);
-        if (Length(temps) > 0) and (temps[1] <> '#') then
-        begin
-          if temps[1] = '*' then
-          begin
-            fields := Explode(temps, #9);
-            case Length(fields) of
-              1..2:
-              begin
-                current_type := 1;
-                current_base := 0;
-                SetLength(Result.Subs, Length(Result.Subs) + 1);
-                Result.Subs[High(Result.Subs)].SubName :=
-                  MidStr(fields[0], 2, Length(fields[0]) - 1);
-                if Length(fields) = 2 then
-                  Result.Subs[High(Result.Subs)].SubDesc := fields[1];
-              end;
-              3:
-              begin
-                current_type := 1;
-                current_base := HexToLong(fields[2]);
-                SetLength(Result.Subs, Length(Result.Subs) + 1);
-                Result.Subs[High(Result.Subs)].SubName :=
-                  MidStr(fields[0], 2, Length(fields[0]) - 1);
-                Result.Subs[High(Result.Subs)].SubDesc := fields[1];
-              end;
-              6:
-              begin
-                current_type    := 2;
-                current_base    := HexToLong(fields[2]);
-                current_package := 0;
-                current_package_size := StrToInt(fields[5]);
-                if fields[4][1] <> '$' then
-                begin
-                  case StrToInt(fields[4]) of
-                    1:
-                      packages := Data[HexToLong(fields[3])];
-                    2:
-                      packages := Data[HexToLong(fields[3])] + Data[HexToLong(fields[3]) + 1] * 256;
-                    4:
-                      packages := Data[HexToLong(fields[3])] + Data[HexToLong(fields[3]) + 1] *
-                        256 + Data[HexToLong(fields[3]) + 2] * 256 * 256 + Data[HexToLong(fields[3]) + 3] * 256 * 256 * 256;
-                  end;
-                end
-                else
-                begin
-                  packages := HexToLong(fields[4]);
-                end;
-                SetLength(Result.Subs, Length(Result.Subs) + packages);
-                for current_package := 0 to packages - 1 do
-                begin
-                  Result.Subs[High(Result.Subs) - packages +
-                    current_package + 1].SubName :=
-                    MidStr(fields[0], 2, Length(fields[0]) - 1) +
-                    '[' + IntToStr(current_package) + ']' + '#' +
-                    IntToHex(current_base + current_package * current_package_size, 8) +
-                    '#' + IntToHex(current_package_size, 8);
-                  Result.Subs[High(Result.Subs) - packages +
-                    current_package + 1].SubDesc :=
-                    fields[1];
-                end;
-              end;
-            end;
-          end
-          else
-          begin
-            fields := Explode(temps, #9);
-            if (Length(fields) = 3) or (Length(fields) = 4) then
-            begin
-              if not AppSettings.HideUnusedData or
-                ((StrToInt(fields[2]) < 1000) or (StrToInt(fields[2]) > 9999)) then
-              begin
-                structentry.Name     := fields[0];
-                structentry.datatype := StrToInt(fields[2]);
-                if Length(fields) = 4 then
-                  structentry.description := fields[3]
-                else
-                  structentry.description := '';
-                if current_type in [0, 1] then
-                begin
-                  structentry.offset := HexToLong(fields[1]) + current_base;
-                  if Length(Result.Subs) = 0 then
-                  begin
-                    SetLength(Result.Global, Length(Result.Global) + 1);
-                    Result.Global[High(Result.Global)] := structentry;
-                  end
-                  else
-                  begin
-                    SetLength(Result.Subs[High(Result.Subs)].Entries,
-                      Length(Result.Subs[High(Result.Subs)].Entries) + 1);
-                    Result.Subs[High(Result.Subs)].Entries[High(
-                      Result.Subs[High(Result.Subs)].Entries)] := structentry;
-                  end;
-                end
-                else
-                begin
-                  for current_package := 0 to packages - 1 do
-                  begin
-                    structentry.offset :=
-                      current_base + current_package * current_package_size + HexToLong(fields[1]);
-                    with Result.Subs[High(Result.Subs) - packages + current_package + 1] do
-                    begin
-                      SetLength(Entries, Length(Entries) + 1);
-                      Entries[High(Entries)] := structentry;
-                    end;
-                  end;
-                end;
-              end;
-            end;
-          end;
-        end;
-      end;
-    end;
-    CloseFile(deffile);
-  end;
-end;
-
-
-begin
-  Raws := '';
-  //  InsertRawListHandler('AGDB',True,AGDB);
-  InsertRawListHandler('AKVA', True, AKVA);
-  InsertRawListHandler('BINA', True, BINA);
-  InsertRawListHandler('OSBD', True, OSBD);
-  InsertRawListHandler('SNDD', True, SNDD);
-  InsertRawListHandler('SUBT', True, SUBT);
-  InsertRawListHandler('TRAM', True, TRAM);
-  InsertRawListHandler('TXMP', True, TXMP);
-end.
Index: oup/current/Code_Exporters.pas
===================================================================
--- oup/current/Code_Exporters.pas	(revision 45)
+++ 	(revision )
@@ -1,256 +1,0 @@
-unit Code_Exporters;
-
-interface
-
-uses Classes, Dialogs, StrUtils, SysUtils, Math, Data, Code_OniImgClass;
-
-procedure ExportDatFile(fileid: LongWord; filename: String);
-procedure ExportRawFile(fileid: LongWord; dat_offset: LongWord; filename: String);
-
-function ExportSNDD(fileid: LongWord; filename: String; convert: Boolean): Integer;
-function ExportTRAC(fileid: LongWord; filename: String; convert: Boolean): Integer;
-function ExportTXAN(fileid: LongWord; filename: String; convert: Boolean): Integer;
-function ExportTXMB(fileid: LongWord; filename: String; convert: Boolean): Integer;
-function ExportTXMP(fileid: LongWord; filename: String; convert: Boolean): Integer;
-
-var
-  ExportHandlers: array[1..1] of TExportHandlers = (
-    //    (Ext:'ABNA'; needed:False),
-    //(Ext:'AGDB'; needed:False),
-    (Ext: 'SNDD'; needed: True; Handler: ExportSNDD)
-{    (Ext:'TRAC'; needed:True; Handler:ExportTRAC),
-    (Ext:'TXAN'; needed:True; Handler:ExportTXAN),
-    (Ext:'TXMB'; needed:True; Handler:ExportTXMB),
-    (Ext:'TXMP'; needed:True; Handler:ExportTXMP)
-});
-
-
-
-implementation
-
-uses Code_Functions, Code_DataStructures, Code_OniDataClass;
-
-
-
-
-procedure ExportDatFile(fileid: LongWord; filename: String);
-var
-  filestream: TFileStream;
-  Data: Tdata;
-begin
-  Data := OniDataConnection.LoadDatFile(fileid);
-  if FileExists(filename) then
-  begin
-    filestream := TFileStream.Create(filename, fmOpenReadWrite);
-    filestream.Seek(0, soFromEnd);
-  end
-  else
-  begin
-    filestream := TFileStream.Create(filename, fmCreate);
-  end;
-  filestream.Write(Data[0], Length(Data));
-  filestream.Free;
-end;
-
-
-
-
-procedure ExportRawFile(fileid: LongWord; dat_offset: LongWord; filename: String);
-var
-  filestream: TFileStream;
-  Data: Tdata;
-begin
-  SetLength(Data, OniDataConnection.GetRawInfo(fileid, dat_offset).raw_size);
-  OniDataConnection.LoadRawFile(fileid, dat_offset, @Data[0]);
-  if FileExists(filename + '.raw0x' + IntToHex(dat_offset, 8)) then
-  begin
-    filestream := TFileStream.Create(filename + '.raw0x' + IntToHex(
-      dat_offset, 8), fmOpenReadWrite);
-    filestream.Seek(0, soFromEnd);
-  end
-  else
-  begin
-    filestream := TFileStream.Create(filename + '.raw0x' + IntToHex(dat_offset, 8), fmCreate);
-  end;
-  filestream.Write(Data[0], Length(Data));
-  filestream.Free;
-end;
-
-
-
-
-function ExportSNDD;
-{  CONST
-    WAVheader:Array[0..0] OF Byte=(
-        Ord('R'),Ord('I'),Ord('F'),Ord('F'),0,0,0,0,Ord('W'),Ord('A'),Ord('V'),Ord('E'),
-        Ord('f'),Ord('m'),Ord('t'),Ord(' '),24,0,0,0,
-      );
-}  type
-  TDatData = record
-    {0x00}
-    _fileid:   LongWord;
-    level:     LongWord;
-    Flag:      LongWord;
-    FormatTag: Word;
-    ChanNo:    Word;
-    {0x10}
-    SampleRate: LongWord;
-    BytesPSec: LongWord;
-    BPSample:  LongWord;
-    BitsPS:    LongWord;
-    {0x20}
-    Unknown:   array[1..7] of LongWord;
-    Unknown2:  Word;
-    {0x40}
-    RawSize:   LongWord;
-    RawPos:    LongWord;
-  end;
-var
-  filestream: TFileStream;
-
-  DatData:     TDatData;
-  //Wave Header Stuff
-  ASCII_Group: LongWord; //"RIFF"
-  WAV_Len:     LongWord;
-  ASCII_WAV:   LongWord; //"WAVE"
-  ASCII_FMT:   LongWord; //"fmt "
-  WAV_FMT_Len: LongWord;
-  ASCII_DATA:  LongWord; //"data"
-  WAV_FolLen:  LongWord;
-
-  Data: Tdata;
-begin
-  Result := export_noerror;
-  OniDataConnection.LoadDatFilePart(fileid, 0, SizeOf(DatData), @DatData);
-  with DatData do
-  begin
-    //Initializing Header vars
-    ASCII_Group := 1179011410; // 'RIFF'
-    WAV_Len     := RAWSize + 70;
-    ASCII_WAV   := 1163280727;  // 'WAVE'
-    ASCII_FMT   := 544501094;   // 'fmt '
-    WAV_FMT_Len := 50;          // 50 bytes
-    ASCII_DATA  := 1635017060;  // 'data'
-    WAV_FolLen  := RAWSize;
-    SetLength(Data, RAWSize);
-    OniDataConnection.LoadRawFile(fileid, $44, Data);
-
-    filestream := TFileStream.Create(filename + '.raw', fmCreate);
-    filestream.Write(Data[0], Length(Data));
-    filestream.Free;
-
-    if convert then
-    begin
-      //Now start packing this into a neat wave...
-      filestream := TFileStream.Create(filename + '.wav', fmCreate);
-      filestream.Write(ASCII_Group, SizeOf(ASCII_Group));
-      filestream.Write(WAV_Len, SizeOf(WAV_Len));
-      filestream.Write(ASCII_WAV, SizeOf(ASCII_WAV));
-      filestream.Write(ASCII_FMT, SizeOf(ASCII_FMT));
-      filestream.Write(WAV_FMT_Len, SizeOf(WAV_FMT_Len));
-      filestream.Write(ChanNo, SizeOf(ChanNo));
-      filestream.Write(Samplerate, SizeOf(Samplerate));
-      filestream.Write(BytesPSec, SizeOf(BytesPSec));
-      filestream.Write(BPSample, SizeOf(BPSample));
-      filestream.Write(BitsPS, SizeOf(BitsPS));
-      filestream.Write(Unknown[1], SizeOf(Unknown));
-      filestream.Write(Unknown2, SizeOf(Unknown2));
-      filestream.Write(ASCII_DATA, SizeOf(ASCII_DATA));
-      filestream.Write(WAV_FolLen, SizeOf(WAV_FolLen));
-      filestream.Write(Data[0], Length(Data));
-      filestream.Free;
-    end;
-  end;
-end;
-
-
-
-
-function ExportTRAC;
-var
-  link: LongWord;
-  linkcount: Word;
-  i: LongWord;
-begin
-  Result := export_noerror;
-
-  OniDataConnection.LoadDatFilePart(fileid, $18, SizeOf(link), @link);
-  link := link div 256;
-
-  OniDataConnection.LoadDatFilePart(fileid, $1E, SizeOf(linkcount), @linkcount);
-  for i := 1 to linkcount do
-  begin
-    OniDataConnection.LoadDatFilePart(fileid, $20 + (i - 1) * 12 + 8, SizeOf(link), @link);
-    link := link div 256;
-  end;
-end;
-
-
-
-
-function ExportTXAN;
-var
-  loop_speed, unknown: Word;
-  linkcount: LongWord;
-  link: LongWord;
-  i: Byte;
-begin
-  Result := export_noerror;
-
-  OniDataConnection.LoadDatFilePart(fileid, $14, SizeOf(loop_speed), @loop_speed);
-  OniDataConnection.LoadDatFilePart(fileid, $16, SizeOf(unknown), @unknown);
-
-  OniDataConnection.LoadDatFilePart(fileid, $1C, SizeOf(linkcount), @linkcount);
-  for i := 0 to linkcount - 1 do
-  begin
-    OniDataConnection.LoadDatFilePart(fileid, $20 + i * 4, SizeOf(link), @link);
-    link := link div 256;
-    if link = 0 then
-      link := fileid - 1;
-  end;
-end;
-
-
-
-
-function ExportTXMB;
-var
-  filestream: TFileStream;
-  //    img:TImgPackage;
-  Data: Tdata;
-begin
-  Result := export_noerror;
-  if convert then
-  begin
-{      img:=LoadTXMBconnected(fileid);
-      data:=ImgdataToBmp(img.imgx,img.imgy,img.imgdepth,img.storetype,img.imgdata);
-      filestream:=TFileStream.Create(filename+'.bmp',fmCreate);
-      filestream.Write(data[0],Length(data));
-      filestream.Free;
-}    end;
-end;
-
-
-
-
-function ExportTXMP;
-var
-  filestream: TFileStream;
-  //    img:TImgPackage;
-begin
-  Result := export_noerror;
-{    img:=LoadImgData(fileid);
-
-    filestream:=TFileStream.Create(filename+'.raw',fmCreate);
-    filestream.Write(img.imgdata[0],Length(img.imgdata));
-    filestream.Free;
-
-    IF convert THEN BEGIN
-      img.imgdata:=ImgdataToBMP(img.imgx,img.imgy,img.imgdepth,img.storetype,img.imgdata);
-      filestream:=TFileStream.Create(filename+'.bmp',fmCreate);
-      filestream.Write(img.imgdata[0],Length(img.imgdata));
-      filestream.Free;
-    END;
-}  end;
-
-end.
Index: oup/current/Code_Functions.pas
===================================================================
--- oup/current/Code_Functions.pas	(revision 45)
+++ 	(revision )
@@ -1,401 +1,0 @@
-unit Code_Functions;
-
-interface
-
-uses Classes, Dialogs, SysUtils, StrUtils, Math, Data;
-
-type
-  TExportSet = set of (DO_dat, DO_raw, DO_convert, DO_toone);
-
-function BoolToStr(bool: Boolean): String;
-function HexToLong(hex: String): LongWord;
-function Decode_Int(buffer: Tdata): LongWord;
-function Encode_Int(input: LongWord): Tdata;
-function Decode_Float(buffer: Tdata): Single;
-function Encode_Float(input: Single): Tdata;
-function DataToBin(Data: Tdata): String;
-function BinToInt(bin: String): Byte;
-
-function ExportFile(fileid: LongWord; filename: String; settings: TExportSet;
-  path: String): Integer;
-
-function StringSmaller(string1, string2: String): Boolean;
-
-function FormatNumber(Value: LongWord; Width: Byte; leadingzeros: Char): String;
-function FormatFileSize(size: LongWord): String;
-function CreateHexString(Data: Tdata; HexOnly: Boolean): String;
-function DecodeHexString(hex: String): Tdata;
-function GetWinFileName(Name: String): String;
-function GetExtractPath: String;
-
-function Explode(_string: String; delimiter: Char): TStringArray;
-
-
-implementation
-
-uses Code_Exporters, Code_OniDataClass;
-
-type
-  TValueSwitcher = record
-    case IsFloat: Boolean of
-      True: (ValueFloat: Single);
-      False: (ValueInt: LongWord);
-  end;
-
-
-
-
-function BoolToStr(bool: Boolean): String;
-begin
-  if bool then
-    Result := 'true'
-  else
-    Result := 'false';
-end;
-
-
-
-
-function HexToLong(hex: String): LongWord;
-
-
-
-
-  function NormalizeHexString(var hex: String): Boolean;
-  var
-    i: Byte;
-  begin
-    if hex[1] = '$' then
-    begin
-      for i := 1 to Length(hex) - 1 do
-      begin
-        hex[i] := hex[i + 1];
-      end;
-      SetLength(hex, Length(hex) - 1);
-    end;
-    if (hex[1] = '0') and (UpCase(hex[2]) = 'X') then
-    begin
-      for i := 1 to Length(hex) - 2 do
-      begin
-        hex[i] := hex[i + 2];
-      end;
-      SetLength(hex, Length(hex) - 2);
-    end;
-    if Length(hex) = 0 then
-      Result := False
-    else
-      Result := True;
-  end;
-
-var
-  i: Byte;
-begin
-  if NormalizeHexString(hex) then
-  begin
-    hex    := UpperCase(hex);
-    Result := 0;
-    for i := 1 to Length(hex) do
-    begin
-      Result := Result shl 4;
-      case hex[i] of
-        '0'..'9':
-          Result := Result + Ord(hex[i]) - 48;
-        'A'..'F':
-          Result := Result + Ord(hex[i]) - 55;
-        else
-          Result := 0;
-          Exit;
-      end;
-    end;
-  end
-  else
-  begin
-    Result := 0;
-  end;
-end;
-
-
-
-
-function Decode_Int(buffer: Tdata): LongWord;
-begin
-  Result := buffer[0] + buffer[1] * 256 + buffer[2] * 256 * 256 + buffer[3] * 256 * 256 * 256;
-end;
-
-
-
-
-function Encode_Int(input: LongWord): Tdata;
-begin
-  SetLength(Result, 4);
-  Result[0] := input mod 256;
-  input     := input div 256;
-  Result[1] := input mod 256;
-  input     := input div 256;
-  Result[2] := input mod 256;
-  input     := input div 256;
-  Result[3] := input mod 256;
-end;
-
-
-
-
-function Decode_Float(buffer: Tdata): Single;
-var
-  _valueswitcher: TValueSwitcher;
-begin
-  _valueswitcher.ValueInt := Decode_Int(buffer);
-  Result := _valueswitcher.ValueFloat;
-  if IsNAN(Result) then
-    Result := 0.0;
-end;
-
-
-
-
-function Encode_Float(input: Single): Tdata;
-var
-  _valueswitcher: TValueSwitcher;
-begin
-  _valueswitcher.ValueFloat := input;
-  Result := Encode_Int(_valueswitcher.ValueInt);
-end;
-
-
-
-
-function DataToBin(Data: Tdata): String;
-var
-  i, j:     Byte;
-  singlebyte: Byte;
-  bytepart: String;
-begin
-  SetLength(bytepart, 8);
-  Result := '';
-  for i := 0 to High(Data) do
-  begin
-    singlebyte := Data[i];
-    for j := 7 downto 0 do
-    begin
-      bytepart[j + 1] := Char((singlebyte and $01) + 48);
-      singlebyte      := singlebyte shr 1;
-    end;
-    Result := Result + bytepart + ' ';
-  end;
-end;
-
-
-
-
-function BinToInt(bin: String): Byte;
-var
-  Add: Integer;
-  i:   Byte;
-begin
-  Result := 0;
-  if Length(bin) <> 8 then
-    Exit;
-  Add := 1;
-  for i := 8 downto 1 do
-  begin
-    if not (bin[i] in ['0', '1']) then
-      Exit;
-    if bin[i] = '1' then
-      Inc(Result, Add);
-    Add := Add shl 1;
-  end;
-end;
-
-
-
-
-function FormatNumber(Value: LongWord; Width: Byte; leadingzeros: Char): String;
-begin
-  Result := AnsiReplaceStr(Format('%' + IntToStr(Width) + 'u', [Value]), ' ', leadingzeros);
-end;
-
-
-
-
-function FormatFileSize(size: LongWord): String;
-begin
-  if size >= 1000 * 1024 * 1024 then
-  begin
-    Result := FloatToStrF(size / 1024 / 1024 / 1024, ffFixed, 5, 1) + ' GB';
-  end
-  else
-  begin
-    if size >= 1000 * 1024 then
-    begin
-      Result := FloatToStrF(size / 1024 / 1024, ffFixed, 5, 1) + ' MB';
-    end
-    else
-    begin
-      if size >= 1000 then
-      begin
-        Result := FloatToStrF(size / 1024, ffFixed, 5, 1) + ' KB';
-      end
-      else
-      begin
-        Result := IntToStr(size) + ' B';
-      end;
-    end;
-  end;
-end;
-
-
-
-
-function CreateHexString(Data: Tdata; HexOnly: Boolean): String;
-var
-  string_build, ascii_version: String;
-  i: LongWord;
-begin
-  string_build  := '';
-  ascii_version := '';
-  for i := 0 to High(Data) do
-  begin
-    if not HexOnly then
-      if (i mod 16) = 0 then
-        string_build := string_build + '0x' + IntToHex(i, 6) + '  ';
-    string_build := string_build + IntToHex(Data[i], 2);
-    if not HexOnly then
-    begin
-      if Data[i] >= 32 then
-        ascii_version := ascii_version + Chr(Data[i])
-      else
-        ascii_version := ascii_version + '.';
-      if ((i + 1) mod 2) = 0 then
-        string_build := string_build + #32;
-      if ((i + 1) mod 16) = 0 then
-      begin
-        string_build  := string_build + #32 + ascii_version + CrLf;
-        ascii_version := '';
-      end;
-    end;
-  end;
-  Result := string_build;
-end;
-
-
-
-
-function DecodeHexString(hex: String): Tdata;
-var
-  i: LongWord;
-begin
-  SetLength(Result, Length(hex) div 2);
-  for i := 0 to Length(Result) do
-  begin
-    Result[i] := 0;
-    case UpCase(hex[1 + i * 2]) of
-      '0'..'9':
-        Result[i] := (Ord(UpCase(hex[1 + i * 2])) - 48) * 16;
-      'A'..'F':
-        Result[i] := (Ord(UpCase(hex[1 + i * 2])) - 55) * 16;
-    end;
-    case UpCase(hex[1 + i * 2 + 1]) of
-      '0'..'9':
-        Result[i] := Result[i] + (Ord(UpCase(hex[1 + i * 2 + 1])) - 48);
-      'A'..'F':
-        Result[i] := Result[i] + (Ord(UpCase(hex[1 + i * 2 + 1])) - 55);
-    end;
-  end;
-end;
-
-
-
-
-function StringSmaller(string1, string2: String): Boolean;
-var
-  i:   Integer;
-  len: Integer;
-begin
-  len := Min(Length(string1), Length(string2));
-  for i := 1 to len do
-    if Ord(string1[i]) <> Ord(string2[i]) then
-    begin
-      Result := Ord(string1[i]) < Ord(string2[i]);
-      Exit;
-    end;
-  Result := Length(string1) < Length(string2);
-end;
-
-
-
-
-function ExportFile(fileid: LongWord; filename: String; settings: TExportSet;
-  path: String): Integer;
-var
-  i: Byte;
-  extension: String;
-  rawlist: TRawList;
-begin
-  Result    := export_noerror;
-  extension := RightStr(filename, 4);
-  if DO_toone in settings then
-  begin
-    ExportDatFile(fileid, path + '\' + GetWinFileName(filename));
-  end
-  else
-  begin
-    if DO_dat in settings then
-      ExportDatFile(fileid, path + '\' + GetWinFileName(filename));
-    if DO_raw in settings then
-    begin
-      rawlist := OniDataConnection.GetRawList(fileid);
-      if Length(rawlist) > 0 then
-      begin
-        for i := 0 to High(rawlist) do
-        begin
-          ExportRawFile(fileid, rawlist[i].src_offset, path + '\' +
-            GetWinFileName(filename));
-        end;
-      end;
-    end;
-  end;
-end;
-
-
-
-
-function Explode(_string: String; delimiter: Char): TStringArray;
-var
-  start, len: Word;
-begin
-  SetLength(Result, 0);
-  start := 1;
-  while PosEx(delimiter, _string, start) > 0 do
-  begin
-    len := PosEx(delimiter, _string, start) - start;
-    SetLength(Result, Length(Result) + 1);
-    Result[High(Result)] := MidStr(_string, start, len);
-    start := start + len + 1;
-  end;
-  SetLength(Result, Length(Result) + 1);
-  Result[High(Result)] := MidStr(_string, start, Length(_string) - start + 1);
-end;
-
-
-
-
-function GetWinFileName(Name: String): String;
-begin
-  Result := Name;
-  Result := AnsiReplaceStr(Result, '\', '__');
-  Result := AnsiReplaceStr(Result, '/', '__');
-  Result := AnsiReplaceStr(Result, '>', '__');
-  Result := AnsiReplaceStr(Result, '<', '__');
-end;
-
-
-
-
-function GetExtractPath: String;
-begin
-  Result := ExtractFilePath(OniDataConnection.FileName) + '\extracted_' +
-    ExtractFileName(OniDataConnection.Filename);
-end;
-
-
-end.
Index: oup/current/Code_OniDataClass.pas
===================================================================
--- oup/current/Code_OniDataClass.pas	(revision 45)
+++ 	(revision )
@@ -1,1322 +1,0 @@
-unit Code_OniDataClass;
-
-interface
-
-uses Data, Code_DataStructures, Classes, SysUtils, StrUtils,
-  Dialogs, ABSDecUtil, ABSMain, DB;
-
-type
-  TOniData = class
-  private
-    FFileName:  String;
-    FLevelInfo: TLevelInfo;
-    FBackend:   Integer;
-    Fos_mac:    Boolean;
-  protected
-  public
-    property FileName: String Read FFileName Write FFileName;
-    property Backend: Integer Read FBackend Write FBackend;
-    property OSisMac: Boolean Read Fos_mac Write Fos_mac;
-    property LevelInfo: TLevelinfo Read FLevelInfo Write FLevelInfo;
-
-    constructor Create(filename: String; var Result: Boolean); virtual; abstract;
-    procedure Close; virtual; abstract;
-
-    function GetFileInfo(fileid: LongWord): TFileInfo; virtual; abstract;
-    function GetFilesList(ext: String; pattern: String;
-      NoEmptyFiles: Boolean): TStringArray; virtual; abstract;
-    function GetFilesCount: LongWord; virtual; abstract;
-    function GetExtensionsList: TStringArray; virtual; abstract;
-    function GetExtendedExtensionsList: TExtensionsMap; virtual; abstract;
-    function ExtractFileID(Name: String): Integer;
-    function GetFileIDByName(Name: String): Integer;
-
-    function LoadDatFile(fileid: LongWord): Tdata; virtual; abstract;
-    procedure UpdateDatFile(fileid: LongWord; Data: Tdata); virtual; abstract;
-    procedure LoadDatFilePart(fileid, offset, size: LongWord; target: Pointer);
-      virtual; abstract;
-    procedure UpdateDatFilePart(fileid, offset, size: LongWord; target: Pointer);
-      virtual; abstract;
-
-    function GetRawList(fileid: LongWord): TRawList; virtual; abstract;
-    function GetRawInfo(fileid, dat_offset: LongWord): TRawInfo;
-    procedure LoadRawFile(fileid, dat_offset: LongWord; target: Pointer);
-      virtual; abstract;
-    procedure UpdateRawFile(fileid, dat_offset: LongWord; size: LongWord; target: Pointer);
-      virtual; abstract;
-    procedure LoadRawFilePart(fileid, dat_offset: LongWord;
-      offset, size: LongWord; target: Pointer); virtual; abstract;
-    procedure UpdateRawFilePart(fileid, dat_offset: LongWord;
-      offset, size: LongWord; target: Pointer); virtual; abstract;
-    function AppendRawFile(loc_sep: Boolean; size: LongWord; target: Pointer): LongWord;
-      virtual; abstract;//Returns new Address
-  published
-  end;
-
-  TOniDataDat = class(TOniData)
-  private
-    Fdat_file:     TFileStream;
-    Fraw_file:     TFileStream;
-    Fsep_file:     TFileStream;
-    Fdat_header:   THeader;
-    Fdat_filesmap: TFilesMap;
-    Fdat_files:    TFiles;
-    Fdat_namedfilesmap: TNamedFilesMap;
-    Fdat_extensionsmap: TExtensionsMap;
-    FUnloadWhenUnused: Boolean;
-    FDatOpened:    Boolean;
-    FRawOpened:    Boolean;
-    FSepOpened:    Boolean;
-  protected
-  public
-    property UnloadWhenUnused: Boolean Read FUnloadWhenUnused Write FUnloadWhenUnused;
-
-    constructor Create(DatFilename: String; var Result: Boolean); override;
-    procedure Close; override;
-
-    function GetFileInfo(fileid: LongWord): TFileInfo; override;
-    function GetFilesList(ext: String; pattern: String;
-      NoEmptyFiles: Boolean): TStringArray; override;
-    function GetFilesCount: LongWord; override;
-    function GetExtensionsList: TStringArray; override;
-    function GetExtendedExtensionsList: TExtensionsMap; override;
-
-    function LoadDatFile(fileid: LongWord): Tdata; override;
-    procedure UpdateDatFile(fileid: LongWord; Data: Tdata); override;
-    procedure LoadDatFilePart(fileid, offset, size: LongWord; target: Pointer); override;
-    procedure UpdateDatFilePart(fileid, offset, size: LongWord; target: Pointer); override;
-
-    procedure LoadRawOffset(loc_sep: Boolean; raw_addr, size: LongWord; target: Pointer);
-    function GetRawList(fileid: LongWord): TRawList; override;
-    procedure LoadRawFile(fileid, dat_offset: LongWord; target: Pointer); override;
-    procedure UpdateRawFile(fileid, dat_offset: LongWord; size: LongWord;
-      target: Pointer); override;
-    procedure LoadRawFilePart(fileid, dat_offset: LongWord;
-      offset, size: LongWord; target: Pointer); override;
-    procedure UpdateRawFilePart(fileid, dat_offset: LongWord;
-      offset, size: LongWord; target: Pointer); override;
-    function AppendRawFile(loc_sep: Boolean; size: LongWord; target: Pointer): LongWord;
-      override;//Returns new Address
-  published
-  end;
-
-  TOniDataADB = class(TOniData)
-  private
-    FDatabase: TABSDatabase;
-    FQuery:    TABSQuery;
-  protected
-  public
-    constructor Create(OLDBFilename: String; var Result: Boolean); override;
-    procedure Close; override;
-
-    //      function GetDatLinks(srcid:LongWord):TDatLinks;
-    function GetFileInfo(fileid: LongWord): TFileInfo; override;
-    function GetFilesList(ext: String; pattern: String;
-      NoEmptyFiles: Boolean): TStringArray; override;
-    function GetFilesCount: LongWord; override;
-    function GetExtensionsList: TStringArray; override;
-    function GetExtendedExtensionsList: TExtensionsMap; override;
-    function GetNamedFilesMap: TNamedFilesMap;
-
-    function LoadDatFile(fileid: LongWord): Tdata; override;
-    procedure UpdateDatFile(fileid: LongWord; Data: Tdata); override;
-    procedure LoadDatFilePart(fileid, offset, size: LongWord; target: Pointer); override;
-    procedure UpdateDatFilePart(fileid, offset, size: LongWord; target: Pointer); override;
-
-    function GetRawList(fileid: LongWord): TRawList; override;
-    procedure LoadRawFile(fileid, dat_offset: LongWord; target: Pointer); override;
-    procedure UpdateRawFile(fileid, dat_offset: LongWord; size: LongWord;
-      target: Pointer); override;
-    procedure LoadRawFilePart(fileid, dat_offset: LongWord;
-      offset, size: LongWord; target: Pointer); override;
-    procedure UpdateRawFilePart(fileid, dat_offset: LongWord;
-      offset, size: LongWord; target: Pointer); override;
-  published
-  end;
-
-
-const
-  ODB_None = -1;
-  ODB_Dat  = 0;
-  ODB_ADB  = 1;
-
-var
-  OniDataConnection: TOniData;
-
-function CreateDataConnection(filename: String; backend: Integer): Boolean;
-procedure CloseDataConnection;
-
-
-
-
-implementation
-
-uses Code_Functions;
-
-
-
-(*
-  Implementation of  TOniData
-*)
-
-function TOniData.GetFileIDByName(Name: String): Integer;
-var
-  files: TStringArray;
-  i:     Integer;
-begin
-  Result := -1;
-  files  := Self.GetFilesList('', Name, False);
-  if Length(files) > 0 then
-    for i := 0 to High(files) do
-      if Pos(Name, files[i]) = Pos('-', files[i]) + 1 then
-      begin
-        //        if MidStr(files[i],Pos('-',files[i])+1,Length(files[i])-Pos('-',files[i])-5)=name then begin
-        Result := Self.ExtractFileID(files[i]);
-        Break;
-      end;
-end;
-
-
-
-
-function TOniData.ExtractFileID(Name: String): Integer;
-begin
-  if Name[5] = '-' then
-    Result := HexToLong(MidStr(Name, 1, 4))
-  else
-    Result := StrToInt(MidStr(Name, 1, 5));
-end;
-
-
-
-
-function TOniData.GetRawInfo(fileid, dat_offset: LongWord): TRawInfo;
-var
-  i: LongWord;
-  raw_list: TRawList;
-begin
-  raw_list      := Self.GetRawList(fileid);
-  Result.src_id := 0;
-  Result.src_offset := 0;
-  Result.raw_addr := 0;
-  Result.raw_size := 0;
-  for i := 0 to High(raw_list) do
-  begin
-    if raw_list[i].src_offset = dat_offset then
-    begin
-      Result.src_id     := fileid;
-      Result.src_offset := raw_list[i].src_offset;
-      Result.raw_addr   := raw_list[i].raw_addr;
-      Result.raw_size   := raw_list[i].raw_size;
-      Result.loc_sep    := raw_list[i].loc_sep;
-      Break;
-    end;
-  end;
-end;
-
-
-
-
-
-
-
-(*
-================================================================================
-                      Implementation of  TOniDataDat
-*)
-
-constructor TOniDataDat.Create(DatFilename: String; var Result: Boolean);
-const
-  header_ident1_pc: array[0..$13] of Byte =
-    ($1F, $27, $DC, $33, $DF, $BC, $03, $00, $31, $33, $52, $56, $40, $00,
-    $14, $00, $10, $00, $08, $00);
-  header_ident1_mac: array[0..$13] of Byte =
-    ($61, $30, $C1, $23, $DF, $BC, $03, $00, $31, $33, $52, $56, $40, $00,
-    $14, $00, $10, $00, $08, $00);
-  header_ident1_macbeta: array[0..$13] of Byte =
-    ($81, $11, $8D, $23, $DF, $BC, $03, $00, $31, $33, $52, $56, $40, $00,
-    $14, $00, $10, $00, $08, $00);
-  header_ident2: array[0..$F] of Byte =
-    ($99, $CF, $40, $00, $90, $4F, $63, $00, $F4, $55, $5F, $00, $90, $4F, $63, $00);
-var
-  i: LongWord;
-  header_pc, header_mac: Boolean;
-begin
-  FUnloadWhenUnused := True;
-  FDatOpened := False;
-  FRawOpened := False;
-  if not FileExists(DatFilename) then
-  begin
-    ShowMessage('File doesn''t exist!!!');
-    Result := False;
-    Exit;
-  end;
-  FFileName := DatFilename;
-  Fdat_file := TFileStream.Create(FFileName, fmOpenRead);
-  Fdat_file.Read(Fdat_header, SizeOf(Fdat_header));
-  header_pc  := True;
-  header_mac := True;
-  for i := 0 to High(Fdat_header.Ident) do
-  begin
-    FLevelInfo.Ident[i] := Fdat_header.Ident[i];
-    if Fdat_header.Ident[i] <> header_ident1_pc[i] then
-      header_pc := False;
-    if Fdat_header.Ident[i] <> header_ident1_mac[i] then
-      header_mac := False;
-  end;
-  if not (header_pc xor header_mac) then
-  begin
-    Result := False;
-    Exit;
-  end
-  else
-  begin
-    if (header_pc and not header_mac) then
-      Fos_mac := False
-    else
-      Fos_mac := True;
-  end;
-  SetLength(Fdat_filesmap, Fdat_header.Files);
-  SetLength(Fdat_files, Fdat_header.Files);
-  for i := 0 to Fdat_header.Files - 1 do
-    Fdat_file.Read(Fdat_filesmap[i], SizeOf(Fdat_filesmap[i]));
-  for i := 0 to Fdat_header.Files - 1 do
-  begin
-    Fdat_files[i].ID := i;
-    Fdat_files[i].Extension := Fdat_filesmap[i].Extension;
-    Fdat_files[i].Extension := ReverseString(Fdat_files[i].Extension);
-    Fdat_files[i].Size      := Fdat_filesmap[i].FileSize;
-    Fdat_files[i].FileType  := Fdat_filesmap[i].FileType;
-    Fdat_files[i].DatAddr   := Fdat_filesmap[i].DataAddr - 8 + Fdat_header.DataAddr;
-    if (Fdat_filesmap[i].FileType and $01) = 0 then
-    begin
-      Fdat_file.Seek(Fdat_filesmap[i].NameAddr + Fdat_header.NamesAddr, soFromBeginning);
-      SetLength(Fdat_files[i].Name, 100);
-      Fdat_file.Read(Fdat_files[i].Name[1], 100);
-      Fdat_files[i].Name := MidStr(Fdat_files[i].Name, 1 + 4, Pos(
-        #0, Fdat_files[i].Name) - 1 - 4);
-    end
-    else
-    begin
-      Fdat_files[i].Name := '';
-    end;
-    Fdat_files[i].FileName    :=
-      FormatNumber(i, 5, '0') + '-' + Fdat_files[i].Name + '.' + Fdat_files[i].Extension;
-    Fdat_files[i].FileNameHex :=
-      IntToHex(i, 4) + '-' + Fdat_files[i].Name + '.' + Fdat_files[i].Extension;
-  end;
-  Fdat_file.Seek($40 + Fdat_header.Files * $14, soFromBeginning);
-  SetLength(Fdat_namedfilesmap, Fdat_header.NamedFiles);
-  for i := 0 to Fdat_header.NamedFiles - 1 do
-    Fdat_file.Read(Fdat_namedfilesmap[i], SizeOf(Fdat_namedfilesmap[i]));
-
-  Fdat_file.Seek($40 + Fdat_header.Files * $14 + Fdat_header.NamedFiles * $8, soFromBeginning);
-  SetLength(Fdat_extensionsmap, Fdat_header.Extensions);
-  for i := 0 to Fdat_header.Extensions - 1 do
-    Fdat_file.Read(Fdat_extensionsmap[i], SizeOf(Fdat_extensionsmap[i]));
-
-  Fdat_file.Seek(Fdat_files[0].DatAddr + 7, soFromBeginning);
-  Fdat_file.Read(FLevelInfo.LevelNumber, 1);
-  FLevelInfo.LevelNumber := FLevelInfo.LevelNumber div 2;
-
-  Fdat_file.Free;
-
-  Result   := True;
-  FBackend := ODB_Dat;
-end;
-
-
-
-
-procedure TOniDataDat.Close;
-begin
-  if not FUnloadWhenUnused and FDatOpened then
-    Fdat_file.Free;
-  if not FUnloadWhenUnused and FRawOpened then
-    Fraw_file.Free;
-  if not FUnloadWhenUnused and FSepOpened then
-    Fsep_file.Free;
-  Self.Free;
-end;
-
-
-
-
-function TOniDataDat.GetFileInfo(fileid: LongWord): TFileInfo;
-begin
-  if fileid < Self.GetFilesCount then
-    Result    := Fdat_files[fileid]
-  else
-    Result.ID := -1;
-end;
-
-
-
-
-function TOniDataDat.GetFilesList(ext: String; pattern: String;
-  NoEmptyFiles: Boolean): TStringArray;
-var
-  i: LongWord;
-begin
-  SetLength(Result, 0);
-  for i := 0 to Fdat_header.Files - 1 do
-  begin
-    if ((Length(ext) = 0) or (Pos(Fdat_files[i].Extension, ext) > 0)) and
-      ((Length(pattern) = 0) or
-      (Pos(UpperCase(pattern), UpperCase(Fdat_files[i].Name)) > 0)) then
-    begin
-      if (NoEmptyFiles = False) or ((Fdat_files[i].FileType and $02) = 0) then
-      begin
-        SetLength(Result, Length(Result) + 1);
-        if AppSettings.FilenumbersAsHex then
-          Result[High(Result)] := Fdat_files[i].FileNameHex
-        else
-          Result[High(Result)] := Fdat_files[i].FileName;
-      end;
-    end;
-  end;
-end;
-
-
-
-
-function TOniDataDat.GetFilesCount: LongWord;
-begin
-  Result := Fdat_header.Files;
-end;
-
-
-
-
-function TOniDataDat.GetExtensionsList: TStringArray;
-var
-  i: LongWord;
-begin
-  SetLength(Result, Fdat_header.Extensions);
-  for i := 0 to Fdat_header.Extensions - 1 do
-  begin
-    with Fdat_extensionsmap[i] do
-    begin
-      Result[i] := Extension[3] + Extension[2] + Extension[1] + Extension[0] +
-        ' (' + IntToStr(ExtCount) + ')';
-    end;
-  end;
-end;
-
-
-
-
-function TOniDataDat.GetExtendedExtensionsList: TExtensionsMap;
-var
-  i: LongWord;
-begin
-  SetLength(Result, Fdat_header.Extensions);
-  for i := 0 to Fdat_header.Extensions - 1 do
-  begin
-    Result[i] := Fdat_extensionsmap[i];
-  end;
-end;
-
-
-
-
-function TOniDataDat.LoadDatFile(fileid: LongWord): Tdata;
-begin
-  if fileid < Self.GetFilesCount then
-  begin
-    if FUnloadWhenUnused or not FDatOpened then
-      Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
-    Fdat_file.Seek(Fdat_files[fileid].DatAddr, soFromBeginning);
-    SetLength(Result, Fdat_files[fileid].Size);
-    Fdat_file.Read(Result[0], Fdat_files[fileid].Size);
-    if UnloadWhenUnused then
-      Fdat_file.Free
-    else
-      FDatOpened := True;
-  end;
-end;
-
-
-
-
-procedure TOniDataDat.UpdateDatFile(fileid: LongWord; Data: Tdata);
-begin
-  if fileid < Self.GetFilesCount then
-  begin
-    if FUnloadWhenUnused or not FDatOpened then
-      Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
-    Fdat_file.Seek(Fdat_files[fileid].DatAddr, soFromBeginning);
-    Fdat_file.Write(Data[0], Length(Data));
-    if UnloadWhenUnused then
-      Fdat_file.Free
-    else
-      FDatOpened := True;
-  end;
-end;
-
-
-
-
-procedure TOniDataDat.LoadDatFilePart(fileid, offset, size: LongWord; target: Pointer);
-begin
-  if fileid < Self.GetFilesCount then
-  begin
-    if FUnloadWhenUnused or not FDatOpened then
-      Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
-    Fdat_file.Seek(Fdat_files[fileid].DatAddr + offset, soFromBeginning);
-    Fdat_file.Read(target^, size);
-    if UnloadWhenUnused then
-      Fdat_file.Free
-    else
-      FDatOpened := True;
-  end;
-end;
-
-
-
-
-procedure TOniDataDat.UpdateDatFilePart(fileid, offset, size: LongWord; target: Pointer);
-begin
-  if fileid < Self.GetFilesCount then
-  begin
-    if FUnloadWhenUnused or not FDatOpened then
-      Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
-    Fdat_file.Seek(Fdat_files[fileid].DatAddr + offset, soFromBeginning);
-    Fdat_file.Write(target^, size);
-    if UnloadWhenUnused then
-      Fdat_file.Free
-    else
-      FDatOpened := True;
-  end;
-end;
-
-
-
-
-function TOniDataDat.GetRawList(fileid: LongWord): TRawList;
-var
-  i: LongWord;
-begin
-  SetLength(Result, 0);
-  for i := 0 to High(RawListHandlers) do
-    if UpperCase(RawListHandlers[i].Ext) = UpperCase(Fdat_files[fileid].extension) then
-      if RawListHandlers[i].needed then
-      begin
-        Result := RawListHandlers[i].Handler(fileid);
-        Break;
-      end
-      else
-        Break;
-end;
-
-
-
-
-procedure TOniDataDat.LoadRawOffset(loc_sep: Boolean; raw_addr, size: LongWord;
-  target: Pointer);
-begin
-  if not loc_sep then
-  begin
-    if FUnloadWhenUnused or not FRawOpened then
-      Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
-        fmOpenReadWrite);
-    if raw_addr <= Fraw_file.Size then
-    begin
-      Fraw_file.Seek(raw_addr, soFromBeginning);
-      Fraw_file.Read(target^, size);
-    end;
-    if UnloadWhenUnused then
-      Fraw_file.Free
-    else
-      FRawOpened := True;
-  end
-  else
-  begin
-    if FUnloadWhenUnused or not FSepOpened then
-      Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
-        fmOpenReadWrite);
-    if raw_addr <= Fsep_file.Size then
-    begin
-      Fsep_file.Seek(raw_addr, soFromBeginning);
-      Fsep_file.Read(target^, size);
-    end;
-    if UnloadWhenUnused then
-      Fsep_file.Free
-    else
-      FSepOpened := True;
-  end;
-end;
-
-
-
-
-procedure TOniDataDat.LoadRawFile(fileid, dat_offset: LongWord; target: Pointer);
-var
-  raw_info: TRawInfo;
-begin
-  if fileid < Self.GetFilesCount then
-  begin
-    raw_info := Self.GetRawInfo(fileid, dat_offset);
-    if not raw_info.loc_sep then
-    begin
-      if FUnloadWhenUnused or not FRawOpened then
-        Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
-          fmOpenReadWrite);
-      Fraw_file.Seek(raw_info.raw_addr, soFromBeginning);
-      Fraw_file.Read(target^, raw_info.raw_size);
-      if UnloadWhenUnused then
-        Fraw_file.Free
-      else
-        FRawOpened := True;
-    end
-    else
-    begin
-      if FUnloadWhenUnused or not FSepOpened then
-        Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
-          fmOpenReadWrite);
-      Fsep_file.Seek(raw_info.raw_addr, soFromBeginning);
-      Fsep_file.Read(target^, raw_info.raw_size);
-      if UnloadWhenUnused then
-        Fsep_file.Free
-      else
-        FSepOpened := True;
-    end;
-  end;
-end;
-
-
-
-
-procedure TOniDataDat.UpdateRawFile(fileid, dat_offset: LongWord;
-  size: LongWord; target: Pointer);
-var
-  raw_info: TRawInfo;
-begin
-  if fileid < Self.GetFilesCount then
-  begin
-    raw_info := Self.GetRawInfo(fileid, dat_offset);
-    if not raw_info.loc_sep then
-    begin
-      if FUnloadWhenUnused or not FRawOpened then
-        Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
-          fmOpenReadWrite);
-      Fraw_file.Seek(raw_info.raw_addr, soFromBeginning);
-      Fraw_file.Write(target^, raw_info.raw_size);
-      if UnloadWhenUnused then
-        Fraw_file.Free
-      else
-        FRawOpened := True;
-    end
-    else
-    begin
-      if FUnloadWhenUnused or not FSepOpened then
-        Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
-          fmOpenReadWrite);
-      Fsep_file.Seek(raw_info.raw_addr, soFromBeginning);
-      Fsep_file.Write(target^, raw_info.raw_size);
-      if UnloadWhenUnused then
-        Fsep_file.Free
-      else
-        FSepOpened := True;
-    end;
-  end;
-end;
-
-
-
-
-procedure TOniDataDat.LoadRawFilePart(fileid, dat_offset: LongWord;
-  offset, size: LongWord; target: Pointer);
-var
-  raw_info: TRawInfo;
-  Data:     Tdata;
-  mem:      TMemoryStream;
-begin
-  if fileid < Self.GetFilesCount then
-  begin
-    raw_info := Self.GetRawInfo(fileid, dat_offset);
-    SetLength(Data, raw_info.raw_size);
-    Self.LoadRawFile(fileid, dat_offset, @Data[0]);
-    mem := TMemoryStream.Create;
-    mem.Write(Data[offset], size);
-    mem.Read(target^, size);
-    mem.Free;
-  end;
-end;
-
-
-
-
-procedure TOniDataDat.UpdateRawFilePart(fileid, dat_offset: LongWord;
-  offset, size: LongWord; target: Pointer);
-var
-  raw_info: TRawInfo;
-begin
-  if fileid < Self.GetFilesCount then
-  begin
-    raw_info := Self.GetRawInfo(fileid, dat_offset);
-    if not raw_info.loc_sep then
-    begin
-      if FUnloadWhenUnused or not FRawOpened then
-        Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
-          fmOpenReadWrite);
-      Fraw_file.Seek(raw_info.raw_addr + offset, soFromBeginning);
-      Fraw_file.Write(target^, raw_info.raw_size);
-      if UnloadWhenUnused then
-        Fraw_file.Free
-      else
-        FRawOpened := True;
-    end
-    else
-    begin
-      if FUnloadWhenUnused or not FSepOpened then
-        Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
-          fmOpenReadWrite);
-      Fsep_file.Seek(raw_info.raw_addr + offset, soFromBeginning);
-      Fsep_file.Write(target^, raw_info.raw_size);
-      if UnloadWhenUnused then
-        Fsep_file.Free
-      else
-        FSepOpened := True;
-    end;
-  end;
-end;
-
-
-
-
-function TOniDataDat.AppendRawFile(loc_sep: Boolean; size: LongWord;
-  target: Pointer): LongWord; //Returns new Address
-begin
-  if not loc_sep then
-  begin
-    if FUnloadWhenUnused or not FRawOpened then
-      Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
-        fmOpenReadWrite);
-    Result := Fraw_file.Size;
-    Fraw_file.Seek(0, soFromEnd);
-    Fraw_file.Write(target^, size);
-    if UnloadWhenUnused then
-      Fraw_file.Free
-    else
-      FRawOpened := True;
-  end
-  else
-  begin
-    if FUnloadWhenUnused or not FSepOpened then
-      Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
-        fmOpenReadWrite);
-    Result := Fsep_file.Size;
-    Fsep_file.Seek(0, soFromEnd);
-    Fsep_file.Write(target^, size);
-    if UnloadWhenUnused then
-      Fsep_file.Free
-    else
-      FSepOpened := True;
-  end;
-end;
-
-
-
-
-
-
-
-
-
-
-
-(*
-================================================================================
-                     Implementation of  TOniDataADB
-*)
-
-constructor TOniDataADB.Create(OLDBFilename: String; var Result: Boolean);
-var
-  i, j:  Byte;
-  temps: String;
-begin
-  if not FileExists(OLDBFilename) then
-  begin
-    ShowMessage('File doesn''t exist!!!');
-    Result := False;
-    Exit;
-  end;
-  FFileName := OLDBFilename;
-  FDatabase := TABSDatabase.Create(nil);
-  FDatabase.DatabaseName := 'OLDBcon';
-  FDatabase.DatabaseFileName := OLDBFilename;
-  FDatabase.Open;
-  FQuery := TABSQuery.Create(FDatabase);
-  FQuery.DatabaseName := 'OLDBcon';
-  FQuery.SQL.Text := 'SELECT [name],[value] FROM globals ORDER BY [name] ASC';
-  FQuery.Open;
-  FQuery.First;
-  repeat
-    if FQuery.FieldByName('name').AsString = 'dbversion' then
-    begin
-      if FQuery.FieldByName('value').AsString <> DBversion then
-      begin
-        ShowMessage('Database-file ' + #13 + #10 +
-          '"' + OLDBFilename + '"' + #13 + #10 +
-          'has wrong version. (Required: ' + DBversion + '; found: ' +
-          FQuery.FieldByName('value').AsString + ')');
-        FQuery.Close;
-        Result := False;
-        Exit;
-      end;
-    end;
-    if FQuery.FieldByName('name').AsString = 'lvl' then
-    begin
-      FLevelInfo.LevelNumber := StrToInt(FQuery.FieldByName('value').AsString);
-    end;
-    if FQuery.FieldByName('name').AsString = 'ident' then
-    begin
-      temps := FQuery.FieldByName('value').AsString;
-      for i := 0 to High(FLevelInfo.Ident) do
-      begin
-        j := i * 2 + 1;
-        case temps[j] of
-          '0'..'9':
-            FLevelInfo.Ident[i] := Ord(temps[j]) - 48;
-          'A'..'F':
-            FLevelInfo.Ident[i] := Ord(temps[j]) - 55;
-        end;
-        FLevelInfo.Ident[i] := FLevelInfo.Ident[i] * 16;
-        case temps[j + 1] of
-          '0'..'9':
-            FLevelInfo.Ident[i] := FLevelInfo.Ident[i] + Ord(temps[j + 1]) - 48;
-          'A'..'F':
-            FLevelInfo.Ident[i] := FLevelInfo.Ident[i] + Ord(temps[j + 1]) - 55;
-        end;
-      end;
-    end;
-    if FQuery.FieldByName('name').AsString = 'ident' then
-    begin
-      temps   := FQuery.FieldByName('value').AsString;
-      Fos_mac := temps = 'MAC';
-    end;
-    FQuery.Next;
-  until FQuery.EOF;
-  FQuery.Close;
-
-  Result   := True;
-  FBackend := ODB_ADB;
-end;
-
-
-
-
-procedure TOniDataADB.Close;
-begin
-  FDatabase.Close;
-  FDatabase.Free;
-  Self.Free;
-end;
-
-
-
-
-function TOniDataADB.GetFileInfo(fileid: LongWord): TFileInfo;
-begin
-  if fileid < Self.GetFilesCount then
-  begin
-    FQuery.SQL.Text := 'SELECT * FROM datfiles WHERE id=' + IntToStr(
-      fileid) + ' ORDER BY id ASC;';
-    FQuery.Open;
-    if FQuery.RecordCount = 1 then
-    begin
-      FQuery.First;
-      Result.ID      := FQuery.FieldByName('id').AsInteger;
-      Result.Name    := FQuery.FieldByName('name').AsString;
-      Result.Extension := FQuery.FieldByName('extension').AsString;
-      Result.FileName := FormatNumber(Result.ID, 5, '0') + '-' + Result.Name + '.' +
-        Result.Extension;
-      Result.Size    := FQuery.FieldByName('size').AsInteger;
-      Result.FileType := HexToLong(FQuery.FieldByName('contenttype').AsString);
-      Result.DatAddr := 0;
-      Result.opened  := False;
-    end;
-    FQuery.Close;
-  end
-  else
-  begin
-    Result.ID := -1;
-  end;
-end;
-
-
-
-
-function TOniDataADB.GetFilesList(ext: String; pattern: String;
-  NoEmptyFiles: Boolean): TStringArray;
-var
-  i:     LongWord;
-  where: String;
-  where_ext: String;
-begin
-  where := '';
-  if Length(ext) > 0 then
-  begin
-    if Length(where) > 0 then
-      where := where + ' AND ';
-    if Pos(',', ext) > 0 then
-    begin
-      i := 1;
-      where_ext := '';
-      while i < Length(ext) do
-      begin
-        if Length(where_ext) > 0 then
-          where_ext := where_ext + ' OR ';
-        where_ext := where_ext + '(extension="' + MidStr(ext, i, 4) + '")';
-        i := i + 5;
-      end;
-      where := where + '(' + where_ext + ')';
-    end
-    else
-    begin
-      where := where + '(extension="' + ext + '")';
-    end;
-  end;
-  if Length(pattern) > 0 then
-  begin
-    if Length(where) > 0 then
-      where := where + ' AND ';
-    where := where + '(name LIKE "%' + pattern + '%")';
-  end;
-  if NoEmptyFiles then
-  begin
-    if Length(where) > 0 then
-      where := where + ' AND ';
-    where := where + '(contenttype<>2)';
-  end;
-  if Length(where) > 0 then
-    where := ' WHERE ' + where;
-  FQuery.SQL.Text := 'SELECT id,name,extension FROM datfiles' + where + ' ORDER BY id ASC;';
-  FQuery.Open;
-  if FQuery.RecordCount > 0 then
-  begin
-    FQuery.First;
-    SetLength(Result, FQuery.RecordCount);
-    i := 0;
-    repeat
-      Result[i] := FormatNumber(FQuery.FieldByName('id').AsInteger, 5, '0') + '-' +
-        FQuery.FieldByName('name').AsString + '.' + FQuery.FieldByName('extension').AsString;
-      Inc(i);
-      FQuery.Next;
-    until FQuery.EOF;
-  end;
-  FQuery.Close;
-end;
-
-
-
-
-function TOniDataADB.GetFilesCount: LongWord;
-begin
-  FQuery.SQL.Text := 'SELECT Count(*) AS cnumber FROM datfiles;';
-  FQuery.Open;
-  if FQuery.RecordCount > 0 then
-  begin
-    FQuery.First;
-    Result := FQuery.FieldByName('cnumber').AsInteger;
-  end
-  else
-    Result := 0;
-  FQuery.Close;
-end;
-
-
-
-
-function TOniDataADB.GetExtensionsList: TStringArray;
-var
-  i: LongWord;
-begin
-  SetLength(Result, 0);
-  FQuery.SQL.Text :=
-    'SELECT extension,count(extension) AS x FROM datfiles GROUP BY extension ORDER BY extension ASC;';
-  FQuery.Open;
-  if FQuery.RecordCount > 0 then
-  begin
-    SetLength(Result, FQuery.RecordCount);
-    i := 0;
-    repeat
-      Result[i] := FQuery.FieldByName('extension').AsString + ' (' +
-        IntToStr(FQuery.FieldByName('x').AsInteger) + ')';
-      Inc(i);
-      FQuery.Next;
-    until FQuery.EOF;
-  end;
-  FQuery.Close;
-end;
-
-
-
-
-function TOniDataADB.GetExtendedExtensionsList: TExtensionsMap;
-var
-  i, j:  LongWord;
-  temps: String;
-  Data:  Tdata;
-begin
-  SetLength(Result, 0);
-  FQuery.SQL.Text := 'SELECT ext,ident FROM extlist ORDER BY ext ASC;';
-  FQuery.Open;
-  if FQuery.RecordCount > 0 then
-  begin
-    SetLength(Result, FQuery.RecordCount);
-    i := 0;
-    repeat
-      temps := FQuery.FieldByName('ext').AsString;
-      for j := 0 to 3 do
-        Result[i].Extension[j] := temps[4 - j];
-      Data := DecodeHexString(FQuery.FieldByName('ident').AsString);
-      for j := 0 to 7 do
-        Result[i].Ident[j] := Data[j];
-      Inc(i);
-      FQuery.Next;
-    until FQuery.EOF;
-  end;
-  FQuery.Close;
-end;
-
-
-
-
-function TOniDataADB.GetNamedFilesMap: TNamedFilesMap;
-var
-  i:     LongWord;
-  temp:  Integer;
-  temps: String;
-  temparray: array of record
-    id: Integer;
-    fullname: String[50];
-  end;
-begin
-  SetLength(temparray, 0);
-  FQuery.SQL.Text :=
-    'SELECT id,(extension+name) AS xname FROM datfiles WHERE Length(name)>0 ORDER BY extension,name ASC;';
-  FQuery.Open;
-  if FQuery.RecordCount > 0 then
-  begin
-    repeat
-      temp  := FQuery.FieldByName('id').AsInteger;
-      temps := FQuery.FieldByName('xname').AsString;
-
-      SetLength(temparray, Length(temparray) + 1);
-      if Length(temparray) > 1 then
-      begin
-        for i := High(temparray) - 1 downto 0 do
-        begin
-          if StringSmaller(temps, temparray[i].fullname) then
-          begin
-            temparray[i + 1] := temparray[i];
-            if i = 0 then
-            begin
-              temparray[i].id := temp;
-              temparray[i].fullname := temps;
-            end;
-          end
-          else
-          begin
-            temparray[i + 1].id := temp;
-            temparray[i + 1].fullname := temps;
-            Break;
-          end;
-        end;
-      end
-      else
-      begin
-        temparray[0].id := temp;
-        temparray[0].fullname := temps;
-      end;
-      FQuery.Next;
-    until FQuery.EOF;
-  end;
-  FQuery.Close;
-  SetLength(Result, Length(temparray));
-  for i := 0 to High(temparray) do
-  begin
-    Result[i].FileNumber := temparray[i].id;
-    Result[i].blubb      := 0;
-  end;
-end;
-
-
-
-
-function TOniDataADB.LoadDatFile(fileid: LongWord): Tdata;
-var
-  mem: TStream;
-begin
-  if fileid < Self.GetFilesCount then
-  begin
-    FQuery.SQL.Text := 'SELECT data FROM datfiles WHERE id=' + IntToStr(fileid) + ';';
-    FQuery.Open;
-    if FQuery.RecordCount > 0 then
-    begin
-      mem := FQuery.CreateBlobStream(FQuery.FieldByName('data'), bmRead);
-      SetLength(Result, mem.Size);
-      mem.Seek(0, soFromBeginning);
-      mem.Read(Result[0], mem.Size);
-      mem.Free;
-    end;
-    FQuery.Close;
-  end;
-end;
-
-
-
-
-procedure TOniDataADB.UpdateDatFile(fileid: LongWord; Data: Tdata);
-var
-  MimeCoder: TStringFormat_MIME64;
-  mem: TMemoryStream;
-begin
-  if fileid < Self.GetFilesCount then
-  begin
-    mimecoder := TStringFormat_MIME64.Create;
-    mem := TMemoryStream.Create;
-    mem.Write(Data[0], Length(Data));
-    mem.Seek(0, soFromBeginning);
-    FQuery.SQL.Text := 'UPDATE datfiles SET data=MimeToBin("' +
-      MimeCoder.StrTo(mem.Memory, mem.Size) + '") WHERE id=' + IntToStr(fileid) + ';';
-    FQuery.ExecSQL;
-    mem.Free;
-    mimecoder.Free;
-  end;
-end;
-
-
-
-
-procedure TOniDataADB.LoadDatFilePart(fileid, offset, size: LongWord; target: Pointer);
-var
-  mem: TStream;
-begin
-  if fileid < Self.GetFilesCount then
-  begin
-    FQuery.SQL.Text := 'SELECT data FROM datfiles WHERE id=' + IntToStr(fileid) + ';';
-    FQuery.Open;
-    if FQuery.RecordCount > 0 then
-    begin
-      mem := FQuery.CreateBlobStream(FQuery.FieldByName('data'), bmRead);
-      mem.Seek(offset, soFromBeginning);
-      mem.Read(target^, size);
-      mem.Free;
-    end;
-    FQuery.Close;
-  end;
-end;
-
-
-
-
-procedure TOniDataADB.UpdateDatFilePart(fileid, offset, size: LongWord; target: Pointer);
-var
-  MimeCoder: TStringFormat_MIME64;
-  mem:  TMemoryStream;
-  Data: Tdata;
-begin
-  if fileid < Self.GetFilesCount then
-  begin
-    Data := Self.LoadDatFile(fileid);
-    mimecoder := TStringFormat_MIME64.Create;
-    mem := TMemoryStream.Create;
-    mem.Write(Data[0], Length(Data));
-    mem.Seek(offset, soFromBeginning);
-    mem.Write(target^, size);
-    mem.Seek(0, soFromBeginning);
-    FQuery.SQL.Text := 'UPDATE datfiles SET data=MimeToBin("' +
-      MimeCoder.StrTo(mem.Memory, mem.Size) + '") WHERE id=' + IntToStr(fileid) + ';';
-    FQuery.ExecSQL;
-    mem.Free;
-    mimecoder.Free;
-  end;
-end;
-
-
-
-
-function TOniDataADB.GetRawList(fileid: LongWord): TRawList;
-var
-  i: LongWord;
-begin
-  SetLength(Result, 0);
-  FQuery.SQL.Text := 'SELECT [src_link_offset],[size],[sep] FROM rawmap WHERE [src_id]=' +
-    IntToStr(fileid) + ' ORDER BY src_link_offset ASC;';
-  FQuery.Open;
-  if FQuery.RecordCount > 0 then
-  begin
-    FQuery.First;
-    SetLength(Result, FQuery.RecordCount);
-    i := 0;
-    repeat
-      Result[i].src_id     := fileid;
-      Result[i].src_offset := FQuery.FieldByName('src_link_offset').AsInteger;
-      Result[i].raw_addr   := 0;
-      Result[i].raw_size   := FQuery.FieldByName('size').AsInteger;
-      Result[i].loc_sep    := FQuery.FieldByName('sep').AsBoolean;
-      Inc(i);
-      FQuery.Next;
-    until FQuery.EOF;
-  end;
-  FQuery.Close;
-end;
-
-
-
-
-procedure TOniDataADB.LoadRawFile(fileid, dat_offset: LongWord; target: Pointer);
-var
-  mem: TStream;
-begin
-  if fileid < Self.GetFilesCount then
-  begin
-    FQuery.SQL.Text := 'SELECT data FROM rawmap WHERE (src_id=' +
-      IntToStr(fileid) + ') AND (src_link_offset=' + IntToStr(dat_offset) + ');';
-    FQuery.Open;
-    if FQuery.RecordCount > 0 then
-    begin
-      mem := FQuery.CreateBlobStream(FQuery.FieldByName('data'), bmRead);
-      mem.Seek(0, soFromBeginning);
-      mem.Read(target^, mem.size);
-      mem.Free;
-    end;
-    FQuery.Close;
-  end;
-end;
-
-
-
-
-procedure TOniDataADB.UpdateRawFile(fileid, dat_offset: LongWord;
-  size: LongWord; target: Pointer);
-var
-  MimeCoder: TStringFormat_MIME64;
-  mem: TMemoryStream;
-begin
-  if fileid < Self.GetFilesCount then
-  begin
-    mimecoder := TStringFormat_MIME64.Create;
-    mem := TMemoryStream.Create;
-    mem.Write(target^, size);
-    mem.Seek(0, soFromBeginning);
-    FQuery.SQL.Text := 'UPDATE rawmap SET data=MimeToBin("' + MimeCoder.StrTo(
-      mem.Memory, mem.Size) + '") WHERE (src_id=' + IntToStr(fileid) +
-      ') AND (src_link_offset=' + IntToStr(dat_offset) + ');';
-    FQuery.ExecSQL;
-    mem.Free;
-    mimecoder.Free;
-  end;
-end;
-
-
-
-
-procedure TOniDataADB.LoadRawFilePart(fileid, dat_offset: LongWord;
-  offset, size: LongWord; target: Pointer);
-var
-  Data: Tdata;
-  mem:  TMemoryStream;
-begin
-  if fileid < Self.GetFilesCount then
-  begin
-    SetLength(Data, Self.GetRawInfo(fileid, dat_offset).raw_size);
-    Self.LoadRawFile(fileid, dat_offset, @Data[0]);
-    mem := TMemoryStream.Create;
-    mem.Write(Data[offset], size);
-    mem.Read(target^, size);
-    mem.Free;
-  end;
-end;
-
-
-
-
-procedure TOniDataADB.UpdateRawFilePart(fileid, dat_offset: LongWord;
-  offset, size: LongWord; target: Pointer);
-var
-  MimeCoder: TStringFormat_MIME64;
-  mem:  TMemoryStream;
-  Data: Tdata;
-begin
-  if fileid < Self.GetFilesCount then
-  begin
-    SetLength(Data, Self.GetRawInfo(fileid, offset).raw_size);
-    Self.LoadRawFile(fileid, offset, @Data[0]);
-    mimecoder := TStringFormat_MIME64.Create;
-    mem := TMemoryStream.Create;
-    mem.Write(Data[0], Length(Data));
-    mem.Seek(offset, soFromBeginning);
-    mem.Write(target^, size);
-    mem.Seek(0, soFromBeginning);
-    FQuery.SQL.Text := 'UPDATE rawmap SET data=MimeToBin("' + MimeCoder.StrTo(
-      mem.Memory, mem.Size) + '") WHERE (src_id=' + IntToStr(fileid) +
-      ') AND (src_link_offset=' + IntToStr(dat_offset) + ');';
-    FQuery.ExecSQL;
-    mem.Free;
-    mimecoder.Free;
-  end;
-end;
-
-
-
-
-
-
-
-
-
-
-
-function CreateDataConnection(filename: String; backend: Integer): Boolean;
-var
-  answer: Boolean;
-begin
-  if Assigned(OniDataConnection) then
-  begin
-    OniDataConnection.Close;
-    OniDataConnection.Free;
-    OniDataConnection := nil;
-  end;
-  case backend of
-    ODB_Dat:
-      OniDataConnection := TOniDataDat.Create(filename, answer);
-    ODB_ADB:
-      OniDataConnection := TOniDataADB.Create(filename, answer);
-    else
-      ShowMessage('Unknown Backend');
-      Result := False;
-      Exit;
-  end;
-
-  if answer then
-  begin
-    //      ShowMessage('file loaded');
-    //      ShowMessage('Files: '+IntToStr(OniDataConnection.GetFilesCount));
-    Result := True;
-  end
-  else
-  begin
-    ShowMessage('File not loaded');
-    OniDataConnection.Close;
-    OniDataConnection.Free;
-    Result := False;
-  end;
-end;
-
-
-
-
-procedure CloseDataConnection;
-begin
-  if Assigned(OniDataConnection) then
-  begin
-    OniDataConnection.Close;
-    OniDataConnection := nil;
-  end;
-end;
-
-end.
Index: oup/current/Code_OniImgClass.pas
===================================================================
--- oup/current/Code_OniImgClass.pas	(revision 45)
+++ 	(revision )
@@ -1,827 +1,0 @@
-unit Code_OniImgClass;
-
-interface
-
-uses Math, Dialogs, Types, SysUtils, Classes, Data, Code_OniDataClass;
-
-type
-  TImgDataType = set of (DT_OniReverted, DT_Oni, DT_Decoded32);
-
-type
-  TOniImage = class
-  private
-    FLoaded:    Boolean;
-    FDataType:  TImgDataType;
-    FData:      Tdata;
-    FWidth, FHeight: Word;
-    FDepth:     Byte;
-    FStoreType: Byte;
-
-    function ResizeImage(oldx, oldy: LongWord; img: Tdata): Tdata;
-    procedure RevertImage;
-    procedure DecodeImage;
-    procedure DecompressImage;
-  protected
-  public
-    property Loaded: Boolean Read FLoaded Write FLoaded;
-    property DataType: TImgDataType Read FDataType Write FDataType;
-    property Width: Word Read FWidth Write FWidth;
-    property Height: Word Read FHeight Write FHeight;
-    property Depth: Byte Read FDepth Write FDepth;
-    property StoreType: Byte Read FStoreType Write FStoreType;
-    property Data: Tdata Read FData Write FData;
-
-    constructor Create;
-    function Load(fileid: LongWord): Boolean;
-    function LoadFromPSpc(fileid: LongWord): Boolean;
-    function LoadFromTXMP(fileid: LongWord): Boolean;
-    function LoadFromTXMB(fileid: LongWord): Boolean;
-    function GetImageDataSize(fading: Boolean): LongWord;
-
-    function GetAsData: Tdata;
-    function GetAs32bit: Tdata;
-    function GetAsBMP: Tdata;
-    function LoadFromBMP(filename: String): Boolean;
-    function WriteToBMP(filename: String): Boolean;
-    function GetMipMappedImage(var faded: Tdata): Boolean;
-  published
-  end;
-
-
-implementation
-
-uses Code_Functions;
-
-
-
-
-constructor TOniImage.Create;
-begin
-  Self.FLoaded   := False;
-  Self.FDataType := [];
-  SetLength(Self.FData, 0);
-  Self.FWidth     := 0;
-  Self.FHeight    := 0;
-  Self.FDepth     := 0;
-  Self.FStoreType := 0;
-end;
-
-
-
-
-function TOniImage.ResizeImage(oldx, oldy: LongWord; img: Tdata): Tdata;
-var
-  i, j: LongWord;
-  col, row, row_orig: LongWord;
-begin
-  SetLength(Result, (oldx div 2) * (oldy div 2) * (Self.FDepth div 8));
-  row_orig := 0;
-  row      := 0;
-  col      := 0;
-  for i := 0 to (oldx * oldy) - 1 do
-  begin
-    if ((i mod oldx) = 0) and (i > 0) then
-    begin
-      Inc(row_orig);
-      if (row_orig mod 2) = 0 then
-      begin
-        Inc(row);
-        col := 0;
-      end;
-    end;
-    if (row_orig mod 2) = 0 then
-    begin
-      if (i mod 2) = 0 then
-      begin
-        for j := 0 to (Self.FDepth div 8) - 1 do
-          Result[((row * (oldx div 2)) + col) * (Self.FDepth div 8) + j] :=
-            img[(i * (Self.FDepth div 8)) + j];
-        Inc(col);
-      end;
-    end;
-  end;
-end;
-
-
-
-
-procedure TOniImage.RevertImage;
-var
-  x, y, i: LongWord;
-  tempd:   Tdata;
-begin
-  SetLength(tempd, Self.FWidth * Self.FHeight * (Self.FDepth div 8));
-  for y := 0 to Self.FHeight - 1 do
-    for x := 0 to Self.FWidth - 1 do
-      for i := 0 to (Self.FDepth div 8) - 1 do
-        tempd[((Self.FWidth * (Self.FHeight - 1 - y) + x) * (Self.FDepth div 8)) + i] :=
-          Self.FData[(Self.FWidth * y + x) * (Self.FDepth div 8) + i];
-  for x := 0 to High(tempd) do
-    Self.FData[x] := tempd[x];
-  if DT_OniReverted in Self.FDataType then
-    Self.FDataType := Self.FDataType - [DT_OniReverted]
-  else
-    Self.FDataType := Self.FDataType + [DT_OniReverted];
-end;
-
-
-
-
-procedure TOniImage.DecodeImage;
-var
-  x, y:  LongWord;
-  tempd: Tdata;
-begin
-  if not (DT_Decoded32 in Self.FDataType) then
-  begin
-    SetLength(tempd, Self.FWidth * Self.FHeight * 4);
-    case Self.FStoreType of
-      0:
-      begin
-        for y := 0 to Self.FHeight - 1 do
-        begin
-          for x := 0 to Self.FWidth - 1 do
-          begin
-            tempd[((Self.FWidth * y + x) * 4) + 0] :=
-              Floor(((Self.FData[(Self.FWidth * y + x) * 2] + Self.FData[(Self.FWidth * y + x) * 2 + 1] * 256) and
-              $000F) / $000F * 255);
-            tempd[((Self.FWidth * y + x) * 4) + 1] :=
-              Floor(((Self.FData[(Self.FWidth * y + x) * 2] + Self.FData[(Self.FWidth * y + x) * 2 + 1] * 256) and
-              $00F0) / $00F0 * 255);
-            tempd[((Self.FWidth * y + x) * 4) + 2] :=
-              Floor(((Self.FData[(Self.FWidth * y + x) * 2] + Self.FData[(Self.FWidth * y + x) * 2 + 1] * 256) and
-              $0F00) / $0F00 * 255);
-            tempd[((Self.FWidth * y + x) * 4) + 3] := 0;
-          end;
-        end;
-      end;
-      1, 2:
-      begin
-        for y := 0 to Self.FHeight - 1 do
-        begin
-          for x := 0 to Self.FWidth - 1 do
-          begin
-            tempd[((Self.FWidth * y + x) * 4) + 0] :=
-              Floor(((Self.FData[(Self.FWidth * y + x) * 2] + Self.FData[(Self.FWidth * y + x) * 2 + 1] * 256) and
-              $001F) / $001F * 255);
-            tempd[((Self.FWidth * y + x) * 4) + 1] :=
-              Floor(((Self.FData[(Self.FWidth * y + x) * 2] + Self.FData[(Self.FWidth * y + x) * 2 + 1] * 256) and
-              $03E0) / $03E0 * 255);
-            tempd[((Self.FWidth * y + x) * 4) + 2] :=
-              Floor(((Self.FData[(Self.FWidth * y + x) * 2] + Self.FData[(Self.FWidth * y + x) * 2 + 1] * 256) and
-              $7C00) / $7C00 * 255);
-            tempd[((Self.FWidth * y + x) * 4) + 3] := 0;
-          end;
-        end;
-      end;
-      9:
-      begin
-        DecompressImage;
-      end;
-    end;
-    Self.FDepth := 32;
-    if (Self.FStoreType <> 9) and (Self.FStoreType <> 8) then
-    begin
-      SetLength(Self.FData, Length(tempd));
-      for x := 0 to High(tempd) do
-        Self.FData[x] := tempd[x];
-    end;
-    Self.FStoreType := 8;
-    if DT_Oni in Self.FDataType then
-      Self.FDataType := Self.FDataType - [DT_Oni];
-    Self.FDataType := Self.FDataType + [DT_Decoded32];
-  end;
-  if DT_OniReverted in Self.FDataType then
-    Self.RevertImage;
-end;
-
-
-
-
-procedure TOniImage.DecompressImage;
-type
-  Tcolor = record
-    RGBb: Byte;
-    RGBg: Byte;
-    RGBr: Byte;
-    RGBa: Byte;
-  end;
-var
-  i, j, x, y: LongWord;
-  color:      array[1..4] of Tcolor;
-  pixel:      array[1..16] of Byte;
-  tempd:      Tdata;
-begin
-  x := 0;
-  y := 0;
-  SetLength(tempd, Self.FWidth * Self.FHeight * 4);
-  for i := 0 to ((Self.FWidth * Self.FHeight) div 16) - 1 do
-  begin
-    Color[1].RGBb := Floor(((Self.FData[(i * 8) + 0] + Self.FData[(i * 8) + 1] * 256) and $001F) /
-      $001F * 255);
-    Color[1].RGBg := Floor(((Self.FData[(i * 8) + 0] + Self.FData[(i * 8) + 1] * 256) and $07E0) /
-      $07E0 * 255);
-    Color[1].RGBr := Floor(((Self.FData[(i * 8) + 0] + Self.FData[(i * 8) + 1] * 256) and $F800) /
-      $F800 * 255);
-    Color[1].RGBa := 255;
-    Color[2].RGBb := Floor(((Self.FData[(i * 8) + 2] + Self.FData[(i * 8) + 3] * 256) and $001F) /
-      $001F * 255);
-    Color[2].RGBg := Floor(((Self.FData[(i * 8) + 2] + Self.FData[(i * 8) + 3] * 256) and $07E0) /
-      $07E0 * 255);
-    Color[2].RGBr := Floor(((Self.FData[(i * 8) + 2] + Self.FData[(i * 8) + 3] * 256) and $F800) /
-      $F800 * 255);
-    Color[2].RGBa := 255;
-    Color[3].RGBb := Floor(Color[1].RGBb / 3 * 2 + Color[2].RGBb / 3);
-    Color[3].RGBg := Floor(Color[1].RGBg / 3 * 2 + Color[2].RGBg / 3);
-    Color[3].RGBr := Floor(Color[1].RGBr / 3 * 2 + Color[2].RGBr / 3);
-    Color[3].RGBa := 255;
-    Color[4].RGBb := Floor(Color[1].RGBb / 3 + Color[2].RGBb / 3 * 2);
-    Color[4].RGBg := Floor(Color[1].RGBg / 3 + Color[2].RGBg / 3 * 2);
-    Color[4].RGBr := Floor(Color[1].RGBr / 3 + Color[2].RGBr / 3 * 2);
-    Color[4].RGBa := 255;
-    Pixel[1]      := Floor((Self.FData[(i * 8) + 4] and $C0) / $40 + 1);
-    Pixel[2]      := Floor((Self.FData[(i * 8) + 4] and $30) / $10 + 1);
-    Pixel[3]      := Floor((Self.FData[(i * 8) + 4] and $0C) / $04 + 1);
-    Pixel[4]      := Floor((Self.FData[(i * 8) + 4] and $03) + 1);
-    Pixel[5]      := Floor((Self.FData[(i * 8) + 5] and $C0) / $40 + 1);
-    Pixel[6]      := Floor((Self.FData[(i * 8) + 5] and $30) / $10 + 1);
-    Pixel[7]      := Floor((Self.FData[(i * 8) + 5] and $0C) / $04 + 1);
-    Pixel[8]      := Floor((Self.FData[(i * 8) + 5] and $03) + 1);
-    Pixel[9]      := Floor((Self.FData[(i * 8) + 6] and $C0) / $40 + 1);
-    Pixel[10]     := Floor((Self.FData[(i * 8) + 6] and $30) / $10 + 1);
-    Pixel[11]     := Floor((Self.FData[(i * 8) + 6] and $0C) / $04 + 1);
-    Pixel[12]     := Floor((Self.FData[(i * 8) + 6] and $03) + 1);
-    Pixel[13]     := Floor((Self.FData[(i * 8) + 7] and $C0) / $40 + 1);
-    Pixel[14]     := Floor((Self.FData[(i * 8) + 7] and $30) / $10 + 1);
-    Pixel[15]     := Floor((Self.FData[(i * 8) + 7] and $0C) / $04 + 1);
-    Pixel[16]     := Floor((Self.FData[(i * 8) + 7] and $03) + 1);
-    for j := 0 to 3 do
-    begin
-      tempd[((y + 3) * Self.FWidth + x + j) * 4 + 0] := Color[Pixel[16 - j]].RGBb;
-      tempd[((y + 3) * Self.FWidth + x + j) * 4 + 1] := Color[Pixel[16 - j]].RGBg;
-      tempd[((y + 3) * Self.FWidth + x + j) * 4 + 2] := Color[Pixel[16 - j]].RGBr;
-      tempd[((y + 3) * Self.FWidth + x + j) * 4 + 3] := 0;
-    end;
-    for j := 0 to 3 do
-    begin
-      tempd[((y + 2) * Self.FWidth + x + j) * 4 + 0] := Color[Pixel[12 - j]].RGBb;
-      tempd[((y + 2) * Self.FWidth + x + j) * 4 + 1] := Color[Pixel[12 - j]].RGBg;
-      tempd[((y + 2) * Self.FWidth + x + j) * 4 + 2] := Color[Pixel[12 - j]].RGBr;
-      tempd[((y + 2) * Self.FWidth + x + j) * 4 + 3] := 0;
-    end;
-    for j := 0 to 3 do
-    begin
-      tempd[((y + 1) * Self.FWidth + x + j) * 4 + 0] := Color[Pixel[8 - j]].RGBb;
-      tempd[((y + 1) * Self.FWidth + x + j) * 4 + 1] := Color[Pixel[8 - j]].RGBg;
-      tempd[((y + 1) * Self.FWidth + x + j) * 4 + 2] := Color[Pixel[8 - j]].RGBr;
-      tempd[((y + 1) * Self.FWidth + x + j) * 4 + 3] := 0;
-    end;
-    for j := 0 to 3 do
-    begin
-      tempd[((y + 0) * Self.FWidth + x + j) * 4 + 0] := Color[Pixel[4 - j]].RGBb;
-      tempd[((y + 0) * Self.FWidth + x + j) * 4 + 1] := Color[Pixel[4 - j]].RGBg;
-      tempd[((y + 0) * Self.FWidth + x + j) * 4 + 2] := Color[Pixel[4 - j]].RGBr;
-      tempd[((y + 0) * Self.FWidth + x + j) * 4 + 3] := 0;
-    end;
-    x := x + 4;
-    if x = Self.FWidth then
-    begin
-      y := y + 4;
-      x := 0;
-    end;
-  end;
-  SetLength(Self.FData, Length(tempd));
-  for i := 0 to High(tempd) do
-    Self.FData[i] := tempd[i];
-  Self.FStoreType := 8;
-  Self.FDepth    := 32;
-  Self.FDataType := Self.FDataType - [DT_Oni] + [DT_Decoded32];
-end;
-
-
-
-
-
-function TOniImage.Load(fileid: LongWord): Boolean;
-var
-  FileInfo: TFileInfo;
-  ext:      String;
-begin
-  FileInfo := OniDataConnection.GetFileInfo(fileid);
-  if FileInfo.Extension = 'PSpc' then
-    Result := LoadFromPSpc(fileid)
-  else if FileInfo.Extension = 'TXMB' then
-    Result := LoadFromTXMB(fileid)
-  else if FileInfo.Extension = 'TXMP' then
-    Result := LoadFromTXMP(fileid)
-  else
-    Result := False;
-end;
-
-
-
-
-function TOniImage.LoadFromPSpc(fileid: LongWord): Boolean;
-type
-  TPoint = packed record
-    X, Y: Word;
-  end;
-
-  TPSpc = packed record
-    p1:   array[0..8] of TPoint;
-    p2:   array[0..8] of TPoint;
-    TXMP: LongWord;
-  end;
-
-  TPart = packed record
-    x_txmp, y_txmp: Word;
-    x_pspc, y_pspc: Word;
-    w, h:    Word;
-    imgdata: Tdata;
-    used:    Boolean;
-  end;
-const
-  PartMatch: array[0..8] of Byte = (0, 3, 6, 1, 4, 7, 2, 5, 8);
-var
-  x, y, pixel: Word;
-  i: Integer;
-
-  PSpc:     TPSpc;
-  txmpimg:  TOniImage;
-  txmpdata: Tdata;
-
-  parts:    array[0..8] of TPart;
-  part:     Byte;
-  cols:     array[0..2] of Word;
-  rows:     array[0..2] of Word;
-  col, row: Byte;
-begin
-  OniDataConnection.LoadDatFilePart(fileid, $08, SizeOf(PSpc), @PSpc);
-  PSpc.TXMP := PSpc.TXMP div 256;
-  if PSpc.TXMP = 0 then
-  begin
-    Result := False;
-    Exit;
-  end;
-  txmpimg := TOniImage.Create;
-  txmpimg.LoadFromTXMP(PSpc.TXMP);
-  txmpimg.DecodeImage;
-  txmpimg.WriteToBMP('C:\file.bmp');
-  txmpdata := txmpimg.GetAs32bit;
-{    ShowMessage(IntToStr(txmpimg.Width)+'x'+IntToStr(txmpimg.Height));
-    for i:=0 to High(txmpdata) do
-      txmpimg.Data[i]:=txmpdata[i];
-    txmpimg.WriteToBMP('D:\file2.bmp');
-}
-  with PSpc do
-  begin
-    for i := 0 to 2 do
-    begin
-      cols[i] := 0;
-      rows[i] := 0;
-    end;
-    for i := 0 to 8 do
-    begin
-      part := PartMatch[i];
-      col  := i div 3;
-      row  := i mod 3;
-      if (p2[i].X > 0) or (p2[i].Y > 0) then
-      begin
-        parts[part].x_txmp := p1[i].X - 1;
-        parts[part].y_txmp := p1[i].Y - 1;
-        parts[part].x_pspc := 0;
-        if col > 0 then
-          for x := 0 to col - 1 do
-            Inc(parts[part].x_pspc, cols[x]);
-        parts[part].y_pspc := 0;
-        if row > 0 then
-          for y := 0 to row - 1 do
-            Inc(parts[part].y_pspc, rows[y]);
-        parts[part].w := p2[i].X - p1[i].X + 1;
-        parts[part].h := p2[i].Y - p1[i].Y + 1;
-        parts[part].used := True;
-        cols[col] := parts[part].w;
-        rows[row] := parts[part].h;
-        SetLength(parts[part].imgdata, parts[part].w * parts[part].h * 4);
-        for y := 0 to parts[part].h - 1 do
-        begin
-          for x := 0 to parts[part].w - 1 do
-          begin
-            for pixel := 0 to 3 do
-            begin
-              parts[part].imgdata[(y * parts[part].w + x) * 4 + pixel] :=
-                txmpdata[((parts[part].y_txmp + y) * txmpimg.Width +
-                parts[part].x_txmp + x) * 4 + pixel];
-            end;
-          end;
-        end;
-      end
-      else
-      begin
-        parts[part].used := False;
-      end;
-    end;
-
-  end;
-
-  txmpimg.Free;
-  txmpimg := TOniImage.Create;
-  for i := 0 to 8 do
-  begin
-    if parts[i].used then
-    begin
-      SetLength(txmpimg.FData, Length(parts[i].imgdata));
-      for pixel := 0 to High(parts[i].imgdata) do
-        txmpimg.Data[pixel] := parts[i].imgdata[pixel];
-      txmpimg.Width := parts[i].w;
-      txmpimg.Height    := parts[i].h;
-      txmpimg.StoreType := 8;
-      txmpimg.DataType  := [DT_Decoded32];
-      txmpimg.Depth     := 32;
-      txmpimg.WriteToBMP('D:\' + IntToStr(i) + '.bmp');
-    end;
-  end;
-  txmpimg.Free;
-
-  Self.FWidth  := 0;
-  Self.FHeight := 0;
-  for i := 0 to 2 do
-  begin
-    Inc(Self.FWidth, cols[i]);
-    Inc(Self.FHeight, rows[i]);
-  end;
-  SetLength(Self.FData, Self.FWidth * Self.FHeight * 4);
-
-  //Combine data parts
-
-  Self.FDepth     := 32;
-  Self.FStoreType := 8;
-  Self.FDataType  := [DT_Decoded32];
-  //    Self.RevertImage;
-end;
-
-
-
-
-function TOniImage.LoadFromTXMP(fileid: LongWord): Boolean;
-var
-  img_addr: LongWord;
-begin
-  Result := True;
-  OniDataConnection.LoadDatFilePart(fileid, $8C, SizeOf(Self.FWidth), @Self.FWidth);
-  OniDataConnection.LoadDatFilePart(fileid, $8E, SizeOf(Self.FHeight), @Self.FHeight);
-  OniDataConnection.LoadDatFilePart(fileid, $90, SizeOf(Self.FStoreType),
-    @Self.FStoreType);
-  if not OniDataConnection.OSisMac then
-    OniDataConnection.LoadDatFilePart(fileid, $9C, SizeOf(img_addr), @img_addr)
-  else
-    OniDataConnection.LoadDatFilePart(fileid, $A0, SizeOf(img_addr), @img_addr);
-
-  case Self.FStoreType of
-    0, 1, 2:
-    begin
-      SetLength(Self.FData, Self.FWidth * Self.FHeight * 2);
-      Self.FDepth := 16;
-    end;
-    8:
-    begin
-      SetLength(Self.FData, Self.FWidth * Self.FHeight * 4);
-      Self.FDepth := 32;
-    end;
-    9:
-    begin
-      SetLength(Self.FData, Self.FWidth * Self.FHeight div 2);
-      Self.FDepth := 16;
-    end;
-    else
-      Result := False;
-      Exit;
-  end;
-
-  if not OniDataConnection.OSisMac then
-    OniDataConnection.LoadRawFile(fileid, $9C, @Self.FData[0])
-  else
-    OniDataConnection.LoadRawFile(fileid, $A0, @Self.FData[0]);
-
-  Self.FDataType := [DT_OniReverted, DT_Oni];
-end;
-
-
-
-
-function TOniImage.LoadFromTXMB(fileid: LongWord): Boolean;
-var
-  i, x, y, x2, y2, pixelid, imgid: LongWord;
-  rows, cols: Word;
-  linkcount: LongWord;
-  link: LongWord;
-  images_decoded: array of TOniImage;
-  x_start, y_start: LongWord;
-begin
-  OniDataConnection.LoadDatFilePart(fileid, $10, SizeOf(Self.FWidth), @Self.FWidth);
-  OniDataConnection.LoadDatFilePart(fileid, $12, SizeOf(Self.FHeight), @Self.FHeight);
-  OniDataConnection.LoadDatFilePart(fileid, $18, SizeOf(cols), @cols);
-  OniDataConnection.LoadDatFilePart(fileid, $1A, SizeOf(rows), @rows);
-  OniDataConnection.LoadDatFilePart(fileid, $1C, SizeOf(linkcount), @linkcount);
-  SetLength(images_decoded, linkcount);
-  for i := 0 to linkcount - 1 do
-  begin
-    OniDataConnection.LoadDatFilePart(fileid, $20 + i * 4, SizeOf(link), @link);
-    link := link div 256;
-    images_decoded[i] := TOniImage.Create;
-    images_decoded[i].LoadFromTXMP(link);
-    images_decoded[i].DecodeImage;
-    images_decoded[i].RevertImage;
-  end;
-  SetLength(Self.FData, Self.FWidth * Self.FHeight * 4);
-  for y := 0 to rows - 1 do
-  begin
-    for x := 0 to cols - 1 do
-    begin
-      imgid   := y * cols + x;
-      x_start := 0;
-      y_start := 0;
-      for i := 0 to x do
-        if i < x then
-          x_start := x_start + images_decoded[i].Width;
-      for i := 0 to y do
-        if i < y then
-          y_start := y_start + images_decoded[i].Height;
-      for y2 := 0 to images_decoded[imgid].Height - 1 do
-      begin
-        for x2 := 0 to images_decoded[imgid].Width - 1 do
-        begin
-          if ((x_start + x2) < Self.FWidth) and ((y_start + y2) < Self.FHeight) then
-          begin
-            pixelid := y_start * Self.FWidth + x_start + y2 * Self.FWidth + x2;
-            Self.FData[pixelid * 4 + 0] :=
-              images_decoded[imgid].Data[(y2 * images_decoded[imgid].Width + x2) * 4 + 0];
-            Self.FData[pixelid * 4 + 1] :=
-              images_decoded[imgid].Data[(y2 * images_decoded[imgid].Width + x2) * 4 + 1];
-            Self.FData[pixelid * 4 + 2] :=
-              images_decoded[imgid].Data[(y2 * images_decoded[imgid].Width + x2) * 4 + 2];
-            Self.FData[pixelid * 4 + 3] :=
-              images_decoded[imgid].Data[(y2 * images_decoded[imgid].Width + x2) * 4 + 3];
-          end;
-        end;
-      end;
-    end;
-  end;
-  for i := 0 to linkcount - 1 do
-    images_decoded[i].Free;
-  Self.FDepth     := 32;
-  Self.FStoreType := 8;
-  Self.FDataType  := [DT_Decoded32];
-  Self.RevertImage;
-end;
-
-
-
-
-function TOniImage.GetImageDataSize(fading: Boolean): LongWord;
-var
-  size: LongWord;
-  x, y: Word;
-  bpp:  Byte;
-begin
-  case Self.FStoreType of
-    9:
-      bpp := 8;
-    0, 1, 2:
-      bpp := 16;
-    8:
-      bpp := 32;
-    else
-      Result := 0;
-      Exit;
-  end;
-
-  x    := Self.FWidth;
-  y    := Self.FHeight;
-  size := x * y * bpp div 8;
-  if fading then
-  begin
-    repeat
-      x    := x div 2;
-      y    := y div 2;
-      size := size + x * y * bpp div 8;
-    until (x = 1) or (y = 1);
-  end;
-  Result := size;
-end;
-
-
-
-
-function TOniImage.GetAsData: Tdata;
-var
-  i:      Integer;
-  revert: Boolean;
-begin
-  //    if not (DT_Decoded32 in Self.FDataType) then
-  //      Self.DecodeImage;
-  if not (DT_OniReverted in Self.FDataType) then
-  begin
-    revert := True;
-    Self.RevertImage;
-  end
-  else
-    revert := False;
-  SetLength(Result, Length(Self.FData));
-  for i := 0 to High(Result) do
-    Result[i] := Self.FData[i];
-  if revert then
-    Self.RevertImage;
-end;
-
-
-
-
-function TOniImage.GetAs32bit: Tdata;
-var
-  i: Integer;
-begin
-  if not (DT_Decoded32 in Self.FDataType) then
-    Self.DecodeImage;
-  SetLength(Result, Length(Self.FData));
-  for i := 0 to High(Result) do
-    Result[i] := Self.FData[i];
-end;
-
-
-
-
-function TOniImage.GetAsBMP: Tdata;
-const
-  BMPheader: array[0..53] of Byte =
-    ($42, $4D, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0,
-    40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, $18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-var
-  i, x, y: LongWord;
-begin
-  if not (DT_Decoded32 in Self.FDataType) then
-    Self.DecodeImage;
-
-  SetLength(Result, Self.FWidth * Self.FHeight * 3 + 54);
-  for y := 0 to Self.FHeight - 1 do
-  begin
-    for x := 0 to Self.FWidth - 1 do
-    begin
-      Result[((Self.FWidth * y + x) * 3) + 0 + 54] := Self.FData[(Self.FWidth * y + x) * 4 + 0];
-      Result[((Self.FWidth * y + x) * 3) + 1 + 54] := Self.FData[(Self.FWidth * y + x) * 4 + 1];
-      Result[((Self.FWidth * y + x) * 3) + 2 + 54] := Self.FData[(Self.FWidth * y + x) * 4 + 2];
-    end;
-  end;
-
-  for i := 0 to High(BMPheader) do
-    Result[i] := BMPheader[i];
-  Result[2] := ((Self.FWidth * Self.FHeight * 3 + 54) and $000000FF) div $1;
-  Result[3]  := ((Self.FWidth * Self.FHeight * 3 + 54) and $0000FF00) div $100;
-  Result[4]  := ((Self.FWidth * Self.FHeight * 3 + 54) and $00FF0000) div $10000;
-  Result[5]  := ((Self.FWidth * Self.FHeight * 3 + 54) and $FF000000) div $1000000;
-  Result[18] := (Self.FWidth and $000000FF) div $1;
-  Result[19] := (Self.FWidth and $0000FF00) div $100;
-  Result[20] := (Self.FWidth and $00FF0000) div $10000;
-  Result[21] := (Self.FWidth and $FF000000) div $1000000;
-  Result[22] := (Self.FHeight and $000000FF) div $1;
-  Result[23] := (Self.FHeight and $0000FF00) div $100;
-  Result[24] := (Self.FHeight and $00FF0000) div $10000;
-  Result[25] := (Self.FHeight and $FF000000) div $1000000;
-  Result[34] := ((Self.FWidth * Self.FHeight * 3) and $000000FF) div $1;
-  Result[35] := ((Self.FWidth * Self.FHeight * 3) and $0000FF00) div $100;
-  Result[36] := ((Self.FWidth * Self.FHeight * 3) and $00FF0000) div $10000;
-  Result[37] := ((Self.FWidth * Self.FHeight * 3) and $FF000000) div $1000000;
-end;
-
-
-
-
-function TOniImage.LoadFromBMP(filename: String): Boolean;
-var
-  filestream: TFileStream;
-  tempd:      Tdata;
-
-  x, y: LongWord;
-begin
-  filestream := TFileStream.Create(filename, fmOpenRead);
-  SetLength(tempd, filestream.Size);
-  filestream.Read(tempd[0], filestream.Size);
-  filestream.Free;
-
-  if not ((tempd[00] = $42) and (tempd[01] = $4D)) then
-  begin
-    Result := False;
-    ShowMessage('Not a standard 24bit bitmap');
-    Exit;
-  end;
-  if not (tempd[10] = 54) then
-  begin
-    Result := False;
-    ShowMessage('Imagedata has to start at 0x54');
-    Exit;
-  end;
-  if not (tempd[14] = 40) then
-  begin
-    Result := False;
-    ShowMessage('Second bitmap header has to have 40 bytes');
-    Exit;
-  end;
-  if not (tempd[28] = 24) then
-  begin
-    Result := False;
-    ShowMessage('Bitmap has to have 24bits');
-    Exit;
-  end;
-  if not (tempd[30] = 0) then
-  begin
-    Result := False;
-    ShowMessage('Bitmap has to be uncompressed');
-    Exit;
-  end;
-
-  Self.FWidth     := tempd[18] + tempd[19] * 256 + tempd[20] * 256 * 256 + tempd[21] * 256 * 256 * 256;
-  Self.FHeight    := tempd[22] + tempd[23] * 256 + tempd[24] * 256 * 256 + tempd[25] * 256 * 256 * 256;
-  Self.FDepth     := 32;
-  Self.FStoreType := 8;
-
-  SetLength(Self.FData, Self.FWidth * Self.FHeight * Self.FDepth div 8);
-  for y := 0 to Self.FHeight - 1 do
-  begin
-    for x := 0 to Self.FWidth - 1 do
-    begin
-      Self.FData[((Self.FWidth * y + x) * 4) + 0] := tempd[54 + (Self.FWidth * y + x) * 3 + 0];
-      Self.FData[((Self.FWidth * y + x) * 4) + 1] := tempd[54 + (Self.FWidth * y + x) * 3 + 1];
-      Self.FData[((Self.FWidth * y + x) * 4) + 2] := tempd[54 + (Self.FWidth * y + x) * 3 + 2];
-      Self.FData[((Self.FWidth * y + x) * 4) + 3] := 0;
-    end;
-  end;
-
-  Self.FDataType := [DT_Decoded32];
-end;
-
-
-
-
-function TOniImage.WriteToBMP(filename: String): Boolean;
-var
-  filestream: TFileStream;
-  tempd:      Tdata;
-begin
-  tempd      := Self.GetAsBMP;
-  filestream := TFileStream.Create(filename, fmCreate);
-  filestream.Write(tempd[0], Length(tempd));
-  filestream.Free;
-end;
-
-
-
-
-function TOniImage.GetMipMappedImage(var faded: Tdata): Boolean;
-var
-  i:      LongWord;
-  x, y:   Word;
-  fadelvldata: Tdata;
-  revert: Boolean;
-begin
-  Result := False;
-
-  //    if not (DT_Decoded32 in Self.FDataType) then
-  //      Self.DecodeImage;
-  if Self.FStoreType = 9 then
-    Self.DecompressImage;
-  if not (DT_OniReverted in Self.FDataType) then
-  begin
-    revert := True;
-    Self.RevertImage;
-  end
-  else
-    revert := False;
-
-  x := Self.FWidth;
-  y := Self.FHeight;
-  SetLength(faded, x * y * Self.FDepth div 8);
-  SetLength(fadelvldata, x * y * Self.FDepth div 8);
-  for i := 0 to Length(faded) - 1 do
-  begin
-    faded[i] := Self.FData[i];
-    fadelvldata[i] := Self.FData[i];
-  end;
-  repeat
-    fadelvldata := Self.ResizeImage(x, y, fadelvldata);
-    x := x div 2;
-    y := y div 2;
-    SetLength(faded, Length(faded) + x * y * Self.FDepth div 8);
-    for i := 0 to Length(fadelvldata) - 1 do
-      faded[Length(faded) - x * y * Self.FDepth div 8 + i] := fadelvldata[i];
-  until (x = 1) or (y = 1) or ((x mod 2) = 1) or ((y mod 2) = 1);
-  if (x > 1) and (y > 1) then
-    Exit;
-  Result := True;
-
-  if revert then
-    Self.RevertImage;
-end;
-
-
-end.
Index: oup/current/Data.pas
===================================================================
--- oup/current/Data.pas	(revision 45)
+++ oup/current/Data.pas	(revision 46)
@@ -100,4 +100,6 @@
   end;
 
+  TSortType = (stIDAsc, stIDDesc, stNameAsc, stNameDesc, stExtAsc, stExtDesc);
+
 var
 {
Index: oup/current/FTypeReg.pas
===================================================================
--- oup/current/FTypeReg.pas	(revision 46)
+++ oup/current/FTypeReg.pas	(revision 46)
@@ -0,0 +1,625 @@
+// -----------------------------------------------------------------------------
+//
+// TFileTypeRegistration-Klasse (Win32-API)
+// Copyright (c) 2004 Mathias Simmack
+//
+// -----------------------------------------------------------------------------
+
+// -- Revision history ---------------------------------------------------------
+//
+//   * erste Version
+//
+// -----------------------------------------------------------------------------
+unit FTypeReg;
+
+interface
+
+uses
+  Windows, ShlObj, SysUtils;
+
+type
+  TFileTypeRegistration = class
+    FRegConnector : HKEY;
+    FExtension,
+    FInternalName : string;
+    FVerb         : string;
+  public
+    constructor Create;
+    destructor Destroy; override;
+    function RegisterType(const Extension, InternalName: string;
+      Description: string = ''; IconFile: string = '';
+      IconIndex: integer = -1): boolean;
+    function UnregisterExtension(const Extension: string): boolean;
+    function UnregisterType(const Extension: string): boolean;
+    procedure UpdateShell;
+    function AddHandler(const HandlerVerb, CommandLine: string;
+      HandlerDescription: string = ''): boolean; overload;
+    function DeleteHandler(const HandlerVerb: string): boolean;
+    function SetDefaultHandler: boolean; overload;
+    function SetDefaultHandler(const HandlerVerb: string): boolean; overload;
+    function GetInternalKey(const Extension: string): string;
+    function AddNewFileSupport(const Extension: string): boolean;
+    function RemoveNewFileSupport(const Extension: string): boolean;
+
+    property Extension: string read FExtension;
+    property InternalName: string read FInternalName;
+    property CurrentVerb: string read FVerb;
+  end;
+
+
+implementation
+
+(* *****************************************************************************
+
+  Beispiel #1: Einen neuen Dateityp registrieren
+  ----------------------------------------------
+
+  ftr := TFileTypeRegistration.Create;
+  if(ftr <> nil) then
+  try
+    // die Dateiendung ".foo" registrieren, der interne Schlüssel
+    // lautet "FooFile", eine Beschreibung und eine Symboldatei
+    // sind ebenfalls angegeben
+    if(ftr.RegisterType('.foo','FooFile','FOO Description',
+      'c:\folder\icon.ico')) then
+    begin
+      // fügt den Handler "open" hinzu und verknüpft ihn mit dem
+      // Programm "foo.exe"
+      ftr.AddHandler('open','"c:\folder\foo.exe" "%1"');
+
+      // setzt den zuletzt benutzten Handler ("open" in dem Fall)
+      // als Standard
+      ftr.SetDefaultHandler;
+    end;
+
+    if(ftr.RegisterType('.foo','ThisIsNotTheFOOKey')) then
+    // Das ist kein Fehler! Obwohl hier der interne Name
+    // "ThisIsNotTheFOOKey" verwendet wird, benutzt die Funktion
+    // intern den bereits vorhandenen Schlüssel "FooFile" (s. oben).
+    begin
+      // zwei neue Handler werden registriert, ...
+      ftr.AddHandler('print','"c:\folder\foo.exe" /p "%1"');
+      ftr.AddHandler('edit','notepad.exe "%1"');
+
+      // ... & dank der überladenen Funktion "SetDefaultHandler"
+      // kann diesmal auch "print" als Standardhandler gesetzt
+      // werden
+      ftr.SetDefaultHandler('print');
+    end;
+  finally
+    ftr.Free;
+  end;
+
+
+  Beispiel #2: Einen neuen Typ mit einem vorhandenen Schlüssel
+  verknüpfen
+  ------------------------------------------------------------
+
+  Das Beispiel registriert die Endung ".foo" auf die gleiche
+  Weise wie Textdateien (.txt). Es wird einfach der interne
+  Schlüsselname ermittelt und für die Endung ".foo" gesetzt
+
+  ftr := TFileTypeRegistration.Create;
+  if(ftr <> nil) then
+  try
+    strInternalTextFileKey := ftr.GetInternalKey('.txt');
+    if(strInternalTextFileKey <> '') then
+      ftr.RegisterType('.foo',strInternalTextFileKey);
+  finally
+    ftr.Free;
+  end;
+
+
+  Beispiel #3: Einen Handler entfernen
+  ------------------------------------
+
+  ftr := TFileTypeRegistration.Create;
+  if(ftr <> nil) then
+  try
+    // den internen Schlüsselnamen des Typs ".foo" ermitteln, ...
+    if(ftr.GetInternalKey('.foo') <> '') then
+    // ... wobei das Ergebnis in dem Fall unwichtig ist, weil
+    // intern auch die Eigenschaft "FInternalName" gesetzt
+    // wird
+    begin
+      // den "print"-Handler entfernen, ...
+      ftr.DeleteHandler('print');
+
+      // ... & den Standardhandler aktualisieren
+      ftr.SetDefaultHandler('open');
+    end;
+  finally
+    ftr.Free;
+  end;
+
+
+  Beispiel #4: Nur eine Dateiendung entfernen
+  -------------------------------------------
+
+  In diesem Fall wird lediglich die Endung ".foo" entfernt. Der
+  evtl. vorhandene interne Schlüssel bleibt bestehen. Das ist
+  für das Beispiel #2 nützlich, wenn die Endung ".foo" entfernt
+  werden soll, intern aber mit den Textdateien verlinkt ist, die
+  ja im Normalfall nicht entfernt werden dürfen/sollten.
+
+    ftr.UnregisterExtension('.foo');
+
+
+  Beispiel #5: Den kompletten Dateityp entfernen
+  ----------------------------------------------
+
+  Dieses Beispiel entfernt dagegen den kompletten Dateityp,
+  inkl. des evtl. vorhandenen internen Schlüssels (vgl. mit
+  Beispiel #4).
+
+    ftr.UnregisterType('.foo');
+
+  Bezogen auf Beispiel #2 wäre das die fatale Lösung, weil dadurch
+  zwar die Endung ".foo" deregistriert wird, gleichzeitig wird
+  aber auch der intern verwendete Schlüssel der Textdateien
+  gelöscht.
+
+  ALSO, VORSICHT!!!
+
+***************************************************************************** *)
+
+
+//
+// Admin-Rechte sind erforderlich (Funktion von NicoDE)
+//
+//{$INCLUDE IsAdmin.inc}
+function GetAdminSid: PSID;
+const
+  // bekannte SIDs ... (WinNT.h)
+  SECURITYNTAUTHORITY: TSIDIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 5));
+  // bekannte RIDs ... (WinNT.h)
+  SECURITYBUILTINDOMAINRID: DWORD = $00000020;
+  DOMAINALIASRIDADMINS: DWORD = $00000220;
+begin
+  Result := nil;
+  AllocateAndInitializeSid(SECURITYNTAUTHORITY, 2, SECURITYBUILTINDOMAINRID,
+    DOMAINALIASRIDADMINS, 0, 0, 0, 0, 0, 0, Result);
+end;
+
+function IsAdmin: LongBool;
+var
+  TokenHandle      : THandle;
+  ReturnLength     : DWORD;
+  TokenInformation : PTokenGroups;
+  AdminSid         : PSID;
+  Loop             : Integer;
+  wv               : TOSVersionInfo;
+begin
+  wv.dwOSVersionInfoSize := sizeof(TOSversionInfo);
+  GetVersionEx(wv);
+
+  Result := (wv.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS);
+
+  if(wv.dwPlatformId = VER_PLATFORM_WIN32_NT) then
+    begin
+      TokenHandle := 0;
+      if OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, TokenHandle) then
+        try
+          ReturnLength := 0;
+          GetTokenInformation(TokenHandle, TokenGroups, nil, 0, ReturnLength);
+          TokenInformation := GetMemory(ReturnLength);
+          if Assigned(TokenInformation) then
+            try
+              if GetTokenInformation(TokenHandle, TokenGroups,
+                TokenInformation, ReturnLength, ReturnLength) then
+              begin
+                AdminSid := GetAdminSid;
+                for Loop := 0 to TokenInformation^.GroupCount - 1 do
+                  begin
+                    if EqualSid(TokenInformation^.Groups[Loop].Sid, AdminSid) then
+                      begin
+                        Result := True;
+                        break;
+                      end;
+                  end;
+                FreeSid(AdminSid);
+              end;
+            finally
+              FreeMemory(TokenInformation);
+            end;
+        finally
+          CloseHandle(TokenHandle);
+        end;
+    end;
+end;
+
+function WVersion: string;
+var
+  OSInfo: TOSVersionInfo;
+begin
+  Result := '3X';
+  OSInfo.dwOSVersionInfoSize := sizeof(TOSVERSIONINFO);
+  GetVersionEx(OSInfo);
+  case OSInfo.dwPlatformID of
+    VER_PLATFORM_WIN32S: begin
+        Result := '3X';
+        Exit;
+      end;
+    VER_PLATFORM_WIN32_WINDOWS: begin
+        Result := '9X';
+        Exit;
+      end;
+    VER_PLATFORM_WIN32_NT: begin
+        Result := 'NT';
+        Exit;
+      end;
+  end; //case
+end;
+
+
+// -----------------------------------------------------------------------------
+//
+// Registry
+//
+// -----------------------------------------------------------------------------
+
+function RegWriteSubKeyVal(const parent: HKEY; SubKeyName: string;
+  ValueName, Value: string): boolean;
+var
+  tmp    : HKEY;
+begin
+  Result := false;
+  if(parent = INVALID_HANDLE_VALUE) or
+    (SubKeyName = '') then exit;
+
+  if(RegCreateKeyEx(parent,pchar(SubKeyName),0,nil,0,KEY_READ or KEY_WRITE,
+    nil,tmp,nil) = ERROR_SUCCESS) then
+  try
+    Result := (RegSetValueEx(tmp,pchar(ValueName),0,REG_SZ,pchar(Value),
+      length(Value) + 1) = ERROR_SUCCESS);
+  finally
+    RegCloseKey(tmp);
+  end;
+end;
+
+function RegReadSubKeyStr(const parent: HKEY; SubKeyName: string;
+  ValueName: string): string;
+var
+  tmp     : HKEY;
+  lpData,
+  dwLen   : dword;
+begin
+  Result  := '';
+  if(parent = INVALID_HANDLE_VALUE) or
+    (SubKeyName = '') then exit;
+
+  if(RegOpenKeyEx(parent,pchar(SubKeyName),0,KEY_READ,
+    tmp) = ERROR_SUCCESS) then
+  try
+    lpData := REG_NONE;
+    dwLen  := 0;
+    if(RegQueryValueEx(tmp,pchar(ValueName),nil,@lpData,nil,
+         @dwLen) = ERROR_SUCCESS) and
+      (lpData in[REG_SZ,REG_EXPAND_SZ]) and
+      (dwLen > 0) then
+    begin
+      SetLength(Result,dwLen);
+
+      if(RegQueryValueEx(tmp,pchar(ValueName),nil,@lpData,
+           @Result[1],@dwLen) = ERROR_SUCCESS) then
+        SetLength(Result,dwLen - 1)
+      else
+        Result := '';
+    end;
+  finally
+    RegCloseKey(tmp);
+  end;
+end;
+
+function RegKeyExists(const parent: HKEY; KeyName: string): boolean;
+var
+  tmp    : HKEY;
+begin
+  Result := (RegOpenKeyEx(parent,pchar(KeyName),0,KEY_READ,tmp) =
+    ERROR_SUCCESS);
+  if(Result) then RegCloseKey(tmp);
+end;
+
+function RegDeleteWholeKey(parent: HKEY; KeyName: string): boolean;
+var
+  reg       : HKEY;
+  dwSubkeys : dword;
+  dwLen     : dword;
+  i         : integer;
+  buf       : array[0..MAX_PATH]of char;
+begin
+  if(RegOpenKeyEx(parent,pchar(KeyName),0,KEY_READ,reg) = ERROR_SUCCESS) then
+  try
+    if(RegQueryInfoKey(reg,nil,nil,nil,@dwSubKeys,nil,
+      nil,nil,nil,nil,nil,nil) = ERROR_SUCCESS) and
+      (dwSubKeys > 0) then
+    for i := 0 to dwSubKeys - 1 do begin
+      ZeroMemory(@buf,sizeof(buf));
+      dwLen   := MAX_PATH;
+
+      if(RegEnumKeyEx(reg,i,buf,dwLen,nil,nil,nil,nil) = ERROR_SUCCESS) and
+        (dwLen > 0) then
+      RegDeleteWholeKey(reg,buf);
+    end;
+  finally
+    RegCloseKey(reg);
+  end;
+
+  Result := (RegDeleteKey(parent,pchar(KeyName)) = ERROR_SUCCESS);
+end;
+
+
+// -----------------------------------------------------------------------------
+//
+// TFileTypeRegistration-Klasse
+//
+// -----------------------------------------------------------------------------
+
+constructor TFileTypeRegistration.Create;
+var
+  key: HKEY;
+  sub: PChar;
+begin
+  FExtension    := '';
+  FInternalName := '';
+  FVerb         := '';
+
+  // Zugriff auf die Registry, & HKEY_CLASSES_ROOT
+  // als Root setzen
+  if(WVersion='9X') or IsAdmin then begin
+    key:=HKEY_CLASSES_ROOT;
+    sub:=nil;
+  end else begin
+    key:=HKEY_CURRENT_USER;
+    sub:=PChar('SOFTWARE\Classes');
+  end;
+
+  if RegOpenKeyEx(key,sub,0,KEY_ALL_ACCESS, FRegConnector) <> ERROR_SUCCESS then
+    FRegConnector := INVALID_HANDLE_VALUE;
+end;
+
+destructor TFileTypeRegistration.Destroy;
+begin
+  if(FRegConnector <> INVALID_HANDLE_VALUE) then
+    RegCloseKey(FRegConnector);
+end;
+
+function TFileTypeRegistration.RegisterType(const Extension,
+  InternalName: string; Description: string = ''; IconFile: string = '';
+  IconIndex: integer = -1): boolean;
+var
+  strDummy : string;
+begin
+  // Standardergebnis
+  Result         := false;
+  if(FRegConnector = INVALID_HANDLE_VALUE) or
+    (Extension = '') or
+    (Extension[1] <> '.') then exit;
+
+  // ist dieser Typ evtl. schon registriert?
+  strDummy := self.GetInternalKey(Extension);
+
+  // Nein. :o)
+  if(strDummy = '') then strDummy := InternalName;
+
+  // den Schlüssel mit der Dateiendung anlegen oder aktualisieren
+  Result := RegWriteSubKeyVal(FRegConnector,Extension,'',strDummy);
+  if(not Result) then exit;
+
+  // den internen Schlüssel öffnen
+  if(Result) then
+  begin
+    // Beschreibung anlegen
+    if(Description <> '') then
+      RegWriteSubKeyVal(FRegConnector,strDummy,'',Description);
+
+    // Symbol zuweisen (Datei muss existieren!)
+    if(IconFile <> '') and
+      (fileexists(IconFile)) then
+    begin
+      if(IconIndex <> -1) then
+        RegWriteSubKeyVal(FRegConnector,strDummy + '\DefaultIcon',
+          '',Format('%s,%d',[IconFile,IconIndex]))
+      else
+        RegWriteSubKeyVal(FRegConnector,strDummy + '\DefaultIcon',
+          '',IconFile);
+    end;
+  end;
+
+  // Systemsymbole aktualisieren
+  self.UpdateShell;
+
+  // Properties aktualisieren
+  if(Result) then
+  begin
+    FExtension    := Extension;
+    FInternalName := strDummy;
+  end;
+end;
+
+function TFileTypeRegistration.UnregisterExtension(const Extension: string):
+  boolean;
+begin
+  Result := false;
+  if(FRegConnector = INVALID_HANDLE_VALUE) or
+    (Extension = '') or
+    (Extension[1] <> '.') then exit;
+
+  // die Endung entfernen
+  Result := (RegKeyExists(FRegConnector,Extension)) and
+    (RegDeleteWholeKey(FRegConnector,Extension));
+
+  // Systemsymbole aktualisieren
+  self.UpdateShell;
+end;
+
+function TFileTypeRegistration.UnregisterType(const Extension: string):
+  boolean;
+var
+  strDummy : string;
+begin
+  Result   := false;
+  if(FRegConnector = INVALID_HANDLE_VALUE) or
+    (Extension = '') or
+    (Extension[1] <> '.') then exit;
+
+  // den internen Namen der Endung ermitteln
+  strDummy := self.GetInternalKey(Extension);
+
+  // die Endung entfernen (s. "UnregisterExtension"), ...
+  Result   := (self.UnregisterExtension(Extension)) and
+  // ... & den internen Schlüssel löschen
+    (strDummy <> '') and
+    (RegKeyExists(FRegConnector,strDummy)) and
+    (RegDeleteWholeKey(FRegConnector,strDummy));
+
+  // Systemsymbole aktualisieren
+  self.UpdateShell;
+end;
+
+procedure TFileTypeRegistration.UpdateShell;
+begin
+  SHChangeNotify(SHCNE_ASSOCCHANGED,SHCNF_IDLIST,nil,nil);
+end;
+
+
+const
+  ShellKey = '%s\shell\%s';
+
+function TFileTypeRegistration.AddHandler(const HandlerVerb,
+  CommandLine: string; HandlerDescription: string = ''): boolean;
+begin
+  // Standardergebnis
+  Result := false;
+  if(FRegConnector = INVALID_HANDLE_VALUE) or
+    (FInternalName = '') or
+    (HandlerVerb = '') or
+    (CommandLine = '') then exit;
+
+  // der interne Schlüssel muss existieren
+  if(RegKeyExists(FRegConnector,FInternalName)) then
+  begin
+    // den Handler (= Verb) erzeugen
+    Result := RegWriteSubKeyVal(FRegConnector,
+      Format(ShellKey + '\command',[FInternalName,HandlerVerb]),
+      '',
+      CommandLine);
+
+    // ggf. Beschreibung für Handler setzen
+    if(HandlerDescription <> '') then
+      RegWriteSubKeyVal(FRegConnector,
+        Format(ShellKey,[FInternalName,HandlerVerb]),
+        '',
+        HandlerDescription);
+  end;
+
+  // interne Eigenschaft anpassen (für "SetDefaultHandler")
+  if(Result) then
+    FVerb := HandlerVerb;
+end;
+
+function TFileTypeRegistration.DeleteHandler(const HandlerVerb: string):
+  boolean;
+begin
+  // Standardergebnis
+  Result := false;
+  if(FRegConnector = INVALID_HANDLE_VALUE) or
+    (FInternalName = '') or
+    (HandlerVerb = '') then exit;
+
+  // Handlerschlüssel entfernen (sofern vorhanden)
+  Result :=
+    (RegKeyExists(FRegConnector,
+       Format(ShellKey,[FInternalName,HandlerVerb]))) and
+    (RegDeleteWholeKey(FRegConnector,
+       Format(ShellKey,[FInternalName,HandlerVerb])));
+end;
+
+function TFileTypeRegistration.SetDefaultHandler: boolean;
+begin
+  if(FInternalName <> '') and (FVerb <> '') then
+    Result := self.SetDefaultHandler(FVerb)
+  else
+    Result := false;
+end;
+
+function TFileTypeRegistration.SetDefaultHandler(const HandlerVerb: string):
+  boolean;
+begin
+  Result := false;
+  if(FRegConnector = INVALID_HANDLE_VALUE) or
+    (FInternalName = '') or
+    (HandlerVerb = '') then exit;
+
+  // interner Schlüssel muss existieren, ...
+  if(RegKeyExists(FRegConnector,FInternalName)) and
+  // ... & Handler muss existieren, ...
+    (RegKeyExists(FRegConnector,
+       Format(ShellKey,[FInternalName,HandlerVerb]))) then
+  begin
+  // ... dann den Handler als Standard eintragen
+    Result := RegWriteSubKeyVal(FRegConnector,FInternalName + '\shell',
+      '',HandlerVerb);
+  end;
+end;
+
+function TFileTypeRegistration.GetInternalKey(const Extension: string): string;
+begin
+  if(FRegConnector = INVALID_HANDLE_VALUE) or
+    (Extension = '') or
+    (Extension[1] <> '.') then exit;
+
+  // einen evtl. eingestellten internen Namen zurücksetzen
+  FInternalName   := '';
+
+  // den Schlüssel der Dateiendung öffnen, ...
+  if(RegKeyExists(FRegConnector,Extension)) then
+    FInternalName := RegReadSubKeyStr(FRegConnector,Extension,'');
+
+  // ... als Funktionsergebnis zurückliefern
+  if(not RegKeyExists(FRegConnector,FInternalName)) then
+    FInternalName := '';
+
+  Result := FInternalName;
+end;
+
+
+function TFileTypeRegistration.AddNewFileSupport(const Extension: string):
+  boolean;
+var
+  Description : string;
+begin
+  Result      := false;
+  if(FRegConnector = INVALID_HANDLE_VALUE) or
+    (Extension = '') or
+    (Extension[1] <> '.') then exit;
+
+  // interne Beschreibung des Typs ermitteln
+  if(self.GetInternalKey(Extension) <> '') then
+    Description := RegReadSubKeyStr(FRegConnector,FInternalName,'')
+  else
+    Description := '';
+
+  // die Beschreibung darf keine Leerzeichen enthalten, weil sie
+  // als Referenz für den neuen Dateinamen verwendet wird, ...
+  if(pos(#32,Description) > 0) or
+  // ... & sie darf auch nicht leer sein
+    (Description = '') then exit;
+
+  Result := (RegKeyExists(FRegConnector,Extension)) and
+    (RegWriteSubKeyVal(FRegConnector,Extension + '\ShellNew','NullFile',''));
+end;
+
+function TFileTypeRegistration.RemoveNewFileSupport(const Extension: string):
+  boolean;
+begin
+  Result := false;
+  if(FRegConnector = INVALID_HANDLE_VALUE) or
+    (Extension = '') or
+    (Extension[1] <> '.') then exit;
+
+  Result := (RegKeyExists(FRegConnector,Extension + '\ShellNew')) and
+    (RegDeleteWholeKey(FRegConnector,Extension + '\ShellNew'));
+end;
+
+end.
Index: oup/current/Helper_LevelDB.pas
===================================================================
--- oup/current/Helper_LevelDB.pas	(revision 45)
+++ oup/current/Helper_LevelDB.pas	(revision 46)
@@ -31,6 +31,6 @@
 {$R *.dfm}
 
-uses ABSMain, ABSDecUtil, Main, Code_Functions, Data,
-  Code_OniImgClass, Code_DataStructures, Code_OniDataClass;
+uses ABSMain, ABSDecUtil, Main, Functions, Data,
+  OniImgClass, DataStructures, OniDataClass;
 
 type
@@ -161,5 +161,5 @@
       temps[j + 1] := ExtensionsHeader[i].Extension[3 - j];
     ExtensionsHeader[i].ExtCount :=
-      Length(OniDataConnection.GetFilesList(temps, '', False));
+      Length(OniDataConnection.GetFilesList(temps, '', False, stIDAsc));
     progress.Position    := i + 1;
     lbl_progress.Caption := 'Extensions done: ' + IntToStr(i + 1) + '/' +
Index: oup/current/Helper_ValueEdit.pas
===================================================================
--- oup/current/Helper_ValueEdit.pas	(revision 45)
+++ oup/current/Helper_ValueEdit.pas	(revision 46)
@@ -35,5 +35,5 @@
 implementation
 
-uses Tool_BinEdit, Tool_RawEdit, Code_DataStructures, Main;
+uses BinEdit, RawEdit, DataStructures, Main;
 
 {$R *.dfm}
Index: oup/current/Main.dfm
===================================================================
--- oup/current/Main.dfm	(revision 45)
+++ oup/current/Main.dfm	(revision 46)
@@ -62,5 +62,5 @@
         object menu_loadfile: TTBItem
           Caption = '&Open level-file ...'
-          ImageIndex = 1
+          ImageIndex = 0
           ShortCut = 16463
           OnClick = menu_loadfileClick
@@ -83,8 +83,10 @@
         object menu_createdb: TTBItem
           Caption = 'Create level-database ...'
+          ImageIndex = 1
           OnClick = menu_createdbClick
         end
         object menu_createlvl: TTBItem
           Caption = 'Create level-files ...'
+          ImageIndex = 2
           OnClick = menu_createlvlClick
         end
@@ -95,4 +97,5 @@
         object menu_preview: TTBItem
           Caption = '&Preview Window ...'
+          ImageIndex = 3
           ShortCut = 16464
           OnClick = menu_previewClick
@@ -100,4 +103,5 @@
         object menu_binedit: TTBItem
           Caption = '&Binary .dat editor ...'
+          ImageIndex = 4
           ShortCut = 16450
           OnClick = menu_bineditClick
@@ -105,4 +109,5 @@
         object menu_rawedit: TTBItem
           Caption = 'Binary .&raw editor ...'
+          ImageIndex = 5
           ShortCut = 16466
           OnClick = menu_raweditClick
@@ -110,4 +115,5 @@
         object menu_txmpreplace: TTBItem
           Caption = '&TXMP replacer ...'
+          ImageIndex = 6
           ShortCut = 16468
           OnClick = menu_txmpreplaceClick
@@ -115,4 +121,5 @@
         object menu_extractor: TTBItem
           Caption = 'File &extractor ...'
+          ImageIndex = 7
           ShortCut = 16453
           OnClick = menu_extractorClick
@@ -121,4 +128,5 @@
           Caption = '&File compare ...'
           Enabled = False
+          ImageIndex = 9
           ShortCut = 16454
           OnClick = menu_filecompareClick
@@ -136,6 +144,10 @@
           OnClick = menu_windows_cascadeClick
         end
+        object menu_windows_tilevert: TTBItem
+          Caption = 'Tile vertical'
+          OnClick = menu_windows_tilevertClick
+        end
         object menu_windows_tile: TTBItem
-          Caption = 'Tile'
+          Caption = 'Tile horizontal'
           OnClick = menu_windows_tileClick
         end
@@ -191,5 +203,5 @@
         Caption = 'Open file'
         DisplayMode = nbdmImageAndText
-        ImageIndex = 1
+        ImageIndex = 0
         OnClick = menu_loadfileClick
       end
@@ -198,34 +210,47 @@
       object tb_preview: TTBItem
         Caption = 'Preview'
+        DisplayMode = nbdmImageAndText
         Enabled = False
+        ImageIndex = 3
         OnClick = menu_previewClick
       end
       object tb_datedit: TTBItem
         Caption = 'DatEditor'
+        DisplayMode = nbdmImageAndText
         Enabled = False
+        ImageIndex = 4
         OnClick = menu_bineditClick
       end
       object tb_rawedit: TTBItem
         Caption = 'RawEditor'
+        DisplayMode = nbdmImageAndText
         Enabled = False
+        ImageIndex = 5
         OnClick = menu_raweditClick
       end
       object tb_txmpreplacer: TTBItem
         Caption = 'TXMP Replacer'
+        DisplayMode = nbdmImageAndText
         Enabled = False
+        ImageIndex = 6
         OnClick = menu_txmpreplaceClick
       end
       object tb_extractor: TTBItem
         Caption = 'File extractor'
+        DisplayMode = nbdmImageAndText
         Enabled = False
+        ImageIndex = 7
         OnClick = menu_extractorClick
       end
       object tb_compare: TTBItem
         Caption = 'File compare'
+        DisplayMode = nbdmImageAndText
         Enabled = False
+        ImageIndex = 9
         OnClick = menu_filecompareClick
       end
       object tb_structure: TTBItem
         Caption = 'Level structure'
+        DisplayMode = nbdmImageAndText
         Enabled = False
       end
@@ -303,141 +328,537 @@
     Top = 112
     Bitmap = {
-      494C010102000400040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
-      0000000000003600000028000000400000001000000001002000000000000010
+      494C01010A000E00040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
+      0000000000003600000028000000400000004000000001002000000000000040
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      000000000000000000000000000000000000FFFFFF0000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      000000000000000000000000000000000000000000000000FF000000FF000000
+      FF000000FF000000000000000000FFFFFF000000000000000000000000000000
+      0000000000000000FF000000FF00000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      000000000000000000000000000000000000000000000000FF000000FF000000
+      FF000000FF0000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+      FF00000000000000FF000000FF00000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      000000000000000000000000000000000000000000000000FF000000FF000000
+      FF000000FF000000000000000000FFFFFF000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      000000000000000000000000000000000000000000000000FF000000FF000000
+      FF000000FF00000000000000000000000000FFFFFF0000000000000000000000
+      0000FF000000FF00000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000FFFFFF000000
+      0000FF000000FF00000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      00000000000000000000000000000000000000000000FF000000FF000000FF00
+      0000FF00000000000000000000000000000000000000FFFFFF00000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      00000000000000000000000000000000000000000000FF000000FF000000FF00
+      0000FF000000000000000000000000000000FFFFFF00FFFFFF00FFFFFF00FFFF
+      FF00FFFFFF00FFFFFF0000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      00000000000000000000000000000000000000000000FF000000FF000000FF00
+      0000FF00000000000000000000000000000000000000FFFFFF00000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      00000000000000000000000000000000000000000000FF000000FF000000FF00
+      0000FF0000000000000000000000000000000000000000000000FFFFFF000000
+      00000000FF000000FF0000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      000000000000000000000000000000000000FFFFFF0000000000000000000000
+      00000000FF000000FF0000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000FFFF0000FFFF0000FF
+      FF0000FFFF000000000000000000FFFFFF000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000FFFF0000FFFF0000FF
+      FF0000FFFF0000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+      FF00000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000FFFF0000FFFF0000FF
+      FF0000FFFF000000000000000000FFFFFF000000000000000000000000000000
+      000000000000FF000000FF000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000FFFF0000FFFF0000FF
+      FF0000FFFF00000000000000000000000000FFFFFF000000000000FFFF0000FF
+      FF0000000000FF000000FF000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      000000000000000000000000000000000000000000000000000000FFFF0000FF
+      FF00000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      000000FFFF0000FFFF0000FFFF0000FFFF000000000000000000000000000000
+      000000FFFF0000FFFF0000FFFF0000FFFF000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      000000000000FFFFFF0000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      00000000000000000000000000000000000000FFFF0000000000000000000000
+      00000000000000C1C100009A9A00008585000085850000000000000000000000
+      00000000000000FFFF0000FFFF0000FFFF00000000000000FF000000FF000000
+      FF000000FF000000000000000000000000000000000000000000000000000000
+      00000000000000000000FFFFFF0000000000FF00000000000000FF0000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      000000000000FF00000000000000FF0000000000FF00000000000000FF000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000FF00000000000000FF0000FFFF0000FFFF00000000000000
+      0000000B0B000032320000707000007C7C00007C7C000070700000323200000B
+      0B00000000000000000000FFFF0000FFFF00000000000000FF000000FF000000
+      FF000000FF0000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+      FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FF00000000000000FF000000FF00
+      0000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF00
+      0000FF000000FF00000000000000FF0000000000FF00000000000000FF000000
+      FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000
+      FF000000FF000000FF00000000000000FF0000FFFF0000FFFF0000D9D9000016
+      16000060600000B1B10000E0E00000F9F90000F9F90000E0E00000B1B1000060
+      600000161600000000000000000000FFFF00000000000000FF000000FF000000
+      FF000000FF000000000000000000000000000000000000000000000000000000
+      00000000000000000000FFFFFF0000000000FF00000000000000FF000000FF00
+      0000000000000000000000000000000000000000000000000000000000000000
+      000000000000FF00000000000000FF0000000000FF00000000000000FF000000
+      FF00000000000000000000000000000000000000000000000000000000000000
+      0000000000000000FF00000000000000FF0000FFFF0000EDED00008C8C000070
+      700000D5D50000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000D5
+      D50000606000000B0B000000000000000000000000000000FF000000FF000000
+      FF000000FF000000000000000000000000000000000000000000000000000000
+      000000000000FFFFFF000000000000000000FF00000000000000FF000000FF00
+      0000000000000000000000000000000000000000000000000000000000000000
+      000000000000FF00000000000000FF0000000000FF00000000000000FF000000
+      FF00000000000000000000000000000000000000000000000000000000000000
+      0000000000000000FF00000000000000FF000000000000C2C2000067670000B1
+      B10000FFFF0000C9C90000414100002C2C00002C2C00002C2C0000EAEA0000FF
+      FF0000B1B1000032320000000000000000000000000000000000000000000000
+      000000000000000000000000000000000000000000000000000000000000FFFF
+      FF0000000000000000000000000000000000FF00000000000000FF000000FF00
+      0000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF00
+      0000FF000000FF00000000000000FF0000000000FF00000000000000FF000000
+      FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000
+      FF000000FF000000FF00000000000000FF0000000000000000000070700000E0
+      E00000C0C000002D2D00002B2B000062620000373700002121000039390000C9
+      C90000E0E00000707000000000000000000000000000FF000000FF000000FF00
+      0000FF0000000000000000000000000000000000000000000000000000000000
+      0000FFFFFF00000000000000000000000000FF00000000000000FF000000FF00
+      0000FF0000000000000000000000000000000000000000000000000000000000
+      000000000000FF00000000000000FF0000000000FF00000000000000FF000000
+      FF000000FF000000000000000000000000000000000000000000000000000000
+      0000000000000000FF00000000000000FF0000000000000000000079790000F8
+      F80000929200003C3C0000C9C90000FFFF0000FFFF0000FFFF0000464600006A
+      6A0000F8F800007C7C00008585000000000000000000FF000000FF000000FF00
+      0000FF00000000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+      FF00FFFFFF00FFFFFF000000000000000000FF00000000000000FF000000FF00
+      0000FF0000000000000000000000000000000000000000000000000000000000
+      000000000000FF00000000000000FF0000000000FF00000000000000FF000000
+      FF000000FF000000000000000000000000000000000000000000000000000000
+      0000000000000000FF00000000000000FF0000000000000000000079790000F8
+      F80000F4F40000F4F40000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FF
+      FF0000F8F800007C7C000085850000FFFF0000000000FF000000FF000000FF00
+      0000FF0000000000000000000000000000000000000000000000000000000000
+      0000FFFFFF00000000000000000000000000FF00000000000000FF000000FF00
+      0000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF00
+      0000FF000000FF00000000000000FF0000000000FF00000000000000FF000000
+      FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000
+      FF000000FF000000FF00000000000000FF0000FFFF00000000000060600000E0
+      E00000FFFF0000424200002A2A0000FFFF0000FFFF00003B3B000052520000FF
+      FF0000E0E00000707000009A9A0000FFFF0000000000FF000000FF000000FF00
+      0000FF000000000000000000000000000000000000000000000000000000FFFF
+      FF0000000000000000000000000000000000FF00000000000000FF000000FF00
+      0000FF000000FF00000000000000000000000000000000000000000000000000
+      000000000000FF00000000000000FF0000000000FF00000000000000FF000000
+      FF000000FF000000FF0000000000000000000000000000000000000000000000
+      0000000000000000FF00000000000000FF0000FFFF0000C2C2000032320000B1
+      B10000C9C900005858000045450000FFFF0000FFFF0000434300005E5E0000FF
+      FF0000B1B1000032320000C2C20000FFFF000000000000000000000000000000
+      00000000000000000000000000000000000000000000FFFFFF00000000000000
+      0000000000000000FF000000FF0000000000FF00000000000000FF000000FF00
+      0000FF000000FF00000000000000000000000000000000000000000000000000
+      000000000000FF00000000000000FF0000000000FF00000000000000FF000000
+      FF000000FF000000FF0000000000000000000000000000000000000000000000
+      0000000000000000FF00000000000000FF0000FFFF0000EDED00008C8C000060
+      600000D5D50000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000D5
+      D50000606000000B0B000000000000FFFF000000000000FFFF0000FFFF0000FF
+      FF0000FFFF000000000000000000000000000000000000000000FFFFFF000000
+      0000000000000000FF000000FF0000000000FF00000000000000FF000000FF00
+      0000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF00
+      0000FF000000FF00000000000000FF0000000000FF00000000000000FF000000
+      FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000
+      FF000000FF000000FF00000000000000FF0000FFFF0000FFFF0000D9D900007F
+      7F000060600000B1B10000E0E00000F8F80000F8F80000E0E00000B1B1000070
+      7000001616000000000000000000000000000000000000FFFF0000FFFF0000FF
+      FF0000FFFF0000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+      FF0000000000000000000000000000000000FF00000000000000FF000000FF00
+      0000FF000000FF000000FF000000000000000000000000000000000000000000
+      000000000000FF00000000000000FF0000000000FF00000000000000FF000000
+      FF000000FF000000FF000000FF00000000000000000000000000000000000000
+      0000000000000000FF00000000000000FF000000000000FFFF0000FFFF0000D9
+      D900008C8C00003232000060600000797900007979000070700000676700008C
+      8C0000D9D9000000000000000000000000000000000000FFFF0000FFFF0000FF
+      FF0000FFFF000000000000000000000000000000000000000000FFFFFF000000
+      000000000000FF000000FF000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      000000000000000000000000000000000000000000000000000000FFFF0000FF
+      FF0000EDED0000C2C2000000000000000000000000000000000000C2C20000ED
+      ED0000FFFF0000FFFF0000000000000000000000000000FFFF0000FFFF0000FF
+      FF0000FFFF0000000000000000000000000000000000FFFFFF00000000000000
+      000000000000FF000000FF000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      00000000000000000000000000000000000000000000000000000000000000FF
+      FF0000FFFF0000FFFF0000FFFF000000000000000000000000000000000000FF
+      FF0000FFFF0000FFFF0000FFFF00000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
       00000000000000000000000000000000000000000000EEB40000EEB40000EEB4
       0000EEB40000EEB40000EEB40000EEB40000EEB40000EEB40000EEB40000EEB4
-      0000EEB40000EEB40000EEB400000000000000000000EEB40000EEB40000EEB4
-      0000EEB40000EEB40000EEB40000EEB40000EEB40000EEB40000EEB40000EEB4
       0000EEB40000EEB40000EEB40000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      00000000000000000000000000000000000000000000A4A4A400A4A4A400A4A4
-      A400A4A4A40000000000EEB40000EEB40000EEB40000EEB4000000000000A4A4
-      A400A4A4A400A4A4A400A4A4A400EEB4000000000000A4A4A400A4A4A400A4A4
+      0000000000000000000000000000FF0000000000FF0000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000FF0000000000FF0000000000000000000000
+      0000000000000000000000000000000000000000000008080800080808000808
+      0800080808001018180010101000080808001010100008080800080810001010
+      10001010100008080800080808000000000000000000A4A4A400A4A4A400A4A4
       A400A4A4A40000000000EEB40000EEB40000EEB40000EEB4000000000000A4A4
       A400A4A4A400A4A4A400A4A4A400EEB400000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      000000000000000000000000000000000000000000004A4A4A004A4A4A004A4A
-      4A00A4A4A40014007F00944131009441310094413100EEB400000E0E0E004A4A
-      4A004A4A4A004A4A4A00A4A4A400EEB40000000000004A4A4A004A4A4A004A4A
+      000000000000FF000000FF000000FF0000000000FF000000FF000000FF000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      000000000000FF000000FF000000FF0000000000FF000000FF000000FF000000
+      0000000000000000000000000000000000000000000000000000202018002920
+      18005252520039313100393131009C9C9C0039313100393131009C9C9C000000
+      000029202000292018000000000000000000000000004A4A4A004A4A4A004A4A
       4A00A4A4A40018800000944131009441310094413100EEB400000E0E0E004A4A
-      4A004A4A4A004A4A4A00A4A4A400EEB400000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      000000000000000000000000000000000000000000004A4A4A004A4A4A004A4A
-      4A00A4A4A40018009400944131009441310094413100EEB40000180094004A4A
-      4A004A4A4A004A4A4A00A4A4A400EEB40000000000004A4A4A004A4A4A004A4A
+      4A004A4A4A004A4A4A00A4A4A400EEB40000000000000000000000000000FF00
+      0000FF000000FF000000FF000000FF0000000000FF000000FF000000FF000000
+      FF000000FF00000000000000000000000000000000000000000000000000FF00
+      0000FF000000FF000000FF000000FF0000000000FF000000FF000000FF000000
+      FF000000FF000000000000000000000000000000000000000000292018002920
+      20005252520039313100DEDEDE00A4A4A40039313100DEDEDE00A4A4A4000000
+      000029202000292020000000000000000000000000004A4A4A004A4A4A004A4A
       4A00A4A4A40018920000944131009441310094413100EEB40000189200004A4A
-      4A004A4A4A004A4A4A00A4A4A400EEB400000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      000000000000000000000000000000000000000000004A4A4A00000000000000
+      4A004A4A4A004A4A4A00A4A4A400EEB4000000000000FF000000FF000000FF00
+      0000FF0000000000000000000000000000000000000000000000000000000000
+      FF000000FF000000FF000000FF000000000000000000FF000000FF0000000000
+      0000000000000000000000000000FF0000000000FF0000000000000000000000
+      0000000000000000FF000000FF00000000000000000000000000292018002920
+      20005252520039313100DEDEDE00A4A4A40039313100DEDEDE00A4A4A4000000
+      000029202000292020000000000000000000000000004A4A4A00000000000000
       0000A4A4A40000000000944131000000000000000000EEB40000020202004A4A
-      4A000000000000000000A4A4A400EEB40000000000004A4A4A00000000000000
-      0000A4A4A40000000000944131000000000000000000EEB40000020202004A4A
-      4A000000000000000000A4A4A400EEB400000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      00000000000000000000000000000000000000000000A4A4A4004A4A4A00A4A4
+      4A000000000000000000A4A4A400EEB40000FF000000FF000000FF000000FF00
+      0000000000000000000000000000000000000000000000000000000000000000
+      00000000FF000000FF000000FF000000FF00FF000000FF000000FF000000FF00
+      0000000000000000000000000000FF0000000000FF0000000000000000000000
+      00000000FF000000FF000000FF000000FF000000000000000000292029003129
+      2900525252003931310039313100A4A4A4003931310039313100A4A4A4000000
+      00003129290031292900000000000000000000000000A4A4A4004A4A4A00A4A4
       A400A4A4A40000000000EEB4000094413100EEB40000EEB4000000000000A4A4
-      A4004A4A4A00A4A4A400A4A4A400EEB4000000000000A4A4A4004A4A4A00A4A4
-      A400A4A4A40000000000EEB4000094413100EEB40000EEB4000000000000A4A4
-      A4004A4A4A00A4A4A400A4A4A400EEB400000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      000000000000000000000000000000000000000000000000000014007F000000
-      0000000000000000000000000000180094000000000014007F00000000000000
-      000014007F0014007F0000000000EEB40000000000000000000014007F000000
+      A4004A4A4A00A4A4A400A4A4A400EEB40000FF000000FF000000FF0000000000
+      00000000000000000000FF000000FF0000000000FF000000FF00000000000000
+      0000000000000000FF000000FF000000FF00FF000000FF000000FF0000000000
+      0000000000000000000000000000FF0000000000FF0000000000000000000000
+      0000000000000000FF000000FF000000FF000000000000000000525252005252
+      5200525252005252520052525200525252005252520052525200525252005252
+      520052525200525252000000000000000000000000000000000014007F000000
       0000000000000000000000000000180094000000000000000000000000000000
-      000014007F001880000000000000EEB400000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000014007F0014007F000000
-      00000000000000000000180094000000000014007F0014007F00000000000000
-      0000000000001800940000000000EEB400000000000018800000188000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000001892000000000000EEB400000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000014007F0014007F000000
-      00000000000000000000000000001800940014007F0000000000000000000000
-      0000000000001800940000000000EEB400000000000018800000188000000000
+      000014007F001880000000000000EEB40000FF000000FF000000FF0000000000
+      000000000000FF000000FF000000FF0000000000FF000000FF000000FF000000
+      0000000000000000FF000000FF000000FF00FF000000FF000000000000000000
+      000000000000FF00000000000000FF0000000000FF00000000000000FF000000
+      000000000000000000000000FF000000FF000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000018800000188000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000001892000000000000EEB40000FF000000FF000000FF0000000000
+      000000000000FF000000FF000000FF0000000000FF000000FF000000FF000000
+      FF000000FF000000FF000000FF000000FF00FF000000FF000000000000000000
+      0000FF000000FF000000FF000000FF0000000000FF000000FF000000FF000000
+      FF0000000000000000000000FF000000FF0000000000000000000000FF000000
+      FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000
+      FF000000FF000000FF0000000000000000000000000018800000188000000000
       0000000000000000000018920000189200000000000000000000000000000000
-      0000000000001892000000000000EEB400000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000014007F0014007F000000
-      0000000000000000000014007F0014007F001800940000000000000000000000
-      0000000000001800940000000000EEB400000000000018800000188000000000
+      0000000000001892000000000000EEB40000FF000000FF000000FF0000000000
+      000000000000FF00000000FFFF0000FFFF0000FFFF0000FFFF000000FF000000
+      FF000000FF000000FF000000FF000000FF00FF000000FF000000000000000000
+      0000FF000000FF00000000FFFF0000FFFF0000FFFF0000FFFF000000FF000000
+      FF0000000000000000000000FF000000FF0000000000000000000000FF000000
+      FF000000FF000000000000000000000000000000000000000000000000000000
+      FF000000FF000000FF0000000000000000000000000018800000188000000000
       0000000000000000000000000000000000001892000000000000000000000000
-      0000000000001892000000000000EEB400000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000014007F00180094000000
-      00000000000014007F0014007F00180094000000000018009400000000000000
-      000014007F001800940000000000EEB400000000000018800000189200000000
+      0000000000001892000000000000EEB40000FF000000FF000000FF0000000000
+      0000000000000000000000FFFF000000000000FFFF0000FFFF0000FFFF0000FF
+      FF000000FF000000FF000000FF000000FF00FF000000FF000000000000000000
+      000000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FF
+      FF0000000000000000000000FF000000FF0000000000000000000000FF000000
+      FF000000000000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00000000000000
+      00000000FF000000FF0000000000000000000000000018800000189200000000
       0000000000000000000000000000180094000000000018920000000000000000
-      0000188000001892000000000000EEB400000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      000000000000000000000000000000000000000000000E0E0E00180094000202
+      0000188000001892000000000000EEB40000FF000000FF00000000FFFF0000FF
+      FF000000000000000000000000000000000000FFFF0000FFFF0000FFFF0000FF
+      FF0000FFFF0000FFFF000000FF000000FF00FF000000FF000000000000000000
+      00000000000000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF000000
+      000000000000000000000000FF000000FF0000000000000000000000FF000000
+      000000000000FFFFFF00FFFFFF000000000000000000FFFFFF00FFFFFF000000
+      0000000000000000FF000000000000000000000000000E0E0E00189200000202
       0200000000000000000000000000A4A4A4000000000000000000000000000000
-      000014007F0014007F0000000000EEB40000000000000E0E0E00189200000202
-      0200000000000000000000000000A4A4A4000000000000000000000000000000
-      0000188000001880000000000000EEB400000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      00000000000000000000000000000000000000000000A4A4A400A4A4A400A4A4
+      0000188000001880000000000000EEB4000000FFFF0000FFFF0000FFFF0000FF
+      FF0000FFFF0000000000000000000000000000FFFF0000FFFF0000FFFF0000FF
+      FF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF000000
+      0000000000000000000000FFFF0000FFFF0000FFFF0000FFFF00000000000000
+      00000000000000FFFF0000FFFF0000FFFF0000000000000000000000FF000000
+      0000FFFFFF00FFFFFF00000000006A00BD006A00BD0000000000FFFFFF00FFFF
+      FF00000000000000FF00000000000000000000000000A4A4A400A4A4A400A4A4
       A400A4A4A400A4A4A400A4A4A40094413100A4A4A400A4A4A400A4A4A400A4A4
-      A400A4A4A400A4A4A400EEB40000EEB4000000000000A4A4A400A4A4A400A4A4
-      A400A4A4A400A4A4A400A4A4A40094413100A4A4A400A4A4A400A4A4A400A4A4
-      A400A4A4A400A4A4A400EEB40000EEB400000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      00000000000000000000000000000000000000000000EEB40000EEB40000EEB4
+      A400A4A4A400A4A4A400EEB40000EEB400000000000000FFFF0000FFFF0000FF
+      FF000000000000000000000000000000000000FFFF0000FFFF0000FFFF0000FF
+      FF0000FFFF0000FFFF0000FFFF00000000000000000000FFFF0000FFFF0000FF
+      FF00000000000000000000FFFF0000FFFF0000FFFF0000FFFF00000000000000
+      000000FFFF0000FFFF0000FFFF000000000000000000000000000000FF000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000FF00000000000000000000000000EEB40000EEB40000EEB4
       0000EEB40000EEB40000EEB40000EEB40000EEB40000EEB40000EEB40000EEB4
-      0000EEB40000EEB40000EEB40000EEB4000000000000EEB40000EEB40000EEB4
-      0000EEB40000EEB40000EEB40000EEB40000EEB40000EEB40000EEB40000EEB4
-      0000EEB40000EEB40000EEB40000EEB400000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      00000000000014007F001800940018009400180094001800940014007F000000
-      0000000000000000000000000000EEB400000000000000000000000000000000
+      0000EEB40000EEB40000EEB40000EEB4000000000000000000000000000000FF
+      FF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FF
+      FF0000FFFF0000000000000000000000000000000000000000000000000000FF
+      FF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FF
+      FF0000FFFF0000000000000000000000000000000000000000000000FF000000
+      FF00000000000000000000000000000000000000000000000000000000000000
+      00000000FF000000FF0000000000000000000000000000000000000000000000
       0000000000001880000018920000189200001892000018920000188000000000
       0000000000000000000000000000EEB400000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      000000000000000000000000000000000000EEB4000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      000000000000000000000000000000000000EEB4000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
+      00000000000000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      00000000000000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF000000
+      00000000000000000000000000000000000000000000000000000000FF000000
+      FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000
+      FF000000FF000000FF000000000000000000EEB4000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      000000000000000000000000000000FFFF0000FFFF0000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      000000000000000000000000000000FFFF0000FFFF0000000000000000000000
       0000000000000000000000000000000000000000000000000000000000000000
       0000000000000000000000000000000000000000000000000000000000000000
       000000000000000000000000000000000000424D3E000000000000003E000000
-      2800000040000000100000000100010000000000800000000000000000000000
-      000000000000000000000000FFFFFF0080018001000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000000000000000000000000000000000000000000000000
-      0000000000000000000100010000000000000000000000000000000000000000
+      2800000040000000400000000100010000000000000200000000000000000000
+      000000000000000000000000FFFFFF0000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      0000000000000000000000000000000000000000000000000000000000000000
+      00000000000000000000000000000000FF7F00FF0000000086F900FF00000000
+      840900FF0000000086FF1F070000000087731F0700000000FFD31F0700000000
+      87BF1F070000000087031F070000000087BF1F070000000087D31F0700000000
+      FF731F070000000086FF1F0700000000840F1F070000000086F900FF00000000
+      874900FF00000000FFCF00FF00000000FFFFFFFF0000FFFBE005E005000087FD
+      400040000000840040004000000087FD40004000000087FB400040000000FFEF
+      40004000000087F7400040000000840340004000000087F740004000000087EF
+      400040000000FFB940004000000087D9400040000000840F40004000000087D9
+      FE05FE05000087B9FFFFFFFF0000FFFF8001FE7FFE7F80010000F81FF81F8001
+      0000E007E0078001000080018001800100000000000080010000000000000000
+      0000000000000000000000000000800100000000000080010000000000008001
+      0000000000008001000000000000800100008001800180010000E007E0078001
+      0000F81FF81F80010001FE7FFE7F800100000000000000000000000000000000
       000000000000}
   end
Index: oup/current/Main.pas
===================================================================
--- oup/current/Main.pas	(revision 45)
+++ oup/current/Main.pas	(revision 46)
@@ -8,7 +8,7 @@
   MPHexEditor, ToolWin, ImgList, Tabs,
   MDITab, TB2Item, TB2Dock, TB2Toolbar, TB2MDI,
-  Code_Functions, Data, Code_DataStructures, Code_OniDataClass,
-  Helper_LevelDB, Code_Exporters, Settings, Tool_Template,
-  Tool_BinEdit, Tool_Extractor, Tool_Preview, Tool_RawEdit, Tool_TxmpReplace;
+  Data, Functions, DataStructures, OniDataClass, Exporters,
+  Helper_LevelDB, Settings, Template,
+  BinEdit, Extractor, Preview, RawEdit, TxmpReplace;
 
 type
@@ -66,4 +66,5 @@
     tb_rawedit: TTBItem;
     tb_datedit: TTBItem;
+    menu_windows_tilevert: TTBItem;
     function TryCloseAll: Boolean;
     procedure menu_AboutClick(Sender: TObject);
@@ -77,5 +78,5 @@
     procedure menu_windows_nextClick(Sender: TObject);
     procedure menu_windows_tileClick(Sender: TObject);
-    function open_child(window_context: String; fileid: Integer): Boolean;
+    function open_child(window_context: String; fileid: Integer): TForm_ToolTemplate;
     procedure menu_windows_closeallClick(Sender: TObject);
     procedure menu_windows_cascadeClick(Sender: TObject);
@@ -97,4 +98,5 @@
     procedure MDITabMouseUp(Sender: TObject; Button: TMouseButton;
       Shift: TShiftState; X, Y: Integer);
+    procedure menu_windows_tilevertClick(Sender: TObject);
   private
   public
@@ -475,4 +477,9 @@
 end;
 
+procedure TForm_Main.menu_windows_tilevertClick(Sender: TObject);
+begin
+  Self.TileMode := tbVertical;
+  Self.Tile;
+end;
 
 
@@ -517,5 +524,5 @@
 
 
-function TForm_Main.open_child(window_context: String; fileid: Integer): Boolean;
+function TForm_Main.open_child(window_context: String; fileid: Integer): TForm_ToolTemplate;
 var
   toolform: TForm_ToolTemplate;
@@ -524,5 +531,5 @@
   iconindex: Integer;
 begin
-  Result := True;
+  Result := nil;
 
   tag := 1;
@@ -538,5 +545,5 @@
     toolform         := TForm_BinEdit.Create(Self);
     toolform.Caption := 'Binary .dat-Editor ' + IntToStr(tag);
-    iconindex        := 0;
+    iconindex        := 4;
   end;
   if window_context = 'extractor' then
@@ -544,4 +551,5 @@
     toolform         := TForm_Extractor.Create(Self);
     toolform.Caption := 'Extractor ' + IntToStr(tag);
+    iconindex        := 7;
   end;
   if window_context = 'preview' then
@@ -549,4 +557,5 @@
     toolform         := TForm_Preview.Create(Self);
     toolform.Caption := 'Preview-Window ' + IntToStr(tag);
+    iconindex        := 3;
   end;
   if window_context = 'rawedit' then
@@ -554,4 +563,5 @@
     toolform         := TForm_RawEdit.Create(Self);
     toolform.Caption := 'Binary .raw-Editor ' + IntToStr(tag);
+    iconindex        := 5;
   end;
   if window_context = 'txmpreplace' then
@@ -559,4 +569,5 @@
     toolform         := TForm_TxmpReplace.Create(Application);
     toolform.Caption := 'TXMP Replacer ' + IntToStr(tag);
+    iconindex        := 6;
   end;
 
@@ -568,4 +579,5 @@
     if fileid > -1 then
       toolform.SelectFileID(fileid);
+    Result := toolform;
   end;
 end;
Index: oup/current/OniUnPacker.bdsproj
===================================================================
--- oup/current/OniUnPacker.bdsproj	(revision 45)
+++ oup/current/OniUnPacker.bdsproj	(revision 46)
@@ -176,6 +176,6 @@
 			<Language Name="ProjectLang">$00000000</Language>
 			<Language Name="RootDir"></Language>
-		</Language>  <Excluded_Packages>
-      <Excluded_Packages Name="C:\Dokumente und Einstellungen\Administrator\Eigene Dateien\Borland Studio Projects\Bpl\TCrossEdit.bpl">(untitled)</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 45)
+++ oup/current/OniUnPacker.dpr	(revision 46)
@@ -4,23 +4,22 @@
   Forms,
   Main in 'Main.pas' {Form_Main},
-  Code_Functions in 'Code_Functions.pas',
   Data in 'Data.pas',
-  Code_Exporters in 'Code_Exporters.pas',
-  Code_OniImgClass in 'Code_OniImgClass.pas',
-  Code_DataStructures in 'Code_DataStructures.pas',
   Helper_LevelDB in 'Helper_LevelDB.pas' {Form_LevelDB},
   Helper_ValueEdit in 'Helper_ValueEdit.pas' {Form_ValueEdit},
   Settings in 'Settings.pas' {Form_Settings},
-  ftypesAPI in 'TFileTypeRegistration\ftypesAPI.pas',
-  Code_OniDataClass in 'Code_OniDataClass.pas',
-  Tool_Template in 'Tool_Template.pas' {Form_ToolTemplate},
-  Tool_Preview in 'Tool_Preview.pas' {Form_Preview},
-  Tool_BinEdit in 'Tool_BinEdit.pas' {Form_ToolTemplate2},
-  Tool_Extractor in 'Tool_Extractor.pas' {Form_ToolTemplate3},
-  Tool_RawEdit in 'Tool_RawEdit.pas' {Form_ToolTemplate4},
-  Tool_TxmpReplace in 'Tool_TxmpReplace.pas' {Form_ToolTemplate5};
+  FTypeReg in 'FTypeReg.pas',
+  Functions in 'Code\Functions.pas',
+  Exporters in 'Code\Exporters.pas',
+  OniImgClass in 'Code\OniImgClass.pas',
+  DataStructures in 'Code\DataStructures.pas',
+  OniDataClass in 'Code\OniDataClass.pas',
+  Template in 'Tools\Template.pas' {Form_ToolTemplate},
+  Preview in 'Tools\Preview.pas' {Form_Preview},
+  BinEdit in 'Tools\BinEdit.pas' {Form_ToolTemplate2},
+  Extractor in 'Tools\Extractor.pas' {Form_ToolTemplate3},
+  RawEdit in 'Tools\RawEdit.pas' {Form_ToolTemplate4},
+  TxmpReplace in 'Tools\TxmpReplace.pas' {Form_ToolTemplate5};
 
 {$R *.res}
-{$R icon2.res}
 
 begin
Index: oup/current/Settings.pas
===================================================================
--- oup/current/Settings.pas	(revision 45)
+++ oup/current/Settings.pas	(revision 46)
@@ -38,5 +38,5 @@
 
 uses
-  Main, Data, ftypesAPI;
+  Main, Data, FTypeReg;
 
 
Index: oup/current/Tool_BinEdit.dfm
===================================================================
--- oup/current/Tool_BinEdit.dfm	(revision 45)
+++ 	(revision )
@@ -1,228 +1,0 @@
-inherited Form_BinEdit: TForm_BinEdit
-  Caption = 'BinEdit'
-  OnCloseQuery = FormCloseQuery
-  OnCreate = FormCreate
-  OnKeyUp = FormKeyUp
-  PixelsPerInch = 96
-  TextHeight = 13
-  inherited panel_files: TPanel
-    inherited filelist: TListBox
-      ExplicitHeight = 256
-    end
-  end
-  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
-      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
-    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/current/Tool_BinEdit.pas
===================================================================
--- oup/current/Tool_BinEdit.pas	(revision 45)
+++ 	(revision )
@@ -1,982 +1,0 @@
-unit Tool_BinEdit;
-interface
-uses
-  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
-  Dialogs, Tool_Template, StdCtrls, ExtCtrls, VirtualTrees, Grids, Wrapgrid,
-  MPHexEditor, VTHeaderPopup, Menus, StrUtils, Clipbrd,
-  Data, Code_OniDataClass, Code_Functions, Code_DataStructures, Code_Exporters;
-
-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: LongWord);
-    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: LongWord;
-  public
-  end;
-
-var
-  Form_BinEdit: TForm_BinEdit;
-
-implementation
-
-uses Helper_ValueEdit, Main, Tool_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.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] := 100;
-//  value_viewer.ColWidths[1] := value_viewer.Width - 150;
-//  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: LongWord);
-var
-  mem:  TMemoryStream;
-  Data: Tdata;
-begin
-  if hex.Modified then
-  begin
-    if not Save then
-    begin
-      Self.SelectFileID(fileid);
-      Exit;
-    end;
-  end;
-  fileid := _fileid;
-  if OniDataConnection.ExtractFileID(
-        filelist.Items.Strings[filelist.ItemIndex]) <> fileid then
-    Self.SelectFileID(fileid);
-  Self.ClearStructViewer;
-  Data := OniDataConnection.LoadDatFile(fileid);
-  if Length(Data) > 0 then
-  begin
-    mem := TMemoryStream.Create;
-    mem.Write(Data[0], Length(Data));
-    mem.Seek(0, soFromBeginning);
-    hex.LoadFromStream(mem);
-    mem.Free;
-    WriteStructureInfos;
-  end
-  else
-  begin
-    ClearValues;
-    hex.DataSize := 0;
-  end;
-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_BinEdit.GetValue(datatype: Word; offset: LongWord): String;
-var
-  Data: Tdata;
-  i:    Word;
-begin
-  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));
-    end;
-    10:
-      Result := IntToBin(hex.Data[offset]);
-    11:
-      Result := '0x' + IntToHex(OniDataConnection.GetRawInfo(fileid, offset).raw_addr, 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(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:  Byte;
-  Data:  Tdata;
-  str:   String;
-  Value: LongWord;
-begin
-  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));
-      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;
-  Data: Tdata;
-  i:    LongWord;
-begin
-  case MessageBox(Self.Handle, PChar('Save changes to file ' +
-      OniDataConnection.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;
-      OniDataConnection.UpdateDatFile(fileid, Data);
-      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) < GetTypeDataLength(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;
-  id: Integer;
-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 OniDataConnection.GetRawInfo(fileid, nodedata.offset).raw_size > 0 then
-          Form_Main.open_child('rawedit', fileid);
-      end;
-      if nodedata.DataType = 12 then
-      begin
-        if (StrToInt(nodedata.Value) < OniDataConnection.GetFilesCount) and
-          (StrToInt(nodedata.Value) > 0) and
-          (StrToInt(nodedata.Value) <> fileid) then
-        begin
-          if OniDataConnection.GetFileInfo(StrToInt(nodedata.Value)).Size > 0 then
-            Form_Main.open_child('binedit', StrToInt(nodedata.Value))
-          else
-            ShowMessage('Linked filed is a zero-byte-file');
-        end;
-      end;
-      if (nodedata.DataType >= 100) and (nodedata.DataType <= 300) then
-      begin
-        if Form_Main.open_child('binedit', -1) then
-        begin
-          TForm_BinEdit(Form_Main.ActiveMDIChild).edit_filtername.Text := nodedata.Value;
-          TForm_BinEdit(Form_Main.ActiveMDIChild).check_filtername.Checked := True;
-          TForm_BinEdit(Form_Main.ActiveMDIChild).check_filternameClick(Self);
-        end;
-      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 + GetTypeDataLength(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: 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_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/current/Tool_Extractor.dfm
===================================================================
--- oup/current/Tool_Extractor.dfm	(revision 45)
+++ 	(revision )
@@ -1,214 +1,0 @@
-inherited Form_Extractor: TForm_Extractor
-  Caption = 'Extractor'
-  OnCreate = FormCreate
-  ExplicitWidth = 320
-  ExplicitHeight = 240
-  PixelsPerInch = 96
-  TextHeight = 13
-  inherited Splitter1: TSplitter
-    Left = 483
-    Align = alRight
-    Visible = False
-    ExplicitLeft = 172
-    ExplicitTop = -8
-    ExplicitHeight = 423
-  end
-  inherited panel_files: TPanel
-    Width = 184
-    Align = alClient
-    ExplicitWidth = 184
-    inherited filelist: TListBox
-      Width = 184
-      ExplicitWidth = 184
-    end
-    inherited panel_extension: TPanel
-      Width = 184
-      ExplicitWidth = 184
-      inherited combo_extension: TComboBox
-        Width = 176
-        ExplicitWidth = 176
-      end
-      inherited edit_filtername: TEdit
-        Width = 176
-        ExplicitWidth = 176
-      end
-    end
-  end
-  inherited content: TPanel
-    Left = 184
-    Width = 299
-    Align = alRight
-    ExplicitLeft = 184
-    ExplicitWidth = 299
-    object group_extract: TGroupBox
-      Left = 3
-      Top = 0
-      Width = 296
-      Height = 423
-      Align = alRight
-      Caption = '2. Select extract-method'
-      TabOrder = 0
-      object group_singlefiles: TGroupBox
-        AlignWithMargins = True
-        Left = 8
-        Top = 16
-        Width = 280
-        Height = 185
-        Margins.Left = 6
-        Margins.Top = 1
-        Margins.Right = 6
-        Align = alTop
-        Caption = 'Write data into single files'
-        TabOrder = 0
-        object btn_sel_dat: TButton
-          Left = 8
-          Top = 16
-          Width = 129
-          Height = 49
-          Caption = 'Selected files (dat contents only)'
-          TabOrder = 0
-          WordWrap = True
-          OnClick = Extract
-        end
-        object btn_sel_datraw: TButton
-          Left = 8
-          Top = 72
-          Width = 129
-          Height = 49
-          Caption = 'Selected files (dat+raw)'
-          TabOrder = 1
-          WordWrap = True
-          OnClick = Extract
-        end
-        object btn_sel_datraw_convert: TButton
-          Left = 8
-          Top = 128
-          Width = 129
-          Height = 49
-          Caption = 'Selected files (dat+raw) (with convert if possible)'
-          TabOrder = 2
-          WordWrap = True
-          OnClick = Extract
-        end
-        object btn_all_dat: TButton
-          Left = 144
-          Top = 16
-          Width = 129
-          Height = 49
-          Caption = 'All files in list (dat contents only)'
-          TabOrder = 3
-          WordWrap = True
-          OnClick = Extract
-        end
-        object btn_all_datraw: TButton
-          Left = 144
-          Top = 72
-          Width = 129
-          Height = 49
-          Caption = 'All files in list (dat+raw)'
-          TabOrder = 4
-          WordWrap = True
-          OnClick = Extract
-        end
-        object btn_all_datraw_convert: TButton
-          Left = 144
-          Top = 128
-          Width = 129
-          Height = 49
-          BiDiMode = bdLeftToRight
-          Caption = 'All files in list (dat+raw) (with convert if possible)'
-          ParentBiDiMode = False
-          TabOrder = 5
-          WordWrap = True
-          OnClick = Extract
-        end
-      end
-      object group_onefile: TGroupBox
-        AlignWithMargins = True
-        Left = 8
-        Top = 205
-        Width = 280
-        Height = 73
-        Margins.Left = 6
-        Margins.Top = 1
-        Margins.Right = 6
-        Align = alTop
-        Caption = 'Write data into one file'
-        TabOrder = 1
-        object btn_sel_files_toone: TButton
-          Left = 8
-          Top = 16
-          Width = 129
-          Height = 49
-          Caption = 'Selected files (dat contents only)'
-          TabOrder = 0
-          WordWrap = True
-          OnClick = Extract
-        end
-        object btn_all_files_toone: TButton
-          Left = 144
-          Top = 16
-          Width = 129
-          Height = 49
-          Caption = 'All files in list (dat contents only)'
-          TabOrder = 1
-          WordWrap = True
-          OnClick = Extract
-        end
-      end
-      object group_progress: TGroupBox
-        AlignWithMargins = True
-        Left = 8
-        Top = 282
-        Width = 280
-        Height = 132
-        Margins.Left = 6
-        Margins.Top = 1
-        Margins.Right = 6
-        Margins.Bottom = 7
-        Align = alClient
-        Caption = 'Progress ...'
-        TabOrder = 2
-        Visible = False
-        object lbl_progress: TLabel
-          Left = 8
-          Top = 40
-          Width = 265
-          Height = 17
-          AutoSize = False
-          Caption = 'Files done: 0/0'
-        end
-        object lbl_estimated: TLabel
-          Left = 8
-          Top = 56
-          Width = 265
-          Height = 17
-          AutoSize = False
-          Caption = 'Estimated finishing time: 00:00:00'
-        end
-        object progress: TProgressBar
-          Left = 8
-          Top = 16
-          Width = 265
-          Height = 17
-          Smooth = True
-          TabOrder = 0
-        end
-        object btn_abort: TButton
-          Left = 8
-          Top = 72
-          Width = 97
-          Height = 23
-          Caption = 'Abort'
-          Enabled = False
-          TabOrder = 1
-          OnClick = btn_abortClick
-        end
-      end
-    end
-  end
-  object saved: TSaveDialog [3]
-    Left = 448
-    Top = 328
-  end
-end
Index: oup/current/Tool_Extractor.pas
===================================================================
--- oup/current/Tool_Extractor.pas	(revision 45)
+++ 	(revision )
@@ -1,190 +1,0 @@
-unit Tool_Extractor;
-interface
-uses
-  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
-  Dialogs, Tool_Template, StdCtrls, ExtCtrls, ComCtrls, Menus;
-
-type
-  TForm_Extractor = class(TForm_ToolTemplate)
-    group_extract: TGroupBox;
-    group_singlefiles: TGroupBox;
-    btn_sel_dat: TButton;
-    btn_sel_datraw: TButton;
-    btn_sel_datraw_convert: TButton;
-    btn_all_dat: TButton;
-    btn_all_datraw: TButton;
-    btn_all_datraw_convert: TButton;
-    btn_sel_files_toone: TButton;
-    btn_all_files_toone: TButton;
-    group_onefile: TGroupBox;
-    group_progress: TGroupBox;
-    lbl_progress: TLabel;
-    lbl_estimated: TLabel;
-    progress: TProgressBar;
-    btn_abort: TButton;
-    saved: TSaveDialog;
-    procedure FormCreate(Sender: TObject);
-    procedure Extract(Sender: TObject);
-    procedure btn_abortClick(Sender: TObject);
-  private
-  public
-  end;
-
-var
-  Form_Extractor: TForm_Extractor;
-
-implementation
-{$R *.dfm}
-uses Main, Code_Functions, Data, Code_OniDataClass;
-
-procedure TForm_Extractor.FormCreate(Sender: TObject);
-begin
-  inherited;
-  Self.AllowMultiSelect := True;
-
-  btn_sel_dat.Caption    := 'Selected files' + CrLf + '(dat contents only)';
-  btn_sel_datraw.Caption := 'Selected files' + CrLf + '(dat+raw contents)';
-  btn_sel_datraw_convert.Caption :=
-    'Selected files' + CrLf + '(dat+raw contents)' + CrLf + '(with convert if possible)';
-  btn_all_dat.Caption    := 'All files in list' + CrLf + '(dat contents only)';
-  btn_all_datraw.Caption := 'All files in list' + CrLf + '(dat+raw contents)';
-  btn_all_datraw_convert.Caption :=
-    'All files in list' + CrLf + '(dat+raw contents)' + CrLf + '(with convert if possible)';
-  btn_sel_files_toone.Caption := 'Selected files' + CrLf + '(dat contents only)';
-  btn_all_files_toone.Caption := 'All files in list' + CrLf + '(dat contents only)';
-end;
-
-procedure TForm_Extractor.btn_abortClick(Sender: TObject);
-begin
-  ShowMessage('X');
-end;
-
-procedure TForm_Extractor.Extract(Sender: TObject);
-var
-  sel_only:  Boolean;
-  dat_only:  Boolean;
-  convert:   Boolean;
-  one_file:  Boolean;
-  settings:  TExportSet;
-  files:     LongWord;
-  i, done:   LongWord;
-  begintime: Double;
-begin
-  sel_only := Pos('sel', TButton(Sender).Name) > 0;
-  dat_only := not (Pos('datraw', TButton(Sender).Name) > 0);
-  convert  := Pos('convert', TButton(Sender).Name) > 0;
-  one_file := Pos('toone', TButton(Sender).Name) > 0;
-  if dat_only then
-    settings := [DO_dat]
-  else
-    settings := [DO_dat, DO_raw];
-  if convert then
-    settings := settings + [DO_convert];
-  if one_file then
-    settings := settings + [DO_toone];
-  progress.Position := 0;
-
-  if saved.Execute then
-  begin
-    begintime := Time;
-    group_progress.Visible := True;
-    panel_files.Enabled := False;
-    group_singlefiles.Enabled := False;
-    group_onefile.Enabled := False;
-    lbl_estimated.Caption := 'Estimated finishing time: unknown';
-    if one_file then
-    begin
-      if FileExists(saved.FileName) then
-      begin
-        if MessageBox(Self.Handle, PChar(
-          'File already exists. Do you want to overwrite it?'), PChar('Warning!'), MB_YESNO) =
-          ID_YES then
-        begin
-          DeleteFile(saved.FileName);
-        end
-        else
-        begin
-          group_progress.Visible    := False;
-          panel_files.Enabled      := True;
-          group_singlefiles.Enabled := True;
-          group_onefile.Enabled     := True;
-          Exit;
-        end;
-      end;
-      i := FileCreate(saved.FileName);
-      FileClose(i);
-      i := 0;
-    end;
-    if sel_only then
-    begin
-      files := filelist.SelCount;
-      lbl_progress.Caption := 'Files done: 0/' + IntToStr(files);
-      progress.Max := files;
-      done  := 0;
-      for i := 0 to filelist.Count - 1 do
-      begin
-        if filelist.Selected[i] then
-        begin
-          if one_file then
-          begin
-            ExportFile(OniDataConnection.ExtractFileID(
-              filelist.Items.Strings[filelist.ItemIndex]), ExtractFileName(saved.FileName),
-              settings, ExtractFileDir(saved.FileName));
-          end
-          else
-          begin
-            ExportFile(OniDataConnection.ExtractFileID(
-              filelist.Items.Strings[filelist.ItemIndex]), filelist.Items.Strings[i], settings, 'D:');
-          end;
-          Inc(done);
-        end;
-        if ((done mod 10) = 0) and (done >= 50) then
-          lbl_estimated.Caption := 'Estimated finishing time: ' + TimeToStr(
-            (Time - begintime) / done * files + begintime);
-        if (i mod 10) = 0 then
-        begin
-          progress.Position    := done;
-          lbl_progress.Caption := 'Files done: ' + IntToStr(done) + '/' + IntToStr(files);
-          Application.ProcessMessages;
-        end;
-      end;
-    end
-    else
-    begin
-      files := filelist.Count;
-      lbl_progress.Caption := 'Files done: 0/' + IntToStr(files);
-      progress.Max := files;
-      for i := 0 to filelist.Count - 1 do
-      begin
-        if one_file then
-        begin
-          ExportFile(OniDataConnection.ExtractFileID(
-            filelist.Items.Strings[filelist.ItemIndex]), ExtractFileName(saved.FileName),
-            settings, ExtractFileDir(saved.FileName));
-        end
-        else
-        begin
-          ExportFile(OniDataConnection.ExtractFileID(
-            filelist.Items.Strings[filelist.ItemIndex]), filelist.Items.Strings[i], settings, 'D:');
-        end;
-        if ((i mod 10) = 0) and (i >= 50) then
-          lbl_estimated.Caption := 'Estimated finishing time: ' + TimeToStr(
-            (Time - begintime) / i * files + begintime);
-        if (i mod 5) = 0 then
-        begin
-          progress.Position    := i;
-          lbl_progress.Caption := 'Files done: ' + IntToStr(i) + '/' + IntToStr(files);
-          Application.ProcessMessages;
-        end;
-      end;
-    end;
-    group_progress.Visible    := False;
-    panel_files.Enabled      := True;
-    group_singlefiles.Enabled := True;
-    group_onefile.Enabled     := True;
-  end;
-end;
-
-begin
-  AddToolListEntry('extractor', 'Extractor', '');
-end.
Index: oup/current/Tool_Preview.dfm
===================================================================
--- oup/current/Tool_Preview.dfm	(revision 45)
+++ 	(revision )
@@ -1,81 +1,0 @@
-inherited Form_Preview: TForm_Preview
-  Caption = 'Preview'
-  OnCreate = FormCreate
-  ExplicitWidth = 320
-  ExplicitHeight = 240
-  PixelsPerInch = 96
-  TextHeight = 13
-  inherited content: TPanel
-    object lbl_notpossible: TLabel
-      Left = 16
-      Top = 56
-      Width = 97
-      Height = 65
-      AutoSize = False
-      Caption = 'No preview possible for this filetype'
-      Font.Charset = DEFAULT_CHARSET
-      Font.Color = clWindowText
-      Font.Height = -16
-      Font.Name = 'Tahoma'
-      Font.Style = []
-      ParentFont = False
-      Visible = False
-      WordWrap = True
-    end
-    object img: TImage
-      Left = 0
-      Top = 20
-      Width = 283
-      Height = 403
-      Align = alClient
-      ExplicitWidth = 313
-      ExplicitHeight = 453
-    end
-    object panel_buttons: TPanel
-      Left = 0
-      Top = 0
-      Width = 283
-      Height = 20
-      Align = alTop
-      BevelOuter = bvNone
-      TabOrder = 0
-      Visible = False
-      OnResize = panel_buttonsResize
-      object btn_dec: TButton
-        Left = 0
-        Top = 0
-        Width = 20
-        Height = 20
-        Caption = '-'
-        Enabled = False
-        TabOrder = 0
-        OnClick = btn_decClick
-      end
-      object btn_startstop: TButton
-        Left = 21
-        Top = 0
-        Width = 80
-        Height = 20
-        Caption = 'Stop automatic'
-        TabOrder = 1
-        OnClick = btn_startstopClick
-      end
-      object btn_inc: TButton
-        Left = 102
-        Top = 0
-        Width = 20
-        Height = 20
-        Caption = '+'
-        Enabled = False
-        TabOrder = 2
-        OnClick = btn_incClick
-      end
-    end
-  end
-  object timer: TTimer [3]
-    Enabled = False
-    OnTimer = timerTimer
-    Left = 400
-    Top = 120
-  end
-end
Index: oup/current/Tool_Preview.pas
===================================================================
--- oup/current/Tool_Preview.pas	(revision 45)
+++ 	(revision )
@@ -1,209 +1,0 @@
-unit Tool_Preview;
-interface
-uses
-  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
-  Dialogs, StdCtrls, Tool_Template, ExtCtrls, Math, StrUtils,
-  Code_OniDataClass, Code_OniImgClass, Data, Menus;
-
-type
-  TForm_Preview = class(TForm_ToolTemplate)
-    lbl_notpossible: TLabel;
-    panel_buttons: TPanel;
-    btn_dec: TButton;
-    btn_startstop: TButton;
-    btn_inc: TButton;
-    img: TImage;
-    timer: TTimer;
-    procedure FormCreate(Sender: TObject);
-    procedure NewFile(fileinfo: TFileInfo);
-
-    procedure PreviewImage;
-    procedure PreviewTXAN;
-    procedure btn_incClick(Sender: TObject);
-    procedure btn_decClick(Sender: TObject);
-    procedure btn_startstopClick(Sender: TObject);
-    procedure timerTimer(Sender: TObject);
-    procedure panel_buttonsResize(Sender: TObject);
-
-    procedure DrawImage(index: Integer);
-    procedure SetBitmapCount(Count: Integer);
-    procedure LoadImage(fileid, index: Integer);
-  private
-    bitmaps:   array of TBitmap;
-    actualimg: Byte;
-    _fileid:   LongWord;
-  public
-  end;
-
-var
-  Form_Preview: TForm_Preview;
-
-implementation
-{$R *.dfm}
-
-
-procedure TForm_Preview.FormCreate(Sender: TObject);
-begin
-  inherited;
-  Self.OnNewFileSelected := NewFile;
-end;
-
-
-procedure TForm_Preview.NewFile(fileinfo: TFileInfo);
-var
-  ext: String;
-begin
-  _fileid := fileinfo.ID;
-  lbl_notpossible.Visible := False;
-  Self.img.Visible := True;
-  Self.timer.Enabled := False;
-  Self.panel_buttons.Visible := False;
-  ext     := fileinfo.Extension;
-  if (ext = 'PSpc') or (ext = 'TXMB') or (ext = 'TXMP') then
-    PreviewImage
-  else if ext = 'TXAN' then
-    PreviewTXAN
-  else
-  begin
-    Self.lbl_notpossible.Visible := True;
-    Self.img.Visible := False;
-  end;
-end;
-
-
-procedure TForm_Preview.LoadImage(fileid, index: Integer);
-var
-  Data:      Tdata;
-  memstream: TMemoryStream;
-  OniImage:  TOniImage;
-
-begin
-  OniImage := TOniImage.Create;
-  OniImage.Load(fileid);
-  Data := OniImage.GetAsBMP;
-  OniImage.Free;
-
-  memstream := TMemoryStream.Create;
-  memstream.Write(Data[0], Length(Data));
-  memstream.Seek(0, soFromBeginning);
-  bitmaps[index].LoadFromStream(memstream);
-  memstream.Free;
-end;
-
-
-procedure TForm_Preview.DrawImage(index: Integer);
-begin
-  BitBlt(img.Canvas.Handle, 0, 0, img.Width, img.Height,
-    bitmaps[index].Canvas.Handle, 0, 0, WHITENESS);
-  BitBlt(img.Canvas.Handle, 0, 0, bitmaps[index].Width, bitmaps[index].Height,
-    bitmaps[index].Canvas.Handle, 0, 0, SRCCOPY);
-  img.Invalidate;
-end;
-
-
-procedure TForm_Preview.SetBitmapCount(Count: Integer);
-var
-  i: Integer;
-begin
-  if Length(bitmaps) > Count then
-  begin
-    for i := Count to High(bitmaps) do
-      bitmaps[i].Free;
-    SetLength(bitmaps, Count);
-  end;
-  if Length(bitmaps) < Count then
-  begin
-    i := Length(bitmaps);
-    SetLength(bitmaps, Count);
-    for i := i to High(bitmaps) do
-      bitmaps[i] := TBitmap.Create;
-  end;
-end;
-
-
-procedure TForm_Preview.PreviewImage;
-begin
-  SetBitmapCount(1);
-  LoadImage(_fileid, 0);
-  DrawImage(0);
-end;
-
-
-procedure TForm_Preview.PreviewTXAN;
-var
-  loop_speed: Word;
-  linkcount: LongWord;
-  link: LongWord;
-  i:    Byte;
-begin
-  OniDataConnection.LoadDatFilePart(_fileid, $14, SizeOf(loop_speed), @loop_speed);
-  OniDataConnection.LoadDatFilePart(_fileid, $1C, SizeOf(linkcount), @linkcount);
-  SetBitmapCount(linkcount);
-  for i := 0 to linkcount - 1 do
-  begin
-    OniDataConnection.LoadDatFilePart(_fileid, $20 + i * 4, SizeOf(link), @link);
-    link := link div 256;
-    if link = 0 then
-      link := _fileid - 1;
-    LoadImage(link, i);
-  end;
-  actualimg := 254;
-  Self.timer.Interval := Floor(loop_speed * (1 / 60) * 1000);
-  Self.timer.Enabled := False;
-  Self.btn_startstopClick(Self);
-  Self.panel_buttons.Visible := True;
-end;
-
-
-procedure TForm_Preview.timerTimer(Sender: TObject);
-begin
-  btn_incClick(Self);
-end;
-
-
-procedure TForm_Preview.btn_startstopClick(Sender: TObject);
-begin
-  Self.timer.Enabled   := not Self.timer.Enabled;
-  Self.btn_dec.Enabled := not Self.timer.Enabled;
-  Self.btn_inc.Enabled := not Self.timer.Enabled;
-  if Self.timer.Enabled then
-    Self.btn_startstop.Caption := 'Stop automatic'
-  else
-    Self.btn_startstop.Caption := 'Start automatic';
-end;
-
-
-procedure TForm_Preview.btn_decClick(Sender: TObject);
-begin
-  if actualimg > 0 then
-    Dec(actualimg)
-  else
-    actualimg := High(bitmaps);
-  Self.Caption := 'Preview ' + OniDataConnection.GetFileInfo(_fileid).FileName +
-    ' (' + IntToStr(actualimg + 1) + '/' + IntToStr(Length(bitmaps)) + ')';
-  DrawImage(actualimg);
-end;
-
-
-procedure TForm_Preview.btn_incClick(Sender: TObject);
-begin
-  if actualimg < High(bitmaps) then
-    Inc(actualimg)
-  else
-    actualimg := 0;
-  Self.Caption := 'Preview ' + OniDataConnection.GetFileInfo(_fileid).FileName +
-    ' (' + IntToStr(actualimg + 1) + '/' + IntToStr(Length(bitmaps)) + ')';
-  DrawImage(actualimg);
-end;
-
-
-procedure TForm_Preview.panel_buttonsResize(Sender: TObject);
-begin
-  btn_startstop.Width := panel_buttons.Width - 45;
-  btn_inc.Left := panel_buttons.Width - 23;
-end;
-
-
-begin
-  AddToolListEntry('preview', 'Preview-Window', '');
-end.
Index: oup/current/Tool_RawEdit.dfm
===================================================================
--- oup/current/Tool_RawEdit.dfm	(revision 45)
+++ 	(revision )
@@ -1,199 +1,0 @@
-inherited Form_RawEdit: TForm_RawEdit
-  Caption = 'RawEdit'
-  OnCloseQuery = FormCloseQuery
-  OnCreate = FormCreate
-  OnKeyUp = FormKeyUp
-  ExplicitWidth = 320
-  ExplicitHeight = 240
-  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 = 102
-      ExplicitHeight = 102
-    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
-    OnResize = panel_contentResize
-    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 = 1
-      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
-      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/current/Tool_RawEdit.pas
===================================================================
--- oup/current/Tool_RawEdit.pas	(revision 45)
+++ 	(revision )
@@ -1,816 +1,0 @@
-unit Tool_RawEdit;
-interface
-uses
-  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
-  Dialogs, Tool_Template, StdCtrls, ExtCtrls, Menus, Grids, Wrapgrid,
-  MPHexEditor, Clipbrd, StrUtils,
-  Data, Code_Functions, Code_DataStructures, Code_Exporters, Code_OniDataClass;
-
-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: TRawInfo);
-    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);
-
-    procedure panel_contentResize(Sender: TObject);
-
-    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
-    fileid:     LongWord;
-    dat_offset: LongWord;
-    fileid_opened, dat_offset_opened: LongWord;
-  public
-  end;
-
-var
-  Form_RawEdit: TForm_RawEdit;
-
-implementation
-{$R *.dfm}
-uses Main, Helper_ValueEdit;
-
-procedure TForm_RawEdit.NewFile(fileinfo: TFileInfo);
-var
-  offsets: TRawList;
-  i: Integer;
-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 := OniDataConnection.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].src_offset, 8) +
-              ', ' + IntToStr(offsets[i].raw_size) + ' bytes');
-    list_offset.Enabled := True;
-  end;
-end;
-
-procedure TForm_RawEdit.LoadRaw(raw_info: TRawInfo);
-var
-  i:    LongWord;
-  Data: Tdata;
-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 OniDataConnection.ExtractFileID(filelist.Items.Strings[i]) = raw_info.src_id 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.src_offset, 8) then
-      begin
-        list_offset.ItemIndex := i;
-        Break;
-      end;
-    end;
-  end;
-  SetLength(Data, raw_info.raw_size);
-  OniDataConnection.LoadRawFile(raw_info.src_id, raw_info.src_offset, @Data[0]);
-  if Length(Data) > 0 then
-  begin
-    hex.DataSize := 0;
-    hex.DataSize := raw_info.raw_size;
-    for i := 0 to High(Data) do
-      hex.Data[i] := Data[i];
-    //WriteStructureInfos(GetStructureInfoId(GetFileInfo(fileid).Extension));
-    //      structs.Height:=structs.RowCount*20;
-    //      IF structs.Height>120 THEN structs.Height:=120;
-    hexSelectionChanged(Self);
-    fileid_opened     := raw_info.src_id;
-    dat_offset_opened := raw_info.src_offset;
-    hex.Modified      := False;
-  end
-  else
-  begin
-    ClearValues;
-    hex.DataSize := 0;
-  end;
-end;
-
-
-
-
-
-
-procedure TForm_RawEdit.list_offsetClick(Sender: TObject);
-var
-  i: LongWord;
-  raw_info: TRawInfo;
-begin
-  ClearValues;
-  dat_offset := StrToInt('$' + MidStr(
-    list_offset.Items.Strings[list_offset.ItemIndex], 3, 8));
-  LoadRaw(OniDataConnection.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;
-begin
-  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));
-    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:  Byte;
-  Data:  Tdata;
-  str:   String;
-  Value: LongWord;
-begin
-  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));
-      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     := 0;
-  value_viewer.ColCount := 2;
-  value_viewer.RowCount := 8;
-  value_viewer.FixedRows := 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] := 100;
-  //
-  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 ' +
-      OniDataConnection.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;
-      OniDataConnection.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.panel_contentResize(Sender: TObject);
-begin
-  value_viewer.ColWidths[1] := value_viewer.Width - value_viewer.ColWidths[0] - 28;
-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 (*.' + OniDataConnection.GetFileInfo(
-    fileid).Extension + ')|*.' + OniDataConnection.GetFileInfo(fileid).Extension +
-    '|All files|*.*';
-  saved.DefaultExt := OniDataConnection.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 (*.' + OniDataConnection.GetFileInfo(
-    fileid).Extension + ')|*.' + OniDataConnection.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.
Index: oup/current/Tool_Template.dfm
===================================================================
--- oup/current/Tool_Template.dfm	(revision 45)
+++ 	(revision )
@@ -1,153 +1,0 @@
-object Form_ToolTemplate: TForm_ToolTemplate
-  Left = 0
-  Top = 0
-  Caption = 'Template'
-  ClientHeight = 423
-  ClientWidth = 492
-  Color = clBtnFace
-  Constraints.MinHeight = 450
-  Constraints.MinWidth = 500
-  Font.Charset = DEFAULT_CHARSET
-  Font.Color = clWindowText
-  Font.Height = -11
-  Font.Name = 'Tahoma'
-  Font.Style = []
-  FormStyle = fsMDIChild
-  OldCreateOrder = False
-  Visible = True
-  WindowState = wsMaximized
-  PixelsPerInch = 96
-  TextHeight = 13
-  object Splitter1: TSplitter
-    Left = 200
-    Top = 0
-    Width = 9
-    Height = 423
-    AutoSnap = False
-    Beveled = True
-    MinSize = 150
-    ExplicitHeight = 473
-  end
-  object panel_files: TPanel
-    Left = 0
-    Top = 0
-    Width = 200
-    Height = 423
-    Align = alLeft
-    BevelOuter = bvNone
-    TabOrder = 0
-    object filelist: TListBox
-      Left = 0
-      Top = 103
-      Width = 200
-      Height = 320
-      Align = alClient
-      ItemHeight = 13
-      PopupMenu = filepopup
-      TabOrder = 0
-      OnMouseDown = listMouseDown
-    end
-    object panel_extension: TPanel
-      Left = 0
-      Top = 0
-      Width = 200
-      Height = 103
-      Align = alTop
-      BevelOuter = bvNone
-      TabOrder = 1
-      DesignSize = (
-        200
-        103)
-      object label_ext: TLabel
-        Left = 2
-        Top = 62
-        Width = 100
-        Height = 17
-        AutoSize = False
-        Caption = 'Filter by &extension:'
-        FocusControl = combo_extension
-      end
-      object combo_extension: TComboBox
-        Left = 2
-        Top = 76
-        Width = 192
-        Height = 21
-        Style = csDropDownList
-        Anchors = [akLeft, akTop, akRight]
-        DropDownCount = 12
-        Font.Charset = DEFAULT_CHARSET
-        Font.Color = clWindowText
-        Font.Height = -11
-        Font.Name = 'Tahoma'
-        Font.Style = []
-        ItemHeight = 13
-        ParentFont = False
-        Sorted = True
-        TabOrder = 3
-        OnClick = combo_extensionClick
-      end
-      object check_zerobyte: TCheckBox
-        Left = 2
-        Top = 44
-        Width = 130
-        Height = 13
-        Caption = 'Show &zero-byte files'
-        TabOrder = 2
-        OnClick = check_zerobyteClick
-      end
-      object edit_filtername: TEdit
-        Left = 2
-        Top = 20
-        Width = 192
-        Height = 18
-        Anchors = [akLeft, akTop, akRight]
-        AutoSize = False
-        TabOrder = 1
-      end
-      object check_filtername: TCheckBox
-        Left = 2
-        Top = 5
-        Width = 130
-        Height = 15
-        Caption = 'Filter by file&name:'
-        TabOrder = 0
-        OnClick = check_filternameClick
-      end
-    end
-  end
-  object content: TPanel
-    Left = 209
-    Top = 0
-    Width = 283
-    Height = 423
-    Align = alClient
-    BevelOuter = bvNone
-    TabOrder = 1
-  end
-  object filepopup: TPopupMenu
-    OnPopup = filepopupPopup
-    Left = 72
-    Top = 216
-    object popup_separator: TMenuItem
-      Caption = '-'
-    end
-    object popup_import: TMenuItem
-      Caption = 'Import binary .dat-file'
-      OnClick = popup_importClick
-    end
-    object popup_export: TMenuItem
-      Caption = 'Export binary .dat-file'
-      OnClick = popup_exportClick
-    end
-  end
-  object importd: TOpenDialog
-    Options = [ofExtensionDifferent, ofPathMustExist, ofFileMustExist, ofEnableSizing]
-    Left = 136
-    Top = 232
-  end
-  object exportd: TSaveDialog
-    Options = [ofHideReadOnly, ofExtensionDifferent, ofPathMustExist, ofEnableSizing]
-    Left = 144
-    Top = 256
-  end
-end
Index: oup/current/Tool_Template.pas
===================================================================
--- oup/current/Tool_Template.pas	(revision 45)
+++ 	(revision )
@@ -1,368 +1,0 @@
-unit Tool_Template;
-
-interface
-
-uses
-  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
-  Dialogs, ExtCtrls, StdCtrls, StrUtils,
-  Code_OniDataClass, Code_Functions, Data, Menus;
-
-type
-  TNewFileSelectedEvent = procedure(fileinfo: TFileInfo) of object;
-
-  TForm_ToolTemplate = class(TForm)
-    panel_files: TPanel;
-    filelist: TListBox;
-    panel_extension: TPanel;
-    label_ext: TLabel;
-    combo_extension: TComboBox;
-    check_zerobyte: TCheckBox;
-    edit_filtername: TEdit;
-    check_filtername: TCheckBox;
-    Splitter1: TSplitter;
-    content: TPanel;
-    filepopup: TPopupMenu;
-    popup_import: TMenuItem;
-    popup_export: TMenuItem;
-    popup_separator: TMenuItem;
-    importd: TOpenDialog;
-    exportd: TSaveDialog;
-    procedure RecreateList;
-    procedure LoadFileNames;
-    procedure SelectFileName(filename: String);
-    procedure SelectFileID(id: Integer);
-    procedure check_filternameClick(Sender: TObject);
-    procedure check_zerobyteClick(Sender: TObject);
-    procedure combo_extensionClick(Sender: TObject);
-    procedure listClick(Sender: TObject);
-    procedure listMouseDown(Sender: TObject; Button: TMouseButton;
-      Shift: TShiftState; X, Y: Integer);
-
-    procedure FormResize(Sender: TObject);
-    procedure FormCreate(Sender: TObject);
-    procedure FormClose(Sender: TObject; var Action: TCloseAction);
-    procedure popup_importClick(Sender: TObject);
-    procedure popup_exportClick(Sender: TObject);
-    procedure popup_opentool(Sender: TObject);
-    procedure filepopupPopup(Sender: TObject);
-  private
-    FOnNewFileSelected: TNewFileSelectedEvent;
-    FAllowedExts: String;
-    FAllowMultiSelect: Boolean;
-    procedure SetAllowedExts(exts: String);
-    procedure SetMultiSelect(allow: Boolean);
-  public
-    constructor Create(AOwner: TComponent); override;
-  published
-    property OnNewFileSelected: TNewFileSelectedEvent read FOnNewFileSelected write FOnNewFileSelected;
-    property AllowedExts: String read FAllowedExts write SetAllowedExts;
-    property AllowMultiSelect: Boolean read FAllowMultiSelect write SetMultiSelect;
-  end;
-
-var
-  ToolList: TToolList;
-procedure AddToolListEntry(context, name, exts: String);
-
-implementation
-{$R *.dfm}
-uses Main, Code_Exporters;
-
-
-procedure TForm_ToolTemplate.RecreateList;
-var
-  i:    LongWord;
-  exts: TStringArray;
-begin
-  combo_extension.Items.Clear;
-  combo_extension.Items.Add('_All files_ (' +
-    IntToStr(OniDataConnection.GetFilesCount) + ')');
-  exts := OniDataConnection.GetExtensionsList;
-  for i := 0 to High(exts) do
-    if Length(FAllowedExts) > 0 then
-    begin
-      if Pos(MidStr(exts[i],1,4), FAllowedExts) > 0 then
-      begin
-        combo_extension.Items.Add(exts[i]);
-      end;
-    end else
-      combo_extension.Items.Add(exts[i]);
-  combo_extension.ItemIndex := 0;
-  combo_extensionClick(Self);
-end;
-
-
-
-
-procedure TForm_ToolTemplate.LoadFileNames;
-var
-  Extension: String;
-  no_zero_bytes: Boolean;
-  pattern: String;
-  files: TStringArray;
-  i: LongWord;
-begin
-  Extension := MidStr(combo_extension.Items.Strings[combo_extension.ItemIndex], 1, 4);
-  no_zero_bytes := not check_zerobyte.Checked;
-  pattern := '';
-  if check_filtername.Checked then
-    pattern := edit_filtername.Text;
-  if Extension = '_All' then
-    if Length(FAllowedExts) > 0 then
-      Extension := FAllowedExts
-    else
-      Extension := '';
-
-  files := OniDataConnection.GetFilesList(extension, pattern, no_zero_bytes);
-
-  filelist.Visible := False;
-  filelist.Items.Clear;
-  if Length(files) > 0 then
-    for i := 0 to High(files) do
-      filelist.Items.Add(files[i]);
-  filelist.Visible := True;
-end;
-
-
-procedure TForm_ToolTemplate.popup_exportClick(Sender: TObject);
-var
-  id: Integer;
-  ext: String;
-begin
-  id := OniDataConnection.ExtractFileID(filelist.Items.Strings[filelist.ItemIndex]);
-  ext := RightStr(filelist.Items.Strings[filelist.ItemIndex], 4);
-  exportd.Filter := 'Files of matching extension (*.' + ext + ')|*.' + ext + '|All files|*.*';
-  exportd.DefaultExt := ext;
-  if exportd.Execute then
-    ExportDatFile(id, exportd.FileName);
-end;
-
-procedure TForm_ToolTemplate.popup_importClick(Sender: TObject);
-var
-  id: Integer;
-  finfo: TFileInfo;
-  fs: TFileStream;
-  data: TData;
-begin
-  id := OniDataConnection.ExtractFileID(filelist.Items.Strings[filelist.ItemIndex]);
-  finfo := OniDataConnection.GetFileInfo(id);
-
-  importd.Filter := 'Files of matching extension (*.' + finfo.Extension + ')|*.' +
-        finfo.Extension + '|All files|*.*';
-  if importd.Execute then
-  begin
-    fs := TFileStream.Create(importd.FileName, fmOpenRead);
-    if fs.Size <> finfo.Size then
-      ShowMessage('Can''t import ' + ExtractFilename(importd.FileName) +
-        ', file has to have same size as file in .dat.' + CrLf +
-        'Size of file in .dat: ' + FormatFileSize(finfo.Size) + CrLf +
-        'Size of chosen file: ' + FormatFileSize(fs.Size))
-    else begin
-      SetLength(data, fs.Size);
-      fs.Read(data[0], fs.Size);
-      OniDataConnection.UpdateDatFile(id, data);
-      Self.listClick(Self);
-    end;
-    fs.Free;
-  end;
-end;
-
-procedure TForm_ToolTemplate.popup_opentool(Sender: TObject);
-var
-  sender_name, context: String;
-  id: Integer;
-begin
-  sender_name := TComponent(Sender).Name;
-  id := OniDataConnection.ExtractFileID(filelist.Items.Strings[filelist.ItemIndex]);
-  context := MidStr(sender_name, Pos('_', sender_name) + 1, Length(sender_name) - Pos('_', sender_name));
-  Form_Main.open_child(context, id);
-end;
-
-procedure TForm_ToolTemplate.combo_extensionClick(Sender: TObject);
-begin
-  LoadFileNames;
-end;
-
-
-constructor TForm_ToolTemplate.Create(AOwner: TComponent);
-var
-  i: Integer;
-  item: TMenuItem;
-begin
-  inherited;
-  RecreateList;
-  if Length(ToolList) > 0 then
-  begin
-    for i := 0 to High(ToolList) do
-    begin
-      item := TMenuItem.Create(filepopup);
-      item.Name := 'popup_' + ToolList[i].context;
-      item.Caption := 'Open with ' + ToolList[i].name;
-      item.OnClick := Self.popup_opentool;
-      filepopup.Items.Insert(i, item);
-    end;
-  end;
-end;
-
-procedure TForm_ToolTemplate.filepopupPopup(Sender: TObject);
-var
-  ext: String;
-  i: Integer;
-begin
-  ext := RightStr(filelist.Items.Strings[filelist.ItemIndex], 4);
-  for i := 0 to High(ToolList) do
-  begin
-    filepopup.Items.Items[i].Enabled := True;
-    if Length(ToolList[i].exts) > 0 then
-      if Pos(ext, ToolList[i].exts) = 0 then
-        filepopup.Items.Items[i].Enabled := False;
-  end;
-end;
-
-procedure TForm_ToolTemplate.check_zerobyteClick(Sender: TObject);
-begin
-  LoadFileNames;
-end;
-
-procedure TForm_ToolTemplate.check_filternameClick(Sender: TObject);
-begin
-  edit_filtername.Enabled := not check_filtername.Checked;
-  LoadFileNames;
-end;
-
-procedure TForm_ToolTemplate.listClick(Sender: TObject);
-var
-  fileid: Integer;
-begin
-  if filelist.ItemIndex > -1 then
-  begin
-    fileid := OniDataConnection.ExtractFileID(
-          filelist.Items.Strings[filelist.ItemIndex]);
-    if Assigned(FOnNewFileSelected) then
-      FOnNewFileSelected(OniDataConnection.GetFileInfo(fileid));
-  end;
-end;
-
-procedure TForm_ToolTemplate.listMouseDown(Sender: TObject; Button: TMouseButton;
-  Shift: TShiftState; X, Y: Integer);
-var
-  pt: TPoint;
-begin
-  pt.X := x;
-  pt.Y := y;
-  filelist.ItemIndex := filelist.ItemAtPos(pt, true);
-  Self.listClick(Self);
-end;
-
-
-
-procedure TForm_ToolTemplate.SelectFileID(id: Integer);
-var
-  i: Integer;
-begin
-  filelist.ItemIndex := -1;
-  if filelist.Items.Count > 0 then
-    for i := 0 to filelist.Items.Count - 1 do
-      if OniDataConnection.ExtractFileID(filelist.Items.Strings[i]) = id then
-      begin
-        filelist.ItemIndex := i;
-        Break;
-      end;
-  Self.listClick(Self);
-end;
-
-procedure TForm_ToolTemplate.SelectFileName(filename: String);
-var
-  i: Integer;
-begin
-  filelist.ItemIndex := -1;
-  if filelist.Items.Count > 0 then
-    for i := 0 to filelist.Items.Count - 1 do
-      if filelist.Items.Strings[i] = filename then
-        filelist.ItemIndex := i;
-  Self.listClick(Self);
-end;
-
-procedure TForm_ToolTemplate.SetAllowedExts(exts: String);
-begin
-  FAllowedExts := exts;
-  RecreateList;
-end;
-
-procedure TForm_ToolTemplate.SetMultiSelect(allow: Boolean);
-begin
-  FAllowMultiSelect := allow;
-  filelist.MultiSelect := allow;
-end;
-
-
-procedure TForm_ToolTemplate.FormResize(Sender: TObject);
-begin
-  if Self.Width < 300 then
-    Self.Width := 300;
-  if Self.Height < 200 then
-    Self.Height := 200;
-end;
-
-
-
-procedure TForm_ToolTemplate.FormCreate(Sender: TObject);
-begin
-  Self.Width  := 260;
-  Self.Height := 300;
-  FOnNewFileSelected := nil;
-  FAllowedExts := '';
-  FAllowMultiSelect := False;
-end;
-
-procedure TForm_ToolTemplate.FormClose(Sender: TObject; var Action: TCloseAction);
-begin
-  Action := caFree;
-end;
-
-
-procedure AddToolListEntryExt(context, ext: String);
-var
-  i: Integer;
-begin
-  for i := 0 to High(ToolList) do
-    if ToolList[i].context = context then
-    begin
-      if Pos(ext, ToolList[i].exts) = 0 then
-      begin
-        if Length(ToolList[i].exts) = 0 then
-          ToolList[i].exts := ext
-        else
-          ToolList[i].exts := ToolList[i].exts + ',' + ext;
-      end;
-      Exit;
-    end;
-end;
-
-procedure AddToolListEntry(context, name, exts: String);
-var
-  i: Integer;
-begin
-  if Length(ToolList) > 0 then
-  begin
-    for i := 0 to High(ToolList) do
-      if ToolList[i].context = context then
-      begin
-        if (Length(ToolList[i].name) = 0) and (Length(name) > 0) then
-          ToolList[i].name := name;
-        if Length(exts) > 0 then
-          AddToolListEntryExt(context, exts);
-        Exit;
-      end;
-  end;
-  SetLength(ToolList, Length(ToolList) + 1);
-  for i := High(ToolList) downto 1 do
-    if ToolList[i - 1].name > name then
-      ToolList[i] := ToolList[i - 1]
-    else
-      Break;
-  ToolList[i].context := context;
-  ToolList[i].name := name;
-  ToolList[i].exts := exts;
-end;
-
-end.
Index: oup/current/Tool_TxmpReplace.dfm
===================================================================
--- oup/current/Tool_TxmpReplace.dfm	(revision 45)
+++ 	(revision )
@@ -1,154 +1,0 @@
-inherited Form_TxmpReplace: TForm_TxmpReplace
-  Caption = 'TxmpReplace'
-  OnClose = FormClose
-  OnCreate = FormCreate
-  ExplicitWidth = 320
-  ExplicitHeight = 240
-  PixelsPerInch = 96
-  TextHeight = 13
-  inherited Splitter1: TSplitter
-    Height = 344
-    ExplicitHeight = 344
-  end
-  inherited panel_files: TPanel
-    Height = 344
-    ExplicitHeight = 344
-    object image_txmppreview: TImage [0]
-      Left = 0
-      Top = 257
-      Width = 200
-      Height = 57
-      Align = alClient
-      ExplicitTop = 111
-      ExplicitHeight = 211
-    end
-    object splitter_txmp: TSplitter [1]
-      Left = 0
-      Top = 249
-      Width = 200
-      Height = 8
-      Cursor = crVSplit
-      Align = alTop
-      AutoSnap = False
-      Beveled = True
-      MinSize = 60
-      ExplicitLeft = -6
-      ExplicitTop = 314
-    end
-    inherited filelist: TListBox
-      Height = 146
-      Align = alTop
-      ExplicitHeight = 146
-    end
-    inherited panel_extension: TPanel
-      Visible = False
-    end
-    object panel_txmppreview: TPanel
-      Left = 0
-      Top = 314
-      Width = 200
-      Height = 30
-      Align = alBottom
-      BevelOuter = bvNone
-      TabOrder = 2
-      object btn_save: TButton
-        Left = 2
-        Top = 2
-        Width = 111
-        Height = 25
-        Caption = 'Save TXMP-Picture'
-        TabOrder = 0
-        OnClick = btn_saveClick
-      end
-    end
-  end
-  inherited content: TPanel
-    Height = 344
-    ExplicitHeight = 344
-    object group_bmpselect: TGroupBox
-      Left = 0
-      Top = 0
-      Width = 283
-      Height = 344
-      Align = alClient
-      Caption = '2. Open BMP to replace with'
-      Enabled = False
-      TabOrder = 0
-      object image_bmppreview: TImage
-        Left = 2
-        Top = 45
-        Width = 279
-        Height = 297
-        Align = alClient
-        ExplicitWidth = 182
-        ExplicitHeight = 302
-      end
-      object panel_load: TPanel
-        Left = 2
-        Top = 15
-        Width = 279
-        Height = 30
-        Align = alTop
-        BevelOuter = bvNone
-        TabOrder = 0
-        object btn_load: TButton
-          Left = 2
-          Top = 2
-          Width = 121
-          Height = 25
-          Caption = 'Load BMP ...'
-          TabOrder = 0
-          OnClick = btn_loadClick
-        end
-      end
-    end
-  end
-  object group_options: TGroupBox [3]
-    Left = 0
-    Top = 344
-    Width = 492
-    Height = 79
-    Align = alBottom
-    Caption = '3. Options && Replace'
-    Enabled = False
-    TabOrder = 2
-    object btn_replace: TButton
-      Left = 4
-      Top = 50
-      Width = 157
-      Height = 25
-      Caption = 'Replace'
-      TabOrder = 0
-      OnClick = btn_replaceClick
-    end
-    object check_transparency: TCheckBox
-      Left = 8
-      Top = 16
-      Width = 105
-      Height = 17
-      Caption = 'Transparency'
-      TabOrder = 1
-    end
-    object check_fading: TCheckBox
-      Left = 8
-      Top = 32
-      Width = 105
-      Height = 17
-      Caption = 'MIP Mapping'
-      TabOrder = 2
-    end
-  end
-  object opend: TOpenDialog [4]
-    Filter = '24bit Bitmap (*.bmp)|*.bmp'
-    Options = [ofPathMustExist, ofFileMustExist, ofEnableSizing]
-    Left = 352
-    Top = 16
-  end
-  object saved: TSaveDialog [5]
-    DefaultExt = 'bmp'
-    Filter = 'Windows Bitmap (*.bmp)|*.bmp'
-    Options = [ofOverwritePrompt, ofHideReadOnly, ofPathMustExist, ofEnableSizing]
-    Left = 104
-    Top = 320
-  end
-end
Index: oup/current/Tool_TxmpReplace.pas
===================================================================
--- oup/current/Tool_TxmpReplace.pas	(revision 45)
+++ 	(revision )
@@ -1,204 +1,0 @@
-unit Tool_TxmpReplace;
-interface
-uses
-  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
-  Dialogs, Tool_Template, StdCtrls, ExtCtrls,
-  Code_Functions, Data, Code_OniImgClass, Menus;
-
-type
-  TForm_TxmpReplace = class(TForm_ToolTemplate)
-    group_options: TGroupBox;
-    btn_replace: TButton;
-    check_transparency: TCheckBox;
-    check_fading: TCheckBox;
-    panel_txmppreview: TPanel;
-    btn_save: TButton;
-    image_txmppreview: TImage;
-    splitter_txmp: TSplitter;
-    group_bmpselect: TGroupBox;
-    image_bmppreview: TImage;
-    panel_load: TPanel;
-    btn_load: TButton;
-    opend: TOpenDialog;
-    saved: TSaveDialog;
-    procedure SelectFile(fileinfo: TFileInfo);
-    procedure FormCreate(Sender: TObject);
-    procedure FormClose(Sender: TObject; var Action: TCloseAction);
-    procedure btn_saveClick(Sender: TObject);
-    procedure btn_loadClick(Sender: TObject);
-    procedure btn_replaceClick(Sender: TObject);
-  private
-    OniImage_Old: TOniImage;
-    OniImage_New: TOniImage;
-    fileid: Integer;
-  public
-  end;
-
-var
-  Form_TxmpReplace: TForm_TxmpReplace;
-
-implementation
-{$R *.dfm}
-uses Main, Code_OniDataClass;
-
-
-
-procedure TForm_TxmpReplace.SelectFile(fileinfo: TFileInfo);
-var
-  Data: Tdata;
-  mem:  TMemoryStream;
-  fadingbyte, depthbyte, storebyte: Byte;
-begin
-  fileid := fileinfo.ID;
-  OniDataConnection.LoadDatFilePart(fileid, $88, SizeOf(fadingbyte), @fadingbyte);
-  OniDataConnection.LoadDatFilePart(fileid, $89, SizeOf(depthbyte), @depthbyte);
-  OniDataConnection.LoadDatFilePart(fileid, $90, SizeOf(storebyte), @storebyte);
-  check_fading.Checked := (fadingbyte and $01) > 0;
-  check_transparency.Checked := (depthbyte and $04) > 0;
-
-  OniImage_Old.LoadFromTXMP(fileid);
-  Data := OniImage_Old.GetAsBMP;
-  mem  := TMemoryStream.Create;
-  mem.Write(Data[0], Length(Data));
-  mem.Seek(0, soFromBeginning);
-  image_txmppreview.Picture.Bitmap.LoadFromStream(mem);
-  mem.Free;
-
-  group_bmpselect.Enabled := True;
-end;
-
-
-procedure TForm_TxmpReplace.btn_loadClick(Sender: TObject);
-var
-  mem:   TMemoryStream;
-  tempd: Tdata;
-begin
-  if opend.Execute then
-  begin
-    OniImage_New.LoadFromBMP(opend.FileName);
-    tempd := OniImage_New.GetAsBMP;
-    mem   := TMemoryStream.Create;
-    mem.Write(tempd[0], Length(tempd));
-    mem.Seek(0, soFromBeginning);
-    image_bmppreview.Picture.Bitmap.LoadFromStream(mem);
-    mem.Free;
-    group_options.Enabled := True;
-  end;
-end;
-
-
-
-
-procedure TForm_TxmpReplace.btn_replaceClick(Sender: TObject);
-var
-  oldsize, newsize: LongWord;
-  old_rawaddr, new_rawaddr: LongWord;
-  oldfading: Byte;
-  tempd:     Tdata;
-
-  datbyte: Word;
-begin
-  if filelist.ItemIndex >= 0 then
-  begin
-    OniDataConnection.LoadDatFilePart(fileid, $88, 1, @oldfading);
-    if OniDataConnection.OSisMac then
-      OniDataConnection.UpdateDatFilePart(fileid, $A0, 4, @old_rawaddr)
-    else
-      OniDataConnection.LoadDatFilePart(fileid, $9C, 4, @old_rawaddr);
-
-    if (OniImage_Old.Width <> OniImage_New.Width) or
-      (OniImage_Old.Height <> OniImage_New.Height) then
-    begin
-      if MessageBox(Self.Handle, PChar(
-        'Current image and new image have different size' + CrLf +
-        '(Current: ' + IntToStr(OniImage_Old.Width) +
-        'x' + IntToStr(OniImage_Old.Height) + ' - New: ' +
-        IntToStr(OniImage_New.Width) + 'x' + IntToStr(OniImage_New.Height) + ')' + CrLf +
-        'Replace anyways?'),
-        PChar(filelist.Items.Strings[filelist.ItemIndex]),
-        MB_YESNO) = idNo then
-        Exit;
-    end;
-
-    oldsize := OniImage_Old.GetImageDataSize((oldfading and $01) > 0);
-
-    if check_fading.Checked then
-      if not OniImage_New.GetMipMappedImage(tempd) then
-        if MessageBox(Self.Handle,
-          PChar('Can not create a MipMapped-image (probably because of a wrong dimension).' +
-          #13 + #10 + 'Do you want to continue without MipMapping?'), PChar('Warning'),
-          MB_YESNO) = ID_YES then
-          check_fading.Checked := False
-        else
-          Exit;
-
-    if not check_fading.Checked then
-      tempd := OniImage_New.GetAsData;
-
-    newsize := OniImage_New.GetImageDataSize(check_fading.Checked);
-    ShowMessage(IntToStr(newsize));
-
-    if (newsize > oldsize) and (OniDataConnection.Backend = ODB_Dat) then
-      new_rawaddr := OniDataConnection.AppendRawFile(
-        OniDataConnection.OSisMac, Length(tempd), tempd)
-    else
-    begin
-      new_rawaddr := old_rawaddr;
-      OniDataConnection.UpdateRawFile(fileid, $9C, Length(tempd), tempd);
-    end;
-
-    datbyte := $00;
-    if check_fading.Checked then
-      datbyte := datbyte or $01;
-    OniDataConnection.UpdateDatFilePart(fileid, $88, 1, @datbyte);
-    datbyte := $10;
-    if check_transparency.Checked then
-      datbyte := datbyte or $04;
-    OniDataConnection.UpdateDatFilePart(fileid, $89, 1, @datbyte);
-    OniDataConnection.UpdateDatFilePart(fileid, $8C, 2, @OniImage_New.Width);
-    OniDataConnection.UpdateDatFilePart(fileid, $8E, 2, @OniImage_New.Height);
-    datbyte := $08;
-    OniDataConnection.UpdateDatFilePart(fileid, $90, 1, @datbyte);
-    if OniDataConnection.OSisMac then
-      OniDataConnection.UpdateDatFilePart(fileid, $A0, 4, @new_rawaddr)
-    else
-      OniDataConnection.UpdateDatFilePart(fileid, $9C, 4, @new_rawaddr);
-
-    ShowMessage('TXMP-image replaced');
-  end;
-end;
-
-
-
-
-procedure TForm_TxmpReplace.FormClose(Sender: TObject; var Action: TCloseAction);
-begin
-  OniImage_Old.Free;
-  OniImage_New.Free;
-  inherited;
-end;
-
-
-
-
-procedure TForm_TxmpReplace.FormCreate(Sender: TObject);
-begin
-  inherited;
-  OniImage_Old := TOniImage.Create;
-  OniImage_New := TOniImage.Create;
-  Self.AllowedExts := 'TXMP';
-  Self.OnNewFileSelected := SelectFile;
-end;
-
-
-
-
-procedure TForm_TxmpReplace.btn_saveClick(Sender: TObject);
-begin
-  if saved.Execute then
-    OniImage_Old.WriteToBMP(saved.FileName);
-end;
-
-begin
-  AddToolListEntry('txmpreplace', 'TXMP Replacer', 'TXMP');
-end.
Index: oup/current/Tools/BinEdit.dfm
===================================================================
--- oup/current/Tools/BinEdit.dfm	(revision 46)
+++ oup/current/Tools/BinEdit.dfm	(revision 46)
@@ -0,0 +1,222 @@
+inherited Form_BinEdit: TForm_BinEdit
+  Caption = 'BinEdit'
+  OnCloseQuery = FormCloseQuery
+  OnKeyUp = FormKeyUp
+  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
+      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
+    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/current/Tools/BinEdit.pas
===================================================================
--- oup/current/Tools/BinEdit.pas	(revision 46)
+++ oup/current/Tools/BinEdit.pas	(revision 46)
@@ -0,0 +1,980 @@
+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, OniDataClass, Functions, DataStructures, Exporters, 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: LongWord);
+    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: LongWord;
+  public
+  end;
+
+var
+  Form_BinEdit: TForm_BinEdit;
+
+implementation
+
+uses Helper_ValueEdit, Main, 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.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] := 100;
+//  value_viewer.ColWidths[1] := value_viewer.Width - 150;
+//  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: LongWord);
+var
+  mem:  TMemoryStream;
+  Data: Tdata;
+begin
+  if hex.Modified then
+  begin
+    if not Save then
+    begin
+      Self.SelectFileID(fileid);
+      Exit;
+    end;
+  end;
+  fileid := _fileid;
+  if OniDataConnection.ExtractFileID(
+        filelist.Items.Strings[filelist.ItemIndex]) <> fileid then
+    Self.SelectFileID(fileid);
+  Self.ClearStructViewer;
+  Data := OniDataConnection.LoadDatFile(fileid);
+  if Length(Data) > 0 then
+  begin
+    mem := TMemoryStream.Create;
+    mem.Write(Data[0], Length(Data));
+    mem.Seek(0, soFromBeginning);
+    hex.LoadFromStream(mem);
+    mem.Free;
+    WriteStructureInfos;
+  end
+  else
+  begin
+    ClearValues;
+    hex.DataSize := 0;
+  end;
+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_BinEdit.GetValue(datatype: Word; offset: LongWord): String;
+var
+  Data: Tdata;
+  i:    Word;
+begin
+  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));
+    end;
+    10:
+      Result := IntToBin(hex.Data[offset]);
+    11:
+      Result := '0x' + IntToHex(OniDataConnection.GetRawInfo(fileid, offset).raw_addr, 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(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:  Byte;
+  Data:  Tdata;
+  str:   String;
+  Value: LongWord;
+begin
+  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));
+      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;
+  Data: Tdata;
+  i:    LongWord;
+begin
+  case MessageBox(Self.Handle, PChar('Save changes to file ' +
+      OniDataConnection.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;
+      OniDataConnection.UpdateDatFile(fileid, Data);
+      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) < GetTypeDataLength(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;
+  id: Integer;
+  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 OniDataConnection.GetRawInfo(fileid, nodedata.offset).raw_size > 0 then
+          Form_Main.open_child('rawedit', fileid);
+      end;
+      if nodedata.DataType = 12 then
+      begin
+        if (StrToInt(nodedata.Value) < OniDataConnection.GetFilesCount) and
+          (StrToInt(nodedata.Value) > 0) and
+          (StrToInt(nodedata.Value) <> fileid) then
+        begin
+          if OniDataConnection.GetFileInfo(StrToInt(nodedata.Value)).Size > 0 then
+            Form_Main.open_child('binedit', 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', -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 + GetTypeDataLength(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: 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_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/current/Tools/Extractor.dfm
===================================================================
--- oup/current/Tools/Extractor.dfm	(revision 46)
+++ oup/current/Tools/Extractor.dfm	(revision 46)
@@ -0,0 +1,211 @@
+inherited Form_Extractor: TForm_Extractor
+  Caption = 'Extractor'
+  PixelsPerInch = 96
+  TextHeight = 13
+  inherited Splitter1: TSplitter
+    Left = 483
+    Align = alRight
+    Visible = False
+    ExplicitLeft = 172
+    ExplicitTop = -8
+    ExplicitHeight = 423
+  end
+  inherited panel_files: TPanel
+    Width = 184
+    Align = alClient
+    ExplicitWidth = 184
+    inherited filelist: TListBox
+      Width = 184
+      ExplicitWidth = 184
+    end
+    inherited panel_extension: TPanel
+      Width = 184
+      ExplicitWidth = 184
+      inherited combo_extension: TComboBox
+        Width = 176
+        ExplicitWidth = 176
+      end
+      inherited edit_filtername: TEdit
+        Width = 176
+        ExplicitWidth = 176
+      end
+    end
+  end
+  inherited content: TPanel
+    Left = 184
+    Width = 299
+    Align = alRight
+    ExplicitLeft = 184
+    ExplicitWidth = 299
+    object group_extract: TGroupBox
+      Left = 3
+      Top = 0
+      Width = 296
+      Height = 423
+      Align = alRight
+      Caption = '2. Select extract-method'
+      TabOrder = 0
+      object group_singlefiles: TGroupBox
+        AlignWithMargins = True
+        Left = 8
+        Top = 16
+        Width = 280
+        Height = 185
+        Margins.Left = 6
+        Margins.Top = 1
+        Margins.Right = 6
+        Align = alTop
+        Caption = 'Write data into single files'
+        TabOrder = 0
+        object btn_sel_dat: TButton
+          Left = 8
+          Top = 16
+          Width = 129
+          Height = 49
+          Caption = 'Selected files (dat contents only)'
+          TabOrder = 0
+          WordWrap = True
+          OnClick = Extract
+        end
+        object btn_sel_datraw: TButton
+          Left = 8
+          Top = 72
+          Width = 129
+          Height = 49
+          Caption = 'Selected files (dat+raw)'
+          TabOrder = 1
+          WordWrap = True
+          OnClick = Extract
+        end
+        object btn_sel_datraw_convert: TButton
+          Left = 8
+          Top = 128
+          Width = 129
+          Height = 49
+          Caption = 'Selected files (dat+raw) (with convert if possible)'
+          TabOrder = 2
+          WordWrap = True
+          OnClick = Extract
+        end
+        object btn_all_dat: TButton
+          Left = 144
+          Top = 16
+          Width = 129
+          Height = 49
+          Caption = 'All files in list (dat contents only)'
+          TabOrder = 3
+          WordWrap = True
+          OnClick = Extract
+        end
+        object btn_all_datraw: TButton
+          Left = 144
+          Top = 72
+          Width = 129
+          Height = 49
+          Caption = 'All files in list (dat+raw)'
+          TabOrder = 4
+          WordWrap = True
+          OnClick = Extract
+        end
+        object btn_all_datraw_convert: TButton
+          Left = 144
+          Top = 128
+          Width = 129
+          Height = 49
+          BiDiMode = bdLeftToRight
+          Caption = 'All files in list (dat+raw) (with convert if possible)'
+          ParentBiDiMode = False
+          TabOrder = 5
+          WordWrap = True
+          OnClick = Extract
+        end
+      end
+      object group_onefile: TGroupBox
+        AlignWithMargins = True
+        Left = 8
+        Top = 205
+        Width = 280
+        Height = 73
+        Margins.Left = 6
+        Margins.Top = 1
+        Margins.Right = 6
+        Align = alTop
+        Caption = 'Write data into one file'
+        TabOrder = 1
+        object btn_sel_files_toone: TButton
+          Left = 8
+          Top = 16
+          Width = 129
+          Height = 49
+          Caption = 'Selected files (dat contents only)'
+          TabOrder = 0
+          WordWrap = True
+          OnClick = Extract
+        end
+        object btn_all_files_toone: TButton
+          Left = 144
+          Top = 16
+          Width = 129
+          Height = 49
+          Caption = 'All files in list (dat contents only)'
+          TabOrder = 1
+          WordWrap = True
+          OnClick = Extract
+        end
+      end
+      object group_progress: TGroupBox
+        AlignWithMargins = True
+        Left = 8
+        Top = 282
+        Width = 280
+        Height = 132
+        Margins.Left = 6
+        Margins.Top = 1
+        Margins.Right = 6
+        Margins.Bottom = 7
+        Align = alClient
+        Caption = 'Progress ...'
+        TabOrder = 2
+        Visible = False
+        object lbl_progress: TLabel
+          Left = 8
+          Top = 40
+          Width = 265
+          Height = 17
+          AutoSize = False
+          Caption = 'Files done: 0/0'
+        end
+        object lbl_estimated: TLabel
+          Left = 8
+          Top = 56
+          Width = 265
+          Height = 17
+          AutoSize = False
+          Caption = 'Estimated finishing time: 00:00:00'
+        end
+        object progress: TProgressBar
+          Left = 8
+          Top = 16
+          Width = 265
+          Height = 17
+          Smooth = True
+          TabOrder = 0
+        end
+        object btn_abort: TButton
+          Left = 8
+          Top = 72
+          Width = 97
+          Height = 23
+          Caption = 'Abort'
+          Enabled = False
+          TabOrder = 1
+          OnClick = btn_abortClick
+        end
+      end
+    end
+  end
+  object saved: TSaveDialog [3]
+    Left = 448
+    Top = 328
+  end
+end
Index: oup/current/Tools/Extractor.pas
===================================================================
--- oup/current/Tools/Extractor.pas	(revision 46)
+++ oup/current/Tools/Extractor.pas	(revision 46)
@@ -0,0 +1,190 @@
+unit Extractor;
+interface
+uses
+  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
+  Dialogs, Template, StdCtrls, ExtCtrls, ComCtrls, Menus, Buttons;
+
+type
+  TForm_Extractor = class(TForm_ToolTemplate)
+    group_extract: TGroupBox;
+    group_singlefiles: TGroupBox;
+    btn_sel_dat: TButton;
+    btn_sel_datraw: TButton;
+    btn_sel_datraw_convert: TButton;
+    btn_all_dat: TButton;
+    btn_all_datraw: TButton;
+    btn_all_datraw_convert: TButton;
+    btn_sel_files_toone: TButton;
+    btn_all_files_toone: TButton;
+    group_onefile: TGroupBox;
+    group_progress: TGroupBox;
+    lbl_progress: TLabel;
+    lbl_estimated: TLabel;
+    progress: TProgressBar;
+    btn_abort: TButton;
+    saved: TSaveDialog;
+    procedure FormCreate(Sender: TObject);
+    procedure Extract(Sender: TObject);
+    procedure btn_abortClick(Sender: TObject);
+  private
+  public
+  end;
+
+var
+  Form_Extractor: TForm_Extractor;
+
+implementation
+{$R *.dfm}
+uses Main, Functions, Data, OniDataClass;
+
+procedure TForm_Extractor.FormCreate(Sender: TObject);
+begin
+  inherited;
+  Self.AllowMultiSelect := True;
+
+  btn_sel_dat.Caption    := 'Selected files' + CrLf + '(dat contents only)';
+  btn_sel_datraw.Caption := 'Selected files' + CrLf + '(dat+raw contents)';
+  btn_sel_datraw_convert.Caption :=
+    'Selected files' + CrLf + '(dat+raw contents)' + CrLf + '(with convert if possible)';
+  btn_all_dat.Caption    := 'All files in list' + CrLf + '(dat contents only)';
+  btn_all_datraw.Caption := 'All files in list' + CrLf + '(dat+raw contents)';
+  btn_all_datraw_convert.Caption :=
+    'All files in list' + CrLf + '(dat+raw contents)' + CrLf + '(with convert if possible)';
+  btn_sel_files_toone.Caption := 'Selected files' + CrLf + '(dat contents only)';
+  btn_all_files_toone.Caption := 'All files in list' + CrLf + '(dat contents only)';
+end;
+
+procedure TForm_Extractor.btn_abortClick(Sender: TObject);
+begin
+  ShowMessage('X');
+end;
+
+procedure TForm_Extractor.Extract(Sender: TObject);
+var
+  sel_only:  Boolean;
+  dat_only:  Boolean;
+  convert:   Boolean;
+  one_file:  Boolean;
+  settings:  TExportSet;
+  files:     LongWord;
+  i, done:   LongWord;
+  begintime: Double;
+begin
+  sel_only := Pos('sel', TButton(Sender).Name) > 0;
+  dat_only := not (Pos('datraw', TButton(Sender).Name) > 0);
+  convert  := Pos('convert', TButton(Sender).Name) > 0;
+  one_file := Pos('toone', TButton(Sender).Name) > 0;
+  if dat_only then
+    settings := [DO_dat]
+  else
+    settings := [DO_dat, DO_raw];
+  if convert then
+    settings := settings + [DO_convert];
+  if one_file then
+    settings := settings + [DO_toone];
+  progress.Position := 0;
+
+  if saved.Execute then
+  begin
+    begintime := Time;
+    group_progress.Visible := True;
+    panel_files.Enabled := False;
+    group_singlefiles.Enabled := False;
+    group_onefile.Enabled := False;
+    lbl_estimated.Caption := 'Estimated finishing time: unknown';
+    if one_file then
+    begin
+      if FileExists(saved.FileName) then
+      begin
+        if MessageBox(Self.Handle, PChar(
+          'File already exists. Do you want to overwrite it?'), PChar('Warning!'), MB_YESNO) =
+          ID_YES then
+        begin
+          DeleteFile(saved.FileName);
+        end
+        else
+        begin
+          group_progress.Visible    := False;
+          panel_files.Enabled      := True;
+          group_singlefiles.Enabled := True;
+          group_onefile.Enabled     := True;
+          Exit;
+        end;
+      end;
+      i := FileCreate(saved.FileName);
+      FileClose(i);
+      i := 0;
+    end;
+    if sel_only then
+    begin
+      files := filelist.SelCount;
+      lbl_progress.Caption := 'Files done: 0/' + IntToStr(files);
+      progress.Max := files;
+      done  := 0;
+      for i := 0 to filelist.Count - 1 do
+      begin
+        if filelist.Selected[i] then
+        begin
+          if one_file then
+          begin
+            ExportFile(OniDataConnection.ExtractFileID(
+              filelist.Items.Strings[filelist.ItemIndex]), ExtractFileName(saved.FileName),
+              settings, ExtractFileDir(saved.FileName));
+          end
+          else
+          begin
+            ExportFile(OniDataConnection.ExtractFileID(
+              filelist.Items.Strings[filelist.ItemIndex]), filelist.Items.Strings[i], settings, 'D:');
+          end;
+          Inc(done);
+        end;
+        if ((done mod 10) = 0) and (done >= 50) then
+          lbl_estimated.Caption := 'Estimated finishing time: ' + TimeToStr(
+            (Time - begintime) / done * files + begintime);
+        if (i mod 10) = 0 then
+        begin
+          progress.Position    := done;
+          lbl_progress.Caption := 'Files done: ' + IntToStr(done) + '/' + IntToStr(files);
+          Application.ProcessMessages;
+        end;
+      end;
+    end
+    else
+    begin
+      files := filelist.Count;
+      lbl_progress.Caption := 'Files done: 0/' + IntToStr(files);
+      progress.Max := files;
+      for i := 0 to filelist.Count - 1 do
+      begin
+        if one_file then
+        begin
+          ExportFile(OniDataConnection.ExtractFileID(
+            filelist.Items.Strings[filelist.ItemIndex]), ExtractFileName(saved.FileName),
+            settings, ExtractFileDir(saved.FileName));
+        end
+        else
+        begin
+          ExportFile(OniDataConnection.ExtractFileID(
+            filelist.Items.Strings[filelist.ItemIndex]), filelist.Items.Strings[i], settings, 'D:');
+        end;
+        if ((i mod 10) = 0) and (i >= 50) then
+          lbl_estimated.Caption := 'Estimated finishing time: ' + TimeToStr(
+            (Time - begintime) / i * files + begintime);
+        if (i mod 5) = 0 then
+        begin
+          progress.Position    := i;
+          lbl_progress.Caption := 'Files done: ' + IntToStr(i) + '/' + IntToStr(files);
+          Application.ProcessMessages;
+        end;
+      end;
+    end;
+    group_progress.Visible    := False;
+    panel_files.Enabled      := True;
+    group_singlefiles.Enabled := True;
+    group_onefile.Enabled     := True;
+  end;
+end;
+
+begin
+  AddToolListEntry('extractor', 'Extractor', '');
+end.
Index: oup/current/Tools/Preview.dfm
===================================================================
--- oup/current/Tools/Preview.dfm	(revision 46)
+++ oup/current/Tools/Preview.dfm	(revision 46)
@@ -0,0 +1,78 @@
+inherited Form_Preview: TForm_Preview
+  Caption = 'Preview'
+  PixelsPerInch = 96
+  TextHeight = 13
+  inherited content: TPanel
+    object lbl_notpossible: TLabel
+      Left = 16
+      Top = 56
+      Width = 97
+      Height = 65
+      AutoSize = False
+      Caption = 'No preview possible for this filetype'
+      Font.Charset = DEFAULT_CHARSET
+      Font.Color = clWindowText
+      Font.Height = -16
+      Font.Name = 'Tahoma'
+      Font.Style = []
+      ParentFont = False
+      Visible = False
+      WordWrap = True
+    end
+    object img: TImage
+      Left = 0
+      Top = 20
+      Width = 283
+      Height = 403
+      Align = alClient
+      ExplicitWidth = 313
+      ExplicitHeight = 453
+    end
+    object panel_buttons: TPanel
+      Left = 0
+      Top = 0
+      Width = 283
+      Height = 20
+      Align = alTop
+      BevelOuter = bvNone
+      TabOrder = 0
+      Visible = False
+      OnResize = panel_buttonsResize
+      object btn_dec: TButton
+        Left = 0
+        Top = 0
+        Width = 20
+        Height = 20
+        Caption = '-'
+        Enabled = False
+        TabOrder = 0
+        OnClick = btn_decClick
+      end
+      object btn_startstop: TButton
+        Left = 21
+        Top = 0
+        Width = 80
+        Height = 20
+        Caption = 'Stop automatic'
+        TabOrder = 1
+        OnClick = btn_startstopClick
+      end
+      object btn_inc: TButton
+        Left = 102
+        Top = 0
+        Width = 20
+        Height = 20
+        Caption = '+'
+        Enabled = False
+        TabOrder = 2
+        OnClick = btn_incClick
+      end
+    end
+  end
+  object timer: TTimer [3]
+    Enabled = False
+    OnTimer = timerTimer
+    Left = 400
+    Top = 120
+  end
+end
Index: oup/current/Tools/Preview.pas
===================================================================
--- oup/current/Tools/Preview.pas	(revision 46)
+++ oup/current/Tools/Preview.pas	(revision 46)
@@ -0,0 +1,209 @@
+unit Preview;
+interface
+uses
+  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
+  Dialogs, StdCtrls, Template, ExtCtrls, Math, StrUtils,
+  OniDataClass, OniImgClass, Data, Menus, Buttons;
+
+type
+  TForm_Preview = class(TForm_ToolTemplate)
+    lbl_notpossible: TLabel;
+    panel_buttons: TPanel;
+    btn_dec: TButton;
+    btn_startstop: TButton;
+    btn_inc: TButton;
+    img: TImage;
+    timer: TTimer;
+    procedure FormCreate(Sender: TObject);
+    procedure NewFile(fileinfo: TFileInfo);
+
+    procedure PreviewImage;
+    procedure PreviewTXAN;
+    procedure btn_incClick(Sender: TObject);
+    procedure btn_decClick(Sender: TObject);
+    procedure btn_startstopClick(Sender: TObject);
+    procedure timerTimer(Sender: TObject);
+    procedure panel_buttonsResize(Sender: TObject);
+
+    procedure DrawImage(index: Integer);
+    procedure SetBitmapCount(Count: Integer);
+    procedure LoadImage(fileid, index: Integer);
+  private
+    bitmaps:   array of TBitmap;
+    actualimg: Byte;
+    _fileid:   LongWord;
+  public
+  end;
+
+var
+  Form_Preview: TForm_Preview;
+
+implementation
+{$R *.dfm}
+
+
+procedure TForm_Preview.FormCreate(Sender: TObject);
+begin
+  inherited;
+  Self.OnNewFileSelected := NewFile;
+end;
+
+
+procedure TForm_Preview.NewFile(fileinfo: TFileInfo);
+var
+  ext: String;
+begin
+  _fileid := fileinfo.ID;
+  lbl_notpossible.Visible := False;
+  Self.img.Visible := True;
+  Self.timer.Enabled := False;
+  Self.panel_buttons.Visible := False;
+  ext     := fileinfo.Extension;
+  if (ext = 'PSpc') or (ext = 'TXMB') or (ext = 'TXMP') then
+    PreviewImage
+  else if ext = 'TXAN' then
+    PreviewTXAN
+  else
+  begin
+    Self.lbl_notpossible.Visible := True;
+    Self.img.Visible := False;
+  end;
+end;
+
+
+procedure TForm_Preview.LoadImage(fileid, index: Integer);
+var
+  Data:      Tdata;
+  memstream: TMemoryStream;
+  OniImage:  TOniImage;
+
+begin
+  OniImage := TOniImage.Create;
+  OniImage.Load(fileid);
+  Data := OniImage.GetAsBMP;
+  OniImage.Free;
+
+  memstream := TMemoryStream.Create;
+  memstream.Write(Data[0], Length(Data));
+  memstream.Seek(0, soFromBeginning);
+  bitmaps[index].LoadFromStream(memstream);
+  memstream.Free;
+end;
+
+
+procedure TForm_Preview.DrawImage(index: Integer);
+begin
+  BitBlt(img.Canvas.Handle, 0, 0, img.Width, img.Height,
+    bitmaps[index].Canvas.Handle, 0, 0, WHITENESS);
+  BitBlt(img.Canvas.Handle, 0, 0, bitmaps[index].Width, bitmaps[index].Height,
+    bitmaps[index].Canvas.Handle, 0, 0, SRCCOPY);
+  img.Invalidate;
+end;
+
+
+procedure TForm_Preview.SetBitmapCount(Count: Integer);
+var
+  i: Integer;
+begin
+  if Length(bitmaps) > Count then
+  begin
+    for i := Count to High(bitmaps) do
+      bitmaps[i].Free;
+    SetLength(bitmaps, Count);
+  end;
+  if Length(bitmaps) < Count then
+  begin
+    i := Length(bitmaps);
+    SetLength(bitmaps, Count);
+    for i := i to High(bitmaps) do
+      bitmaps[i] := TBitmap.Create;
+  end;
+end;
+
+
+procedure TForm_Preview.PreviewImage;
+begin
+  SetBitmapCount(1);
+  LoadImage(_fileid, 0);
+  DrawImage(0);
+end;
+
+
+procedure TForm_Preview.PreviewTXAN;
+var
+  loop_speed: Word;
+  linkcount: LongWord;
+  link: LongWord;
+  i:    Byte;
+begin
+  OniDataConnection.LoadDatFilePart(_fileid, $14, SizeOf(loop_speed), @loop_speed);
+  OniDataConnection.LoadDatFilePart(_fileid, $1C, SizeOf(linkcount), @linkcount);
+  SetBitmapCount(linkcount);
+  for i := 0 to linkcount - 1 do
+  begin
+    OniDataConnection.LoadDatFilePart(_fileid, $20 + i * 4, SizeOf(link), @link);
+    link := link div 256;
+    if link = 0 then
+      link := _fileid - 1;
+    LoadImage(link, i);
+  end;
+  actualimg := 254;
+  Self.timer.Interval := Floor(loop_speed * (1 / 60) * 1000);
+  Self.timer.Enabled := False;
+  Self.btn_startstopClick(Self);
+  Self.panel_buttons.Visible := True;
+end;
+
+
+procedure TForm_Preview.timerTimer(Sender: TObject);
+begin
+  btn_incClick(Self);
+end;
+
+
+procedure TForm_Preview.btn_startstopClick(Sender: TObject);
+begin
+  Self.timer.Enabled   := not Self.timer.Enabled;
+  Self.btn_dec.Enabled := not Self.timer.Enabled;
+  Self.btn_inc.Enabled := not Self.timer.Enabled;
+  if Self.timer.Enabled then
+    Self.btn_startstop.Caption := 'Stop automatic'
+  else
+    Self.btn_startstop.Caption := 'Start automatic';
+end;
+
+
+procedure TForm_Preview.btn_decClick(Sender: TObject);
+begin
+  if actualimg > 0 then
+    Dec(actualimg)
+  else
+    actualimg := High(bitmaps);
+  Self.Caption := 'Preview ' + OniDataConnection.GetFileInfo(_fileid).FileName +
+    ' (' + IntToStr(actualimg + 1) + '/' + IntToStr(Length(bitmaps)) + ')';
+  DrawImage(actualimg);
+end;
+
+
+procedure TForm_Preview.btn_incClick(Sender: TObject);
+begin
+  if actualimg < High(bitmaps) then
+    Inc(actualimg)
+  else
+    actualimg := 0;
+  Self.Caption := 'Preview ' + OniDataConnection.GetFileInfo(_fileid).FileName +
+    ' (' + IntToStr(actualimg + 1) + '/' + IntToStr(Length(bitmaps)) + ')';
+  DrawImage(actualimg);
+end;
+
+
+procedure TForm_Preview.panel_buttonsResize(Sender: TObject);
+begin
+  btn_startstop.Width := panel_buttons.Width - 45;
+  btn_inc.Left := panel_buttons.Width - 23;
+end;
+
+
+begin
+  AddToolListEntry('preview', 'Preview-Window', '');
+end.
Index: oup/current/Tools/RawEdit.dfm
===================================================================
--- oup/current/Tools/RawEdit.dfm	(revision 46)
+++ oup/current/Tools/RawEdit.dfm	(revision 46)
@@ -0,0 +1,196 @@
+inherited Form_RawEdit: TForm_RawEdit
+  Caption = 'RawEdit'
+  OnCloseQuery = FormCloseQuery
+  OnKeyUp = FormKeyUp
+  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 = 76
+      ExplicitHeight = 76
+    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
+    OnResize = panel_contentResize
+    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 = 1
+      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
+      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/current/Tools/RawEdit.pas
===================================================================
--- oup/current/Tools/RawEdit.pas	(revision 46)
+++ oup/current/Tools/RawEdit.pas	(revision 46)
@@ -0,0 +1,816 @@
+unit RawEdit;
+interface
+uses
+  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
+  Dialogs, Template, StdCtrls, ExtCtrls, Menus, Grids, Wrapgrid,
+  MPHexEditor, Clipbrd, StrUtils,
+  Data, Functions, DataStructures, Exporters, OniDataClass, 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: TRawInfo);
+    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);
+
+    procedure panel_contentResize(Sender: TObject);
+
+    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
+    fileid:     LongWord;
+    dat_offset: LongWord;
+    fileid_opened, dat_offset_opened: LongWord;
+  public
+  end;
+
+var
+  Form_RawEdit: TForm_RawEdit;
+
+implementation
+{$R *.dfm}
+uses Main, Helper_ValueEdit;
+
+procedure TForm_RawEdit.NewFile(fileinfo: TFileInfo);
+var
+  offsets: TRawList;
+  i: Integer;
+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 := OniDataConnection.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].src_offset, 8) +
+              ', ' + IntToStr(offsets[i].raw_size) + ' bytes');
+    list_offset.Enabled := True;
+  end;
+end;
+
+procedure TForm_RawEdit.LoadRaw(raw_info: TRawInfo);
+var
+  i:    LongWord;
+  Data: Tdata;
+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 OniDataConnection.ExtractFileID(filelist.Items.Strings[i]) = raw_info.src_id 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.src_offset, 8) then
+      begin
+        list_offset.ItemIndex := i;
+        Break;
+      end;
+    end;
+  end;
+  SetLength(Data, raw_info.raw_size);
+  OniDataConnection.LoadRawFile(raw_info.src_id, raw_info.src_offset, @Data[0]);
+  if Length(Data) > 0 then
+  begin
+    hex.DataSize := 0;
+    hex.DataSize := raw_info.raw_size;
+    for i := 0 to High(Data) do
+      hex.Data[i] := Data[i];
+    //WriteStructureInfos(GetStructureInfoId(GetFileInfo(fileid).Extension));
+    //      structs.Height:=structs.RowCount*20;
+    //      IF structs.Height>120 THEN structs.Height:=120;
+    hexSelectionChanged(Self);
+    fileid_opened     := raw_info.src_id;
+    dat_offset_opened := raw_info.src_offset;
+    hex.Modified      := False;
+  end
+  else
+  begin
+    ClearValues;
+    hex.DataSize := 0;
+  end;
+end;
+
+
+
+
+
+
+procedure TForm_RawEdit.list_offsetClick(Sender: TObject);
+var
+  i: LongWord;
+  raw_info: TRawInfo;
+begin
+  ClearValues;
+  dat_offset := StrToInt('$' + MidStr(
+    list_offset.Items.Strings[list_offset.ItemIndex], 3, 8));
+  LoadRaw(OniDataConnection.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;
+begin
+  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));
+    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:  Byte;
+  Data:  Tdata;
+  str:   String;
+  Value: LongWord;
+begin
+  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));
+      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     := 0;
+  value_viewer.ColCount := 2;
+  value_viewer.RowCount := 8;
+  value_viewer.FixedRows := 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] := 100;
+  //
+  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 ' +
+      OniDataConnection.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;
+      OniDataConnection.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.panel_contentResize(Sender: TObject);
+begin
+  value_viewer.ColWidths[1] := value_viewer.Width - value_viewer.ColWidths[0] - 28;
+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 (*.' + OniDataConnection.GetFileInfo(
+    fileid).Extension + ')|*.' + OniDataConnection.GetFileInfo(fileid).Extension +
+    '|All files|*.*';
+  saved.DefaultExt := OniDataConnection.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 (*.' + OniDataConnection.GetFileInfo(
+    fileid).Extension + ')|*.' + OniDataConnection.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.
Index: oup/current/Tools/Template.dfm
===================================================================
--- oup/current/Tools/Template.dfm	(revision 46)
+++ oup/current/Tools/Template.dfm	(revision 46)
@@ -0,0 +1,259 @@
+object Form_ToolTemplate: TForm_ToolTemplate
+  Left = 0
+  Top = 0
+  Caption = 'Template'
+  ClientHeight = 423
+  ClientWidth = 492
+  Color = clBtnFace
+  Constraints.MinHeight = 450
+  Constraints.MinWidth = 500
+  Font.Charset = DEFAULT_CHARSET
+  Font.Color = clWindowText
+  Font.Height = -11
+  Font.Name = 'Tahoma'
+  Font.Style = []
+  FormStyle = fsMDIChild
+  OldCreateOrder = False
+  Visible = True
+  WindowState = wsMaximized
+  OnClose = FormClose
+  OnCreate = FormCreate
+  OnResize = FormResize
+  PixelsPerInch = 96
+  TextHeight = 13
+  object Splitter1: TSplitter
+    Left = 200
+    Top = 0
+    Width = 9
+    Height = 423
+    AutoSnap = False
+    Beveled = True
+    MinSize = 150
+    ExplicitHeight = 473
+  end
+  object panel_files: TPanel
+    Left = 0
+    Top = 0
+    Width = 200
+    Height = 423
+    Align = alLeft
+    BevelOuter = bvNone
+    TabOrder = 0
+    object filelist: TListBox
+      Left = 0
+      Top = 129
+      Width = 200
+      Height = 294
+      Align = alClient
+      ItemHeight = 13
+      PopupMenu = filepopup
+      TabOrder = 0
+      OnMouseDown = listMouseDown
+    end
+    object panel_extension: TPanel
+      Left = 0
+      Top = 0
+      Width = 200
+      Height = 129
+      Align = alTop
+      BevelOuter = bvNone
+      TabOrder = 1
+      DesignSize = (
+        200
+        129)
+      object label_ext: TLabel
+        Left = 2
+        Top = 62
+        Width = 100
+        Height = 17
+        AutoSize = False
+        Caption = 'Filter by &extension:'
+        FocusControl = combo_extension
+      end
+      object btn_sort_id_asc: TSpeedButton
+        Left = 16
+        Top = 101
+        Width = 23
+        Height = 22
+        Hint = 'Sort files by id, ascending'
+        GroupIndex = 1
+        Down = True
+        Glyph.Data = {
+          F6000000424DF600000000000000760000002800000010000000100000000100
+          0400000000008000000000000000000000001000000000000000C0C0C0000000
+          9900990000000000000000000000000000000000000000000000000000000000
+          0000000000000000000000000000000000000000000000000000000000000000
+          0000000001100000300000001001000030000000000100033300000001110003
+          3300000010010033333000001001000030000000011000003000000000000000
+          3000000002200000300000002002000030000000200200003000000020020000
+          3000000020020000300000002002000030000000022000003000}
+        ParentShowHint = False
+        ShowHint = True
+        OnClick = btn_sortClick
+      end
+      object btn_sort_id_desc: TSpeedButton
+        Left = 40
+        Top = 101
+        Width = 23
+        Height = 22
+        Hint = 'Sort files by id, descending'
+        GroupIndex = 1
+        Glyph.Data = {
+          F6000000424DF600000000000000760000002800000010000000100000000100
+          0400000000008000000000000000000000001000000000000000C0C0C0000000
+          9900990000000000000000000000000000000000000000000000000000000000
+          0000000000000000000000000000000000000000000000000000000000000000
+          0000000002200000300000002002000030000000200200033300000020020003
+          3300000020020033333000002002000030000000022000003000000000000000
+          3000000001100000300000001001000030000000000100003000000001110000
+          3000000010010000300000001001000030000000011000003000}
+        ParentShowHint = False
+        ShowHint = True
+        OnClick = btn_sortClick
+      end
+      object btn_sort_name_asc: TSpeedButton
+        Left = 64
+        Top = 101
+        Width = 23
+        Height = 22
+        Hint = 'Sort files by name, ascending'
+        GroupIndex = 1
+        Glyph.Data = {
+          F6000000424DF600000000000000760000002800000010000000100000000100
+          0400000000008000000000000000000000001000000000000000C0C0C0000000
+          9900990000000000000000000000000000000000000000000000000000000000
+          0000000000000000000000000000000000000000000000000000000000000000
+          0000011111100000300001100010000030000011000000033300000110000003
+          3300000011000033333001000110000030000111111000003000000000000000
+          3000022202220000300000200020000030000022222000003000000202000000
+          3000000222000000300000002000000030000000200000003000}
+        ParentShowHint = False
+        ShowHint = True
+        OnClick = btn_sortClick
+      end
+      object btn_sort_name_desc: TSpeedButton
+        Left = 88
+        Top = 101
+        Width = 23
+        Height = 22
+        Hint = 'Sort files by name, descending'
+        GroupIndex = 1
+        Glyph.Data = {
+          F6000000424DF600000000000000760000002800000010000000100000000100
+          0400000000008000000000000000000000001000000000000000C0C0C0000000
+          9900990000000000000000000000000000000000000000000000000000000000
+          0000000000000000000000000000000000000000000000000000000000000000
+          0000022202220000300000200020000030000022222000033300000202000003
+          3300000222000033333000002000000030000000200000003000000000000000
+          3000011111100000300001100010000030000011000000003000000110000000
+          3000000011000000300001000110000030000111111000003000}
+        ParentShowHint = False
+        ShowHint = True
+        OnClick = btn_sortClick
+      end
+      object btn_sort_ext_asc: TSpeedButton
+        Left = 112
+        Top = 101
+        Width = 23
+        Height = 22
+        Hint = 'Sort files by extension, ascending'
+        GroupIndex = 1
+        ParentShowHint = False
+        ShowHint = True
+        OnClick = btn_sortClick
+      end
+      object btn_sort_ext_desc: TSpeedButton
+        Left = 136
+        Top = 101
+        Width = 23
+        Height = 22
+        Hint = 'Sort files by extension, descending'
+        GroupIndex = 1
+        ParentShowHint = False
+        ShowHint = True
+        OnClick = btn_sortClick
+      end
+      object combo_extension: TComboBox
+        Left = 2
+        Top = 76
+        Width = 192
+        Height = 21
+        Style = csDropDownList
+        Anchors = [akLeft, akTop, akRight]
+        DropDownCount = 12
+        Font.Charset = DEFAULT_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -11
+        Font.Name = 'Tahoma'
+        Font.Style = []
+        ItemHeight = 0
+        ParentFont = False
+        Sorted = True
+        TabOrder = 3
+        OnClick = combo_extensionClick
+      end
+      object check_zerobyte: TCheckBox
+        Left = 2
+        Top = 44
+        Width = 130
+        Height = 13
+        Caption = 'Show &zero-byte files'
+        TabOrder = 2
+        OnClick = check_zerobyteClick
+      end
+      object edit_filtername: TEdit
+        Left = 2
+        Top = 20
+        Width = 192
+        Height = 18
+        Anchors = [akLeft, akTop, akRight]
+        AutoSize = False
+        TabOrder = 1
+      end
+      object check_filtername: TCheckBox
+        Left = 2
+        Top = 5
+        Width = 130
+        Height = 15
+        Caption = 'Filter by file&name:'
+        TabOrder = 0
+        OnClick = check_filternameClick
+      end
+    end
+  end
+  object content: TPanel
+    Left = 209
+    Top = 0
+    Width = 283
+    Height = 423
+    Align = alClient
+    BevelOuter = bvNone
+    TabOrder = 1
+  end
+  object filepopup: TPopupMenu
+    OnPopup = filepopupPopup
+    Left = 72
+    Top = 216
+    object popup_separator: TMenuItem
+      Caption = '-'
+    end
+    object popup_import: TMenuItem
+      Caption = 'Import binary .dat-file'
+      OnClick = popup_importClick
+    end
+    object popup_export: TMenuItem
+      Caption = 'Export binary .dat-file'
+      OnClick = popup_exportClick
+    end
+  end
+  object importd: TOpenDialog
+    Options = [ofExtensionDifferent, ofPathMustExist, ofFileMustExist, ofEnableSizing]
+    Left = 136
+    Top = 232
+  end
+  object exportd: TSaveDialog
+    Options = [ofHideReadOnly, ofExtensionDifferent, ofPathMustExist, ofEnableSizing]
+    Left = 144
+    Top = 256
+  end
+end
Index: oup/current/Tools/Template.pas
===================================================================
--- oup/current/Tools/Template.pas	(revision 46)
+++ oup/current/Tools/Template.pas	(revision 46)
@@ -0,0 +1,416 @@
+unit Template;
+
+interface
+
+uses
+  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
+  Dialogs, ExtCtrls, StdCtrls, StrUtils,
+  OniDataClass, Functions, Data, Menus, Buttons;
+
+type
+  TNewFileSelectedEvent = procedure(fileinfo: TFileInfo) of object;
+
+  TForm_ToolTemplate = class(TForm)
+    panel_files: TPanel;
+    filelist: TListBox;
+    panel_extension: TPanel;
+    label_ext: TLabel;
+    combo_extension: TComboBox;
+    check_zerobyte: TCheckBox;
+    edit_filtername: TEdit;
+    check_filtername: TCheckBox;
+    Splitter1: TSplitter;
+    content: TPanel;
+    filepopup: TPopupMenu;
+    popup_import: TMenuItem;
+    popup_export: TMenuItem;
+    popup_separator: TMenuItem;
+    importd: TOpenDialog;
+    exportd: TSaveDialog;
+    btn_sort_id_asc: TSpeedButton;
+    btn_sort_id_desc: TSpeedButton;
+    btn_sort_name_asc: TSpeedButton;
+    btn_sort_name_desc: TSpeedButton;
+    btn_sort_ext_asc: TSpeedButton;
+    btn_sort_ext_desc: TSpeedButton;
+    procedure RecreateList;
+    procedure LoadFileNames;
+    procedure SelectFileName(filename: String);
+    procedure SelectFileID(id: Integer);
+    procedure check_filternameClick(Sender: TObject);
+    procedure check_zerobyteClick(Sender: TObject);
+    procedure combo_extensionClick(Sender: TObject);
+    procedure listClick(Sender: TObject);
+    procedure listMouseDown(Sender: TObject; Button: TMouseButton;
+      Shift: TShiftState; X, Y: Integer);
+
+    procedure FormResize(Sender: TObject);
+    procedure FormCreate(Sender: TObject);
+    procedure FormClose(Sender: TObject; var Action: TCloseAction);
+    procedure popup_importClick(Sender: TObject);
+    procedure popup_exportClick(Sender: TObject);
+    procedure popup_opentool(Sender: TObject);
+    procedure filepopupPopup(Sender: TObject);
+    procedure btn_sortClick(Sender: TObject);
+  private
+    FSortBy: TSortType;
+    FOnNewFileSelected: TNewFileSelectedEvent;
+    FAllowedExts: String;
+    FAllowMultiSelect: Boolean;
+    procedure SetAllowedExts(exts: String);
+    procedure SetMultiSelect(allow: Boolean);
+  public
+    constructor Create(AOwner: TComponent); override;
+    procedure SetFileFilters(pattern, extension: String; zerobytes: Boolean);
+  published
+    property OnNewFileSelected: TNewFileSelectedEvent read FOnNewFileSelected write FOnNewFileSelected;
+    property AllowedExts: String read FAllowedExts write SetAllowedExts;
+    property AllowMultiSelect: Boolean read FAllowMultiSelect write SetMultiSelect;
+  end;
+
+var
+  ToolList: TToolList;
+procedure AddToolListEntry(context, name, exts: String);
+
+implementation
+{$R *.dfm}
+uses Main, Exporters;
+
+
+procedure TForm_ToolTemplate.RecreateList;
+var
+  i:    LongWord;
+  exts: TStringArray;
+begin
+  combo_extension.Items.Clear;
+  combo_extension.Items.Add('_All files_ (' +
+    IntToStr(OniDataConnection.GetFilesCount) + ')');
+  exts := OniDataConnection.GetExtensionsList;
+  for i := 0 to High(exts) do
+    if Length(FAllowedExts) > 0 then
+    begin
+      if Pos(MidStr(exts[i],1,4), FAllowedExts) > 0 then
+      begin
+        combo_extension.Items.Add(exts[i]);
+      end;
+    end else
+      combo_extension.Items.Add(exts[i]);
+  combo_extension.ItemIndex := 0;
+  combo_extensionClick(Self);
+end;
+
+
+
+
+procedure TForm_ToolTemplate.LoadFileNames;
+var
+  Extension: String;
+  no_zero_bytes: Boolean;
+  pattern: String;
+  files: TStringArray;
+  i: LongWord;
+begin
+  Extension := MidStr(combo_extension.Items.Strings[combo_extension.ItemIndex], 1, 4);
+  no_zero_bytes := not check_zerobyte.Checked;
+  pattern := '';
+  if check_filtername.Checked then
+    pattern := edit_filtername.Text;
+  if Extension = '_All' then
+    if Length(FAllowedExts) > 0 then
+      Extension := FAllowedExts
+    else
+      Extension := '';
+
+  files := OniDataConnection.GetFilesList(extension, pattern, no_zero_bytes, FSortBy);
+
+  filelist.Visible := False;
+  filelist.Items.Clear;
+  if Length(files) > 0 then
+    for i := 0 to High(files) do
+      filelist.Items.Add(files[i]);
+  filelist.Visible := True;
+end;
+
+
+procedure TForm_ToolTemplate.popup_exportClick(Sender: TObject);
+var
+  id: Integer;
+  ext: String;
+begin
+  id := OniDataConnection.ExtractFileID(filelist.Items.Strings[filelist.ItemIndex]);
+  ext := RightStr(filelist.Items.Strings[filelist.ItemIndex], 4);
+  exportd.Filter := 'Files of matching extension (*.' + ext + ')|*.' + ext + '|All files|*.*';
+  exportd.DefaultExt := ext;
+  if exportd.Execute then
+    ExportDatFile(id, exportd.FileName);
+end;
+
+procedure TForm_ToolTemplate.popup_importClick(Sender: TObject);
+var
+  id: Integer;
+  finfo: TFileInfo;
+  fs: TFileStream;
+  data: TData;
+begin
+  id := OniDataConnection.ExtractFileID(filelist.Items.Strings[filelist.ItemIndex]);
+  finfo := OniDataConnection.GetFileInfo(id);
+
+  importd.Filter := 'Files of matching extension (*.' + finfo.Extension + ')|*.' +
+        finfo.Extension + '|All files|*.*';
+  if importd.Execute then
+  begin
+    fs := TFileStream.Create(importd.FileName, fmOpenRead);
+    if fs.Size <> finfo.Size then
+      ShowMessage('Can''t import ' + ExtractFilename(importd.FileName) +
+        ', file has to have same size as file in .dat.' + CrLf +
+        'Size of file in .dat: ' + FormatFileSize(finfo.Size) + CrLf +
+        'Size of chosen file: ' + FormatFileSize(fs.Size))
+    else begin
+      SetLength(data, fs.Size);
+      fs.Read(data[0], fs.Size);
+      OniDataConnection.UpdateDatFile(id, data);
+      Self.listClick(Self);
+    end;
+    fs.Free;
+  end;
+end;
+
+procedure TForm_ToolTemplate.popup_opentool(Sender: TObject);
+var
+  sender_name, context: String;
+  id: Integer;
+begin
+  sender_name := TComponent(Sender).Name;
+  id := OniDataConnection.ExtractFileID(filelist.Items.Strings[filelist.ItemIndex]);
+  context := MidStr(sender_name, Pos('_', sender_name) + 1, Length(sender_name) - Pos('_', sender_name));
+  Form_Main.open_child(context, id);
+end;
+
+procedure TForm_ToolTemplate.combo_extensionClick(Sender: TObject);
+begin
+  LoadFileNames;
+end;
+
+
+constructor TForm_ToolTemplate.Create(AOwner: TComponent);
+var
+  i: Integer;
+  item: TMenuItem;
+begin
+  inherited;
+  RecreateList;
+  if Length(ToolList) > 0 then
+  begin
+    for i := 0 to High(ToolList) do
+    begin
+      item := TMenuItem.Create(filepopup);
+      item.Name := 'popup_' + ToolList[i].context;
+      item.Caption := 'Open with ' + ToolList[i].name;
+      item.OnClick := Self.popup_opentool;
+      filepopup.Items.Insert(i, item);
+    end;
+  end;
+end;
+
+procedure TForm_ToolTemplate.filepopupPopup(Sender: TObject);
+var
+  ext: String;
+  i: Integer;
+begin
+  ext := RightStr(filelist.Items.Strings[filelist.ItemIndex], 4);
+  for i := 0 to High(ToolList) do
+  begin
+    filepopup.Items.Items[i].Enabled := True;
+    if Length(ToolList[i].exts) > 0 then
+      if Pos(ext, ToolList[i].exts) = 0 then
+        filepopup.Items.Items[i].Enabled := False;
+  end;
+end;
+
+procedure TForm_ToolTemplate.check_zerobyteClick(Sender: TObject);
+begin
+  LoadFileNames;
+end;
+
+procedure TForm_ToolTemplate.btn_sortClick(Sender: TObject);
+begin
+  if btn_sort_id_asc.Down then
+    FSortBy := stIDAsc
+  else if btn_sort_id_desc.Down then
+    FSortBy := stIDDesc
+  else if btn_sort_name_asc.Down then
+    FSortBy := stNameAsc
+  else if btn_sort_name_desc.Down then
+    FSortBy := stNameDesc
+  else if btn_sort_ext_asc.Down then
+    FSortBy := stExtAsc
+  else if btn_sort_ext_desc.Down then
+    FSortBy := stExtDesc;
+  LoadFileNames;
+end;
+
+procedure TForm_ToolTemplate.check_filternameClick(Sender: TObject);
+begin
+  edit_filtername.Enabled := not check_filtername.Checked;
+  LoadFileNames;
+end;
+
+procedure TForm_ToolTemplate.listClick(Sender: TObject);
+var
+  fileid: Integer;
+begin
+  if filelist.ItemIndex > -1 then
+  begin
+    fileid := OniDataConnection.ExtractFileID(
+          filelist.Items.Strings[filelist.ItemIndex]);
+    if Assigned(FOnNewFileSelected) then
+      FOnNewFileSelected(OniDataConnection.GetFileInfo(fileid));
+  end;
+end;
+
+procedure TForm_ToolTemplate.listMouseDown(Sender: TObject; Button: TMouseButton;
+  Shift: TShiftState; X, Y: Integer);
+var
+  pt: TPoint;
+begin
+  pt.X := x;
+  pt.Y := y;
+  filelist.ItemIndex := filelist.ItemAtPos(pt, true);
+  Self.listClick(Self);
+end;
+
+
+
+procedure TForm_ToolTemplate.SelectFileID(id: Integer);
+var
+  i: Integer;
+begin
+  filelist.ItemIndex := -1;
+  if filelist.Items.Count > 0 then
+    for i := 0 to filelist.Items.Count - 1 do
+      if OniDataConnection.ExtractFileID(filelist.Items.Strings[i]) = id then
+      begin
+        filelist.ItemIndex := i;
+        Break;
+      end;
+  Self.listClick(Self);
+end;
+
+procedure TForm_ToolTemplate.SelectFileName(filename: String);
+var
+  i: Integer;
+begin
+  filelist.ItemIndex := -1;
+  if filelist.Items.Count > 0 then
+    for i := 0 to filelist.Items.Count - 1 do
+      if filelist.Items.Strings[i] = filename then
+        filelist.ItemIndex := i;
+  Self.listClick(Self);
+end;
+
+procedure TForm_ToolTemplate.SetAllowedExts(exts: String);
+begin
+  FAllowedExts := exts;
+  RecreateList;
+end;
+
+procedure TForm_ToolTemplate.SetFileFilters(pattern, extension: String;
+  zerobytes: Boolean);
+var
+  i: Integer;
+begin
+  if Length(pattern) > 0 then
+    Self.edit_filtername.Text := pattern;
+  Self.check_filtername.Checked := Length(pattern) > 0;
+  if Length(extension) > 0 then
+  begin
+    for i := 0 to Self.combo_extension.Items.Count - 1 do
+      if Pos(extension, Self.combo_extension.Items.Strings[i]) > 0 then
+        Break;
+    if i < Self.combo_extension.Items.Count then
+      Self.combo_extension.ItemIndex := i
+    else
+      Self.combo_extension.ItemIndex := -1;
+  end;
+  Self.check_zerobyte.Checked := zerobytes;
+  Self.LoadFileNames;
+end;
+
+procedure TForm_ToolTemplate.SetMultiSelect(allow: Boolean);
+begin
+  FAllowMultiSelect := allow;
+  filelist.MultiSelect := allow;
+end;
+
+
+procedure TForm_ToolTemplate.FormResize(Sender: TObject);
+begin
+  if Self.Width < 300 then
+    Self.Width := 300;
+  if Self.Height < 200 then
+    Self.Height := 200;
+end;
+
+
+
+procedure TForm_ToolTemplate.FormCreate(Sender: TObject);
+begin
+  Self.Width  := 260;
+  Self.Height := 300;
+  FOnNewFileSelected := nil;
+  FAllowedExts := '';
+  FAllowMultiSelect := False;
+end;
+
+procedure TForm_ToolTemplate.FormClose(Sender: TObject; var Action: TCloseAction);
+begin
+  Action := caFree;
+end;
+
+
+procedure AddToolListEntryExt(context, ext: String);
+var
+  i: Integer;
+begin
+  for i := 0 to High(ToolList) do
+    if ToolList[i].context = context then
+    begin
+      if Pos(ext, ToolList[i].exts) = 0 then
+      begin
+        if Length(ToolList[i].exts) = 0 then
+          ToolList[i].exts := ext
+        else
+          ToolList[i].exts := ToolList[i].exts + ',' + ext;
+      end;
+      Exit;
+    end;
+end;
+
+procedure AddToolListEntry(context, name, exts: String);
+var
+  i: Integer;
+begin
+  if Length(ToolList) > 0 then
+  begin
+    for i := 0 to High(ToolList) do
+      if ToolList[i].context = context then
+      begin
+        if (Length(ToolList[i].name) = 0) and (Length(name) > 0) then
+          ToolList[i].name := name;
+        if Length(exts) > 0 then
+          AddToolListEntryExt(context, exts);
+        Exit;
+      end;
+  end;
+  SetLength(ToolList, Length(ToolList) + 1);
+  for i := High(ToolList) downto 1 do
+    if ToolList[i - 1].name > name then
+      ToolList[i] := ToolList[i - 1]
+    else
+      Break;
+  ToolList[i].context := context;
+  ToolList[i].name := name;
+  ToolList[i].exts := exts;
+end;
+
+end.
Index: oup/current/Tools/TxmpReplace.dfm
===================================================================
--- oup/current/Tools/TxmpReplace.dfm	(revision 46)
+++ oup/current/Tools/TxmpReplace.dfm	(revision 46)
@@ -0,0 +1,150 @@
+inherited Form_TxmpReplace: TForm_TxmpReplace
+  Caption = 'TxmpReplace'
+  PixelsPerInch = 96
+  TextHeight = 13
+  inherited Splitter1: TSplitter
+    Height = 344
+    ExplicitHeight = 344
+  end
+  inherited panel_files: TPanel
+    Height = 344
+    ExplicitHeight = 344
+    object image_txmppreview: TImage [0]
+      Left = 0
+      Top = 283
+      Width = 200
+      Height = 31
+      Align = alClient
+      ExplicitTop = 111
+      ExplicitHeight = 211
+    end
+    object splitter_txmp: TSplitter [1]
+      Left = 0
+      Top = 275
+      Width = 200
+      Height = 8
+      Cursor = crVSplit
+      Align = alTop
+      AutoSnap = False
+      Beveled = True
+      MinSize = 60
+      ExplicitLeft = -6
+      ExplicitTop = 314
+    end
+    inherited filelist: TListBox
+      Height = 146
+      Align = alTop
+      ExplicitHeight = 146
+    end
+    inherited panel_extension: TPanel
+      Visible = False
+    end
+    object panel_txmppreview: TPanel
+      Left = 0
+      Top = 314
+      Width = 200
+      Height = 30
+      Align = alBottom
+      BevelOuter = bvNone
+      TabOrder = 2
+      object btn_save: TButton
+        Left = 2
+        Top = 2
+        Width = 111
+        Height = 25
+        Caption = 'Save TXMP-Picture'
+        TabOrder = 0
+        OnClick = btn_saveClick
+      end
+    end
+  end
+  inherited content: TPanel
+    Height = 344
+    ExplicitHeight = 344
+    object group_bmpselect: TGroupBox
+      Left = 0
+      Top = 0
+      Width = 283
+      Height = 344
+      Align = alClient
+      Caption = '2. Open BMP to replace with'
+      Enabled = False
+      TabOrder = 0
+      object image_bmppreview: TImage
+        Left = 2
+        Top = 45
+        Width = 279
+        Height = 297
+        Align = alClient
+        ExplicitWidth = 182
+        ExplicitHeight = 302
+      end
+      object panel_load: TPanel
+        Left = 2
+        Top = 15
+        Width = 279
+        Height = 30
+        Align = alTop
+        BevelOuter = bvNone
+        TabOrder = 0
+        object btn_load: TButton
+          Left = 2
+          Top = 2
+          Width = 121
+          Height = 25
+          Caption = 'Load BMP ...'
+          TabOrder = 0
+          OnClick = btn_loadClick
+        end
+      end
+    end
+  end
+  object group_options: TGroupBox [3]
+    Left = 0
+    Top = 344
+    Width = 492
+    Height = 79
+    Align = alBottom
+    Caption = '3. Options && Replace'
+    Enabled = False
+    TabOrder = 2
+    object btn_replace: TButton
+      Left = 4
+      Top = 50
+      Width = 157
+      Height = 25
+      Caption = 'Replace'
+      TabOrder = 0
+      OnClick = btn_replaceClick
+    end
+    object check_transparency: TCheckBox
+      Left = 8
+      Top = 16
+      Width = 105
+      Height = 17
+      Caption = 'Transparency'
+      TabOrder = 1
+    end
+    object check_fading: TCheckBox
+      Left = 8
+      Top = 32
+      Width = 105
+      Height = 17
+      Caption = 'MIP Mapping'
+      TabOrder = 2
+    end
+  end
+  object opend: TOpenDialog [4]
+    Filter = '24bit Bitmap (*.bmp)|*.bmp'
+    Options = [ofPathMustExist, ofFileMustExist, ofEnableSizing]
+    Left = 352
+    Top = 16
+  end
+  object saved: TSaveDialog [5]
+    DefaultExt = 'bmp'
+    Filter = 'Windows Bitmap (*.bmp)|*.bmp'
+    Options = [ofOverwritePrompt, ofHideReadOnly, ofPathMustExist, ofEnableSizing]
+    Left = 104
+    Top = 320
+  end
+end
Index: oup/current/Tools/TxmpReplace.pas
===================================================================
--- oup/current/Tools/TxmpReplace.pas	(revision 46)
+++ oup/current/Tools/TxmpReplace.pas	(revision 46)
@@ -0,0 +1,204 @@
+unit TxmpReplace;
+interface
+uses
+  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
+  Dialogs, Template, StdCtrls, ExtCtrls,
+  Functions, Data, OniImgClass, Menus, Buttons;
+
+type
+  TForm_TxmpReplace = class(TForm_ToolTemplate)
+    group_options: TGroupBox;
+    btn_replace: TButton;
+    check_transparency: TCheckBox;
+    check_fading: TCheckBox;
+    panel_txmppreview: TPanel;
+    btn_save: TButton;
+    image_txmppreview: TImage;
+    splitter_txmp: TSplitter;
+    group_bmpselect: TGroupBox;
+    image_bmppreview: TImage;
+    panel_load: TPanel;
+    btn_load: TButton;
+    opend: TOpenDialog;
+    saved: TSaveDialog;
+    procedure SelectFile(fileinfo: TFileInfo);
+    procedure FormCreate(Sender: TObject);
+    procedure FormClose(Sender: TObject; var Action: TCloseAction);
+    procedure btn_saveClick(Sender: TObject);
+    procedure btn_loadClick(Sender: TObject);
+    procedure btn_replaceClick(Sender: TObject);
+  private
+    OniImage_Old: TOniImage;
+    OniImage_New: TOniImage;
+    fileid: Integer;
+  public
+  end;
+
+var
+  Form_TxmpReplace: TForm_TxmpReplace;
+
+implementation
+{$R *.dfm}
+uses Main, OniDataClass;
+
+
+
+procedure TForm_TxmpReplace.SelectFile(fileinfo: TFileInfo);
+var
+  Data: Tdata;
+  mem:  TMemoryStream;
+  fadingbyte, depthbyte, storebyte: Byte;
+begin
+  fileid := fileinfo.ID;
+  OniDataConnection.LoadDatFilePart(fileid, $88, SizeOf(fadingbyte), @fadingbyte);
+  OniDataConnection.LoadDatFilePart(fileid, $89, SizeOf(depthbyte), @depthbyte);
+  OniDataConnection.LoadDatFilePart(fileid, $90, SizeOf(storebyte), @storebyte);
+  check_fading.Checked := (fadingbyte and $01) > 0;
+  check_transparency.Checked := (depthbyte and $04) > 0;
+
+  OniImage_Old.LoadFromTXMP(fileid);
+  Data := OniImage_Old.GetAsBMP;
+  mem  := TMemoryStream.Create;
+  mem.Write(Data[0], Length(Data));
+  mem.Seek(0, soFromBeginning);
+  image_txmppreview.Picture.Bitmap.LoadFromStream(mem);
+  mem.Free;
+
+  group_bmpselect.Enabled := True;
+end;
+
+
+procedure TForm_TxmpReplace.btn_loadClick(Sender: TObject);
+var
+  mem:   TMemoryStream;
+  tempd: Tdata;
+begin
+  if opend.Execute then
+  begin
+    OniImage_New.LoadFromBMP(opend.FileName);
+    tempd := OniImage_New.GetAsBMP;
+    mem   := TMemoryStream.Create;
+    mem.Write(tempd[0], Length(tempd));
+    mem.Seek(0, soFromBeginning);
+    image_bmppreview.Picture.Bitmap.LoadFromStream(mem);
+    mem.Free;
+    group_options.Enabled := True;
+  end;
+end;
+
+
+
+
+procedure TForm_TxmpReplace.btn_replaceClick(Sender: TObject);
+var
+  oldsize, newsize: LongWord;
+  old_rawaddr, new_rawaddr: LongWord;
+  oldfading: Byte;
+  tempd:     Tdata;
+
+  datbyte: Word;
+begin
+  if filelist.ItemIndex >= 0 then
+  begin
+    OniDataConnection.LoadDatFilePart(fileid, $88, 1, @oldfading);
+    if OniDataConnection.OSisMac then
+      OniDataConnection.UpdateDatFilePart(fileid, $A0, 4, @old_rawaddr)
+    else
+      OniDataConnection.LoadDatFilePart(fileid, $9C, 4, @old_rawaddr);
+
+    if (OniImage_Old.Width <> OniImage_New.Width) or
+      (OniImage_Old.Height <> OniImage_New.Height) then
+    begin
+      if MessageBox(Self.Handle, PChar(
+        'Current image and new image have different size' + CrLf +
+        '(Current: ' + IntToStr(OniImage_Old.Width) +
+        'x' + IntToStr(OniImage_Old.Height) + ' - New: ' +
+        IntToStr(OniImage_New.Width) + 'x' + IntToStr(OniImage_New.Height) + ')' + CrLf +
+        'Replace anyways?'),
+        PChar(filelist.Items.Strings[filelist.ItemIndex]),
+        MB_YESNO) = idNo then
+        Exit;
+    end;
+
+    oldsize := OniImage_Old.GetImageDataSize((oldfading and $01) > 0);
+
+    if check_fading.Checked then
+      if not OniImage_New.GetMipMappedImage(tempd) then
+        if MessageBox(Self.Handle,
+          PChar('Can not create a MipMapped-image (probably because of a wrong dimension).' +
+          #13 + #10 + 'Do you want to continue without MipMapping?'), PChar('Warning'),
+          MB_YESNO) = ID_YES then
+          check_fading.Checked := False
+        else
+          Exit;
+
+    if not check_fading.Checked then
+      tempd := OniImage_New.GetAsData;
+
+    newsize := OniImage_New.GetImageDataSize(check_fading.Checked);
+    ShowMessage(IntToStr(newsize));
+
+    if (newsize > oldsize) and (OniDataConnection.Backend = ODB_Dat) then
+      new_rawaddr := OniDataConnection.AppendRawFile(
+        OniDataConnection.OSisMac, Length(tempd), tempd)
+    else
+    begin
+      new_rawaddr := old_rawaddr;
+      OniDataConnection.UpdateRawFile(fileid, $9C, Length(tempd), tempd);
+    end;
+
+    datbyte := $00;
+    if check_fading.Checked then
+      datbyte := datbyte or $01;
+    OniDataConnection.UpdateDatFilePart(fileid, $88, 1, @datbyte);
+    datbyte := $10;
+    if check_transparency.Checked then
+      datbyte := datbyte or $04;
+    OniDataConnection.UpdateDatFilePart(fileid, $89, 1, @datbyte);
+    OniDataConnection.UpdateDatFilePart(fileid, $8C, 2, @OniImage_New.Width);
+    OniDataConnection.UpdateDatFilePart(fileid, $8E, 2, @OniImage_New.Height);
+    datbyte := $08;
+    OniDataConnection.UpdateDatFilePart(fileid, $90, 1, @datbyte);
+    if OniDataConnection.OSisMac then
+      OniDataConnection.UpdateDatFilePart(fileid, $A0, 4, @new_rawaddr)
+    else
+      OniDataConnection.UpdateDatFilePart(fileid, $9C, 4, @new_rawaddr);
+
+    ShowMessage('TXMP-image replaced');
+  end;
+end;
+
+
+
+
+procedure TForm_TxmpReplace.FormClose(Sender: TObject; var Action: TCloseAction);
+begin
+  OniImage_Old.Free;
+  OniImage_New.Free;
+  inherited;
+end;
+
+
+
+
+procedure TForm_TxmpReplace.FormCreate(Sender: TObject);
+begin
+  inherited;
+  OniImage_Old := TOniImage.Create;
+  OniImage_New := TOniImage.Create;
+  Self.AllowedExts := 'TXMP';
+  Self.OnNewFileSelected := SelectFile;
+end;
+
+
+
+
+procedure TForm_TxmpReplace.btn_saveClick(Sender: TObject);
+begin
+  if saved.Execute then
+    OniImage_Old.WriteToBMP(saved.FileName);
+end;
+
+begin
+  AddToolListEntry('txmpreplace', 'TXMP Replacer', 'TXMP');
+end.
Index: oup/current/blubb.txt
===================================================================
--- oup/current/blubb.txt	(revision 45)
+++ 	(revision )
@@ -1,6 +1,0 @@
-___FILEINDEX___.txt
-
-
-TXMP:
-MipMapping: Bit0=an/aus
-ColorDepth: Bit0=??AnimationPic??, Bit1=shade vertex, Bit2=transparency, Bit4=16bit, Bit5=32bit
Index: oup/current/changelog.txt
===================================================================
--- oup/current/changelog.txt	(revision 45)
+++ 	(revision )
@@ -1,114 +1,0 @@
-OniUnPacker v0.32a
-------------------
-+DB2Dat functionality enhanced (*can* be used but is not yet finished)
-+PSpc Preview added (but not yet working cause of some weird bugs)
-
-OniUnPacker v0.32a
-------------------
-+Raw-part "BodyPartAnimation data" of TRAMs
-+Added basic DB2Dat functionality (SHOULD NOT BE USED YET!!!)
-+CharSet selection (works for ValueViewer only right now)
-
-OniUnPacker v0.31a
-------------------
-+Dat2DB function working
-+Fixed a bug which appeared when multiple windows of the same class were opened at one time (eg 2*BinEdit)
-
-OniUnPacker v0.30a
-------------------
-+Completely rewritten data-backend-connection-classes (Unit15_Classes.pas)
-
-OniUnPacker v0.29a
-------------------
-+Little changes in StructureDefs
-
-OniUnPacker v0.29a
-------------------
-+New StructureViewer
-+New StructureTypes: 12=.dat-file-ID, 13..16=SignedInteger, 1000..9999=Unused data
-+Dynamic Structures (look at TXAN-files or AISA-files for examples)
-+File-type associations (.dat, .oldb, .opf) with OUP possible
-+File IDs as Hex
-
-OniUnPacker v0.28a
-------------------
-+StructureDefinitions as separate txt-files
-+Minor bugfixes
-+Ctrl+C for Hex-fields
-
-OniUnPacker v0.27a
-------------------
-+Added MAC-file support
-+Added StructureDefs for ONCCs / TRAMs (thanks to SSG)
-
-OniUnPacker v0.26a
-------------------
-+Fixed some bugs again ;)
-
-OniUnPacker v0.25a
-------------------
-+Fixed some bugs here and there ;)
-+BinEdit/RawEdit: Added keycombo CTRL+S for saving current file
-
-OniUnPacker v0.24a
-------------------
-+RawEdit. Open it by doubleclick on a Raw-Link in the StructureViewer of BinEdit or enter the FileID and the offset of the raw-link in the .dat-file manually
-
-OniUnPacker v0.23a
-------------------
-+Added copy2clipboard functions to ValueViewer (rightclick)
-+Enhanced FileList-filters
-+Added ValueEditor to BinEdit -> StructViewer / ValueViewer (doubleclick on either value field of ValueViewer or StructViewer)
-
-OniUnPacker v0.22a
-------------------
-+Replaced DB-Backend (much faster conversion of levels)
-+Added ValueViewer to BinEdit (decodes selected area as different variable-types)
-
-OniUnPacker v0.21a
-------------------
-+Extractor tool works almost completely (you can't select where the files are stored if you *don't* choose to put them all in one file. They are stored in the root of drive d:)
-+Corrected string-display in the structure viewer of BinEdit (strings are now displayed as a hint of the value-box if you move the mouse over it)
-
-OniUnPacker v0.20a
-------------------
-+? (Forgot what I added here ;) )
-
-OniUnPacker v0.19a
-------------------
-+.dat/.raw -> OUP-Level-DB-Convert basics
-+Extractor tool (not working yet :D )
-
-OniUnPacker v0.18a
-------------------
-+Completely rewritten GUI
-
-OniUnPacker v0.17a
-------------------
-+Binary-editor: Structure-viewer (only TXMP so far)
-
-OniUnPacker v0.16a
-------------------
-+Replaced hex-view-box with a true hex-component
-+Binary-editor for .dat-files
-
-OniUnPacker v0.15a
-------------------
-+Extract menu
-+Changed layout
-
-OniUnPacker v0.14a
-------------------
-+Corrected image-decoder for 32bit images
-+TXMP-Replace: 32bit option (for prevention from quality loss)
-
-OniUnPacker v0.13a
-------------------
-+TXMP-Replace: Transparency option
-+TXMP-Replace: Fading option
-+TXMP-Replace: Overwrites old data if the new fits in that space (to keep the raw as small as possible)
-
-OniUnPacker v0.12a
-------------------
-+TXMP-Replace function (Menu -> Tools -> TXMP Replacer)
-+TXMB-Decoder (export with convert & preview)
Index: oup/current/irf_oni.onlv.vb
===================================================================
--- oup/current/irf_oni.onlv.vb	(revision 45)
+++ 	(revision )
@@ -1,545 +1,0 @@
-Public Type LWOPolygon
-  NumVe As Integer
-  P1 As Integer
-  P2 As Integer
-  P3 As Integer
-  Surfa As Integer
-End Type
-
-Public Type PolDef
-  P1 As Integer
-  P2 As Integer
-  P3 As Integer
-End Type
-
-'Texture Coordinate Entry
-Public Type TXCAentry
-  X As Single
-  Y As Single
-End Type
-
-'Texture Coordinate Lists
-Public Type TXCA            'Length
-  ID As Long                '4
-  Version As Long           '8
-  Filler(1 To 5) As Long    '28
-  NumEntries As Long        '32
-End Type
-
-'Level Data Reference List
-Public Type ONLV            'Length
-  ID As Long                '4
-  Version As Long           '8
-  LevelName As String * 64  '72
-  AKEVid As Long            '76
-  OBOAid As Long            '80
-  ONMAid As Long            '84
-  ONFAid As Long            '88
-  ONTAid As Long            '92
-  ONSKid As Long            '96
-  Unkn As Long              '100
-  AISAid As Long            '104
-  AITRid As Long            '108
-  ONSAid As Long            '112
-  OBDCid As Long            '116
-  ONOAid As Long            '120
-  Fill(1 To 161) As Long    '764
-  CRSAid As Long            '768
-End Type
-
-Public Type AGQG
-  ID As Long
-  unk(1 To 24) As Byte
-  NumEntries As Long
-End Type
-
-Public Type AGQGEntry
-  VertIndex(1 To 4) As Long
-  VertUVIndex(1 To 4) As Long
-  LData_1(1 To 4) As Byte
-  LData_2(1 To 4) As Byte
-  LData_3(1 To 4) As Byte
-  LData_4(1 To 4) As Byte
-  unk(1 To 2) As Long
-End Type
-
-Public Type AGQREntry
-  TexIndex As Integer
-  unk As Integer
-End Type
-
-Public Type TXMA
-   ID As Long
-   shit(1 To 24) As Byte
-   NumEntries As Long
-End Type
-
-Public Type TXMAEntry
-   TXMP_ID As Long
-End Type
-
-
-
-
-
-Public Sub CExportONLV(Optional FileName As String)
-Form1.StatusBar1.SimpleText = "Status: Extracting LEVEL....."
-Dim ID4 As Long
-Dim I As Long
-Dim L As Long
-Dim LwoP() As LWOPolygon
-Dim OniPol2() As PolDef
-Dim NP As Long
-Dim numb As Long
-
-Dim TXMA1 As TXMA
-Dim AGQR1 As TXMA
-Dim TXCA1 As TXCA
-Dim TXCA_E() As TXCAentry
-Dim TXMA_E() As TXMAEntry
-Dim AGQR_E() As AGQREntry
-Dim TexNames() As String
-
-If FileName = "" Then
-  Form1.CD.DialogTitle = "Unpack resource..."
-  Form1.CD.FileName = OniEntry(Curr).szTagName
-  Form1.CD.Filter = "LightWave (*.lwo)|*.lwo"
-  Form1.CD.Flags = &H2 + &H4
-  Form1.CD.ShowSave
-  FileName = Form1.CD.FileName
-  If FileName = "" Then Exit Sub
-End If
-
-DoEvents
-
-Open DatFile For Binary As #1
-  Get 1, OniEntry(Curr).rDataPosition, ONLV
-  For I = 0 To UBound(OniEntry) - 1
-    Get 1, OniEntry(I).rDataPosition, ID4
-    If ID4 = ONLV.AKEVid Then
-      Get 1, OniEntry(I).rDataPosition, AKEV
-      Exit For
-    End If
-  Next I
-
-  'Find ID of PNTA
-  For I = 0 To UBound(OniEntry) - 1
-    Get 1, OniEntry(I).rDataPosition, ID4
-    If ID4 = AKEV.PNTAid Then
-       Get 1, OniEntry(I).rDataPosition, PNTA
-       ReDim PNTAentry(PNTA.NumEntries - 1)
-       Get 1, , PNTAentry
-       Exit For
-    End If
-  Next I
-
-  For I = 0 To UBound(OniEntry) - 1
-    Get 1, OniEntry(I).rDataPosition, ID4
-    If ID4 = AKEV.AGQGid Then
-       Get 1, OniEntry(I).rDataPosition, AGQG
-       ReDim AGQGEntry(AGQG.NumEntries - 1)
-       Get 1, , AGQGEntry
-       Exit For
-    End If
-  Next I
-
-  'TXCA
-  For I = 0 To UBound(OniEntry) - 1
-    Get 1, OniEntry(I).rDataPosition, ID4
-    If ID4 = AKEV.TXCAid Then
-       Get 1, OniEntry(I).rDataPosition, TXCA1
-       ReDim TXCA_E(TXCA1.NumEntries - 1)
-       Get 1, , TXCA_E
-       ReDim Preserve TXCA_E(PNTA.NumEntries - 1)
-       Exit For
-    End If
-  Next I
-
-  'TXMA
-  For I = 0 To UBound(OniEntry) - 1
-    Get 1, OniEntry(I).rDataPosition, ID4
-    If ID4 = AKEV.TXMAid Then
-       Get 1, OniEntry(I).rDataPosition, TXMA1
-       ReDim TXMA_E(TXMA1.NumEntries - 1)
-       Get 1, , TXMA_E
-       Exit For
-    End If
-  Next I
-
-  'AGQR
-  For I = 0 To UBound(OniEntry) - 1
-    Get 1, OniEntry(I).rDataPosition, ID4
-    If ID4 = AKEV.AGQRid Then
-       Get 1, OniEntry(I).rDataPosition, AGQR1
-       ReDim AGQR_E(AGQR1.NumEntries - 1)
-       Get 1, , AGQR_E
-       Exit For
-    End If
-  Next I
-
-  ReDim TexNames(TXMA1.NumEntries - 1)
-
-  For I = 0 To TXMA1.NumEntries - 1
-    For L = 0 To UBound(OniEntry) - 1
-      Get 1, OniEntry(L).rDataPosition, ID4
-      If ID4 = TXMA_E(I).TXMP_ID Then
-        TexNames(I) = OniEntry(L).szTagName + Ext
-        Exit For
-      End If
-    Next L
-  Next I
-
-Close
-'Ok
-' so we have: 3D points, Texture coordinates and list of polygons,
-' end reading, now convert data
-I = 0
-Open App.Path + "\lwo.tmp" For Binary As #11
-Form1.StatusBar1.SimpleText = "Status: Extracting LEVEL [Reading Polygons...]"
-Seek 11, 1
-
-'reading polygons.......
-
-NP = AGQG.NumEntries * 2
-For I = 0 To AGQG.NumEntries - 1
-Select Case GetPureFile(TexNames(AGQR_E(I).TexIndex))
-  Case "BLUEGRID02", "_DOOR_FRAME", "", "COLLISION"
-  NP = NP - 2
-  Case Else
-    Select Case Mid$(GetPureFile(TexNames(AGQR_E(I).TexIndex)), 1, 5)
-     Case "_DOOR"
-       NP = NP - 2
-     Case Else
-       Put 11, , TestSwapInt(AGQGEntry(I).VertIndex(1))
-       Put 11, , TestSwapInt(AGQGEntry(I).VertIndex(2))
-       Put 11, , TestSwapInt(AGQGEntry(I).VertIndex(3))
-       Put 11, , TestSwapInt(AGQGEntry(I).VertIndex(3))
-       Put 11, , TestSwapInt(AGQGEntry(I).VertIndex(4))
-       Put 11, , TestSwapInt(AGQGEntry(I).VertIndex(1))
-    End Select
-  End Select
-Next I
-
-
-
-ReDim OniPol2(NP - 1)
-ReDim LwoP(NP - 1)
-Get 11, 1, OniPol2
-
-For I = 0 To NP - 1
-  LwoP(I).NumVe = ISItoMSI(3)
-  LwoP(I).P1 = OniPol2(I).P1
-  LwoP(I).P2 = OniPol2(I).P2
-  LwoP(I).P3 = OniPol2(I).P3
-  LwoP(I).Surfa = ISItoMSI(1)
-Next I
-
-I = Empty
-
-Close
-
-On Error Resume Next
-  Kill App.Path + "\*.tmp"
-On Error GoTo 0
-
-Form1.StatusBar1.SimpleText = "Status: Extracting LEVEL [Writing...]"
-Form1.ProgressBar1.Max = PNTA.NumEntries
-Form1.ProgressBar1.Value = 0
-If LevelType = 5 Or LevelType = 10 Then
-  FileName = GetPureFile(FileName) + ".raw"
-End If
-
-For I = 0 To PNTA.NumEntries - 1
-   If PNTAentry(I).X > 2000000.1 Then PNTAentry(I).X = 0
-   If PNTAentry(I).Y > 2000000.1 Then PNTAentry(I).Y = 0
-   If PNTAentry(I).Z > 2000000.1 Then PNTAentry(I).Z = 0
-   If PNTAentry(I).X < -2000000.1 Then PNTAentry(I).X = 0
-   If PNTAentry(I).Y < -2000000.1 Then PNTAentry(I).Y = 0
-   If PNTAentry(I).Z < -2000000.1 Then PNTAentry(I).Z = 0
-Next I
-
-Select Case LevelType
-Case 1
-
-Open FileName For Binary As #1
-  Put 1, , "FORM"
-  Put 1, , ISLtoMSL(12 + (PNTA.NumEntries * 12) + 8 + 6 + 8 + (NP * 10))
-  Put 1, , "LWOBPNTS"
-  Put 1, , ISLtoMSL(PNTA.NumEntries * 12)
-  For I = 0 To PNTA.NumEntries - 1
-    Put 1, , SwapFloat(PNTAentry(I).X)
-    Put 1, , SwapFloat(PNTAentry(I).Y)
-    Put 1, , SwapFloat(PNTAentry(I).Z)
-    Form1.ProgressBar1.Value = I
-  Next I
-  Put 1, , "SRFS"
-  Put 1, , ISLtoMSL(6)
-  Put 1, , "Level"
-  Put 1, , CByte(0)
-  Put 1, , "POLS"
-  Put 1, , ISLtoMSL(NP * 10)
-  Put 1, , LwoP
-Close
-Case 6
-
-' Convert Oni level to RAW 3D Binary
-Open GetPureFile(FileName) + ".rwb" For Binary As #1
-For I = 0 To AGQG.NumEntries - 1
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(1)).X
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(1)).Y
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(1)).Z
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(2)).X
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(2)).Y
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(2)).Z
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(3)).X
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(3)).Y
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(3)).Z
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(3)).X
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(3)).Y
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(3)).Z
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(4)).X
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(4)).Y
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(4)).Z
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(1)).X
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(1)).Y
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(1)).Z
-Next I
-
-Close
-Case 7
-
-' B3D
-Open GetPureFile(FileName) + ".b3d" For Binary As #1
-Put 1, , "Big3DbyOleg"
-Put 1, , CLng(1067030938)
-Put 1, , "POINTS  "
-Put 1, , CLng(PNTA.NumEntries)
-For I = 0 To PNTA.NumEntries - 1
-  Put 1, , PNTAentry(I).X
-  Put 1, , PNTAentry(I).Y
-  Put 1, , PNTAentry(I).Z
-Next I
-
-Put 1, , "POLYGONS"
-Put 1, , CLng(NP * 2)
-For I = 0 To AGQG.NumEntries - 1
-Select Case GetPureFile(TexNames(AGQR_E(I).TexIndex))
-  Case "BLUEGRID02", "_DOOR_FRAME", "", "COLLISION"
-    'nothing
-  Case Else
-    Select Case Mid$(GetPureFile(TexNames(AGQR_E(I).TexIndex)), 1, 5)
-     Case "_DOOR"
-       'nothing
-     Case Else
-       Put 1, , CLng(3)
-       Put 1, , AGQGEntry(I).VertIndex(1)
-       Put 1, , AGQGEntry(I).VertIndex(2)
-       Put 1, , AGQGEntry(I).VertIndex(3)
-       Put 1, , CLng(0)
-       Put 1, , CLng(3)
-       Put 1, , AGQGEntry(I).VertIndex(3)
-       Put 1, , AGQGEntry(I).VertIndex(4)
-       Put 1, , AGQGEntry(I).VertIndex(1)
-       Put 1, , CLng(0)
-    End Select
-End Select
-Next I
-Put 1, , CLng(0)
-Close
-
-Case 8
-
-'Delete shit from the Oni level
-numb = AGQG.NumEntries
-   ReDim Preserve PNTAentry(PNTA.NumEntries + 3)
-   PNTAentry(PNTA.NumEntries + 0).X = -9
-   PNTAentry(PNTA.NumEntries + 0).Y = 0
-   PNTAentry(PNTA.NumEntries + 0).Z = -3
-   PNTAentry(PNTA.NumEntries + 1).X = -9
-   PNTAentry(PNTA.NumEntries + 1).Y = 0
-   PNTAentry(PNTA.NumEntries + 1).Z = 8
-   PNTAentry(PNTA.NumEntries + 2).X = 11
-   PNTAentry(PNTA.NumEntries + 2).Y = 0
-   PNTAentry(PNTA.NumEntries + 2).Z = -3
-   PNTAentry(PNTA.NumEntries + 3).X = 11
-   PNTAentry(PNTA.NumEntries + 3).Y = 0
-   PNTAentry(PNTA.NumEntries + 3).Z = 8
-
-   If Form1.mnuDelGarbage.Checked = True Then
-   For I = 0 To AGQG.NumEntries - 1
-     Select Case Mid$(GetPureFile(TexNames(AGQR_E(I).TexIndex)), 1, 5)
-     Case "_DOOR"
-        AGQGEntry(I).VertIndex(1) = PNTA.NumEntries + 0
-        AGQGEntry(I).VertIndex(2) = PNTA.NumEntries + 1
-        AGQGEntry(I).VertIndex(3) = PNTA.NumEntries + 2
-        AGQGEntry(I).VertIndex(4) = PNTA.NumEntries + 3
-        'numb = numb - 1
-     End Select
-   Next I
-   End If
-
-   For I = 0 To AGQG.NumEntries - 1
-     Select Case GetPureFile(TexNames(AGQR_E(I).TexIndex))
-     Case "BLUEGRID02", "_DOOR_FRAME", "", "COLLISION"
-        AGQGEntry(I).VertIndex(1) = PNTA.NumEntries + 0
-        AGQGEntry(I).VertIndex(2) = PNTA.NumEntries + 1
-        AGQGEntry(I).VertIndex(3) = PNTA.NumEntries + 2
-        AGQGEntry(I).VertIndex(4) = PNTA.NumEntries + 3
-        numb = numb - 1
-     End Select
-   Next I
-
-'B3D + materials
-Open GetPureFile(FileName) + ".b3d" For Binary As #1
-Put 1, , "Big3DbyOleg"
-Put 1, , CLng(1067030938)
-Put 1, , "POINTS  "
-Put 1, , CLng(numb * 4)
-
-For I = 0 To AGQG.NumEntries - 1
-  ' Begin polygon
-Select Case GetPureFile(TexNames(AGQR_E(I).TexIndex))
- Case "BLUEGRID02", "_DOOR_FRAME", "", "COLLISION"
-  'nothing
- Case Else
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(1)).X
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(1)).Y
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(1)).Z
-
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(2)).X
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(2)).Y
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(2)).Z
-
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(3)).X
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(3)).Y
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(3)).Z
-
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(4)).X
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(4)).Y
-  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(4)).Z
-End Select
-  ' end polygon
-Next I
-
-Put 1, , "POLYGONS"
-Put 1, , CLng(numb * 2)
-L = 0
-ID4 = 0
-For I = 0 To AGQG.NumEntries - 1
-Select Case GetPureFile(TexNames(AGQR_E(I).TexIndex))
- Case "BLUEGRID02", "_DOOR_FRAME", "", "COLLISION"
-  'nothing
- Case Else
-  Put 1, , CLng(3)
-  Put 1, , CLng(L)
-  Put 1, , CLng(L + 1)
-  Put 1, , CLng(L + 2)
-  Put 1, , CLng(ID4)
-  Put 1, , CLng(3)
-  Put 1, , CLng(L + 2)
-  Put 1, , CLng(L + 3)
-  Put 1, , CLng(L)
-  Put 1, , CLng(ID4)
-  ID4 = ID4 + 1
-  L = L + 4
-End Select
-Next I
-
-Put 1, , CLng(1)
-Put 1, , "TEX_UV  "
-Put 1, , CLng(numb * 4)
-L = 0
-
-For I = 0 To AGQG.NumEntries - 1
-Select Case GetPureFile(TexNames(AGQR_E(I).TexIndex))
- Case "BLUEGRID02", "_DOOR_FRAME", "", "COLLISION"
-  'nothing
- Case Else
-  Put 1, , CLng(L)
-  L = L + 1
-  Put 1, , TXCA_E(AGQGEntry(I).VertUVIndex(1)).X
-  Put 1, , TXCA_E(AGQGEntry(I).VertUVIndex(1)).Y
-  Put 1, , CLng(L)
-  L = L + 1
-  Put 1, , TXCA_E(AGQGEntry(I).VertUVIndex(2)).X
-  Put 1, , TXCA_E(AGQGEntry(I).VertUVIndex(2)).Y
-  Put 1, , CLng(L)
-  L = L + 1
-  Put 1, , TXCA_E(AGQGEntry(I).VertUVIndex(3)).X
-  Put 1, , TXCA_E(AGQGEntry(I).VertUVIndex(3)).Y
-  Put 1, , CLng(L)
-  L = L + 1
-  Put 1, , TXCA_E(AGQGEntry(I).VertUVIndex(4)).X
-  Put 1, , TXCA_E(AGQGEntry(I).VertUVIndex(4)).Y
-End Select
-  'Put 1, , CSng((-TXCA_E(I).Y) + 1)
-Next I
-
-L = 0
-Put 1, , "MATERIAL"
-Put 1, , CLng(numb)
-For I = 0 To AGQG.NumEntries - 1
-Select Case GetPureFile(TexNames(AGQR_E(I).TexIndex))
- Case "BLUEGRID02", "_DOOR_FRAME", "", "COLLISION"
-  'nothing
- Case Else
-  Put 1, , CLng(1)
-  Put 1, , CLng(L)
-  Put 1, , CLng(Len(TexNames(AGQR_E(I).TexIndex)))
-  Put 1, , TexNames(AGQR_E(I).TexIndex)
-  L = L + 1
-End Select
-Next I
-Close
-
-Open GetPureFile(FileName) + ".tlist" For Binary As #4
-  For I = 0 To AGQR1.NumEntries - 1
-  Select Case GetPureFile(TexNames(AGQR_E(I).TexIndex))
-  Case "BLUEGRID02", "_DOOR_FRAME", "", "COLLISION"
-   'nothing
-  Case Else
-    Put 4, , AGQR_E(I).TexIndex
-  End Select
-  Next I
-Close
-
-Open GetPureFile(FileName) + ".txt" For Output As #4
-  Print #4, CStr(TXMA1.NumEntries)
-  For I = 0 To TXMA1.NumEntries - 1
-    Print #4, CStr(GetPureFile(TexNames(I)))
-  Next I
-Close
-
-If Form1.mnuB3DLight.Checked = True Then
-Open GetPureFile(FileName) + ".ltcs" For Binary As #4
-  For I = 0 To AGQR1.NumEntries - 1
-  Select Case GetPureFile(TexNames(AGQR_E(I).TexIndex))
-  Case "BLUEGRID02", "_DOOR_FRAME", "", "COLLISION"
-   'nothing
-  Case Else
-    Put 4, , AGQGEntry(I).LData_1
-    Put 4, , AGQGEntry(I).LData_2
-    Put 4, , AGQGEntry(I).LData_3
-    Put 4, , AGQGEntry(I).LData_4
-  End Select
-  Next I
-Close
-End If
-End Select
-
-Form1.ProgressBar1.Value = 0
-Form1.ProgressBar1.Max = UBound(OniEntry)
-
-Form1.StatusBar1.SimpleText = "OK"
-'Dispose
-I = Empty
-NP = Empty
-Erase LwoP
-Erase PNTAentry
-Erase OniPol2
-Erase AGQGEntry
-Erase AGQR_E
-Erase TXMA_E
-Erase TXCA_E
-Erase TexNames
-End Sub
Index: oup/current/selects.txt
===================================================================
--- oup/current/selects.txt	(revision 45)
+++ 	(revision )
@@ -1,3 +1,0 @@
-SELECT (datfiles.name || "." || datfiles.extension) AS name, count(src_id) AS x, src_id FROM linkmap LEFT JOIN datfiles ON datfiles.id=src_id GROUP BY src_id ORDER BY x DESC
-
-SELECT (datfiles.name || "." || datfiles.extension) AS name, count(src_id) AS x, src_id FROM rawmap LEFT JOIN datfiles ON datfiles.id=src_id GROUP BY src_id ORDER BY x DESC
Index: oup/current/text/_irf_oni.onlv.vb
===================================================================
--- oup/current/text/_irf_oni.onlv.vb	(revision 46)
+++ oup/current/text/_irf_oni.onlv.vb	(revision 46)
@@ -0,0 +1,545 @@
+Public Type LWOPolygon
+  NumVe As Integer
+  P1 As Integer
+  P2 As Integer
+  P3 As Integer
+  Surfa As Integer
+End Type
+
+Public Type PolDef
+  P1 As Integer
+  P2 As Integer
+  P3 As Integer
+End Type
+
+'Texture Coordinate Entry
+Public Type TXCAentry
+  X As Single
+  Y As Single
+End Type
+
+'Texture Coordinate Lists
+Public Type TXCA            'Length
+  ID As Long                '4
+  Version As Long           '8
+  Filler(1 To 5) As Long    '28
+  NumEntries As Long        '32
+End Type
+
+'Level Data Reference List
+Public Type ONLV            'Length
+  ID As Long                '4
+  Version As Long           '8
+  LevelName As String * 64  '72
+  AKEVid As Long            '76
+  OBOAid As Long            '80
+  ONMAid As Long            '84
+  ONFAid As Long            '88
+  ONTAid As Long            '92
+  ONSKid As Long            '96
+  Unkn As Long              '100
+  AISAid As Long            '104
+  AITRid As Long            '108
+  ONSAid As Long            '112
+  OBDCid As Long            '116
+  ONOAid As Long            '120
+  Fill(1 To 161) As Long    '764
+  CRSAid As Long            '768
+End Type
+
+Public Type AGQG
+  ID As Long
+  unk(1 To 24) As Byte
+  NumEntries As Long
+End Type
+
+Public Type AGQGEntry
+  VertIndex(1 To 4) As Long
+  VertUVIndex(1 To 4) As Long
+  LData_1(1 To 4) As Byte
+  LData_2(1 To 4) As Byte
+  LData_3(1 To 4) As Byte
+  LData_4(1 To 4) As Byte
+  unk(1 To 2) As Long
+End Type
+
+Public Type AGQREntry
+  TexIndex As Integer
+  unk As Integer
+End Type
+
+Public Type TXMA
+   ID As Long
+   shit(1 To 24) As Byte
+   NumEntries As Long
+End Type
+
+Public Type TXMAEntry
+   TXMP_ID As Long
+End Type
+
+
+
+
+
+Public Sub CExportONLV(Optional FileName As String)
+Form1.StatusBar1.SimpleText = "Status: Extracting LEVEL....."
+Dim ID4 As Long
+Dim I As Long
+Dim L As Long
+Dim LwoP() As LWOPolygon
+Dim OniPol2() As PolDef
+Dim NP As Long
+Dim numb As Long
+
+Dim TXMA1 As TXMA
+Dim AGQR1 As TXMA
+Dim TXCA1 As TXCA
+Dim TXCA_E() As TXCAentry
+Dim TXMA_E() As TXMAEntry
+Dim AGQR_E() As AGQREntry
+Dim TexNames() As String
+
+If FileName = "" Then
+  Form1.CD.DialogTitle = "Unpack resource..."
+  Form1.CD.FileName = OniEntry(Curr).szTagName
+  Form1.CD.Filter = "LightWave (*.lwo)|*.lwo"
+  Form1.CD.Flags = &H2 + &H4
+  Form1.CD.ShowSave
+  FileName = Form1.CD.FileName
+  If FileName = "" Then Exit Sub
+End If
+
+DoEvents
+
+Open DatFile For Binary As #1
+  Get 1, OniEntry(Curr).rDataPosition, ONLV
+  For I = 0 To UBound(OniEntry) - 1
+    Get 1, OniEntry(I).rDataPosition, ID4
+    If ID4 = ONLV.AKEVid Then
+      Get 1, OniEntry(I).rDataPosition, AKEV
+      Exit For
+    End If
+  Next I
+
+  'Find ID of PNTA
+  For I = 0 To UBound(OniEntry) - 1
+    Get 1, OniEntry(I).rDataPosition, ID4
+    If ID4 = AKEV.PNTAid Then
+       Get 1, OniEntry(I).rDataPosition, PNTA
+       ReDim PNTAentry(PNTA.NumEntries - 1)
+       Get 1, , PNTAentry
+       Exit For
+    End If
+  Next I
+
+  For I = 0 To UBound(OniEntry) - 1
+    Get 1, OniEntry(I).rDataPosition, ID4
+    If ID4 = AKEV.AGQGid Then
+       Get 1, OniEntry(I).rDataPosition, AGQG
+       ReDim AGQGEntry(AGQG.NumEntries - 1)
+       Get 1, , AGQGEntry
+       Exit For
+    End If
+  Next I
+
+  'TXCA
+  For I = 0 To UBound(OniEntry) - 1
+    Get 1, OniEntry(I).rDataPosition, ID4
+    If ID4 = AKEV.TXCAid Then
+       Get 1, OniEntry(I).rDataPosition, TXCA1
+       ReDim TXCA_E(TXCA1.NumEntries - 1)
+       Get 1, , TXCA_E
+       ReDim Preserve TXCA_E(PNTA.NumEntries - 1)
+       Exit For
+    End If
+  Next I
+
+  'TXMA
+  For I = 0 To UBound(OniEntry) - 1
+    Get 1, OniEntry(I).rDataPosition, ID4
+    If ID4 = AKEV.TXMAid Then
+       Get 1, OniEntry(I).rDataPosition, TXMA1
+       ReDim TXMA_E(TXMA1.NumEntries - 1)
+       Get 1, , TXMA_E
+       Exit For
+    End If
+  Next I
+
+  'AGQR
+  For I = 0 To UBound(OniEntry) - 1
+    Get 1, OniEntry(I).rDataPosition, ID4
+    If ID4 = AKEV.AGQRid Then
+       Get 1, OniEntry(I).rDataPosition, AGQR1
+       ReDim AGQR_E(AGQR1.NumEntries - 1)
+       Get 1, , AGQR_E
+       Exit For
+    End If
+  Next I
+
+  ReDim TexNames(TXMA1.NumEntries - 1)
+
+  For I = 0 To TXMA1.NumEntries - 1
+    For L = 0 To UBound(OniEntry) - 1
+      Get 1, OniEntry(L).rDataPosition, ID4
+      If ID4 = TXMA_E(I).TXMP_ID Then
+        TexNames(I) = OniEntry(L).szTagName + Ext
+        Exit For
+      End If
+    Next L
+  Next I
+
+Close
+'Ok
+' so we have: 3D points, Texture coordinates and list of polygons,
+' end reading, now convert data
+I = 0
+Open App.Path + "\lwo.tmp" For Binary As #11
+Form1.StatusBar1.SimpleText = "Status: Extracting LEVEL [Reading Polygons...]"
+Seek 11, 1
+
+'reading polygons.......
+
+NP = AGQG.NumEntries * 2
+For I = 0 To AGQG.NumEntries - 1
+Select Case GetPureFile(TexNames(AGQR_E(I).TexIndex))
+  Case "BLUEGRID02", "_DOOR_FRAME", "", "COLLISION"
+  NP = NP - 2
+  Case Else
+    Select Case Mid$(GetPureFile(TexNames(AGQR_E(I).TexIndex)), 1, 5)
+     Case "_DOOR"
+       NP = NP - 2
+     Case Else
+       Put 11, , TestSwapInt(AGQGEntry(I).VertIndex(1))
+       Put 11, , TestSwapInt(AGQGEntry(I).VertIndex(2))
+       Put 11, , TestSwapInt(AGQGEntry(I).VertIndex(3))
+       Put 11, , TestSwapInt(AGQGEntry(I).VertIndex(3))
+       Put 11, , TestSwapInt(AGQGEntry(I).VertIndex(4))
+       Put 11, , TestSwapInt(AGQGEntry(I).VertIndex(1))
+    End Select
+  End Select
+Next I
+
+
+
+ReDim OniPol2(NP - 1)
+ReDim LwoP(NP - 1)
+Get 11, 1, OniPol2
+
+For I = 0 To NP - 1
+  LwoP(I).NumVe = ISItoMSI(3)
+  LwoP(I).P1 = OniPol2(I).P1
+  LwoP(I).P2 = OniPol2(I).P2
+  LwoP(I).P3 = OniPol2(I).P3
+  LwoP(I).Surfa = ISItoMSI(1)
+Next I
+
+I = Empty
+
+Close
+
+On Error Resume Next
+  Kill App.Path + "\*.tmp"
+On Error GoTo 0
+
+Form1.StatusBar1.SimpleText = "Status: Extracting LEVEL [Writing...]"
+Form1.ProgressBar1.Max = PNTA.NumEntries
+Form1.ProgressBar1.Value = 0
+If LevelType = 5 Or LevelType = 10 Then
+  FileName = GetPureFile(FileName) + ".raw"
+End If
+
+For I = 0 To PNTA.NumEntries - 1
+   If PNTAentry(I).X > 2000000.1 Then PNTAentry(I).X = 0
+   If PNTAentry(I).Y > 2000000.1 Then PNTAentry(I).Y = 0
+   If PNTAentry(I).Z > 2000000.1 Then PNTAentry(I).Z = 0
+   If PNTAentry(I).X < -2000000.1 Then PNTAentry(I).X = 0
+   If PNTAentry(I).Y < -2000000.1 Then PNTAentry(I).Y = 0
+   If PNTAentry(I).Z < -2000000.1 Then PNTAentry(I).Z = 0
+Next I
+
+Select Case LevelType
+Case 1
+
+Open FileName For Binary As #1
+  Put 1, , "FORM"
+  Put 1, , ISLtoMSL(12 + (PNTA.NumEntries * 12) + 8 + 6 + 8 + (NP * 10))
+  Put 1, , "LWOBPNTS"
+  Put 1, , ISLtoMSL(PNTA.NumEntries * 12)
+  For I = 0 To PNTA.NumEntries - 1
+    Put 1, , SwapFloat(PNTAentry(I).X)
+    Put 1, , SwapFloat(PNTAentry(I).Y)
+    Put 1, , SwapFloat(PNTAentry(I).Z)
+    Form1.ProgressBar1.Value = I
+  Next I
+  Put 1, , "SRFS"
+  Put 1, , ISLtoMSL(6)
+  Put 1, , "Level"
+  Put 1, , CByte(0)
+  Put 1, , "POLS"
+  Put 1, , ISLtoMSL(NP * 10)
+  Put 1, , LwoP
+Close
+Case 6
+
+' Convert Oni level to RAW 3D Binary
+Open GetPureFile(FileName) + ".rwb" For Binary As #1
+For I = 0 To AGQG.NumEntries - 1
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(1)).X
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(1)).Y
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(1)).Z
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(2)).X
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(2)).Y
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(2)).Z
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(3)).X
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(3)).Y
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(3)).Z
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(3)).X
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(3)).Y
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(3)).Z
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(4)).X
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(4)).Y
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(4)).Z
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(1)).X
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(1)).Y
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(1)).Z
+Next I
+
+Close
+Case 7
+
+' B3D
+Open GetPureFile(FileName) + ".b3d" For Binary As #1
+Put 1, , "Big3DbyOleg"
+Put 1, , CLng(1067030938)
+Put 1, , "POINTS  "
+Put 1, , CLng(PNTA.NumEntries)
+For I = 0 To PNTA.NumEntries - 1
+  Put 1, , PNTAentry(I).X
+  Put 1, , PNTAentry(I).Y
+  Put 1, , PNTAentry(I).Z
+Next I
+
+Put 1, , "POLYGONS"
+Put 1, , CLng(NP * 2)
+For I = 0 To AGQG.NumEntries - 1
+Select Case GetPureFile(TexNames(AGQR_E(I).TexIndex))
+  Case "BLUEGRID02", "_DOOR_FRAME", "", "COLLISION"
+    'nothing
+  Case Else
+    Select Case Mid$(GetPureFile(TexNames(AGQR_E(I).TexIndex)), 1, 5)
+     Case "_DOOR"
+       'nothing
+     Case Else
+       Put 1, , CLng(3)
+       Put 1, , AGQGEntry(I).VertIndex(1)
+       Put 1, , AGQGEntry(I).VertIndex(2)
+       Put 1, , AGQGEntry(I).VertIndex(3)
+       Put 1, , CLng(0)
+       Put 1, , CLng(3)
+       Put 1, , AGQGEntry(I).VertIndex(3)
+       Put 1, , AGQGEntry(I).VertIndex(4)
+       Put 1, , AGQGEntry(I).VertIndex(1)
+       Put 1, , CLng(0)
+    End Select
+End Select
+Next I
+Put 1, , CLng(0)
+Close
+
+Case 8
+
+'Delete shit from the Oni level
+numb = AGQG.NumEntries
+   ReDim Preserve PNTAentry(PNTA.NumEntries + 3)
+   PNTAentry(PNTA.NumEntries + 0).X = -9
+   PNTAentry(PNTA.NumEntries + 0).Y = 0
+   PNTAentry(PNTA.NumEntries + 0).Z = -3
+   PNTAentry(PNTA.NumEntries + 1).X = -9
+   PNTAentry(PNTA.NumEntries + 1).Y = 0
+   PNTAentry(PNTA.NumEntries + 1).Z = 8
+   PNTAentry(PNTA.NumEntries + 2).X = 11
+   PNTAentry(PNTA.NumEntries + 2).Y = 0
+   PNTAentry(PNTA.NumEntries + 2).Z = -3
+   PNTAentry(PNTA.NumEntries + 3).X = 11
+   PNTAentry(PNTA.NumEntries + 3).Y = 0
+   PNTAentry(PNTA.NumEntries + 3).Z = 8
+
+   If Form1.mnuDelGarbage.Checked = True Then
+   For I = 0 To AGQG.NumEntries - 1
+     Select Case Mid$(GetPureFile(TexNames(AGQR_E(I).TexIndex)), 1, 5)
+     Case "_DOOR"
+        AGQGEntry(I).VertIndex(1) = PNTA.NumEntries + 0
+        AGQGEntry(I).VertIndex(2) = PNTA.NumEntries + 1
+        AGQGEntry(I).VertIndex(3) = PNTA.NumEntries + 2
+        AGQGEntry(I).VertIndex(4) = PNTA.NumEntries + 3
+        'numb = numb - 1
+     End Select
+   Next I
+   End If
+
+   For I = 0 To AGQG.NumEntries - 1
+     Select Case GetPureFile(TexNames(AGQR_E(I).TexIndex))
+     Case "BLUEGRID02", "_DOOR_FRAME", "", "COLLISION"
+        AGQGEntry(I).VertIndex(1) = PNTA.NumEntries + 0
+        AGQGEntry(I).VertIndex(2) = PNTA.NumEntries + 1
+        AGQGEntry(I).VertIndex(3) = PNTA.NumEntries + 2
+        AGQGEntry(I).VertIndex(4) = PNTA.NumEntries + 3
+        numb = numb - 1
+     End Select
+   Next I
+
+'B3D + materials
+Open GetPureFile(FileName) + ".b3d" For Binary As #1
+Put 1, , "Big3DbyOleg"
+Put 1, , CLng(1067030938)
+Put 1, , "POINTS  "
+Put 1, , CLng(numb * 4)
+
+For I = 0 To AGQG.NumEntries - 1
+  ' Begin polygon
+Select Case GetPureFile(TexNames(AGQR_E(I).TexIndex))
+ Case "BLUEGRID02", "_DOOR_FRAME", "", "COLLISION"
+  'nothing
+ Case Else
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(1)).X
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(1)).Y
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(1)).Z
+
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(2)).X
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(2)).Y
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(2)).Z
+
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(3)).X
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(3)).Y
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(3)).Z
+
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(4)).X
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(4)).Y
+  Put 1, , PNTAentry(AGQGEntry(I).VertIndex(4)).Z
+End Select
+  ' end polygon
+Next I
+
+Put 1, , "POLYGONS"
+Put 1, , CLng(numb * 2)
+L = 0
+ID4 = 0
+For I = 0 To AGQG.NumEntries - 1
+Select Case GetPureFile(TexNames(AGQR_E(I).TexIndex))
+ Case "BLUEGRID02", "_DOOR_FRAME", "", "COLLISION"
+  'nothing
+ Case Else
+  Put 1, , CLng(3)
+  Put 1, , CLng(L)
+  Put 1, , CLng(L + 1)
+  Put 1, , CLng(L + 2)
+  Put 1, , CLng(ID4)
+  Put 1, , CLng(3)
+  Put 1, , CLng(L + 2)
+  Put 1, , CLng(L + 3)
+  Put 1, , CLng(L)
+  Put 1, , CLng(ID4)
+  ID4 = ID4 + 1
+  L = L + 4
+End Select
+Next I
+
+Put 1, , CLng(1)
+Put 1, , "TEX_UV  "
+Put 1, , CLng(numb * 4)
+L = 0
+
+For I = 0 To AGQG.NumEntries - 1
+Select Case GetPureFile(TexNames(AGQR_E(I).TexIndex))
+ Case "BLUEGRID02", "_DOOR_FRAME", "", "COLLISION"
+  'nothing
+ Case Else
+  Put 1, , CLng(L)
+  L = L + 1
+  Put 1, , TXCA_E(AGQGEntry(I).VertUVIndex(1)).X
+  Put 1, , TXCA_E(AGQGEntry(I).VertUVIndex(1)).Y
+  Put 1, , CLng(L)
+  L = L + 1
+  Put 1, , TXCA_E(AGQGEntry(I).VertUVIndex(2)).X
+  Put 1, , TXCA_E(AGQGEntry(I).VertUVIndex(2)).Y
+  Put 1, , CLng(L)
+  L = L + 1
+  Put 1, , TXCA_E(AGQGEntry(I).VertUVIndex(3)).X
+  Put 1, , TXCA_E(AGQGEntry(I).VertUVIndex(3)).Y
+  Put 1, , CLng(L)
+  L = L + 1
+  Put 1, , TXCA_E(AGQGEntry(I).VertUVIndex(4)).X
+  Put 1, , TXCA_E(AGQGEntry(I).VertUVIndex(4)).Y
+End Select
+  'Put 1, , CSng((-TXCA_E(I).Y) + 1)
+Next I
+
+L = 0
+Put 1, , "MATERIAL"
+Put 1, , CLng(numb)
+For I = 0 To AGQG.NumEntries - 1
+Select Case GetPureFile(TexNames(AGQR_E(I).TexIndex))
+ Case "BLUEGRID02", "_DOOR_FRAME", "", "COLLISION"
+  'nothing
+ Case Else
+  Put 1, , CLng(1)
+  Put 1, , CLng(L)
+  Put 1, , CLng(Len(TexNames(AGQR_E(I).TexIndex)))
+  Put 1, , TexNames(AGQR_E(I).TexIndex)
+  L = L + 1
+End Select
+Next I
+Close
+
+Open GetPureFile(FileName) + ".tlist" For Binary As #4
+  For I = 0 To AGQR1.NumEntries - 1
+  Select Case GetPureFile(TexNames(AGQR_E(I).TexIndex))
+  Case "BLUEGRID02", "_DOOR_FRAME", "", "COLLISION"
+   'nothing
+  Case Else
+    Put 4, , AGQR_E(I).TexIndex
+  End Select
+  Next I
+Close
+
+Open GetPureFile(FileName) + ".txt" For Output As #4
+  Print #4, CStr(TXMA1.NumEntries)
+  For I = 0 To TXMA1.NumEntries - 1
+    Print #4, CStr(GetPureFile(TexNames(I)))
+  Next I
+Close
+
+If Form1.mnuB3DLight.Checked = True Then
+Open GetPureFile(FileName) + ".ltcs" For Binary As #4
+  For I = 0 To AGQR1.NumEntries - 1
+  Select Case GetPureFile(TexNames(AGQR_E(I).TexIndex))
+  Case "BLUEGRID02", "_DOOR_FRAME", "", "COLLISION"
+   'nothing
+  Case Else
+    Put 4, , AGQGEntry(I).LData_1
+    Put 4, , AGQGEntry(I).LData_2
+    Put 4, , AGQGEntry(I).LData_3
+    Put 4, , AGQGEntry(I).LData_4
+  End Select
+  Next I
+Close
+End If
+End Select
+
+Form1.ProgressBar1.Value = 0
+Form1.ProgressBar1.Max = UBound(OniEntry)
+
+Form1.StatusBar1.SimpleText = "OK"
+'Dispose
+I = Empty
+NP = Empty
+Erase LwoP
+Erase PNTAentry
+Erase OniPol2
+Erase AGQGEntry
+Erase AGQR_E
+Erase TXMA_E
+Erase TXCA_E
+Erase TexNames
+End Sub
Index: oup/current/text/blubb.txt
===================================================================
--- oup/current/text/blubb.txt	(revision 46)
+++ oup/current/text/blubb.txt	(revision 46)
@@ -0,0 +1,6 @@
+___FILEINDEX___.txt
+
+
+TXMP:
+MipMapping: Bit0=an/aus
+ColorDepth: Bit0=??AnimationPic??, Bit1=shade vertex, Bit2=transparency, Bit4=16bit, Bit5=32bit
Index: oup/current/text/changelog.txt
===================================================================
--- oup/current/text/changelog.txt	(revision 46)
+++ oup/current/text/changelog.txt	(revision 46)
@@ -0,0 +1,114 @@
+OniUnPacker v0.32a
+------------------
++DB2Dat functionality enhanced (*can* be used but is not yet finished)
++PSpc Preview added (but not yet working cause of some weird bugs)
+
+OniUnPacker v0.32a
+------------------
++Raw-part "BodyPartAnimation data" of TRAMs
++Added basic DB2Dat functionality (SHOULD NOT BE USED YET!!!)
++CharSet selection (works for ValueViewer only right now)
+
+OniUnPacker v0.31a
+------------------
++Dat2DB function working
++Fixed a bug which appeared when multiple windows of the same class were opened at one time (eg 2*BinEdit)
+
+OniUnPacker v0.30a
+------------------
++Completely rewritten data-backend-connection-classes (Unit15_Classes.pas)
+
+OniUnPacker v0.29a
+------------------
++Little changes in StructureDefs
+
+OniUnPacker v0.29a
+------------------
++New StructureViewer
++New StructureTypes: 12=.dat-file-ID, 13..16=SignedInteger, 1000..9999=Unused data
++Dynamic Structures (look at TXAN-files or AISA-files for examples)
++File-type associations (.dat, .oldb, .opf) with OUP possible
++File IDs as Hex
+
+OniUnPacker v0.28a
+------------------
++StructureDefinitions as separate txt-files
++Minor bugfixes
++Ctrl+C for Hex-fields
+
+OniUnPacker v0.27a
+------------------
++Added MAC-file support
++Added StructureDefs for ONCCs / TRAMs (thanks to SSG)
+
+OniUnPacker v0.26a
+------------------
++Fixed some bugs again ;)
+
+OniUnPacker v0.25a
+------------------
++Fixed some bugs here and there ;)
++BinEdit/RawEdit: Added keycombo CTRL+S for saving current file
+
+OniUnPacker v0.24a
+------------------
++RawEdit. Open it by doubleclick on a Raw-Link in the StructureViewer of BinEdit or enter the FileID and the offset of the raw-link in the .dat-file manually
+
+OniUnPacker v0.23a
+------------------
++Added copy2clipboard functions to ValueViewer (rightclick)
++Enhanced FileList-filters
++Added ValueEditor to BinEdit -> StructViewer / ValueViewer (doubleclick on either value field of ValueViewer or StructViewer)
+
+OniUnPacker v0.22a
+------------------
++Replaced DB-Backend (much faster conversion of levels)
++Added ValueViewer to BinEdit (decodes selected area as different variable-types)
+
+OniUnPacker v0.21a
+------------------
++Extractor tool works almost completely (you can't select where the files are stored if you *don't* choose to put them all in one file. They are stored in the root of drive d:)
++Corrected string-display in the structure viewer of BinEdit (strings are now displayed as a hint of the value-box if you move the mouse over it)
+
+OniUnPacker v0.20a
+------------------
++? (Forgot what I added here ;) )
+
+OniUnPacker v0.19a
+------------------
++.dat/.raw -> OUP-Level-DB-Convert basics
++Extractor tool (not working yet :D )
+
+OniUnPacker v0.18a
+------------------
++Completely rewritten GUI
+
+OniUnPacker v0.17a
+------------------
++Binary-editor: Structure-viewer (only TXMP so far)
+
+OniUnPacker v0.16a
+------------------
++Replaced hex-view-box with a true hex-component
++Binary-editor for .dat-files
+
+OniUnPacker v0.15a
+------------------
++Extract menu
++Changed layout
+
+OniUnPacker v0.14a
+------------------
++Corrected image-decoder for 32bit images
++TXMP-Replace: 32bit option (for prevention from quality loss)
+
+OniUnPacker v0.13a
+------------------
++TXMP-Replace: Transparency option
++TXMP-Replace: Fading option
++TXMP-Replace: Overwrites old data if the new fits in that space (to keep the raw as small as possible)
+
+OniUnPacker v0.12a
+------------------
++TXMP-Replace function (Menu -> Tools -> TXMP Replacer)
++TXMB-Decoder (export with convert & preview)
Index: oup/current/text/selects.txt
===================================================================
--- oup/current/text/selects.txt	(revision 46)
+++ oup/current/text/selects.txt	(revision 46)
@@ -0,0 +1,3 @@
+SELECT (datfiles.name || "." || datfiles.extension) AS name, count(src_id) AS x, src_id FROM linkmap LEFT JOIN datfiles ON datfiles.id=src_id GROUP BY src_id ORDER BY x DESC
+
+SELECT (datfiles.name || "." || datfiles.extension) AS name, count(src_id) AS x, src_id FROM rawmap LEFT JOIN datfiles ON datfiles.id=src_id GROUP BY src_id ORDER BY x DESC
Index: oup/current/text/todo.txt
===================================================================
--- oup/current/text/todo.txt	(revision 46)
+++ oup/current/text/todo.txt	(revision 46)
@@ -0,0 +1,79 @@
+-Non32bit MipMapping (???)
+-32byte paddings
+
+-Compo: TBitSetEdit mit 8 CheckBoxes + Captions
+-ValueEdit: TBitSetEdit
+
+-StructViewer: TBitSetEdit?
+-Structs: Nach Paketen wieder Global?
+-Idents: Unterschied für Sep-Linked und SNDD
+-NamedLinks: Überprüfung auf 0 files? (level0.dat)
+-Links: Wenn level0 dann OUP mit level0 laden?
+
+-History:Geyser:14.04.06 15:11:45, 16.04.06 15:21:29
+-Patching: History Geyser 2006-04-30 - 04:07:00
+
+-RawParts: AGDB immer 32 bytes
+
+-Signed vs Unsigned
+
+-PNG statt/zusätzlich zu BMP
+
+-AppSettings: Erst initialisieren mit defaults, dann .ini lesen
+
+-Exporters (-> TOniImage etc)
+
+-Wiki etc: Links für benutzte Componenten
+-SourceCode docu (eg: http://www.time2help.com/)
+-ProgHelp
+-Localization (eg: http://dybdahl.dk/dxgettext/)
+-About
+
+-StructViewer: Strings bis 0x00, BitSets besser darstellen? (SSG: 18.04.06/10:52:58),
+  Dat-Link value="Not used" wenn not-used, SUBT-Packages: Value=0???,
+  file-ID-value dblclick=edit / anderes=follow,
+  "typed"-file-id-links?,
+  0 packages -> crash?
+
+-Dateityp-Name anzeigen (SUBT -> Subtitles etc)
+
+-IGSt: Bei DEAD: OUP hangs (ValueViewer:String?)
+
+-Bug bei SetNewValue mit String
+
+-Preview PSpc (!!!)
+-Preview: Models? 3D-Data?
+
+-Get files die bestimmten content haben (string etc)
+
+-Cursor Sanduhr bei Wartezeiten (db-access etc)
+
+-RawMap: was ist laut link+size used bereich, was nicht
+-StructViewer Raw: DynamicInfos aus .dat
+
+-Exporter: Checkboxes für was man im einzelnen will (zb Checkbox "in eine Datei ja/nein")
+-Extrahier-Ordner-Option (mit Platzhalter für .dat-Name)
+-Extractor: Wohin?
+
+-Hex: Paste
+
+-Persist.dat editor
+
+
+
+-SELECT [src_id],MIN(datfiles.[name]),SUM(rawmap.[size]) FROM rawmap INNER  JOIN datfiles ON datfiles.[id]=[src_id] GROUP BY [src_id] ORDER BY [src_id] ASC
+
+
+-BinEdit: Zusatzfunktionen wie: Suche, 
+
+-FileCompare: Ergebnis=Tabelle, jede Zeile eine differenz-addresse, spalten = werte an addr. für compared files
+
+-TXMP-Replace: MultiReplace
+
+-Move-Freischalter (Mindestlvl eingabe)
+
+-Löschen einer Datei auf die gelinkt wird: Liste der Links und sicherheitsfrage
+
+-STRG+C auf Dateilisten etc für kopieren des Namens
+
+-REPACKING: testen lvl0: 690-collisions.txmp einbauen, script: collisions-zeug
Index: oup/current/todo.txt
===================================================================
--- oup/current/todo.txt	(revision 45)
+++ 	(revision )
@@ -1,96 +1,0 @@
--DatLinks patchen
--Non32bit MipMapping (???)
--32byte paddings
-
--BinEdit: wenn Backend=ADB: erste 8 Bytes nicht aus file sondern aus fileID+levelID der Connection
--TOniConnectionADB: FileList cachen!
--TOniConnectionADB: AddFile, SetLevelID, etc
-
--Compo: TBitSetEdit mit 8 CheckBoxes + Captions
--ValueEdit: TBitSetEdit
-
--StructViewer: TBitSetEdit?
--Structs: Nach Paketen wieder Global?
--Idents: Unterschied für Sep-Linked und SNDD
--NamedLinks: Überprüfung auf 0 files? (level0.dat)
--Links: Wenn level0 dann OUP mit level0 laden?
-
--History:Geyser:14.04.06 15:11:45, 16.04.06 15:21:29
--Patching: History Geyser 2006-04-30 - 04:07:00
-
--Exports: FileExists => Abfrage
--Export etc: If dest-file exists zZt anhängen, stattdessen neuschreiben?!
--Export: dat+raw eines Files in eine datei
-
--TOniImage: Statt Floor (bei farben) Round
-
--RawParts: AGDB immer 32 bytes
-
--DatEdit: Komplette .dat im Hex + Treeview der verschiedenen Parts etc
-
--Signed vs Unsigned
-
--PNG statt/zusätzlich zu BMP
-
--AppSettings: Erst initialisieren mit defaults, dann .ini lesen
-
--Exporters (-> TOniImage etc)
-
--Wiki etc: Links für benutzte Componenten
--SourceCode docu (eg: http://www.time2help.com/)
--ProgHelp
--Localization (eg: http://dybdahl.dk/dxgettext/)
--About
-
--StructViewer: Strings bis 0x00, BitSets besser darstellen? (SSG: 18.04.06/10:52:58),
-  Dat-Link value="Not used" wenn not-used, SUBT-Packages: Value=0???,
-  file-ID-value dblclick=edit / anderes=follow,
-  "typed"-file-id-links?,
-  0 packages -> crash?
-
--Floats: "." statt ","?
-
--Preview: Export?
-
--Dateityp-Name anzeigen (SUBT -> Subtitles etc)
-
--IGSt: Bei DEAD: OUP hangs (ValueViewer:String?)
-
--Bug bei SetNewValue mit String
-
--Preview PSpc (!!!)
--Preview: Models? 3D-Data?
-
--Get files die bestimmten content haben (string etc)
-
--Cursor Sanduhr bei Wartezeiten (db-access etc)
-
--RawMap: was ist laut link+size used bereich, was nicht
--StructViewer Raw: DynamicInfos aus .dat
-
--Exporter: Checkboxes für was man im einzelnen will (zb Checkbox "in eine Datei ja/nein")
--Extrahier-Ordner-Option (mit Platzhalter für .dat-Name)
--Extractor: Wohin?
-
--Hex: Paste
-
--Persist.dat editor
-
-
-
--SELECT [src_id],MIN(datfiles.[name]),SUM(rawmap.[size]) FROM rawmap INNER  JOIN datfiles ON datfiles.[id]=[src_id] GROUP BY [src_id] ORDER BY [src_id] ASC
-
-
--BinEdit: Zusatzfunktionen wie: Suche, 
-
--FileCompare: Ergebnis=Tabelle, jede Zeile eine differenz-addresse, spalten = werte an addr. für compared files
-
--TXMP-Replace: MultiReplace
-
--Move-Freischalter (Mindestlvl eingabe)
-
--Löschen einer Datei auf die gelinkt wird: Liste der Links und sicherheitsfrage
-
--STRG+C auf Dateilisten etc für kopieren des Namens
-
--REPACKING: testen lvl0: 690-collisions.txmp einbauen, script: collisions-zeug
