DEADSOFTWARE

no more old mapreader: use textmap reader both for text and for binary maps
authorKetmar Dark <ketmar@ketmar.no-ip.org>
Wed, 30 Aug 2017 01:27:34 +0000 (04:27 +0300)
committerKetmar Dark <ketmar@ketmar.no-ip.org>
Wed, 30 Aug 2017 01:28:16 +0000 (04:28 +0300)
28 files changed:
src/engine/e_graphics.pas
src/game/Doom2DF.dpr
src/game/g_game.pas
src/game/g_gui.pas
src/game/g_holmes.pas
src/game/g_main.pas
src/game/g_map.pas
src/game/g_menu.pas
src/game/g_monsters.pas
src/game/g_panel.pas
src/game/g_phys.pas
src/game/g_player.pas
src/game/g_playermodel.pas
src/game/g_saveload.pas
src/game/g_textures.pas
src/game/g_triggers.pas
src/game/g_weapons.pas
src/shared/MAPDEF.pas
src/shared/MAPREADER.pas [deleted file]
src/shared/MAPSTRUCT.pas [deleted file]
src/shared/mapdef.inc [new file with mode: 0644]
src/shared/mapdef.txt
src/shared/mapstructio.inc [deleted file]
src/shared/mapstructsizes.inc [deleted file]
src/shared/wadreader.pas
src/shared/xdynrec.pas
src/shared/xparser.pas
src/shared/zmapgen.dpr [new file with mode: 0644]

index 83664b1c0050562fd35ae231ffcf7567d18273e9..b7ddd2c5f06a46d8834afe1dcce0cbb54964aa3a 100644 (file)
@@ -29,9 +29,6 @@ type
     X, Y: Integer;
   end;
 
-  TPoint = MAPDEF.TPoint; // TODO: create an utiltypes.pas or something
-                          //       for other types like rect as well
-
   TPoint2f = record
     X, Y: Double;
   end;
@@ -49,7 +46,7 @@ type
    R, G, B: Byte;
   end;
 
-  PPoint = ^TPoint;
+  PDFPoint = ^TDFPoint;
   PPoint2f = ^TPoint2f;
   PRect = ^TRect;
   PRectWH = ^TRectWH;
@@ -65,7 +62,7 @@ procedure e_ResizeWindow(Width, Height: Integer);
 procedure e_Draw(ID: DWORD; X, Y: Integer; Alpha: Byte; AlphaChannel: Boolean;
                  Blending: Boolean; Mirror: TMirrorType = M_NONE);
 procedure e_DrawAdv(ID: DWORD; X, Y: Integer; Alpha: Byte; AlphaChannel: Boolean;
-                    Blending: Boolean; Angle: Single; RC: PPoint; Mirror: TMirrorType = M_NONE);
+                    Blending: Boolean; Angle: Single; RC: PDFPoint; Mirror: TMirrorType = M_NONE);
 procedure e_DrawSize(ID: DWORD; X, Y: Integer; Alpha: Byte; AlphaChannel: Boolean;
                      Blending: Boolean; Width, Height: Word; Mirror: TMirrorType = M_NONE);
 procedure e_DrawSizeMirror(ID: DWORD; X, Y: Integer; Alpha: Byte; AlphaChannel: Boolean;
@@ -683,7 +680,7 @@ begin
 end;
 
 procedure e_DrawAdv(ID: DWORD; X, Y: Integer; Alpha: Byte; AlphaChannel: Boolean;
-                    Blending: Boolean; Angle: Single; RC: PPoint; Mirror: TMirrorType = M_NONE);
+                    Blending: Boolean; Angle: Single; RC: PDFPoint; Mirror: TMirrorType = M_NONE);
 begin
   if e_NoGraphics then Exit;
 
index bfd07a5b8f15c1a6668a003710606823d283b118..a66e792b6e38d9f44e537b7ac95d34254e571787 100644 (file)
@@ -59,8 +59,6 @@ uses
   sfsPlainFS in '../sfs/sfsPlainFS.pas',
   sfsZipFS in '../sfs/sfsZipFS.pas',
   wadreader in '../shared/wadreader.pas',
-  MAPSTRUCT in '../shared/MAPSTRUCT.pas',
-  MAPREADER in '../shared/MAPREADER.pas',
   MAPDEF in '../shared/MAPDEF.pas',
   CONFIG in '../shared/CONFIG.pas',
   g_basic in 'g_basic.pas',
index 93368940da0d943a1223f77191f923c7432b5bfd..1cf480864080a2c4115db2cae221b07de7e16299 100644 (file)
@@ -20,7 +20,7 @@ interface
 
 uses
   g_basic, g_player, e_graphics, Classes, g_res_downloader,
-  SysUtils, g_sound, g_gui, MAPSTRUCT, wadreader, md5, xprofiler;
+  SysUtils, g_sound, g_gui, MAPDEF, wadreader, md5, xprofiler;
 
 type
   TGameSettings = record
@@ -63,7 +63,7 @@ type
 
   THearPoint = record
     Active: Boolean;
-    Coords: TPoint;
+    Coords: TDFPoint;
   end;
 
 function  g_Game_IsNet(): Boolean;
@@ -209,9 +209,9 @@ var
   gPlayer1Settings: TPlayerSettings;
   gPlayer2Settings: TPlayerSettings;
   gGameOn: Boolean;
-  gPlayerScreenSize: TPoint;
-  gPlayer1ScreenCoord: TPoint;
-  gPlayer2ScreenCoord: TPoint;
+  gPlayerScreenSize: TDFPoint;
+  gPlayer1ScreenCoord: TDFPoint;
+  gPlayer2ScreenCoord: TDFPoint;
   gPlayer1: TPlayer = nil;
   gPlayer2: TPlayer = nil;
   gPlayerDrawn: TPlayer = nil;
@@ -338,7 +338,7 @@ uses
   g_textures, g_main, g_window, g_menu,
   e_input, e_log, g_console, g_items, g_map, g_panel,
   g_playermodel, g_gfx, g_options, g_weapons, Math,
-  g_triggers, MAPDEF, g_monsters, e_sound, CONFIG,
+  g_triggers, g_monsters, e_sound, CONFIG,
   BinEditor, g_language, g_net, SDL,
   ENet, e_msg, g_netmsg, g_netmaster, GL, GLExt,
   utils, sfs, g_holmes;
@@ -5017,7 +5017,7 @@ procedure DebugCommands(P: SArray);
 var
   a, b: Integer;
   cmd: string;
-  //pt: TPoint;
+  //pt: TDFPoint;
   mon: TMonster;
 begin
 // Êîìàíäû îòëàäî÷íîãî ðåæèìà:
index 5c60e10d77ec9a8ce97bea6abc446b984350034d..45b2364f8adba30e40aa89565fc3648bfd26e24a 100644 (file)
@@ -19,7 +19,7 @@ unit g_gui;
 interface
 
 uses
-  e_graphics, e_input, e_log, g_playermodel, g_basic, MAPSTRUCT, wadreader;
+  e_graphics, e_input, e_log, g_playermodel, g_basic, MAPDEF, wadreader;
 
 const
   MAINMENU_HEADER_COLOR: TRGB = (R:255; G:255; B:255);
@@ -348,7 +348,7 @@ type
   TGUIMapPreview = class(TGUIControl)
   private
     FMapData: array of TPreviewPanel;
-    FMapSize: TPoint;
+    FMapSize: TDFPoint;
     FScale: Single;
   public
     constructor Create();
@@ -546,8 +546,8 @@ implementation
 
 uses
   GL, GLExt, g_textures, g_sound, SysUtils,
-  g_game, Math, StrUtils, g_player, g_options, MAPREADER,
-  g_map, MAPDEF, g_weapons;
+  g_game, Math, StrUtils, g_player, g_options,
+  g_map, g_weapons, xdynrec;
 
 var
   Box: Array [0..8] of DWORD;
@@ -2775,7 +2775,7 @@ end;
 procedure TGUIMapPreview.SetMap(Res: string);
 var
   WAD: TWADFile;
-  MapReader: TMapReader_1;
+  //MapReader: TMapReader_1;
   panels: TPanelsRec1Array;
   header: TMapHeaderRec_1;
   a: Integer;
@@ -2783,7 +2783,13 @@ var
   Data: Pointer;
   Len: Integer;
   rX, rY: Single;
+  map: TDynRecord = nil;
 begin
+  FMapSize.X := 0;
+  FMapSize.Y := 0;
+  FScale := 0.0;
+  FMapData := nil;
+
   FileName := g_ExtractWadName(Res);
 
   WAD := TWADFile.Create();
@@ -2802,8 +2808,15 @@ begin
 
   WAD.Free();
 
-  MapReader := TMapReader_1.Create();
+  try
+    map := g_Map_ParseMap(Data, Len);
+  except
+    map.Free();
+    raise;
+  end;
 
+  {
+  MapReader := TMapReader_1.Create();
   if not MapReader.LoadMap(Data) then
   begin
     FreeMem(Data);
@@ -2814,11 +2827,12 @@ begin
     FMapData := nil;
     Exit;
   end;
+  }
 
   FreeMem(Data);
 
-  panels := MapReader.GetPanels();
-  header := MapReader.GetMapHeader();
+  panels := GetPanels(map);
+  header := GetMapHeader(map);
 
   FMapSize.X := header.Width div 16;
   FMapSize.Y := header.Height div 16;
@@ -2863,7 +2877,8 @@ begin
 
   panels := nil;
 
-  MapReader.Free();
+  //MapReader.Free();
+  map.Free();
 end;
 
 procedure TGUIMapPreview.ClearMap();
index ae7c7b49e67e8c629b8fa7a2f28772048e3c5339..dfa8a00c5bb6eb86df978e88a432af2ad1bd7628 100644 (file)
@@ -102,7 +102,7 @@ implementation
 
 uses
   SysUtils, Classes, GL, SDL2,
-  MAPDEF, g_options, utils, hashtable, xparser;
+  MAPDEF, g_main, g_options, utils, hashtable, xparser;
 
 
 var
@@ -1206,7 +1206,7 @@ begin
 
     // load bindings from file
     try
-      st := openDiskFileRO('holmes.rc');
+      st := openDiskFileRO(GameDir+'holmes.rc');
       pr := TFileTextParser.Create(st);
       conwriteln('parsing "holmes.rc"...');
       while (pr.tokType <> pr.TTEOF) do
index 7864bedebfd18c005a89a1e1c7003f51d39cb3d2..1b131f14e7bec2d12111b4487525f4a7232c5916 100644 (file)
@@ -40,7 +40,7 @@ uses
   e_graphics, e_input, g_game, g_console, g_gui,
   e_sound, g_options, g_sound, g_player,
   g_weapons, SysUtils, g_triggers, MAPDEF, g_map,
-  MAPSTRUCT, g_menu, g_language, g_net,
+  g_menu, g_language, g_net,
   utils, conbuf, envvars;
 
 var
index 4bb340d1026a97f86893f6843e0f0f3dfb93a61a..924dc000ada380a2b1b7a9010bffa327148b06fa 100644 (file)
@@ -20,8 +20,8 @@ unit g_map;
 interface
 
 uses
-  e_graphics, g_basic, MAPSTRUCT, g_textures, Classes,
-  g_phys, wadreader, BinEditor, g_panel, g_grid, md5, binheap, xprofiler;
+  e_graphics, g_basic, MAPDEF, g_textures, Classes,
+  g_phys, wadreader, BinEditor, g_panel, g_grid, md5, binheap, xprofiler, xparser, xdynrec;
 
 type
   TMapInfo = record
@@ -115,6 +115,17 @@ procedure g_Map_ProfilersBegin ();
 procedure g_Map_ProfilersEnd ();
 
 
+function g_Map_ParseMap (data: Pointer; dataLen: Integer): TDynRecord;
+
+const
+  NNF_NO_NAME         = 0;
+  NNF_NAME_BEFORE     = 1;
+  NNF_NAME_EQUALS     = 2;
+  NNF_NAME_AFTER      = 3;
+
+function g_Texture_NumNameFindStart(name: String): Boolean;
+function g_Texture_NumNameFindNext(var newName: String): Byte;
+
 const
   RESPAWNPOINT_PLAYER1 = 1;
   RESPAWNPOINT_PLAYER2 = 2;
@@ -178,7 +189,7 @@ var
   gFlags: array [FLAG_RED..FLAG_BLUE] of TFlag;
   //gDOMFlags: array of TFlag;
   gMapInfo: TMapInfo;
-  gBackSize: TPoint;
+  gBackSize: TDFPoint;
   gDoorMap: array of array of DWORD;
   gLiftMap: array of array of DWORD;
   gWADHash: TMD5Digest;
@@ -206,9 +217,9 @@ implementation
 uses
   g_main, e_log, SysUtils, g_items, g_gfx, g_console,
   GL, GLExt, g_weapons, g_game, g_sound, e_sound, CONFIG,
-  g_options, MAPREADER, g_triggers, g_player, MAPDEF,
+  g_options, g_triggers, g_player,
   Math, g_monsters, g_saveload, g_language, g_netmsg,
-  utils, sfs, xparser, xdynrec, xstreams,
+  utils, sfs, xstreams,
   ImagingTypes, Imaging, ImagingUtility,
   ImagingGif, ImagingNetworkGraphics;
 
@@ -218,7 +229,6 @@ const
   FLAG_SIGNATURE = $47414C46; // 'FLAG'
 
 
-{$IF DEFINED(D2D_NEW_MAP_READER)}
 var
   dfmapdef: TDynMapDef = nil;
 
@@ -240,12 +250,27 @@ begin
   if (st = nil) then
   begin
     WAD := TWADFile.Create();
-    if not WAD.ReadFile(GameWAD) then raise Exception.Create('cannot load "game.wad"');
-    st := WAD.openFileStream('mapdef.txt');
+    if not WAD.ReadFile(GameWAD) then
+    begin
+      //raise Exception.Create('cannot load "game.wad"');
+      st := nil;
+    end
+    else
+    begin
+      st := WAD.openFileStream('mapdef.txt');
+    end;
   end;
 
-  if (st = nil) then raise Exception.Create('cannot open "mapdef.txt"');
-  pr := TFileTextParser.Create(st);
+  if (st = nil) then
+  begin
+    //raise Exception.Create('cannot open "mapdef.txt"');
+    e_LogWritefln('using default "mapdef.txt"...', [], MSG_WARNING);
+    pr := TStrTextParser.Create(defaultMapDef);
+  end
+  else
+  begin
+    pr := TFileTextParser.Create(st);
+  end;
 
   try
     dfmapdef := TDynMapDef.Create(pr);
@@ -256,7 +281,117 @@ begin
   st.Free();
   WAD.Free();
 end;
-{$ENDIF}
+
+
+function g_Map_ParseMap (data: Pointer; dataLen: Integer): TDynRecord;
+var
+  wst: TSFSMemoryChunkStream = nil;
+  pr: TTextParser = nil;
+begin
+  result := nil;
+  if (dataLen < 4) then exit;
+  loadMapDefinition();
+  if (dfmapdef = nil) then raise Exception.Create('internal map loader error');
+
+  wst := TSFSMemoryChunkStream.Create(data, dataLen);
+
+  if (PAnsiChar(data)[0] = 'M') and (PAnsiChar(data)[1] = 'A') and (PAnsiChar(data)[2] = 'P') and (PByte(data)[3] = 1) then
+  begin
+    // binary map
+    try
+      result := dfmapdef.parseBinMap(wst);
+    except on e: Exception do
+      begin
+        e_LogWritefln('ERROR: %s', [e.message]);
+        wst.Free();
+        result := nil;
+        exit;
+      end;
+    end;
+    wst.Free();
+  end
+  else
+  begin
+    // text map
+    pr := TFileTextParser.Create(wst);
+    try
+      result := dfmapdef.parseMap(pr);
+    except on e: Exception do
+      begin
+        if (pr <> nil) then e_LogWritefln('ERROR at (%s,%s): %s', [pr.line, pr.col, e.message])
+        else e_LogWritefln('ERROR: %s', [e.message]);
+        pr.Free(); // will free `wst`
+        result := nil;
+        exit;
+      end;
+    end;
+    pr.Free(); // will free `wst`
+  end;
+end;
+
+
+var
+  NNF_PureName: String; // Èìÿ òåêñòóðû áåç öèôð â êîíöå
+  NNF_FirstNum: Integer; // ×èñëî ó íà÷àëüíîé òåêñòóðû
+  NNF_CurrentNum: Integer; // Ñëåäóþùåå ÷èñëî ó òåêñòóðû
+
+
+function g_Texture_NumNameFindStart(name: String): Boolean;
+var
+  i: Integer;
+
+begin
+  Result := False;
+  NNF_PureName := '';
+  NNF_FirstNum := -1;
+  NNF_CurrentNum := -1;
+
+  for i := Length(name) downto 1 do
+    if (name[i] = '_') then // "_" - ñèìâîë íà÷àëà íîìåðíîãî ïîñòôèêñà
+    begin
+      if i = Length(name) then
+        begin // Íåò öèôð â êîíöå ñòðîêè
+          Exit;
+        end
+      else
+        begin
+          NNF_PureName := Copy(name, 1, i);
+          Delete(name, 1, i);
+          Break;
+        end;
+    end;
+
+// Íå ïåðåâåñòè â ÷èñëî:
+  if not TryStrToInt(name, NNF_FirstNum) then
+    Exit;
+
+  NNF_CurrentNum := 0;
+
+  Result := True;
+end;
+
+
+function g_Texture_NumNameFindNext(var newName: String): Byte;
+begin
+  if (NNF_PureName = '') or (NNF_CurrentNum < 0) then
+  begin
+    newName := '';
+    Result := NNF_NO_NAME;
+    Exit;
+  end;
+
+  newName := NNF_PureName + IntToStr(NNF_CurrentNum);
+
+  if NNF_CurrentNum < NNF_FirstNum then
+    Result := NNF_NAME_BEFORE
+  else
+    if NNF_CurrentNum > NNF_FirstNum then
+      Result := NNF_NAME_AFTER
+    else
+      Result := NNF_NAME_EQUALS;
+
+  Inc(NNF_CurrentNum);
+end;
 
 
 function panelTypeToTag (panelType: Word): Integer;
@@ -659,7 +794,7 @@ begin
     Width := 1;
     Height := 1;
     Anim := False;
-    TextureID := TEXTURE_NONE;
+    TextureID := LongWord(TEXTURE_NONE);
   end;
 end;
 
@@ -692,13 +827,13 @@ begin
       TextureName := RecName;
 
       if TextureName = TEXTURE_NAME_WATER then
-        TextureID := TEXTURE_SPECIAL_WATER
+        TextureID := LongWord(TEXTURE_SPECIAL_WATER)
       else
         if TextureName = TEXTURE_NAME_ACID1 then
-          TextureID := TEXTURE_SPECIAL_ACID1
+          TextureID := LongWord(TEXTURE_SPECIAL_ACID1)
         else
           if TextureName = TEXTURE_NAME_ACID2 then
-            TextureID := TEXTURE_SPECIAL_ACID2;
+            TextureID := LongWord(TEXTURE_SPECIAL_ACID2);
 
       Anim := False;
     end;
@@ -1147,7 +1282,7 @@ begin
     gExternalResources.Add(res);
 end;
 
-procedure generateExternalResourcesList(mapReader: TMapReader_1);
+procedure generateExternalResourcesList({mapReader: TMapReader_1}map: TDynRecord);
 var
   textures: TTexturesRec1Array;
   mapHeader: TMapHeaderRec_1;
@@ -1158,7 +1293,7 @@ begin
     gExternalResources := TStringList.Create;
 
   gExternalResources.Clear;
-  textures := mapReader.GetTextures();
+  textures := GetTextures(map);
   for i := 0 to High(textures) do
   begin
     addResToExternalResList(resFile);
@@ -1166,7 +1301,7 @@ begin
 
   textures := nil;
 
-  mapHeader := mapReader.GetMapHeader;
+  mapHeader := GetMapHeader(map);
 
   addResToExternalResList(mapHeader.MusicName);
   addResToExternalResList(mapHeader.SkyName);
@@ -1291,7 +1426,8 @@ const
   DefaultSkyRes = 'Standart.wad:STDSKY\SKY0';
 var
   WAD: TWADFile;
-  MapReader: TMapReader_1;
+  //MapReader: TMapReader_1;
+  mapReader: TDynRecord = nil;
   Header: TMapHeaderRec_1;
   _textures: TTexturesRec1Array;
   _texnummap: array of Integer; // `_textures` -> `Textures`
@@ -1315,12 +1451,6 @@ var
   Len: Integer;
   ok, isAnim, trigRef: Boolean;
   CurTex, ntn: Integer;
-  {$IF DEFINED(D2D_NEW_MAP_READER)}
-  pr: TTextParser = nil;
-  st: TStream = nil;
-  wst: TSFSMemoryChunkStream = nil;
-  rec: TDynRecord;
-  {$ENDIF}
 begin
   mapGrid.Free();
   mapGrid := nil;
@@ -1367,58 +1497,67 @@ begin
     e_LogWritefln('Loading map: %s', [mapResName], MSG_NOTIFY);
     g_Game_SetLoadingText(_lc[I_LOAD_MAP], 0, False);
 
-    {$IF DEFINED(D2D_NEW_MAP_READER)}
-      if (PChar(Data)[0] = 'M') and (PChar(Data)[1] = 'A') and (PChar(Data)[2] = 'P') and (PByte(Data)[3] = 1) then
-      begin
-        // nothing
-      end
-      else
-      begin
-        e_LogWritefln('Loading text map: %s', [mapResName]);
-        loadMapDefinition();
-        if (dfmapdef = nil) then raise Exception.Create('internal map loader error');
-        //e_LogWritefln('***'#10'%s'#10'***', [dfmapdef.headerType.definition]);
-        wst := TSFSMemoryChunkStream.Create(Data, Len);
-        try
-          pr := TFileTextParser.Create(wst);
-          e_LogWritefln('parsing text map: %s', [mapResName]);
-          rec := dfmapdef.parseMap(pr);
-        except on e: Exception do
-          begin
-            if (pr <> nil) then e_LogWritefln('ERROR at (%s,%s): %s', [pr.line, pr.col, e.message])
-            else e_LogWritefln('ERROR: %s', [e.message]);
-            pr.Free();
-            wst.Free();
-            FreeMem(Data);
-            exit;
-          end;
+    {
+    if (PChar(Data)[0] = 'M') and (PChar(Data)[1] = 'A') and (PChar(Data)[2] = 'P') and (PByte(Data)[3] = 1) then
+    begin
+      // nothing
+    end
+    else
+    begin
+      e_LogWritefln('Loading text map: %s', [mapResName]);
+      loadMapDefinition();
+      if (dfmapdef = nil) then raise Exception.Create('internal map loader error');
+      //e_LogWritefln('***'#10'%s'#10'***', [dfmapdef.headerType.definition]);
+      wst := TSFSMemoryChunkStream.Create(Data, Len);
+      try
+        pr := TFileTextParser.Create(wst);
+        e_LogWritefln('parsing text map: %s', [mapResName]);
+        rec := dfmapdef.parseMap(pr);
+      except on e: Exception do
+        begin
+          if (pr <> nil) then e_LogWritefln('ERROR at (%s,%s): %s', [pr.line, pr.col, e.message])
+          else e_LogWritefln('ERROR: %s', [e.message]);
+          pr.Free();
+          wst.Free();
+          FreeMem(Data);
+          exit;
         end;
-        pr.Free();
-        //wst.Free(); // pr will do it
-        e_LogWritefln('writing text map to temporary bin storage...', []);
-        st := TMemoryStream.Create();
-        try
-          rec.writeBinTo(st);
-          Len := Integer(st.position);
-          st.position := 0;
+      end;
+      pr.Free();
+      //wst.Free(); // pr will do it
+      e_LogWritefln('writing text map to temporary bin storage...', []);
+      st := TMemoryStream.Create();
+      try
+        rec.writeBinTo(st);
+        Len := Integer(st.position);
+        st.position := 0;
+        FreeMem(Data);
+        GetMem(Data, Len);
+        st.ReadBuffer(Data^, Len);
+      except on e: Exception do
+        begin
+          rec.Free();
+          st.Free();
+          e_LogWritefln('ERROR: %s', [e.message]);
           FreeMem(Data);
-          GetMem(Data, Len);
-          st.ReadBuffer(Data^, Len);
-        except on e: Exception do
-          begin
-            rec.Free();
-            st.Free();
-            e_LogWritefln('ERROR: %s', [e.message]);
-            FreeMem(Data);
-            exit;
-          end;
+          exit;
         end;
-        st.Free();
       end;
-    {$ENDIF}
+      st.Free();
+    end;
+    }
+    try
+      mapReader := g_Map_ParseMap(Data, Len);
+    except
+      mapReader.Free();
+      g_FatalError(Format(_lc[I_GAME_ERROR_MAP_LOAD], [Res]));
+      FreeMem(Data);
+      MapReader.Free();
+      Exit;
+    end;
 
+    {
     MapReader := TMapReader_1.Create();
-
     if not MapReader.LoadMap(Data) then
     begin
       g_FatalError(Format(_lc[I_GAME_ERROR_MAP_LOAD], [Res]));
@@ -1426,18 +1565,19 @@ begin
       MapReader.Free();
       Exit;
     end;
+    }
 
     FreeMem(Data);
     generateExternalResourcesList(MapReader);
   // Çàãðóçêà òåêñòóð:
     g_Game_SetLoadingText(_lc[I_LOAD_TEXTURES], 0, False);
-    _textures := MapReader.GetTextures();
+    _textures := GetTextures(mapReader);
     _texnummap := nil;
 
   // Çàãðóçêà îïèñàíèÿ êàðòû:
     e_WriteLog('  Reading map info...', MSG_NOTIFY);
     g_Game_SetLoadingText(_lc[I_LOAD_MAP_HEADER], 0, False);
-    Header := MapReader.GetMapHeader();
+    Header := GetMapHeader(mapReader);
 
     with gMapInfo do
     begin
@@ -1500,12 +1640,12 @@ begin
     gTriggerClientID := 0;
     e_WriteLog('  Loading triggers...', MSG_NOTIFY);
     g_Game_SetLoadingText(_lc[I_LOAD_TRIGGERS], 0, False);
-    triggers := MapReader.GetTriggers();
+    triggers := GetTriggers(mapReader);
 
   // Çàãðóçêà ïàíåëåé:
     e_WriteLog('  Loading panels...', MSG_NOTIFY);
     g_Game_SetLoadingText(_lc[I_LOAD_PANELS], 0, False);
-    panels := MapReader.GetPanels();
+    panels := GetPanels(mapReader);
 
     // check texture numbers for panels
     for a := 0 to High(panels) do
@@ -1716,28 +1856,41 @@ begin
   // Åñëè íå LoadState, òî ñîçäàåì òðèããåðû:
     if (triggers <> nil) and not gLoadGameMode then
     begin
-      e_WriteLog('  Creating triggers...', MSG_NOTIFY);
+      e_LogWritefln('  Creating triggers (%d)...', [Length(triggers)]);
       g_Game_SetLoadingText(_lc[I_LOAD_CREATE_TRIGGERS], 0, False);
     // Óêàçûâàåì òèï ïàíåëè, åñëè åñòü:
       for a := 0 to High(triggers) do
       begin
-        if triggers[a].TexturePanel <> -1 then
-          b := panels[TriggersTable[a].TexturePanel].PanelType
+        if (triggers[a].TexturePanel <> -1) then
+        begin
+          if (TriggersTable[a].TexturePanel < 0) or (TriggersTable[a].TexturePanel > High(panels)) then
+          begin
+            e_WriteLog('error loading map: invalid panel index for trigger', MSG_FATALERROR);
+            result := false;
+            exit;
+          end;
+          b := panels[TriggersTable[a].TexturePanel].PanelType;
+        end
         else
+        begin
           b := 0;
-        if (triggers[a].TriggerType = TRIGGER_SHOT) and
-           (TTriggerData(triggers[a].DATA).ShotPanelID <> -1) then
+        end;
+        if (triggers[a].TriggerType = TRIGGER_SHOT) and (TTriggerData(triggers[a].DATA).ShotPanelID <> -1) then
+        begin
           c := panels[TriggersTable[a].ShotPanel].PanelType
+        end
         else
+        begin
           c := 0;
+        end;
         CreateTrigger(triggers[a], b, c);
       end;
     end;
 
   // Çàãðóçêà ïðåäìåòîâ:
-    e_WriteLog('  Loading triggers...', MSG_NOTIFY);
+    e_WriteLog('  Loading items...', MSG_NOTIFY);
     g_Game_SetLoadingText(_lc[I_LOAD_ITEMS], 0, False);
-    items := MapReader.GetItems();
+    items := GetItems(mapReader);
 
   // Åñëè íå LoadState, òî ñîçäàåì ïðåäìåòû:
     if (items <> nil) and not gLoadGameMode then
@@ -1751,7 +1904,7 @@ begin
   // Çàãðóçêà îáëàñòåé:
     e_WriteLog('  Loading areas...', MSG_NOTIFY);
     g_Game_SetLoadingText(_lc[I_LOAD_AREAS], 0, False);
-    areas := MapReader.GetAreas();
+    areas := GetAreas(mapReader);
 
   // Åñëè íå LoadState, òî ñîçäàåì îáëàñòè:
     if areas <> nil then
@@ -1765,7 +1918,7 @@ begin
   // Çàãðóçêà ìîíñòðîâ:
     e_WriteLog('  Loading monsters...', MSG_NOTIFY);
     g_Game_SetLoadingText(_lc[I_LOAD_MONSTERS], 0, False);
-    monsters := MapReader.GetMonsters();
+    monsters := GetMonsters(mapReader);
 
     gTotalMonsters := 0;
 
@@ -1865,7 +2018,7 @@ end;
 function g_Map_GetMapInfo(Res: String): TMapInfo;
 var
   WAD: TWADFile;
-  MapReader: TMapReader_1;
+  MapReader: TDynRecord;
   Header: TMapHeaderRec_1;
   FileName: String;
   Data: Pointer;
@@ -1890,8 +2043,8 @@ begin
 
   WAD.Free();
 
+  {
   MapReader := TMapReader_1.Create();
-
   if not MapReader.LoadMap(Data) then
     begin
       g_Console_Add(Format(_lc[I_GAME_ERROR_MAP_LOAD], [Res]), True);
@@ -1905,10 +2058,32 @@ begin
       Result.Name := Header.MapName;
       Result.Description := Header.MapDescription;
     end;
+  }
+  try
+    mapReader := g_Map_ParseMap(Data, Len);
+  except
+    mapReader := nil;
+  end;
 
   FreeMem(Data);
+  //MapReader.Free();
+
+  if (mapReader <> nil) then Header := GetMapHeader(mapReader) else FillChar(Header, sizeof(Header), 0);
   MapReader.Free();
 
+  if (Header.Width > 0) and (Header.Height > 0) then
+  begin
+    Result.Name := Header.MapName;
+    Result.Description := Header.MapDescription;
+  end
+  else
+  begin
+    g_Console_Add(Format(_lc[I_GAME_ERROR_MAP_LOAD], [Res]), True);
+    ZeroMemory(@Header, SizeOf(Header));
+    Result.Name := _lc[I_GAME_ERROR_MAP_SELECT];
+    Result.Description := _lc[I_GAME_ERROR_MAP_SELECT];
+  end;
+
   Result.Map := Res;
   Result.Author := Header.MapAuthor;
   Result.Height := Header.Height;
@@ -2016,7 +2191,7 @@ begin
         if Textures[a].Anim then
           g_Frames_DeleteByID(Textures[a].FramesID)
         else
-          if Textures[a].TextureID <> TEXTURE_NONE then
+          if Textures[a].TextureID <> LongWord(TEXTURE_NONE) then
             e_DeleteTexture(Textures[a].TextureID);
 
     Textures := nil;
@@ -2354,7 +2529,7 @@ var
   end;
 
 begin
-  texid := TEXTURE_NONE;
+  texid := LongWord(TEXTURE_NONE);
   result := texid;
   if not checkPanels(gWater) then
     if not checkPanels(gAcid1) then
@@ -2481,7 +2656,7 @@ begin
   if (profMapCollision <> nil) then profMapCollision.sectionBeginAccum('liquids');
   if gdbg_map_use_accel_coldet then
   begin
-    texid := TEXTURE_NONE;
+    texid := LongWord(TEXTURE_NONE);
     if (Width = 1) and (Height = 1) then
     begin
       mapGrid.forEachAtPoint(X, Y, checker, (GridTagWater or GridTagAcid1 or GridTagAcid2));
index 0905cdc6ddc78c02cc4ba1f520d23215c2331b30..5371f413c26e01849bafc272bbdd4c3e2d4aef6a 100644 (file)
@@ -45,7 +45,7 @@ uses
   g_gui, g_textures, e_graphics, g_main, g_window, g_game, g_map,
   g_basic, g_console, g_sound, g_gfx, g_player, g_options, g_weapons,
   e_log, SysUtils, CONFIG, g_playermodel, DateUtils,
-  MAPSTRUCT, wadreader, Math, g_saveload,
+  MAPDEF, wadreader, Math, g_saveload,
   e_texture, GL, GLExt, g_language,
   g_net, g_netmsg, g_netmaster, g_items, e_input;
 
index 2b70da642e49892257507eadf3da63de2a0d32db..5ec0099df31ef59bf398bb2c52b229cba0a5dc31 100644 (file)
@@ -452,8 +452,8 @@ const
        LeftAnim: Boolean;
        wX, wY: Integer; // Îòêóäà âûëåòèò ïóëÿ
        AnimSpeed: Array [ANIM_SLEEP..ANIM_PAIN] of Byte;
-       AnimDeltaRight: Array [ANIM_SLEEP..ANIM_PAIN] of TPoint;
-       AnimDeltaLeft: Array [ANIM_SLEEP..ANIM_PAIN] of TPoint;
+       AnimDeltaRight: Array [ANIM_SLEEP..ANIM_PAIN] of TDFPoint;
+       AnimDeltaLeft: Array [ANIM_SLEEP..ANIM_PAIN] of TDFPoint;
      end =          // SLEEP           GO              DIE             MESS            ATTACK          ATTACK2         PAIN
    ((LeftAnim: False; wX: 54; wY: 32; AnimSpeed:(3, 2, 3, 2, 3, 0, 4); //DEMON
      AnimDeltaRight: ((X:  1; Y:  4), (X:  1; Y:  4), (X:  0; Y:  4), (X:  0; Y:  4), (X:  2; Y:  6), (X:  2; Y:  6), (X:  2; Y:  5));
index 96bd7f1817f333246c470eea1933052bf2c2df83..c562934ec753748f26269fb776a629cd7d61ab08 100644 (file)
@@ -19,7 +19,7 @@ unit g_panel;
 interface
 
 uses
-  MAPSTRUCT, BinEditor, g_textures;
+  MAPDEF, BinEditor, g_textures;
 
 type
   TAddTextureArray = Array of
@@ -94,7 +94,7 @@ type
 implementation
 
 uses
-  SysUtils, g_basic, g_map, MAPDEF, g_game, e_graphics,
+  SysUtils, g_basic, g_map, g_game, e_graphics,
   g_console, g_language, e_log, GL;
 
 const
@@ -187,11 +187,11 @@ begin
 
     case PanelRec.PanelType of
       PANEL_WATER:
-        FTextureIDs[0].Tex := TEXTURE_SPECIAL_WATER;
+        FTextureIDs[0].Tex := LongWord(TEXTURE_SPECIAL_WATER);
       PANEL_ACID1:
-        FTextureIDs[0].Tex := TEXTURE_SPECIAL_ACID1;
+        FTextureIDs[0].Tex := LongWord(TEXTURE_SPECIAL_ACID1);
       PANEL_ACID2:
-        FTextureIDs[0].Tex := TEXTURE_SPECIAL_ACID2;
+        FTextureIDs[0].Tex := LongWord(TEXTURE_SPECIAL_ACID2);
     end;
 
     FCurTexture := 0;
@@ -289,16 +289,16 @@ begin
     else
       begin // Îáû÷íàÿ òåêñòóðà
         case FTextureIDs[FCurTexture].Tex of
-          TEXTURE_SPECIAL_WATER:
+          LongWord(TEXTURE_SPECIAL_WATER):
             e_DrawFillQuad(X, Y, X+Width-1, Y+Height-1,
                            0, 0, 255, 0, B_FILTER);
-          TEXTURE_SPECIAL_ACID1:
+          LongWord(TEXTURE_SPECIAL_ACID1):
             e_DrawFillQuad(X, Y, X+Width-1, Y+Height-1,
                            0, 128, 0, 0, B_FILTER);
-          TEXTURE_SPECIAL_ACID2:
+          LongWord(TEXTURE_SPECIAL_ACID2):
             e_DrawFillQuad(X, Y, X+Width-1, Y+Height-1,
                            128, 0, 0, 0, B_FILTER);
-          TEXTURE_NONE:
+          LongWord(TEXTURE_NONE):
             if g_Texture_Get('NOTEXTURE', NoTextureID) then
             begin
               e_GetTextureSize(NoTextureID, @NW, @NH);
@@ -354,10 +354,10 @@ begin
     if not FTextureIDs[FCurTexture].Anim then
     begin
       case FTextureIDs[FCurTexture].Tex of
-        TEXTURE_SPECIAL_WATER: exit;
-        TEXTURE_SPECIAL_ACID1: exit;
-        TEXTURE_SPECIAL_ACID2: exit;
-        TEXTURE_NONE: exit;
+        LongWord(TEXTURE_SPECIAL_WATER): exit;
+        LongWord(TEXTURE_SPECIAL_ACID1): exit;
+        LongWord(TEXTURE_SPECIAL_ACID2): exit;
+        LongWord(TEXTURE_NONE): exit;
       end;
     end;
     if (X+Width < lightX-radius) then exit;
@@ -498,7 +498,7 @@ end;
 
 function TPanel.GetTextureID(): DWORD;
 begin
-  Result := TEXTURE_NONE;
+  Result := LongWord(TEXTURE_NONE);
 
   if (FCurTexture >= 0) then
   begin
index 7780b3ba74806b71cc8d29d8fbfab261f1e5aae2..498bd7587489f9faf6e72ffca873c72e06de6702 100644 (file)
@@ -461,13 +461,13 @@ _move:
                                          Obj^.Rect.Width,
                                          Obj^.Rect.Height*2 div 3);
       case wtx of
-        TEXTURE_SPECIAL_WATER:
+        LongWord(TEXTURE_SPECIAL_WATER):
           g_Obj_Splash(Obj, 3);
-        TEXTURE_SPECIAL_ACID1:
+        LongWord(TEXTURE_SPECIAL_ACID1):
           g_Obj_Splash(Obj, 2);
-        TEXTURE_SPECIAL_ACID2:
+        LongWord(TEXTURE_SPECIAL_ACID2):
           g_Obj_Splash(Obj, 1);
-        TEXTURE_NONE:
+        LongWord(TEXTURE_NONE):
           ;
         else
           g_Obj_Splash(Obj, 0);
index ebbd2043e5fc69d7784346b031c5b51d804f637c..488cee9edc6ce085a2c329f1f5d26f506bf4cb9e 100644 (file)
@@ -20,7 +20,7 @@ interface
 
 uses
   e_graphics, g_playermodel, g_basic, g_textures,
-  g_weapons, g_phys, g_sound, g_saveload, MAPSTRUCT,
+  g_weapons, g_phys, g_sound, g_saveload, MAPDEF,
   BinEditor, g_panel;
 
 const
@@ -524,7 +524,7 @@ implementation
 
 uses
   e_log, g_map, g_items, g_console, SysUtils, g_gfx, Math,
-  g_options, g_triggers, g_menu, MAPDEF, g_game, g_grid,
+  g_options, g_triggers, g_menu, g_game, g_grid,
   wadreader, g_main, g_monsters, CONFIG, g_language,
   g_net, g_netmsg, g_window, GL, g_holmes;
 
@@ -563,7 +563,7 @@ const
   ANGLE_LEFTUP    = 125;
   ANGLE_LEFTDOWN  = -145;
   PLAYER_HEADRECT: TRectWH = (X:24; Y:12; Width:20; Height:12);
-  WEAPONPOINT: Array [TDirection] of TPoint = ((X:16; Y:32), (X:47; Y:32));
+  WEAPONPOINT: Array [TDirection] of TDFPoint = ((X:16; Y:32), (X:47; Y:32));
   BOT_MAXJUMP = 84;
   BOT_LONGDIST   = 300;
   BOT_UNSAFEDIST = 128;
@@ -1711,7 +1711,7 @@ end;
 procedure g_Player_DrawCorpses();
 var
   i: Integer;
-  a: TPoint;
+  a: TDFPoint;
 begin
   if gGibs <> nil then
     for i := 0 to High(gGibs) do
@@ -1742,7 +1742,7 @@ end;
 procedure g_Player_DrawShells();
 var
   i: Integer;
-  a: TPoint;
+  a: TDFPoint;
 begin
   if gShells <> nil then
     for i := 0 to High(gShells) do
index 3c121dba7854435f9a2e5d6a5cc4419b82f72a40..72f5fb23e726f916f937f888e9991ebd7e69bbbf 100644 (file)
@@ -19,7 +19,7 @@ unit g_playermodel;
 interface
 
 uses
-  g_textures, g_basic, g_weapons, e_graphics, wadreader;
+  MAPDEF, g_textures, g_basic, g_weapons, e_graphics, wadreader;
 
 const
   A_STAND      = 0;
@@ -78,7 +78,7 @@ type
   TGibsArray = Array of TGibSprite;
   TWeaponPoints = Array [WP_FIRST + 1..WP_LAST] of
                   Array [A_STAND..A_LAST] of
-                  Array [D_LEFT..D_RIGHT] of Array of TPoint;
+                  Array [D_LEFT..D_RIGHT] of Array of TDFPoint;
 
   TPlayerModel = class (TObject)
   private
@@ -95,7 +95,7 @@ type
     FCurrentWeapon:    Byte;
     FDrawWeapon:       Boolean;
     FFlag:             Byte;
-    FFlagPoint:        TPoint;
+    FFlagPoint:        TDFPoint;
     FFlagAngle:        SmallInt;
     FFlagAnim:         TAnimation;
     FFire:             Boolean;
@@ -141,7 +141,7 @@ type
   TPlayerModelInfo = record
     Info:         TModelInfo;
     ModelSpeed:   Array [A_STAND..A_PAIN] of Byte;
-    FlagPoint:    TPoint;
+    FlagPoint:    TDFPoint;
     FlagAngle:    SmallInt;
     WeaponPoints: TWeaponPoints;
     Gibs:         TGibsArray;
@@ -158,10 +158,10 @@ const
   W_ACT_NORMAL = 0;
   W_ACT_FIRE   = 1;
 
-  FLAG_BASEPOINT: TPoint = (X:16; Y:43);
-  FLAG_DEFPOINT:  TPoint = (X:32; Y:16);
+  FLAG_BASEPOINT: TDFPoint = (X:16; Y:43);
+  FLAG_DEFPOINT:  TDFPoint = (X:32; Y:16);
   FLAG_DEFANGLE = -20;
-  WEAPONBASE: Array [WP_FIRST + 1..WP_LAST] of TPoint =
+  WEAPONBASE: Array [WP_FIRST + 1..WP_LAST] of TDFPoint =
               ((X:8; Y:4), (X:8; Y:8), (X:16; Y:16), (X:16; Y:24),
                (X:16; Y:16), (X:24; Y:24), (X:16; Y:16), (X:24; Y:24),
                (X:16; Y:16), (X:8; Y:8));
@@ -198,7 +198,7 @@ begin
   end;
 end;
 
-function GetPoint(var str: String; var point: TPoint): Boolean;
+function GetPoint(var str: String; var point: TDFPoint): Boolean;
 var
   a, x, y: Integer;
   s: String;
@@ -802,7 +802,7 @@ procedure TPlayerModel.Draw(X, Y: Integer; Alpha: Byte = 0);
 var
   Mirror: TMirrorType;
   pos, act: Byte;
-  p: TPoint;
+  p: TDFPoint;
 begin
 // Ôëàãè:
   if Direction = D_LEFT then
index e6a1ca293344ca1b603ff026a4fbc514c0ee7f54..5a130981eae9232f2e22269e20275397098f1829 100644 (file)
@@ -42,7 +42,7 @@ implementation
 uses
   g_game, g_items, g_map, g_monsters, g_triggers,
   g_basic, g_main, SysUtils, Math, wadreader,
-  MAPSTRUCT, MAPDEF, g_weapons, g_player, g_console,
+  MAPDEF, g_weapons, g_player, g_console,
   e_log, g_language;
 
 const
index 660e999351988a4fb3dad1ccdecabe614d6dda3b..02098004a6432c4d64385e6d6f208c1380e2a569 100644 (file)
@@ -19,7 +19,7 @@ unit g_textures;
 interface
 
 uses
-  e_graphics, BinEditor, ImagingTypes, Imaging, ImagingUtility;
+  e_graphics, MAPDEF, BinEditor, ImagingTypes, Imaging, ImagingUtility;
 
 Type
   TLevelTexture = record
@@ -55,7 +55,7 @@ Type
     constructor Create(FramesID: DWORD; Loop: Boolean; Speed: Byte);
     destructor  Destroy(); override;
     procedure   Draw(X, Y: Integer; Mirror: TMirrorType);
-    procedure   DrawEx(X, Y: Integer; Mirror: TMirrorType; RPoint: TPoint;
+    procedure   DrawEx(X, Y: Integer; Mirror: TMirrorType; RPoint: TDFPoint;
                        Angle: SmallInt);
     procedure   Reset();
     procedure   Update();
@@ -785,7 +785,7 @@ begin
   FEnabled := True;
 end;
 
-procedure TAnimation.DrawEx(X, Y: Integer; Mirror: TMirrorType; RPoint: TPoint;
+procedure TAnimation.DrawEx(X, Y: Integer; Mirror: TMirrorType; RPoint: TDFPoint;
                             Angle: SmallInt);
 begin
   if not FEnabled then
index 3b1f911bf133db08b97b0c1f50da8e5a1732fed1..c327fdb55c2afcd0257ec015562191cdcc0aade1 100644 (file)
@@ -19,7 +19,7 @@ unit g_triggers;
 interface
 
 uses
-  MAPSTRUCT, e_graphics, MAPDEF, g_basic, g_sound,
+  MAPDEF, e_graphics, g_basic, g_sound,
   BinEditor;
 
 type
index aa78ebd94e7ddae5fa7f224eada8b21f0cf3f79e..5d6a7848adf18b7b061505e667026823c8f13098 100644 (file)
@@ -2497,7 +2497,7 @@ procedure g_Weapon_Draw();
 var
   i: Integer;
   a: SmallInt;
-  p: TPoint;
+  p: TDFPoint;
 begin
   if Shots = nil then
     Exit;
index f6678e921683bb659ec77dd3a6805658f21fb0b2..12e05628ab16110b1582075be182cc15c0b5cb6f 100644 (file)
@@ -28,330 +28,248 @@ MAPDEF.PAS 
 interface
 
 uses
-  MAPSTRUCT;
+  xdynrec;
+
 
-// *** WARNING! ***
-//   keep all constants in sync with "mapdesc.txt"!
-//   or even better: regenerate this part directly from "mapdesc.txt".
 const
-  PANEL_NONE      = 0;
-  PANEL_WALL      = 1;
-  PANEL_BACK      = 2;
-  PANEL_FORE      = 4;
-  PANEL_WATER     = 8;
-  PANEL_ACID1     = 16;
-  PANEL_ACID2     = 32;
-  PANEL_STEP      = 64;
-  PANEL_LIFTUP    = 128;
-  PANEL_LIFTDOWN  = 256;
-  PANEL_OPENDOOR  = 512;
-  PANEL_CLOSEDOOR = 1024;
-  PANEL_BLOCKMON  = 2048;
-  PANEL_LIFTLEFT  = 4096;
-  PANEL_LIFTRIGHT = 8192;
-
-  PANEL_FLAG_BLENDING      = 1;
-  PANEL_FLAG_HIDE          = 2;
-  PANEL_FLAG_WATERTEXTURES = 4;
-
-  EFFECT_NONE     = 0;
-  EFFECT_TELEPORT = 1;
-  EFFECT_RESPAWN  = 2;
-  EFFECT_FIRE     = 3;
-
-  ITEM_NONE                  = 0;
-  ITEM_MEDKIT_SMALL          = 1;
-  ITEM_MEDKIT_LARGE          = 2;
-  ITEM_MEDKIT_BLACK          = 3;
-  ITEM_ARMOR_GREEN           = 4;
-  ITEM_ARMOR_BLUE            = 5;
-  ITEM_SPHERE_BLUE           = 6;
-  ITEM_SPHERE_WHITE          = 7;
-  ITEM_SUIT                  = 8;
-  ITEM_OXYGEN                = 9;
-  ITEM_INVUL                 = 10;
-  ITEM_WEAPON_SAW            = 11;
-  ITEM_WEAPON_SHOTGUN1       = 12;
-  ITEM_WEAPON_SHOTGUN2       = 13;
-  ITEM_WEAPON_CHAINGUN       = 14;
-  ITEM_WEAPON_ROCKETLAUNCHER = 15;
-  ITEM_WEAPON_PLASMA         = 16;
-  ITEM_WEAPON_BFG            = 17;
-  ITEM_WEAPON_SUPERPULEMET   = 18;
-  ITEM_AMMO_BULLETS          = 19;
-  ITEM_AMMO_BULLETS_BOX      = 20;
-  ITEM_AMMO_SHELLS           = 21;
-  ITEM_AMMO_SHELLS_BOX       = 22;
-  ITEM_AMMO_ROCKET           = 23;
-  ITEM_AMMO_ROCKET_BOX       = 24;
-  ITEM_AMMO_CELL             = 25;
-  ITEM_AMMO_CELL_BIG         = 26;
-  ITEM_AMMO_BACKPACK         = 27;
-  ITEM_KEY_RED               = 28;
-  ITEM_KEY_GREEN             = 29;
-  ITEM_KEY_BLUE              = 30;
-  ITEM_WEAPON_KASTET         = 31;
-  ITEM_WEAPON_PISTOL         = 32;
-  ITEM_BOTTLE                = 33;
-  ITEM_HELMET                = 34;
-  ITEM_JETPACK               = 35;
-  ITEM_INVIS                 = 36;
-  ITEM_WEAPON_FLAMETHROWER   = 37;
-  ITEM_AMMO_FUELCAN          = 38;
-
-  ITEM_MAX                   = 38; // store the last item's id in here
-                                   // use this in for loops
-
-  ITEM_OPTION_ONLYDM = 1;
-  ITEM_OPTION_FALL   = 2;
-
-  AREA_NONE          = 0;
-  AREA_PLAYERPOINT1  = 1;
-  AREA_PLAYERPOINT2  = 2;
-  AREA_DMPOINT       = 3;
-  AREA_REDFLAG       = 4;
-  AREA_BLUEFLAG      = 5;
-  AREA_DOMFLAG       = 6;
-  AREA_REDTEAMPOINT  = 7;
-  AREA_BLUETEAMPOINT = 8;
-
-  MONSTER_NONE   = 0;
-  MONSTER_DEMON  = 1;
-  MONSTER_IMP    = 2;
-  MONSTER_ZOMBY  = 3;
-  MONSTER_SERG   = 4;
-  MONSTER_CYBER  = 5;
-  MONSTER_CGUN   = 6;
-  MONSTER_BARON  = 7;
-  MONSTER_KNIGHT = 8;
-  MONSTER_CACO   = 9;
-  MONSTER_SOUL   = 10;
-  MONSTER_PAIN   = 11;
-  MONSTER_SPIDER = 12;
-  MONSTER_BSP    = 13;
-  MONSTER_MANCUB = 14;
-  MONSTER_SKEL   = 15;
-  MONSTER_VILE   = 16;
-  MONSTER_FISH   = 17;
-  MONSTER_BARREL = 18;
-  MONSTER_ROBO   = 19;
-  MONSTER_MAN    = 20;
-
-  TRIGGER_NONE            = 0;
-  TRIGGER_EXIT            = 1;
-  TRIGGER_TELEPORT        = 2;
-  TRIGGER_OPENDOOR        = 3;
-  TRIGGER_CLOSEDOOR       = 4;
-  TRIGGER_DOOR            = 5;
-  TRIGGER_DOOR5           = 6;
-  TRIGGER_CLOSETRAP       = 7;
-  TRIGGER_TRAP            = 8;
-  TRIGGER_PRESS           = 9;
-  TRIGGER_SECRET          = 10;
-  TRIGGER_LIFTUP          = 11;
-  TRIGGER_LIFTDOWN        = 12;
-  TRIGGER_LIFT            = 13;
-  TRIGGER_TEXTURE         = 14;
-  TRIGGER_ON              = 15;
-  TRIGGER_OFF             = 16;
-  TRIGGER_ONOFF           = 17;
-  TRIGGER_SOUND           = 18;
-  TRIGGER_SPAWNMONSTER    = 19;
-  TRIGGER_SPAWNITEM       = 20;
-  TRIGGER_MUSIC           = 21;
-  TRIGGER_PUSH            = 22;
-  TRIGGER_SCORE           = 23;
-  TRIGGER_MESSAGE         = 24;
-  TRIGGER_DAMAGE          = 25;
-  TRIGGER_HEALTH          = 26;
-  TRIGGER_SHOT            = 27;
-  TRIGGER_EFFECT          = 28;
-  TRIGGER_SCRIPT          = 29;
-  TRIGGER_MAX             = 29;
-
-  TRIGGER_SHOT_PISTOL  = 0;
-  TRIGGER_SHOT_BULLET  = 1;
-  TRIGGER_SHOT_SHOTGUN = 2;
-  TRIGGER_SHOT_SSG     = 3;
-  TRIGGER_SHOT_IMP     = 4;
-  TRIGGER_SHOT_PLASMA  = 5;
-  TRIGGER_SHOT_SPIDER  = 6;
-  TRIGGER_SHOT_CACO    = 7;
-  TRIGGER_SHOT_BARON   = 8;
-  TRIGGER_SHOT_MANCUB  = 9;
-  TRIGGER_SHOT_REV     = 10;
-  TRIGGER_SHOT_ROCKET  = 11;
-  TRIGGER_SHOT_BFG     = 12;
-  TRIGGER_SHOT_EXPL    = 13;
-  TRIGGER_SHOT_BFGEXPL = 14;
-  TRIGGER_SHOT_MAX     = 14;
-
-  TRIGGER_SHOT_TARGET_NONE   = 0;
-  TRIGGER_SHOT_TARGET_MON    = 1;
-  TRIGGER_SHOT_TARGET_PLR    = 2;
-  TRIGGER_SHOT_TARGET_RED    = 3;
-  TRIGGER_SHOT_TARGET_BLUE   = 4;
-  TRIGGER_SHOT_TARGET_MONPLR = 5;
-  TRIGGER_SHOT_TARGET_PLRMON = 6;
-
-  TRIGGER_SHOT_AIM_DEFAULT   = 0;
-  TRIGGER_SHOT_AIM_ALLMAP    = 1;
-  TRIGGER_SHOT_AIM_TRACE     = 2;
-  TRIGGER_SHOT_AIM_TRACEALL  = 3;
-
-  TRIGGER_EFFECT_PARTICLE  = 0;
-  TRIGGER_EFFECT_ANIMATION = 1;
-
-  TRIGGER_EFFECT_SLIQUID = 0;
-  TRIGGER_EFFECT_LLIQUID = 1;
-  TRIGGER_EFFECT_DLIQUID = 2;
-  TRIGGER_EFFECT_BLOOD   = 3;
-  TRIGGER_EFFECT_SPARK   = 4;
-  TRIGGER_EFFECT_BUBBLE  = 5;
-  TRIGGER_EFFECT_MAX     = 5;
-
-  TRIGGER_EFFECT_POS_CENTER = 0;
-  TRIGGER_EFFECT_POS_AREA   = 1;
-
-  ACTIVATE_PLAYERCOLLIDE  = 1;
-  ACTIVATE_MONSTERCOLLIDE = 2;
-  ACTIVATE_PLAYERPRESS    = 4;
-  ACTIVATE_MONSTERPRESS   = 8;
-  ACTIVATE_SHOT           = 16;
-  ACTIVATE_NOMONSTER      = 32;
-  ACTIVATE_CUSTOM         = 255;
-
-  KEY_RED      = 1;
-  KEY_GREEN    = 2;
-  KEY_BLUE     = 4;
-  KEY_REDTEAM  = 8;
-  KEY_BLUETEAM = 16;
+  MAP_SIGNATURE = 'MAP';
+
 
+const
   TEXTURE_NAME_WATER = '_water_0';
   TEXTURE_NAME_ACID1 = '_water_1';
   TEXTURE_NAME_ACID2 = '_water_2';
 
-  TEXTURE_SPECIAL_WATER = DWORD(-1);
-  TEXTURE_SPECIAL_ACID1 = DWORD(-2);
-  TEXTURE_SPECIAL_ACID2 = DWORD(-3);
-  TEXTURE_NONE = DWORD(-4);
 
 type
-  TPoint = packed record
+  TDFPoint = packed record
     X, Y: LongInt;
   end;
 
-  TTriggerData = record
-    case Byte of
-      0: (Default: Byte128);
-      TRIGGER_EXIT:         (MapName: Char16);
-      TRIGGER_TELEPORT:     (TargetPoint: TPoint;
-                             d2d_teleport: Boolean;
-                             silent_teleport: Boolean;
-                             TlpDir: Byte);
-      TRIGGER_OPENDOOR,
-      TRIGGER_CLOSEDOOR,
-      TRIGGER_DOOR,
-      TRIGGER_DOOR5,
-      TRIGGER_CLOSETRAP,
-      TRIGGER_TRAP,
-      TRIGGER_LIFTUP,
-      TRIGGER_LIFTDOWN,
-      TRIGGER_LIFT:         (PanelID: Integer;
-                             NoSound: Boolean;
-                             d2d_doors: Boolean);
-      TRIGGER_PRESS,
-      TRIGGER_ON,
-      TRIGGER_OFF,
-      TRIGGER_ONOFF:        (tX, tY: Integer;
-                             tWidth, tHeight: Word;
-                             Wait: Word;
-                             Count: Word;
-                             MonsterID: Integer;
-                             ExtRandom: Boolean);
-      TRIGGER_SECRET:       ();
-      TRIGGER_TEXTURE:      (ActivateOnce: Boolean;
-                             AnimOnce: Boolean);
-      TRIGGER_SOUND:        (SoundName: Char64;
-                             Volume: Byte;
-                             Pan: Byte;
-                             Local: Boolean;
-                             PlayCount: Byte;
-                             SoundSwitch: Boolean);
-      TRIGGER_SPAWNMONSTER: (MonPos: TPoint;
-                             MonType: Byte;
-                             MonHealth: Integer;
-                             MonDir: Byte;
-                             MonActive: Boolean;
-                             MonCount: Integer;
-                             MonEffect: Byte;
-                             MonMax: Word;
-                             MonDelay: Word;
-                             MonBehav: Byte);
-      TRIGGER_SPAWNITEM:    (ItemPos: TPoint;
-                             ItemType: Byte;
-                             ItemFalls: Boolean;
-                             ItemOnlyDM: Boolean;
-                             ItemCount: Integer;
-                             ItemEffect: Byte;
-                             ItemMax: Word;
-                             ItemDelay: Word);
-      TRIGGER_MUSIC:        (MusicName: Char64;
-                             MusicAction: Byte);
-      TRIGGER_PUSH:         (PushAngle: Word;
-                             PushForce: Byte;
-                             ResetVel: Boolean);
-      TRIGGER_SCORE:        (ScoreAction: Byte;
-                             ScoreCount: Byte;
-                             ScoreTeam: Byte;
-                             ScoreCon,
-                             ScoreMsg: Boolean);
-      TRIGGER_MESSAGE:      (MessageKind: Byte;
-                             MessageSendTo: Byte;
-                             MessageText: Char100;
-                             MessageTime: Word);
-      TRIGGER_DAMAGE:       (DamageValue: Word;
-                             DamageInterval: Word);
-      TRIGGER_HEALTH:       (HealValue: Word;
-                             HealInterval: Word;
-                             HealMax: Boolean;
-                             HealSilent: Boolean);
-      TRIGGER_SHOT:         (ShotPos: TPoint;
-                             ShotType: Byte;
-                             ShotTarget: Byte;
-                             ShotSound: Boolean;
-                             ShotAim: Byte;
-                             ShotPanelID: Integer;
-                             ShotIntSight: Word;
-                             ShotAngle: Word;
-                             ShotWait: Word;
-                             ShotAccuracy: Word;
-                             ShotAmmo: Word;
-                             ShotIntReload: Word);
-      TRIGGER_EFFECT:       (FXCount: Byte;
-                             FXType: Byte;
-                             FXSubType: Byte;
-                             FXColorR: Byte;
-                             FXColorG: Byte;
-                             FXColorB: Byte;
-                             FXPos: Byte;
-                             FXWait: Word;
-                             FXVelX: ShortInt;
-                             FXVelY: ShortInt;
-                             FXSpreadL: Byte;
-                             FXSpreadR: Byte;
-                             FXSpreadU: Byte;
-                             FXSpreadD: Byte);
-      TRIGGER_SCRIPT:       (SCRProc: Char64;
-                             SCRArg: Integer);
-  end;
+  Char16     = packed array[0..15] of Char;
+  Char32     = packed array[0..31] of Char;
+  Char64     = packed array[0..63] of Char;
+  Char100    = packed array[0..99] of Char;
+  Char256    = packed array[0..255] of Char;
+  Byte128    = packed array[0..127] of Byte;
+
+{$INCLUDE mapdef.inc}
+
+type
+  TTexturesRec1Array = array of TTextureRec_1;
+  TPanelsRec1Array = array of TPanelRec_1;
+  TItemsRec1Array = array of TItemRec_1;
+  TMonsterRec1Array = array of TMonsterRec_1;
+  TAreasRec1Array = array of TAreaRec_1;
+  TTriggersRec1Array = array of TTriggerRec_1;
+
+
+function GetMapHeader (rec: TDynRecord): TMapHeaderRec_1;
+function GetTextures (rec: TDynRecord): TTexturesRec1Array;
+function GetPanels (rec: TDynRecord): TPanelsRec1Array;
+function GetItems (rec: TDynRecord): TItemsRec1Array;
+function GetAreas (rec: TDynRecord): TAreasRec1Array;
+function GetMonsters (rec: TDynRecord): TMonsterRec1Array;
+function GetTriggers (rec: TDynRecord): TTriggersRec1Array;
 
-{$INCLUDE mapstructsizes.inc}
 
 implementation
 
-uses SysUtils;
+uses
+  e_log, xparser, xstreams;
+
+
+function GetMapHeader (rec: TDynRecord): TMapHeaderRec_1;
+var
+  ws: TSFSMemoryChunkStream = nil;
+begin
+  FillChar(result, sizeof(result), 0);
+  if (rec = nil) then exit;
+  try
+    ws := TSFSMemoryChunkStream.Create(@result, sizeof(result));
+    rec.writeBinTo(ws, -1, true); // only fields
+  except // sorry
+    FillChar(result, sizeof(result), 0);
+  end;
+  ws.Free();
+end;
+
+
+function GetTextures (rec: TDynRecord): TTexturesRec1Array;
+var
+  ws: TSFSMemoryChunkStream = nil;
+  fld: TDynField;
+  f: Integer;
+begin
+  result := nil;
+  fld := rec.field['texture'];
+  if (fld = nil) or (fld.baseType <> fld.TType.TList) or (fld.list.count = 0) then exit;
+  ws := TSFSMemoryChunkStream.Create(nil, 0);
+  try
+    SetLength(result, fld.list.count);
+    for f := 0 to fld.list.count-1 do
+    begin
+      FillChar(result[f], sizeof(result[f]), 0);
+      ws.setup(@result[f], sizeof(result[f]));
+      fld.list[f].writeBinTo(ws, -1, true); // only fields
+    end;
+  except
+    result := nil;
+  end;
+  ws.Free();
+end;
+
+
+function GetPanels (rec: TDynRecord): TPanelsRec1Array;
+var
+  ws: TSFSMemoryChunkStream = nil;
+  fld: TDynField;
+  f: Integer;
+begin
+  result := nil;
+  fld := rec.field['panel'];
+  if (fld = nil) or (fld.baseType <> fld.TType.TList) or (fld.list.count = 0) then exit;
+  ws := TSFSMemoryChunkStream.Create(nil, 0);
+  try
+    SetLength(result, fld.list.count);
+    for f := 0 to fld.list.count-1 do
+    begin
+      FillChar(result[f], sizeof(result[f]), 0);
+      ws.setup(@result[f], sizeof(result[f]));
+      fld.list[f].writeBinTo(ws, -1, true); // only fields
+    end;
+  except
+    result := nil;
+  end;
+  ws.Free();
+end;
+
+
+function GetItems (rec: TDynRecord): TItemsRec1Array;
+var
+  ws: TSFSMemoryChunkStream = nil;
+  fld: TDynField;
+  f: Integer;
+begin
+  result := nil;
+  fld := rec.field['item'];
+  if (fld = nil) or (fld.baseType <> fld.TType.TList) or (fld.list.count = 0) then exit;
+  ws := TSFSMemoryChunkStream.Create(nil, 0);
+  try
+    SetLength(result, fld.list.count);
+    for f := 0 to fld.list.count-1 do
+    begin
+      FillChar(result[f], sizeof(result[f]), 0);
+      ws.setup(@result[f], sizeof(result[f]));
+      fld.list[f].writeBinTo(ws, -1, true); // only fields
+    end;
+  except
+    result := nil;
+  end;
+  ws.Free();
+end;
+
+
+function GetAreas (rec: TDynRecord): TAreasRec1Array;
+var
+  ws: TSFSMemoryChunkStream = nil;
+  fld: TDynField;
+  f: Integer;
+begin
+  result := nil;
+  fld := rec.field['area'];
+  if (fld = nil) or (fld.baseType <> fld.TType.TList) or (fld.list.count = 0) then exit;
+  ws := TSFSMemoryChunkStream.Create(nil, 0);
+  try
+    SetLength(result, fld.list.count);
+    for f := 0 to fld.list.count-1 do
+    begin
+      FillChar(result[f], sizeof(result[f]), 0);
+      ws.setup(@result[f], sizeof(result[f]));
+      fld.list[f].writeBinTo(ws, -1, true); // only fields
+    end;
+  except
+    result := nil;
+  end;
+  ws.Free();
+end;
+
+
+function GetMonsters (rec: TDynRecord): TMonsterRec1Array;
+var
+  ws: TSFSMemoryChunkStream = nil;
+  fld: TDynField;
+  f: Integer;
+begin
+  result := nil;
+  fld := rec.field['monster'];
+  if (fld = nil) or (fld.baseType <> fld.TType.TList) or (fld.list.count = 0) then exit;
+  ws := TSFSMemoryChunkStream.Create(nil, 0);
+  try
+    SetLength(result, fld.list.count);
+    for f := 0 to fld.list.count-1 do
+    begin
+      FillChar(result[f], sizeof(result[f]), 0);
+      ws.setup(@result[f], sizeof(result[f]));
+      fld.list[f].writeBinTo(ws, -1, true); // only fields
+    end;
+  except
+    result := nil;
+  end;
+  ws.Free();
+end;
+
+
+function GetTriggers (rec: TDynRecord): TTriggersRec1Array;
+var
+  ws: TSFSMemoryChunkStream = nil;
+  fld: TDynField;
+  f: Integer;
+  //wr: TTextWriter;
+  //fo: File;
+begin
+  result := nil;
+  fld := rec.field['trigger'];
+  if (fld = nil) or (fld.baseType <> fld.TType.TList) or (fld.list.count = 0) then exit;
+  ws := TSFSMemoryChunkStream.Create(nil, 0);
+  try
+    //wr := TFileTextWriter.Create('z00.txt');
+    SetLength(result, fld.list.count);
+    for f := 0 to fld.list.count-1 do
+    begin
+      FillChar(result[f], sizeof(result[f]), 0);
+      //e_LogWritefln(': trigger #%s; TexturePanel=%s', [f, result[f].TexturePanel]);
+      ws.setup(@result[f], sizeof(result[f]));
+      fld.list[f].writeBinTo(ws, -1, true); // only fields
+      {
+      e_LogWritefln(': trigger #%s; X=%s; Y=%s; Width=%s; Height=%s; Enabled=%s; TexturePanel=%s; TriggerType=%s; ActivateType=%s; Keys=%s', [f,
+       result[f].X,
+       result[f].Y,
+       result[f].Width,
+       result[f].Height,
+       result[f].Enabled,
+       result[f].TexturePanel,
+       result[f].TriggerType,
+       result[f].ActivateType,
+       result[f].Keys
+       ]);
+      //e_LogWritefln('***'#10'%s'#10'***', [);
+      fld.list[f].writeTo(wr);
+      if (f = 0) then
+      begin
+        AssignFile(fo, 'z00.bin');
+        Rewrite(fo, 1);
+        BlockWrite(fo, result[f], sizeof(result[f]));
+        CloseFile(fo);
+      end;
+      }
+    end;
+    //wr.Free();
+  except
+    result := nil;
+  end;
+  ws.Free();
+end;
 
-{$INCLUDE mapstructio.inc}
 
 end.
diff --git a/src/shared/MAPREADER.pas b/src/shared/MAPREADER.pas
deleted file mode 100644 (file)
index 4ea7beb..0000000
+++ /dev/null
@@ -1,424 +0,0 @@
-(* Copyright (C)  DooM 2D:Forever Developers
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *)
-{$INCLUDE a_modes.inc}
-unit MAPREADER;
-
-{
------------------------------------
-MAPREADER.PAS ÂÅÐÑÈß ÎÒ 13.11.07
-
-Ïîääåðæêà êàðò âåðñèè 1
------------------------------------
-}
-
-interface
-
-uses
-  MAPSTRUCT;
-
-type
-  TDataBlock = packed record
-   Block: TBlock;
-   Data:  Pointer;
-  end;
-
-  TDataBlocksArray = packed array of TDataBlock;
-
-  TMapReader = class(TObject)
-   private
-    FError: Byte;
-    FVersion: Byte;
-    FDataBlocks: TDataBlocksArray;
-    function GetBlocks(BlocksType: Byte): TDataBlocksArray;
-   public
-    constructor Create();
-    destructor Destroy(); override;
-    function LoadMap(Data: Pointer): Boolean;
-    procedure FreeMap();
-    function HandledVersion(): Byte; virtual;
-
-    property GetError: Byte read FError;
-    property GetVersion: Byte read FVersion;
-  end;
-
-  TMapReader_1 = class(TMapReader)
-   private
-   public
-    function GetMapHeader(): TMapHeaderRec_1;
-    function GetTextures(): TTexturesRec1Array;
-    function GetPanels(): TPanelsRec1Array;
-    function GetItems(): TItemsRec1Array;
-    function GetAreas(): TAreasRec1Array;
-    function GetMonsters(): TMonsterRec1Array;
-    function GetTriggers(): TTriggersRec1Array;
-    function HandledVersion(): Byte; override;
-  end;
-
-const
-  MAP_ERROR_NONE      = $00;
-  MAP_ERROR_SIGNATURE = $01;
-  MAP_ERROR_VERSION   = $02;
-
-  NNF_NO_NAME         = 0;
-  NNF_NAME_BEFORE     = 1;
-  NNF_NAME_EQUALS     = 2;
-  NNF_NAME_AFTER      = 3;
-
-function g_Texture_NumNameFindStart(name: String): Boolean;
-function g_Texture_NumNameFindNext(var newName: String): Byte;
-
-implementation
-
-uses
-  SysUtils, BinEditor, MAPDEF;
-
-var
-  NNF_PureName: String; // Èìÿ òåêñòóðû áåç öèôð â êîíöå
-  NNF_FirstNum: Integer; // ×èñëî ó íà÷àëüíîé òåêñòóðû
-  NNF_CurrentNum: Integer; // Ñëåäóþùåå ÷èñëî ó òåêñòóðû
-
-function g_Texture_NumNameFindStart(name: String): Boolean;
-var
-  i: Integer;
-
-begin
-  Result := False;
-  NNF_PureName := '';
-  NNF_FirstNum := -1;
-  NNF_CurrentNum := -1;
-
-  for i := Length(name) downto 1 do
-    if (name[i] = '_') then // "_" - ñèìâîë íà÷àëà íîìåðíîãî ïîñòôèêñà
-    begin
-      if i = Length(name) then
-        begin // Íåò öèôð â êîíöå ñòðîêè
-          Exit;
-        end
-      else
-        begin
-          NNF_PureName := Copy(name, 1, i);
-          Delete(name, 1, i);
-          Break;
-        end;
-    end;
-
-// Íå ïåðåâåñòè â ÷èñëî:
-  if not TryStrToInt(name, NNF_FirstNum) then
-    Exit;
-
-  NNF_CurrentNum := 0;
-
-  Result := True;
-end;
-
-function g_Texture_NumNameFindNext(var newName: String): Byte;
-begin
-  if (NNF_PureName = '') or (NNF_CurrentNum < 0) then
-  begin
-    newName := '';
-    Result := NNF_NO_NAME;
-    Exit;
-  end;
-
-  newName := NNF_PureName + IntToStr(NNF_CurrentNum);
-
-  if NNF_CurrentNum < NNF_FirstNum then
-    Result := NNF_NAME_BEFORE
-  else
-    if NNF_CurrentNum > NNF_FirstNum then
-      Result := NNF_NAME_AFTER
-    else
-      Result := NNF_NAME_EQUALS;
-
-  Inc(NNF_CurrentNum);
-end;
-
-{ T M a p R e a d e r _ 1 : }
-
-function TMapReader_1.GetAreas(): TAreasRec1Array;
-var
-  TempDataBlocks: TDataBlocksArray;
-  a: Integer;
-  b, Size: NativeUInt;
-begin
- Result := nil;
-
- TempDataBlocks := GetBlocks(BLOCK_AREAS);
-
- if TempDataBlocks = nil then Exit;
-
- size := SizeOf_TAreaRec_1;
-
- for a := 0 to High(TempDataBlocks) do
-  for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
-  begin
-   SetLength(Result, Length(Result)+1);
-   //CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
-   mb_Read_TAreaRec_1(Result[High(Result)], Pointer(NativeUInt(TempDataBlocks[a].Data)+b*size)^, size);
-  end;
-
- TempDataBlocks := nil;
-end;
-
-function TMapReader_1.GetItems(): TItemsRec1Array;
-var
-  TempDataBlocks: TDataBlocksArray;
-  a: Integer;
-  b, Size: NativeUInt;
-begin
- Result := nil;
-
- TempDataBlocks := GetBlocks(BLOCK_ITEMS);
-
- if TempDataBlocks = nil then Exit;
-
- size := SizeOf_TItemRec_1;
-
- for a := 0 to High(TempDataBlocks) do
-  for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
-  begin
-   SetLength(Result, Length(Result)+1);
-   //CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
-   mb_Read_TItemRec_1(Result[High(Result)], Pointer(NativeUInt(TempDataBlocks[a].Data)+b*size)^, size);
-  end;
-
- TempDataBlocks := nil;
-end;
-
-function TMapReader_1.GetMapHeader(): TMapHeaderRec_1;
-var
-  TempDataBlocks: TDataBlocksArray;
-begin
- ZeroMemory(@Result, SizeOf(TMapHeaderRec_1));
-
- TempDataBlocks := GetBlocks(BLOCK_HEADER);
-
- if TempDataBlocks = nil then Exit;
-
- //CopyMemory(@Result, TempDataBlocks[0].Data, SizeOf(TMapHeaderRec_1));
- mb_Read_TMapHeaderRec_1(Result, TempDataBlocks[0].Data^, SizeOf_TMapHeaderRec_1);
-
- TempDataBlocks := nil;
-end;
-
-function TMapReader_1.GetMonsters(): TMonsterRec1Array;
-var
-  TempDataBlocks: TDataBlocksArray;
-  a: Integer;
-  b, Size: NativeUInt;
-begin
- Result := nil;
-
- TempDataBlocks := GetBlocks(BLOCK_MONSTERS);
-
- if TempDataBlocks = nil then Exit;
-
- size := SizeOf_TMonsterRec_1;
-
- for a := 0 to High(TempDataBlocks) do
-  for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
-  begin
-   SetLength(Result, Length(Result)+1);
-   //CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
-   mb_Read_TMonsterRec_1(Result[High(Result)], Pointer(NativeUInt(TempDataBlocks[a].Data)+b*size)^, size);
-  end;
-
- TempDataBlocks := nil;
-end;
-
-function TMapReader_1.GetPanels(): TPanelsRec1Array;
-var
-  TempDataBlocks: TDataBlocksArray;
-  a: Integer;
-  b, Size: NativeUInt;
-begin
- Result := nil;
-
- TempDataBlocks := GetBlocks(BLOCK_PANELS);
-
- if TempDataBlocks = nil then Exit;
-
- size := SizeOf_TPanelRec_1;
-
- for a := 0 to High(TempDataBlocks) do
-  for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
-  begin
-   SetLength(Result, Length(Result)+1);
-   //CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
-   mb_Read_TPanelRec_1(Result[High(Result)], Pointer(NativeUInt(TempDataBlocks[a].Data)+b*size)^, size);
-  end;
-
- TempDataBlocks := nil;
-end;
-
-function TMapReader_1.GetTextures(): TTexturesRec1Array;
-var
-  TempDataBlocks: TDataBlocksArray;
-  a: Integer;
-  b, Size: NativeUInt;
-begin
- Result := nil;
-
- TempDataBlocks := GetBlocks(BLOCK_TEXTURES);
-
- if TempDataBlocks = nil then Exit;
-
- size := SizeOf_TTextureRec_1;
-
- for a := 0 to High(TempDataBlocks) do
-  for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
-  begin
-   SetLength(Result, Length(Result)+1);
-    //CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
-    mb_Read_TTextureRec_1(Result[High(Result)], Pointer(NativeUInt(TempDataBlocks[a].Data)+b*size)^, size);
-  end;
-
- TempDataBlocks := nil;
-end;
-
-function TMapReader_1.GetTriggers(): TTriggersRec1Array;
-var
-  TempDataBlocks: TDataBlocksArray;
-  a: Integer;
-  b: NativeUInt;
-  Size: LongWord;
-  trdata: TTriggerData;
-begin
- Result := nil;
-
- TempDataBlocks := GetBlocks(BLOCK_TRIGGERS);
-
- if TempDataBlocks = nil then Exit;
-
- size := SizeOf_TTriggerRec_1;
-
- for a := 0 to High(TempDataBlocks) do
-  for b := 0 to (TempDataBlocks[a].Block.BlockSize div size)-1 do
-  begin
-   SetLength(Result, Length(Result)+1);
-   //CopyMemory(@Result[High(Result)], Pointer(LongWord(TempDataBlocks[a].Data)+b*size), size);
-   mb_Read_TTriggerRec_1(Result[High(Result)], Pointer(NativeUInt(TempDataBlocks[a].Data)+b*size)^, size);
-   if (Result[High(Result)].TriggerType <> 0) then
-   begin
-     // preprocess trigger data
-     ZeroMemory(@trdata, SizeOf(trdata));
-     mb_Read_TriggerData(trdata, Result[High(Result)].TriggerType, Result[High(Result)].DATA, sizeof(trdata));
-     Result[High(Result)].DATA := trdata.Default;
-   end;
-  end;
-
- TempDataBlocks := nil;
-end;
-
-function TMapReader_1.HandledVersion: Byte;
-begin
- Result := $01;
-end;
-
-{ T M a p R e a d e r : }
-
-constructor TMapReader.Create();
-begin
- FDataBlocks := nil;
- FError := MAP_ERROR_NONE;
- FVersion := $00;
-end;
-
-destructor TMapReader.Destroy();
-begin
- FreeMap();
-
- inherited;
-end;
-
-procedure TMapReader.FreeMap();
-var
-  a: Integer;
-begin
- if FDataBlocks <> nil then
-  for a := 0 to High(FDataBlocks) do
-   if FDataBlocks[a].Data <> nil then FreeMem(FDataBlocks[a].Data);
-
- FDataBlocks := nil;
- FVersion := $00;
- FError := MAP_ERROR_NONE;
-end;
-
-function TMapReader.GetBlocks(BlocksType: Byte): TDataBlocksArray;
-var
-  a: Integer;
-begin
- Result := nil;
-
- if FDataBlocks = nil then Exit;
-
- for a := 0 to High(FDataBlocks) do
-  if FDataBlocks[a].Block.BlockType = BlocksType then
-  begin
-   SetLength(Result, Length(Result)+1);
-    Result[High(Result)] := FDataBlocks[a];
-  end;
-end;
-
-function TMapReader.HandledVersion(): Byte;
-begin
- Result := $00;
-end;
-
-function TMapReader.LoadMap(Data: Pointer): Boolean;
-var
-  adr: NativeUInt;
-  _id: Integer;
-  Sign: array[0..2] of Char;
-  Ver: Byte;
-begin
- Result := False;
-
- CopyMemory(@Sign[0], Data, 3);
- if Sign <> MAP_SIGNATURE then
- begin
-  FError := MAP_ERROR_SIGNATURE;
-  Exit;
- end;
- adr := 3;
-
- CopyMemory(@Ver, Pointer(NativeUInt(Data)+adr), 1);
- FVersion := Ver;
- if Ver > HandledVersion() then
- begin
-  FError := MAP_ERROR_VERSION;
-  Exit;
- end;
- adr := adr+1;
-
- repeat
-  SetLength(FDataBlocks, Length(FDataBlocks)+1);
-  _id := High(FDataBlocks);
-
-  CopyMemory(@FDataBlocks[_id].Block, Pointer(NativeUInt(Data)+adr), SizeOf(TBlock));
-  adr := adr+SizeOf(TBlock);
-
-  FDataBlocks[_id].Data := GetMemory(FDataBlocks[_id].Block.BlockSize);
-
-  CopyMemory(FDataBlocks[_id].Data, Pointer(NativeUInt(Data)+adr), FDataBlocks[_id].Block.BlockSize);
-
-  adr := adr+FDataBlocks[_id].Block.BlockSize;
- until FDataBlocks[_id].Block.BlockType = BLOCK_NONE;
-
- Result := True;
-end;
-
-end.
diff --git a/src/shared/MAPSTRUCT.pas b/src/shared/MAPSTRUCT.pas
deleted file mode 100644 (file)
index f2bc726..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-(* Copyright (C)  DooM 2D:Forever Developers
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *)
-{$INCLUDE a_modes.inc}
-{$M+}
-unit MAPSTRUCT;
-
-{
------------------------------------
-MAPSTRUCT.PAS ÂÅÐÑÈß ÎÒ 13.11.07
-
-Ïîääåðæêà êàðò âåðñèè 1
------------------------------------
-}
-
-{
- Êàðòà ïðåäñòàâëÿåò ñîáîþ WAD, â êîòîðîì ðåñóðñû â êîðíå - ñîáñòâåííî ñàìè êàðòû
- (MAP01, MAP02 è ò.ä.).
-
- Áëîêè çàêàí÷èâàþòñÿ íóëåâûì áëîêîì (BlockType=BLOCK_NONE)
-
- Ñòðóêòóðà êàðòû (MAP01, MAP02...):
- --------------------------------------
- SIGNATURE    | Byte[3]         | 'MAP'
- VERSION      | Byte            | $01
- BLOCK1       | TBlock          |
- BLOCK1DATA   | RAW             |
- ...          | ......          |
- BLOCKN       | TBlock          |
- BLOCKNDATA   | RAW             |
- --------------------------------------
-
- Ñòðóêòóðà áëîêà:
- --------------------------------------
- BLOCKTYPE    | Byte     | (BLOCK_TEXTURES, BLOCK_PANELS,...)
- RESERVED     | LongWord | $00000000
- BLOCKSIZE    | LongWord | Ñêîëüêî ýòîò áëîê â ðàçìåðå (áàéò ïîñëå record'à)
- --------------------------------------
-}
-
-interface
-
-const
-  MAP_SIGNATURE = 'MAP';
-  BLOCK_NONE      = 0;
-  BLOCK_TEXTURES  = 1;
-  BLOCK_PANELS    = 2;
-  BLOCK_ITEMS     = 3;
-  BLOCK_AREAS     = 4;
-  BLOCK_MONSTERS  = 5;
-  BLOCK_TRIGGERS  = 6;
-  BLOCK_HEADER    = 7;
-
-type
-  Char16     = packed array[0..15] of Char;
-  Char32     = packed array[0..31] of Char;
-  Char64     = packed array[0..63] of Char;
-  Char100    = packed array[0..99] of Char;
-  Char256    = packed array[0..255] of Char;
-  Byte128    = packed array[0..127] of Byte;
-
-  TMapHeaderRec_1 = packed record
-   MapName:        Char32;
-   MapAuthor:      Char32;
-   MapDescription: Char256;
-   MusicName:      Char64;
-   SkyName:        Char64;
-   Width:          Word;
-   Height:         Word;
-  end;
-
-  TTextureRec_1 = packed record
-   Resource: Char64;
-   Anim:     Byte;
-  end;
-
-  TPanelRec_1 = packed record
-   X, Y:       Integer;
-   Width,
-   Height:     Word;
-   TextureNum: Word;
-   PanelType:  Word;
-   Alpha:      Byte;
-   Flags:      Byte;
-  end;
-
-  TItemRec_1 = packed record
-   X, Y:     Integer;
-   ItemType: Byte;
-   Options:  Byte;
-  end;
-
-  TMonsterRec_1 = packed record
-   X, Y:        Integer;
-   MonsterType: Byte;
-   Direction:   Byte;
-  end;
-
-  TAreaRec_1 = packed record
-   X, Y:      Integer;
-   AreaType:  Byte;
-   Direction: Byte;
-  end;
-
-  TTriggerRec_1 = packed record
-   X, Y:         Integer;
-   Width,
-   Height:       Word;
-   Enabled:      Byte;
-   TexturePanel: Integer;
-   TriggerType:  Byte;
-   ActivateType: Byte;
-   Keys:         Byte;
-   DATA:         Byte128; //WARNING! should be exactly equal to sizeof(TTriggerData)
-  end;
-
-  TBlock = packed record
-   BlockType: Byte;
-   Reserved:  LongWord;
-   BlockSize: LongWord;
-  end;
-
-  TTexturesRec1Array = array of TTextureRec_1;
-  TPanelsRec1Array = array of TPanelRec_1;
-  TItemsRec1Array = array of TItemRec_1;
-  TMonsterRec1Array = array of TMonsterRec_1;
-  TAreasRec1Array = array of TAreaRec_1;
-  TTriggersRec1Array = array of TTriggerRec_1;
-
-implementation
-
-end.
diff --git a/src/shared/mapdef.inc b/src/shared/mapdef.inc
new file mode 100644 (file)
index 0000000..595dff4
--- /dev/null
@@ -0,0 +1,1148 @@
+// *** WARNING! ***
+//   regenerate this part directly from "mapdef.txt" with 'zmapgen', NEVER manually change anything here!
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+// enums and bitsets
+
+// TextureSpecial
+const
+  TEXTURE_SPECIAL_WATER = -1;
+  TEXTURE_SPECIAL_ACID1 = -2;
+  TEXTURE_SPECIAL_ACID2 = -3;
+  TEXTURE_NONE = -4;
+
+// DirType
+const
+  DIR_LEFT = 0;
+  DIR_RIGHT = 1;
+  DIR_SOMETHING2 = 2;
+
+// TriggerType
+const
+  TRIGGER_NONE = 0;
+  TRIGGER_EXIT = 1;
+  TRIGGER_TELEPORT = 2;
+  TRIGGER_OPENDOOR = 3;
+  TRIGGER_CLOSEDOOR = 4;
+  TRIGGER_DOOR = 5;
+  TRIGGER_DOOR5 = 6;
+  TRIGGER_CLOSETRAP = 7;
+  TRIGGER_TRAP = 8;
+  TRIGGER_PRESS = 9;
+  TRIGGER_SECRET = 10;
+  TRIGGER_LIFTUP = 11;
+  TRIGGER_LIFTDOWN = 12;
+  TRIGGER_LIFT = 13;
+  TRIGGER_TEXTURE = 14;
+  TRIGGER_ON = 15;
+  TRIGGER_OFF = 16;
+  TRIGGER_ONOFF = 17;
+  TRIGGER_SOUND = 18;
+  TRIGGER_SPAWNMONSTER = 19;
+  TRIGGER_SPAWNITEM = 20;
+  TRIGGER_MUSIC = 21;
+  TRIGGER_PUSH = 22;
+  TRIGGER_SCORE = 23;
+  TRIGGER_MESSAGE = 24;
+  TRIGGER_DAMAGE = 25;
+  TRIGGER_HEALTH = 26;
+  TRIGGER_SHOT = 27;
+  TRIGGER_EFFECT = 28;
+  TRIGGER_SCRIPT = 29;
+  TRIGGER_MAX = 29;
+
+// PanelType
+const
+  PANEL_NONE = 0;
+  PANEL_WALL = 1;
+  PANEL_BACK = 2;
+  PANEL_FORE = 4;
+  PANEL_WATER = 8;
+  PANEL_ACID1 = 16;
+  PANEL_ACID2 = 32;
+  PANEL_STEP = 64;
+  PANEL_LIFTUP = 128;
+  PANEL_LIFTDOWN = 256;
+  PANEL_OPENDOOR = 512;
+  PANEL_CLOSEDOOR = 1024;
+  PANEL_BLOCKMON = 2048;
+  PANEL_LIFTLEFT = 4096;
+  PANEL_LIFTRIGHT = 8192;
+
+// PanelFlag
+const
+  PANEL_FLAG_NONE = 0;
+  PANEL_FLAG_BLENDING = 1;
+  PANEL_FLAG_HIDE = 2;
+  PANEL_FLAG_WATERTEXTURES = 4;
+
+// EffectAction
+const
+  EFFECT_NONE = 0;
+  EFFECT_TELEPORT = 1;
+  EFFECT_RESPAWN = 2;
+  EFFECT_FIRE = 3;
+
+// Item
+const
+  ITEM_NONE = 0;
+  ITEM_MEDKIT_SMALL = 1;
+  ITEM_MEDKIT_LARGE = 2;
+  ITEM_MEDKIT_BLACK = 3;
+  ITEM_ARMOR_GREEN = 4;
+  ITEM_ARMOR_BLUE = 5;
+  ITEM_SPHERE_BLUE = 6;
+  ITEM_SPHERE_WHITE = 7;
+  ITEM_SUIT = 8;
+  ITEM_OXYGEN = 9;
+  ITEM_INVUL = 10;
+  ITEM_WEAPON_SAW = 11;
+  ITEM_WEAPON_SHOTGUN1 = 12;
+  ITEM_WEAPON_SHOTGUN2 = 13;
+  ITEM_WEAPON_CHAINGUN = 14;
+  ITEM_WEAPON_ROCKETLAUNCHER = 15;
+  ITEM_WEAPON_PLASMA = 16;
+  ITEM_WEAPON_BFG = 17;
+  ITEM_WEAPON_SUPERPULEMET = 18;
+  ITEM_AMMO_BULLETS = 19;
+  ITEM_AMMO_BULLETS_BOX = 20;
+  ITEM_AMMO_SHELLS = 21;
+  ITEM_AMMO_SHELLS_BOX = 22;
+  ITEM_AMMO_ROCKET = 23;
+  ITEM_AMMO_ROCKET_BOX = 24;
+  ITEM_AMMO_CELL = 25;
+  ITEM_AMMO_CELL_BIG = 26;
+  ITEM_AMMO_BACKPACK = 27;
+  ITEM_KEY_RED = 28;
+  ITEM_KEY_GREEN = 29;
+  ITEM_KEY_BLUE = 30;
+  ITEM_WEAPON_KASTET = 31;
+  ITEM_WEAPON_PISTOL = 32;
+  ITEM_BOTTLE = 33;
+  ITEM_HELMET = 34;
+  ITEM_JETPACK = 35;
+  ITEM_INVIS = 36;
+  ITEM_WEAPON_FLAMETHROWER = 37;
+  ITEM_AMMO_FUELCAN = 38;
+  ITEM_MAX = 38;
+
+// ItemOption
+const
+  ITEM_OPTION_NONE = 0;
+  ITEM_OPTION_ONLYDM = 1;
+  ITEM_OPTION_FALL = 2;
+
+// AreaType
+const
+  AREA_NONE = 0;
+  AREA_PLAYERPOINT1 = 1;
+  AREA_PLAYERPOINT2 = 2;
+  AREA_DMPOINT = 3;
+  AREA_REDFLAG = 4;
+  AREA_BLUEFLAG = 5;
+  AREA_DOMFLAG = 6;
+  AREA_REDTEAMPOINT = 7;
+  AREA_BLUETEAMPOINT = 8;
+
+// Monster
+const
+  MONSTER_NONE = 0;
+  MONSTER_DEMON = 1;
+  MONSTER_IMP = 2;
+  MONSTER_ZOMBY = 3;
+  MONSTER_SERG = 4;
+  MONSTER_CYBER = 5;
+  MONSTER_CGUN = 6;
+  MONSTER_BARON = 7;
+  MONSTER_KNIGHT = 8;
+  MONSTER_CACO = 9;
+  MONSTER_SOUL = 10;
+  MONSTER_PAIN = 11;
+  MONSTER_SPIDER = 12;
+  MONSTER_BSP = 13;
+  MONSTER_MANCUB = 14;
+  MONSTER_SKEL = 15;
+  MONSTER_VILE = 16;
+  MONSTER_FISH = 17;
+  MONSTER_BARREL = 18;
+  MONSTER_ROBO = 19;
+  MONSTER_MAN = 20;
+
+// TriggerShot
+const
+  TRIGGER_SHOT_PISTOL = 0;
+  TRIGGER_SHOT_BULLET = 1;
+  TRIGGER_SHOT_SHOTGUN = 2;
+  TRIGGER_SHOT_SSG = 3;
+  TRIGGER_SHOT_IMP = 4;
+  TRIGGER_SHOT_PLASMA = 5;
+  TRIGGER_SHOT_SPIDER = 6;
+  TRIGGER_SHOT_CACO = 7;
+  TRIGGER_SHOT_BARON = 8;
+  TRIGGER_SHOT_MANCUB = 9;
+  TRIGGER_SHOT_REV = 10;
+  TRIGGER_SHOT_ROCKET = 11;
+  TRIGGER_SHOT_BFG = 12;
+  TRIGGER_SHOT_EXPL = 13;
+  TRIGGER_SHOT_BFGEXPL = 14;
+  TRIGGER_SHOT_MAX = 14;
+
+// TriggerShotTarget
+const
+  TRIGGER_SHOT_TARGET_NONE = 0;
+  TRIGGER_SHOT_TARGET_MON = 1;
+  TRIGGER_SHOT_TARGET_PLR = 2;
+  TRIGGER_SHOT_TARGET_RED = 3;
+  TRIGGER_SHOT_TARGET_BLUE = 4;
+  TRIGGER_SHOT_TARGET_MONPLR = 5;
+  TRIGGER_SHOT_TARGET_PLRMON = 6;
+
+// TriggerShotAim
+const
+  TRIGGER_SHOT_AIM_DEFAULT = 0;
+  TRIGGER_SHOT_AIM_ALLMAP = 1;
+  TRIGGER_SHOT_AIM_TRACE = 2;
+  TRIGGER_SHOT_AIM_TRACEALL = 3;
+
+// TriggerEffect
+const
+  TRIGGER_EFFECT_PARTICLE = 0;
+  TRIGGER_EFFECT_ANIMATION = 1;
+
+// TriggerEffectType
+const
+  TRIGGER_EFFECT_SLIQUID = 0;
+  TRIGGER_EFFECT_LLIQUID = 1;
+  TRIGGER_EFFECT_DLIQUID = 2;
+  TRIGGER_EFFECT_BLOOD = 3;
+  TRIGGER_EFFECT_SPARK = 4;
+  TRIGGER_EFFECT_BUBBLE = 5;
+  TRIGGER_EFFECT_MAX = 5;
+
+// TriggerEffectPos
+const
+  TRIGGER_EFFECT_POS_CENTER = 0;
+  TRIGGER_EFFECT_POS_AREA = 1;
+
+// ActivateType
+const
+  ACTIVATE_NONE = 0;
+  ACTIVATE_PLAYERCOLLIDE = 1;
+  ACTIVATE_MONSTERCOLLIDE = 2;
+  ACTIVATE_PLAYERPRESS = 4;
+  ACTIVATE_MONSTERPRESS = 8;
+  ACTIVATE_SHOT = 16;
+  ACTIVATE_NOMONSTER = 32;
+  ACTIVATE_CUSTOM = 255;
+
+// Key
+const
+  KEY_NONE = 0;
+  KEY_RED = 1;
+  KEY_GREEN = 2;
+  KEY_BLUE = 4;
+  KEY_REDTEAM = 8;
+  KEY_BLUETEAM = 16;
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+// records
+type
+  TMapHeaderRec_1 = packed record
+    MapName: Char32;
+    MapAuthor: Char32;
+    MapDescription: Char256;
+    MusicName: Char64;
+    SkyName: Char64;
+    Width, Height: Word;
+  end;
+
+  TTextureRec_1 = packed record
+    Resource: Char64;
+    Anim: Boolean;
+  end;
+
+  TPanelRec_1 = packed record
+    X, Y: Integer;
+    Width, Height: Word;
+    TextureNum: Word;
+    PanelType: Word;
+    Alpha: Byte;
+    Flags: Byte;
+  end;
+
+  TItemRec_1 = packed record
+    X, Y: Integer;
+    ItemType: Byte;
+    Options: Byte;
+  end;
+
+  TMonsterRec_1 = packed record
+    X, Y: Integer;
+    MonsterType: Byte;
+    Direction: Byte;
+  end;
+
+  TAreaRec_1 = packed record
+    X, Y: Integer;
+    AreaType: Byte;
+    Direction: Byte;
+  end;
+
+  TTriggerRec_1 = packed record
+    X, Y: Integer;
+    Width, Height: Word;
+    Enabled: Boolean;
+    TexturePanel: LongInt;
+    TriggerType: Byte;
+    ActivateType: Byte;
+    Keys: Byte;
+    DATA: Byte128;
+  end;
+
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+// triggerdata
+type
+  TTriggerData = record
+    case Byte of
+      0: (Default: Byte128);
+      TRIGGER_EXIT: (
+        MapName: Char16;
+      );
+      TRIGGER_TELEPORT: (
+        TargetPoint: TDFPoint;
+        d2d_teleport: Boolean;
+        silent_teleport: Boolean;
+        TlpDir: Byte;
+      );
+      TRIGGER_OPENDOOR, TRIGGER_CLOSEDOOR, TRIGGER_DOOR, TRIGGER_DOOR5, TRIGGER_CLOSETRAP, TRIGGER_TRAP, TRIGGER_LIFTUP, TRIGGER_LIFTDOWN, TRIGGER_LIFT: (
+        PanelID: LongInt;
+        NoSound: Boolean;
+        d2d_doors: Boolean;
+      );
+      TRIGGER_PRESS, TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF: (
+        tX, tY: Integer;
+        tWidth, tHeight: Word;
+        Wait: Word;
+        Count: Word;
+        MonsterID: LongInt;
+        ExtRandom: Boolean;
+      );
+      TRIGGER_SECRET: (
+      );
+      TRIGGER_TEXTURE: (
+        ActivateOnce: Boolean;
+        AnimOnce: Boolean;
+      );
+      TRIGGER_SOUND: (
+        SoundName: Char64;
+        Volume: Byte;
+        Pan: Byte;
+        Local: Boolean;
+        PlayCount: Byte;
+        SoundSwitch: Boolean;
+      );
+      TRIGGER_SPAWNMONSTER: (
+        MonPos: TDFPoint;
+        MonType: Byte;
+        MonHealth: LongInt;
+        MonDir: Byte;
+        MonActive: Boolean;
+        MonCount: LongInt;
+        MonEffect: Byte;
+        MonMax: Word;
+        MonDelay: Word;
+        MonBehav: Byte;
+      );
+      TRIGGER_SPAWNITEM: (
+        ItemPos: TDFPoint;
+        ItemType: Byte;
+        ItemFalls: Boolean;
+        ItemOnlyDM: Boolean;
+        ItemCount: LongInt;
+        ItemEffect: Byte;
+        ItemMax: Word;
+        ItemDelay: Word;
+      );
+      TRIGGER_MUSIC: (
+        MusicName: Char64;
+        MusicAction: Byte;
+      );
+      TRIGGER_PUSH: (
+        PushAngle: Word;
+        PushForce: Byte;
+        ResetVel: Boolean;
+      );
+      TRIGGER_SCORE: (
+        ScoreAction: Byte;
+        ScoreCount: Byte;
+        ScoreTeam: Byte;
+        ScoreCon: Boolean;
+        ScoreMsg: Boolean;
+      );
+      TRIGGER_MESSAGE: (
+        MessageKind: Byte;
+        MessageSendTo: Byte;
+        MessageText: Char100;
+        MessageTime: Word;
+      );
+      TRIGGER_DAMAGE: (
+        DamageValue: Word;
+        DamageInterval: Word;
+      );
+      TRIGGER_HEALTH: (
+        HealValue: Word;
+        HealInterval: Word;
+        HealMax: Boolean;
+        HealSilent: Boolean;
+      );
+      TRIGGER_SHOT: (
+        ShotPos: TDFPoint;
+        ShotType: Byte;
+        ShotTarget: Byte;
+        ShotSound: Boolean;
+        ShotAim: ShortInt;
+        ShotPanelID: LongInt;
+        ShotIntSight: Word;
+        ShotAngle: Word;
+        ShotWait: Word;
+        ShotAccuracy: Word;
+        ShotAmmo: Word;
+        ShotIntReload: Word;
+      );
+      TRIGGER_EFFECT: (
+        FXCount: Byte;
+        FXType: Byte;
+        FXSubType: Byte;
+        FXColorR: Byte;
+        FXColorG: Byte;
+        FXColorB: Byte;
+        FXPos: Byte;
+        FXWait: Word;
+        FXVelX: ShortInt;
+        FXVelY: ShortInt;
+        FXSpreadL: Byte;
+        FXSpreadR: Byte;
+        FXSpreadU: Byte;
+        FXSpreadD: Byte;
+      );
+  end;
+
+
+const defaultMapDef: AnsiString = ''+
+  #47#47#32#121#101#115#44#32#116#104#105#115#32#102#105#108#101#32#115#101+
+  #114#118#101#115#32#98#111#116#104#32#97#115#32#102#111#114#109#97#116#32+
+  #100#101#115#99#114#105#112#116#105#111#110#32#97#110#100#32#97#115#32#116+
+  #101#109#112#108#97#116#101#32#102#111#114#32#99#111#100#101#32#103#101#110+
+  #101#114#97#116#105#111#110#10#47#47#32#116#104#101#32#101#110#103#105#110+
+  #101#32#119#105#108#108#32#117#115#101#32#116#104#105#115#32#100#101#115#99+
+  #114#105#112#116#105#111#110#32#116#111#32#112#111#112#117#108#97#116#101#32+
+  #116#104#101#32#99#111#114#114#101#115#112#111#110#100#105#110#103#32#114+
+  #101#99#111#114#100#115#32#102#114#111#109#32#77#65#80#42#46#112#97#115#10+
+  #47#47#32#97#108#115#111#44#32#116#104#101#32#101#110#103#105#110#101#32#119+
+  #105#108#108#32#107#101#101#112#32#116#104#101#32#108#111#97#100#101#100#32+
+  #109#97#112#32#97#115#32#97#32#108#105#115#116#32#111#102#32#116#104#101#115+
+  #101#32#115#116#114#117#99#116#117#114#101#115#10#10#47#47#32#110#111#116+
+  #101#115#58#10#47#47#32#32#32#102#105#101#108#100#32#119#105#116#104#111#117+
+  #116#32#111#102#102#115#101#116#32#105#115#32#110#111#116#32#105#110#32#98+
+  #105#110#97#114#121#32#102#111#114#109#97#116#10#47#47#32#32#32#102#105#101+
+  #108#100#115#32#119#105#116#104#32#96#111#109#105#116#100#101#102#97#117#108+
+  #116#96#32#119#111#110#39#116#32#98#101#32#119#114#105#116#116#101#110#32+
+  #119#104#101#110#32#116#104#101#121#32#99#111#110#116#97#105#110#32#100#101+
+  #102#97#117#108#116#32#118#97#108#117#101#115#10#47#47#32#32#32#102#105#101+
+  #108#100#115#32#119#105#116#104#32#96#105#110#116#101#114#110#97#108#96#32+
+  #119#111#110#39#116#32#98#101#32#119#114#105#116#116#101#110#32#116#111#32+
+  #97#110#121#32#102#105#108#101#32#101#118#101#114#32#40#97#110#100#32#119+
+  #111#110#39#116#32#98#101#32#114#101#97#100#41#10#47#47#32#32#32#96#117#98+
+  #121#116#101#96#32#105#115#32#117#110#115#105#103#110#101#100#32#98#121#116+
+  #101#44#32#97#110#100#32#96#98#121#116#101#96#32#105#115#32#115#105#103#110+
+  #101#100#32#98#121#116#101#10#47#47#32#32#32#97#108#108#32#115#116#114#105+
+  #110#103#115#32#97#114#101#32#105#110#32#117#116#102#45#56#10#47#47#32#32#32+
+  #115#116#114#117#99#116#32#119#105#116#104#32#96#104#101#97#100#101#114#96+
+  #32#102#108#97#103#32#119#105#108#108#32#99#111#110#116#97#105#110#32#97#108+
+  #108#32#111#116#104#101#114#32#115#116#114#117#99#116#115#32#97#110#100#32+
+  #105#116#39#115#32#111#119#110#32#102#105#101#108#100#115#10#47#47#32#32#32+
+  #32#32#97#115#32#116#111#112#45#108#101#118#101#108#32#101#110#116#105#116+
+  #105#101#115#10#47#47#32#32#32#105#110#32#98#105#110#97#114#121#44#32#96#115+
+  #105#122#101#96#32#105#115#32#116#119#111#32#117#115#104#111#114#116#115#10+
+  #47#47#32#32#32#96#97#115#32#120#121#96#32#119#105#108#108#32#117#115#101#32+
+  #96#88#96#32#97#110#100#32#96#89#96#32#102#111#114#32#112#111#105#110#116+
+  #115#10#47#47#32#32#32#96#97#115#32#116#120#121#96#32#119#105#108#108#32#117+
+  #115#101#32#96#116#88#96#32#97#110#100#32#96#116#89#96#32#102#111#114#32#112+
+  #111#105#110#116#115#10#47#47#32#32#32#96#97#115#32#119#104#96#32#119#105+
+  #108#108#32#117#115#101#32#96#87#105#100#116#104#96#32#97#110#100#32#96#72+
+  #101#105#103#104#116#96#32#102#111#114#32#115#105#122#101#10#47#47#32#32#32+
+  #96#97#115#32#116#119#104#96#32#119#105#108#108#32#117#115#101#32#96#116#87+
+  #105#100#116#104#96#32#97#110#100#32#96#116#72#101#105#103#104#116#96#32#102+
+  #111#114#32#115#105#122#101#10#10#10#47#47#47#47#47#47#47#47#47#47#47#47#47+
+  #47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47+
+  #47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47+
+  #47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#10#47#47#32#109#97#105+
+  #110#32#98#108#111#99#107#115#10#84#77#97#112#72#101#97#100#101#114#82#101+
+  #99#95#49#32#105#115#32#34#109#97#112#34#32#115#105#122#101#32#52#53#50#32+
+  #98#121#116#101#115#32#104#101#97#100#101#114#32#98#105#110#98#108#111#99+
+  #107#32#55#32#123#10#32#32#47#47#95#32#105#115#32#34#118#101#114#115#105#111+
+  #110#34#32#116#121#112#101#32#117#105#110#116#32#109#105#110#118#97#108#117+
+  #101#32#49#32#109#97#120#118#97#108#117#101#32#49#59#10#32#32#77#97#112#78+
+  #97#109#101#32#105#115#32#34#110#97#109#101#34#32#116#121#112#101#32#99#104+
+  #97#114#91#51#50#93#32#111#102#102#115#101#116#32#48#59#10#32#32#77#97#112+
+  #65#117#116#104#111#114#32#105#115#32#34#97#117#116#104#111#114#34#32#116+
+  #121#112#101#32#99#104#97#114#91#51#50#93#32#111#102#102#115#101#116#32#51+
+  #50#32#100#101#102#97#117#108#116#32#34#34#32#111#109#105#116#100#101#102#97+
+  #117#108#116#59#10#32#32#77#97#112#68#101#115#99#114#105#112#116#105#111#110+
+  #32#105#115#32#34#100#101#115#99#114#105#112#116#105#111#110#34#32#116#121+
+  #112#101#32#99#104#97#114#91#50#53#54#93#32#111#102#102#115#101#116#32#54#52+
+  #32#100#101#102#97#117#108#116#32#34#34#32#111#109#105#116#100#101#102#97+
+  #117#108#116#59#10#32#32#77#117#115#105#99#78#97#109#101#32#105#115#32#34+
+  #109#117#115#105#99#34#32#116#121#112#101#32#99#104#97#114#91#54#52#93#32+
+  #111#102#102#115#101#116#32#51#50#48#32#100#101#102#97#117#108#116#32#39#83+
+  #116#97#110#100#97#114#116#46#119#97#100#58#68#50#68#77#85#83#92#208#159#208+
+  #160#208#158#208#161#208#162#208#158#208#162#208#144#39#32#111#109#105#116+
+  #100#101#102#97#117#108#116#59#10#32#32#83#107#121#78#97#109#101#32#105#115+
+  #32#34#115#107#121#34#32#116#121#112#101#32#99#104#97#114#91#54#52#93#32#111+
+  #102#102#115#101#116#32#51#56#52#32#100#101#102#97#117#108#116#32#39#83#116+
+  #97#110#100#97#114#116#46#119#97#100#58#68#50#68#83#75#89#92#82#83#75#89#49+
+  #39#32#111#109#105#116#100#101#102#97#117#108#116#59#10#32#32#47#47#87#105+
+  #100#116#104#32#105#115#32#34#119#105#100#116#104#34#32#116#121#112#101#32+
+  #117#115#104#111#114#116#32#111#102#102#115#101#116#32#52#52#56#59#10#32#32+
+  #47#47#72#101#105#103#104#116#32#105#115#32#34#104#101#105#103#104#116#34#32+
+  #116#121#112#101#32#117#115#104#111#114#116#32#111#102#102#115#101#116#32#52+
+  #53#48#59#10#32#32#83#105#122#101#32#105#115#32#34#115#105#122#101#34#32#116+
+  #121#112#101#32#115#105#122#101#32#111#102#102#115#101#116#32#52#52#56#32#97+
+  #115#32#119#104#59#10#32#32#47#47#32#110#111#116#32#105#110#32#98#105#110#97+
+  #114#121#10#32#32#84#105#116#108#101#32#105#115#32#34#116#105#116#108#101#34+
+  #32#116#121#112#101#32#115#116#114#105#110#103#32#100#101#102#97#117#108#116+
+  #32#34#34#32#32#111#109#105#116#100#101#102#97#117#108#116#59#10#125#10#10+
+  #84#84#101#120#116#117#114#101#82#101#99#95#49#32#105#115#32#34#116#101#120+
+  #116#117#114#101#34#32#115#105#122#101#32#54#53#32#98#121#116#101#115#32#98+
+  #105#110#98#108#111#99#107#32#49#32#123#10#32#32#82#101#115#111#117#114#99+
+  #101#32#105#115#32#34#112#97#116#104#34#32#116#121#112#101#32#99#104#97#114+
+  #91#54#52#93#32#111#102#102#115#101#116#32#48#59#10#32#32#65#110#105#109#32+
+  #105#115#32#34#97#110#105#109#97#116#101#100#34#32#116#121#112#101#32#98#111+
+  #111#108#32#111#102#102#115#101#116#32#54#52#32#100#101#102#97#117#108#116+
+  #32#102#97#108#115#101#32#111#109#105#116#100#101#102#97#117#108#116#59#10+
+  #32#32#47#47#32#105#110#116#101#114#110#97#108#115#10#32#32#84#101#120#73+
+  #100#120#32#105#115#32#34#116#101#120#105#100#120#34#32#116#121#112#101#32+
+  #117#105#110#116#32#105#110#116#101#114#110#97#108#59#10#125#10#10#84#80#97+
+  #110#101#108#82#101#99#95#49#32#105#115#32#34#112#97#110#101#108#34#32#115+
+  #105#122#101#32#49#56#32#98#121#116#101#115#32#98#105#110#98#108#111#99#107+
+  #32#50#32#123#10#32#32#47#47#88#32#105#115#32#34#120#34#32#116#121#112#101+
+  #32#105#110#116#32#111#102#102#115#101#116#32#48#59#10#32#32#47#47#89#32#105+
+  #115#32#34#121#34#32#116#121#112#101#32#105#110#116#32#111#102#102#115#101+
+  #116#32#52#59#10#32#32#80#111#115#32#105#115#32#34#112#111#115#105#116#105+
+  #111#110#34#32#116#121#112#101#32#112#111#105#110#116#32#111#102#102#115#101+
+  #116#32#48#32#97#115#32#120#121#59#10#32#32#47#47#87#105#100#116#104#32#105+
+  #115#32#34#119#105#100#116#104#34#32#116#121#112#101#32#117#115#104#111#114+
+  #116#32#111#102#102#115#101#116#32#56#59#10#32#32#47#47#72#101#105#103#104+
+  #116#32#105#115#32#34#104#101#105#103#104#116#34#32#116#121#112#101#32#117+
+  #115#104#111#114#116#32#111#102#102#115#101#116#32#49#48#59#10#32#32#83#105+
+  #122#101#32#105#115#32#34#115#105#122#101#34#32#116#121#112#101#32#115#105+
+  #122#101#32#111#102#102#115#101#116#32#56#32#97#115#32#119#104#32#97#115#32+
+  #119#104#59#10#32#32#84#101#120#116#117#114#101#78#117#109#32#105#115#32#34+
+  #116#101#120#116#117#114#101#34#32#116#121#112#101#32#117#115#104#111#114+
+  #116#32#111#102#102#115#101#116#32#49#50#32#116#101#120#116#117#114#101#59+
+  #10#32#32#80#97#110#101#108#84#121#112#101#32#105#115#32#34#116#121#112#101+
+  #34#32#116#121#112#101#32#117#115#104#111#114#116#32#111#102#102#115#101#116+
+  #32#49#52#32#98#105#116#115#101#116#32#117#110#105#113#117#101#32#80#97#110+
+  #101#108#84#121#112#101#59#10#32#32#65#108#112#104#97#32#105#115#32#34#97+
+  #108#112#104#97#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102+
+  #115#101#116#32#49#54#32#100#101#102#97#117#108#116#32#48#32#111#109#105#116+
+  #100#101#102#97#117#108#116#59#10#32#32#70#108#97#103#115#32#105#115#32#34+
+  #102#108#97#103#115#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102+
+  #102#115#101#116#32#49#55#32#98#105#116#115#101#116#32#80#97#110#101#108#70+
+  #108#97#103#32#100#101#102#97#117#108#116#32#80#65#78#69#76#95#70#76#65#71+
+  #95#78#79#78#69#32#111#109#105#116#100#101#102#97#117#108#116#59#10#32#32#47+
+  #47#32#110#111#116#32#105#110#32#98#105#110#97#114#121#10#32#32#47#47#73#100+
+  #32#105#115#32#34#105#100#34#32#116#121#112#101#32#115#116#114#105#110#103+
+  #32#100#101#102#97#117#108#116#32#34#34#32#111#109#105#116#100#101#102#97+
+  #117#108#116#59#10#32#32#47#47#32#105#110#116#101#114#110#97#108#115#10#32+
+  #32#80#97#110#73#100#120#32#105#115#32#34#112#97#110#105#100#120#34#32#116+
+  #121#112#101#32#117#105#110#116#32#105#110#116#101#114#110#97#108#59#10#125+
+  #10#10#84#73#116#101#109#82#101#99#95#49#32#105#115#32#34#105#116#101#109#34+
+  #32#115#105#122#101#32#49#48#32#98#121#116#101#115#32#98#105#110#98#108#111+
+  #99#107#32#51#32#123#10#32#32#47#47#88#32#105#115#32#34#120#34#32#116#121+
+  #112#101#32#105#110#116#32#111#102#102#115#101#116#32#48#59#10#32#32#47#47+
+  #89#32#105#115#32#34#121#34#32#116#121#112#101#32#105#110#116#32#111#102#102+
+  #115#101#116#32#52#59#10#32#32#80#111#115#32#105#115#32#34#112#111#115#105+
+  #116#105#111#110#34#32#116#121#112#101#32#112#111#105#110#116#32#111#102#102+
+  #115#101#116#32#48#32#97#115#32#120#121#59#10#32#32#73#116#101#109#84#121+
+  #112#101#32#105#115#32#34#116#121#112#101#34#32#116#121#112#101#32#117#98+
+  #121#116#101#32#111#102#102#115#101#116#32#56#32#101#110#117#109#32#73#116+
+  #101#109#59#10#32#32#79#112#116#105#111#110#115#32#105#115#32#34#111#112#116+
+  #105#111#110#115#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102+
+  #115#101#116#32#57#32#98#105#116#115#101#116#32#73#116#101#109#79#112#116+
+  #105#111#110#32#100#101#102#97#117#108#116#32#73#84#69#77#95#79#80#84#73#79+
+  #78#95#78#79#78#69#32#111#109#105#116#100#101#102#97#117#108#116#59#10#32#32+
+  #47#47#32#110#111#116#32#105#110#32#98#105#110#97#114#121#10#32#32#47#47#73+
+  #100#32#105#115#32#34#105#100#34#32#116#121#112#101#32#115#116#114#105#110+
+  #103#32#100#101#102#97#117#108#116#32#34#34#32#111#109#105#116#100#101#102+
+  #97#117#108#116#59#10#32#32#47#47#32#105#110#116#101#114#110#97#108#115#10+
+  #32#32#73#116#101#109#73#100#120#32#105#115#32#34#105#116#101#109#105#100+
+  #120#34#32#116#121#112#101#32#117#105#110#116#32#105#110#116#101#114#110#97+
+  #108#59#10#125#10#10#84#77#111#110#115#116#101#114#82#101#99#95#49#32#105+
+  #115#32#34#109#111#110#115#116#101#114#34#32#115#105#122#101#32#49#48#32#98+
+  #121#116#101#115#32#98#105#110#98#108#111#99#107#32#53#32#123#10#32#32#47#47+
+  #88#32#105#115#32#34#120#34#32#116#121#112#101#32#105#110#116#32#111#102#102+
+  #115#101#116#32#48#59#10#32#32#47#47#89#32#105#115#32#34#121#34#32#116#121+
+  #112#101#32#105#110#116#32#111#102#102#115#101#116#32#52#59#10#32#32#80#111+
+  #115#32#105#115#32#34#112#111#115#105#116#105#111#110#34#32#116#121#112#101+
+  #32#112#111#105#110#116#32#111#102#102#115#101#116#32#48#32#97#115#32#120+
+  #121#59#10#32#32#77#111#110#115#116#101#114#84#121#112#101#32#105#115#32#34+
+  #116#121#112#101#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102+
+  #115#101#116#32#56#32#101#110#117#109#32#77#111#110#115#116#101#114#59#10#32+
+  #32#68#105#114#101#99#116#105#111#110#32#105#115#32#34#100#105#114#101#99+
+  #116#105#111#110#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102+
+  #115#101#116#32#57#32#101#110#117#109#32#68#105#114#84#121#112#101#32#100+
+  #101#102#97#117#108#116#32#68#73#82#95#76#69#70#84#32#111#109#105#116#100+
+  #101#102#97#117#108#116#59#10#32#32#47#47#32#110#111#116#32#105#110#32#98+
+  #105#110#97#114#121#10#32#32#47#47#73#100#32#105#115#32#34#105#100#34#32#116+
+  #121#112#101#32#115#116#114#105#110#103#32#100#101#102#97#117#108#116#32#34+
+  #34#32#111#109#105#116#100#101#102#97#117#108#116#59#10#32#32#47#47#32#105+
+  #110#116#101#114#110#97#108#115#10#32#32#77#111#110#115#73#100#120#32#105+
+  #115#32#34#109#111#110#115#105#100#120#34#32#116#121#112#101#32#117#105#110+
+  #116#32#105#110#116#101#114#110#97#108#59#10#125#10#10#84#65#114#101#97#82+
+  #101#99#95#49#32#105#115#32#34#97#114#101#97#34#32#115#105#122#101#32#49#48+
+  #32#98#121#116#101#115#32#98#105#110#98#108#111#99#107#32#52#32#123#10#32#32+
+  #47#47#88#32#105#115#32#34#120#34#32#116#121#112#101#32#105#110#116#32#111+
+  #102#102#115#101#116#32#48#59#10#32#32#47#47#89#32#105#115#32#34#121#34#32+
+  #116#121#112#101#32#105#110#116#32#111#102#102#115#101#116#32#52#59#10#32#32+
+  #80#111#115#32#105#115#32#34#112#111#115#105#116#105#111#110#34#32#116#121+
+  #112#101#32#112#111#105#110#116#32#111#102#102#115#101#116#32#48#32#97#115+
+  #32#120#121#59#10#32#32#65#114#101#97#84#121#112#101#32#105#115#32#34#116+
+  #121#112#101#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115+
+  #101#116#32#56#32#101#110#117#109#32#65#114#101#97#84#121#112#101#59#10#32+
+  #32#68#105#114#101#99#116#105#111#110#32#105#115#32#34#100#105#114#101#99+
+  #116#105#111#110#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102+
+  #115#101#116#32#57#32#101#110#117#109#32#68#105#114#84#121#112#101#32#100+
+  #101#102#97#117#108#116#32#68#73#82#95#76#69#70#84#32#111#109#105#116#100+
+  #101#102#97#117#108#116#59#10#32#32#47#47#32#110#111#116#32#105#110#32#98+
+  #105#110#97#114#121#10#32#32#47#47#73#100#32#105#115#32#34#105#100#34#32#116+
+  #121#112#101#32#115#116#114#105#110#103#32#100#101#102#97#117#108#116#32#34+
+  #34#32#111#109#105#116#100#101#102#97#117#108#116#59#10#32#32#47#47#32#105+
+  #110#116#101#114#110#97#108#115#10#32#32#65#114#101#97#73#100#120#32#105#115+
+  #32#34#97#114#101#97#105#100#120#34#32#116#121#112#101#32#117#105#110#116#32+
+  #105#110#116#101#114#110#97#108#59#10#125#10#10#84#84#114#105#103#103#101+
+  #114#82#101#99#95#49#32#105#115#32#34#116#114#105#103#103#101#114#34#32#115+
+  #105#122#101#32#49#52#56#32#98#121#116#101#115#32#98#105#110#98#108#111#99+
+  #107#32#54#32#123#10#32#32#47#47#88#32#105#115#32#34#120#34#32#116#121#112+
+  #101#32#105#110#116#32#111#102#102#115#101#116#32#48#59#10#32#32#47#47#89#32+
+  #105#115#32#34#121#34#32#116#121#112#101#32#105#110#116#32#111#102#102#115+
+  #101#116#32#52#59#10#32#32#80#111#115#32#105#115#32#34#112#111#115#105#116+
+  #105#111#110#34#32#116#121#112#101#32#112#111#105#110#116#32#111#102#102#115+
+  #101#116#32#48#32#97#115#32#120#121#59#10#32#32#47#47#87#105#100#116#104#32+
+  #105#115#32#34#119#105#100#116#104#34#32#116#121#112#101#32#117#115#104#111+
+  #114#116#32#111#102#102#115#101#116#32#56#59#10#32#32#47#47#72#101#105#103+
+  #104#116#32#105#115#32#34#104#101#105#103#104#116#34#32#116#121#112#101#32+
+  #117#115#104#111#114#116#32#111#102#102#115#101#116#32#49#48#59#10#32#32#83+
+  #105#122#101#32#105#115#32#34#115#105#122#101#34#32#116#121#112#101#32#115+
+  #105#122#101#32#111#102#102#115#101#116#32#56#32#97#115#32#119#104#59#10#32+
+  #32#69#110#97#98#108#101#100#32#105#115#32#34#101#110#97#98#108#101#100#34+
+  #32#116#121#112#101#32#98#111#111#108#32#111#102#102#115#101#116#32#49#50#32+
+  #100#101#102#97#117#108#116#32#116#114#117#101#32#111#109#105#116#100#101+
+  #102#97#117#108#116#59#10#32#32#84#101#120#116#117#114#101#80#97#110#101#108+
+  #32#105#115#32#34#116#101#120#116#117#114#101#112#97#110#101#108#34#32#116+
+  #121#112#101#32#105#110#116#32#111#102#102#115#101#116#32#49#51#32#112#97+
+  #110#101#108#32#100#101#102#97#117#108#116#32#110#117#108#108#32#111#109#105+
+  #116#100#101#102#97#117#108#116#59#10#32#32#84#114#105#103#103#101#114#84+
+  #121#112#101#32#105#115#32#34#116#121#112#101#34#32#116#121#112#101#32#117+
+  #98#121#116#101#32#111#102#102#115#101#116#32#49#55#32#101#110#117#109#32#84+
+  #114#105#103#103#101#114#84#121#112#101#59#10#32#32#65#99#116#105#118#97#116+
+  #101#84#121#112#101#32#105#115#32#34#97#99#116#105#118#97#116#101#116#121+
+  #112#101#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101+
+  #116#32#49#56#32#98#105#116#115#101#116#32#65#99#116#105#118#97#116#101#84+
+  #121#112#101#59#10#32#32#75#101#121#115#32#105#115#32#34#107#101#121#115#34+
+  #32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101#116#32#49+
+  #57#32#98#105#116#115#101#116#32#75#101#121#32#100#101#102#97#117#108#116#32+
+  #75#69#89#95#78#79#78#69#32#111#109#105#116#100#101#102#97#117#108#116#59#10+
+  #32#32#47#47#87#65#82#78#73#78#71#58#32#34#116#114#105#103#100#97#116#97#34+
+  #32#77#85#83#84#32#98#101#32#100#101#102#105#110#101#100#32#98#101#102#111+
+  #114#101#32#34#116#121#112#101#34#44#32#97#110#100#32#34#116#121#112#101#34+
+  #32#77#85#83#84#32#98#101#32#110#97#109#101#100#32#34#116#121#112#101#34#32+
+  #40#102#111#114#32#110#111#119#44#32#99#97#110#32#98#101#32#99#104#97#110+
+  #103#101#100#32#108#97#116#101#114#41#10#32#32#68#65#84#65#32#105#115#32#34+
+  #116#114#105#103#103#101#114#100#97#116#97#34#32#116#121#112#101#32#116#114+
+  #105#103#100#97#116#97#91#49#50#56#93#32#111#102#102#115#101#116#32#50#48#59+
+  #32#47#47#32#116#104#101#32#111#110#108#121#32#115#112#101#99#105#97#108#32+
+  #110#101#115#116#101#100#32#115#116#114#117#99#116#117#114#101#10#32#32#47+
+  #47#32#110#111#116#32#105#110#32#98#105#110#97#114#121#10#32#32#47#47#73#100+
+  #32#105#115#32#34#105#100#34#32#116#121#112#101#32#115#116#114#105#110#103+
+  #32#100#101#102#97#117#108#116#32#34#34#32#111#109#105#116#100#101#102#97+
+  #117#108#116#59#10#32#32#47#47#32#105#110#116#101#114#110#97#108#115#10#32+
+  #32#84#114#105#103#73#100#120#32#105#115#32#34#116#114#105#103#105#100#120+
+  #34#32#116#121#112#101#32#117#105#110#116#32#105#110#116#101#114#110#97#108+
+  #59#10#125#10#10#10#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47+
+  #47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47+
+  #47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47+
+  #47#47#47#47#47#47#47#47#47#47#47#10#47#42#10#101#110#117#109#32#123#10#32+
+  #32#84#69#88#84#85#82#69#95#78#65#77#69#95#87#65#84#69#82#32#61#32#39#95#119+
+  #97#116#101#114#95#48#39#44#10#32#32#84#69#88#84#85#82#69#95#78#65#77#69#95+
+  #65#67#73#68#49#32#61#32#39#95#119#97#116#101#114#95#49#39#44#10#32#32#84#69+
+  #88#84#85#82#69#95#78#65#77#69#95#65#67#73#68#50#32#61#32#39#95#119#97#116+
+  #101#114#95#50#39#44#10#125#10#42#47#10#10#101#110#117#109#32#84#101#120#116+
+  #117#114#101#83#112#101#99#105#97#108#32#123#10#32#32#84#69#88#84#85#82#69+
+  #95#83#80#69#67#73#65#76#95#87#65#84#69#82#32#61#32#45#49#44#10#32#32#84#69+
+  #88#84#85#82#69#95#83#80#69#67#73#65#76#95#65#67#73#68#49#32#61#32#45#50#44+
+  #10#32#32#84#69#88#84#85#82#69#95#83#80#69#67#73#65#76#95#65#67#73#68#50#32+
+  #61#32#45#51#44#10#32#32#84#69#88#84#85#82#69#95#78#79#78#69#32#61#32#45#52+
+  #44#10#125#10#10#47#47#32#100#105#114#101#99#116#105#111#110#115#10#101#110+
+  #117#109#32#68#105#114#84#121#112#101#32#123#10#32#32#68#73#82#95#76#69#70+
+  #84#44#32#47#47#32#48#10#32#32#68#73#82#95#82#73#71#72#84#44#32#47#47#32#49+
+  #10#32#32#68#73#82#95#83#79#77#69#84#72#73#78#71#50#44#32#47#47#32#50#10#125+
+  #10#10#47#47#32#116#114#105#103#103#101#114#115#10#101#110#117#109#32#84#114+
+  #105#103#103#101#114#84#121#112#101#32#123#10#32#32#84#82#73#71#71#69#82#95+
+  #78#79#78#69#44#32#47#47#32#48#10#32#32#84#82#73#71#71#69#82#95#69#88#73#84+
+  #44#32#47#47#32#49#10#32#32#84#82#73#71#71#69#82#95#84#69#76#69#80#79#82#84+
+  #44#32#47#47#32#50#10#32#32#84#82#73#71#71#69#82#95#79#80#69#78#68#79#79#82+
+  #44#32#47#47#32#51#10#32#32#84#82#73#71#71#69#82#95#67#76#79#83#69#68#79#79+
+  #82#44#32#47#47#32#52#10#32#32#84#82#73#71#71#69#82#95#68#79#79#82#44#32#47+
+  #47#32#53#10#32#32#84#82#73#71#71#69#82#95#68#79#79#82#53#44#32#47#47#32#54+
+  #10#32#32#84#82#73#71#71#69#82#95#67#76#79#83#69#84#82#65#80#44#32#47#47#32+
+  #55#10#32#32#84#82#73#71#71#69#82#95#84#82#65#80#44#32#47#47#32#56#10#32#32+
+  #84#82#73#71#71#69#82#95#80#82#69#83#83#44#32#47#47#32#57#10#32#32#84#82#73+
+  #71#71#69#82#95#83#69#67#82#69#84#44#32#47#47#32#49#48#10#32#32#84#82#73#71+
+  #71#69#82#95#76#73#70#84#85#80#44#32#47#47#32#49#49#10#32#32#84#82#73#71#71+
+  #69#82#95#76#73#70#84#68#79#87#78#44#32#47#47#32#49#50#10#32#32#84#82#73#71+
+  #71#69#82#95#76#73#70#84#44#32#47#47#32#49#51#10#32#32#84#82#73#71#71#69#82+
+  #95#84#69#88#84#85#82#69#44#32#47#47#32#49#52#10#32#32#84#82#73#71#71#69#82+
+  #95#79#78#44#32#47#47#32#49#53#10#32#32#84#82#73#71#71#69#82#95#79#70#70#44+
+  #32#47#47#32#49#54#10#32#32#84#82#73#71#71#69#82#95#79#78#79#70#70#44#32#47+
+  #47#32#49#55#10#32#32#84#82#73#71#71#69#82#95#83#79#85#78#68#44#32#47#47#32+
+  #49#56#10#32#32#84#82#73#71#71#69#82#95#83#80#65#87#78#77#79#78#83#84#69#82+
+  #44#32#47#47#32#49#57#10#32#32#84#82#73#71#71#69#82#95#83#80#65#87#78#73#84+
+  #69#77#44#32#47#47#32#50#48#10#32#32#84#82#73#71#71#69#82#95#77#85#83#73#67+
+  #44#32#47#47#32#50#49#10#32#32#84#82#73#71#71#69#82#95#80#85#83#72#44#32#47+
+  #47#32#50#50#10#32#32#84#82#73#71#71#69#82#95#83#67#79#82#69#44#32#47#47#32+
+  #50#51#10#32#32#84#82#73#71#71#69#82#95#77#69#83#83#65#71#69#44#32#47#47#32+
+  #50#52#10#32#32#84#82#73#71#71#69#82#95#68#65#77#65#71#69#44#32#47#47#32#50+
+  #53#10#32#32#84#82#73#71#71#69#82#95#72#69#65#76#84#72#44#32#47#47#32#50#54+
+  #10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#44#32#47#47#32#50#55#10#32#32+
+  #84#82#73#71#71#69#82#95#69#70#70#69#67#84#44#32#47#47#32#50#56#10#32#32#84+
+  #82#73#71#71#69#82#95#83#67#82#73#80#84#44#32#47#47#32#50#57#10#32#32#47#47+
+  #10#32#32#84#82#73#71#71#69#82#95#77#65#88#32#61#32#77#65#88#44#10#125#10#10+
+  #47#47#32#34#97#115#32#88#88#88#34#32#109#101#97#110#115#32#34#103#101#110+
+  #101#114#97#116#101#32#116#104#105#115#32#105#100#101#110#116#105#102#105+
+  #101#114#32#102#111#114#32#112#97#115#99#97#108#32#115#111#117#114#99#101+
+  #115#10#98#105#116#115#101#116#32#80#97#110#101#108#84#121#112#101#32#123#10+
+  #32#32#80#65#78#69#76#95#78#79#78#69#32#61#32#48#44#32#47#47#32#48#10#32#32+
+  #80#65#78#69#76#95#87#65#76#76#44#32#47#47#32#49#10#32#32#80#65#78#69#76#95+
+  #66#65#67#75#44#32#47#47#32#50#10#32#32#80#65#78#69#76#95#70#79#82#69#44#32+
+  #47#47#32#52#10#32#32#80#65#78#69#76#95#87#65#84#69#82#44#32#47#47#32#56#10+
+  #32#32#80#65#78#69#76#95#65#67#73#68#49#44#32#47#47#32#49#54#10#32#32#80#65+
+  #78#69#76#95#65#67#73#68#50#44#32#47#47#32#51#50#10#32#32#80#65#78#69#76#95+
+  #83#84#69#80#44#32#47#47#32#54#52#10#32#32#80#65#78#69#76#95#76#73#70#84#85+
+  #80#44#32#47#47#32#49#50#56#10#32#32#80#65#78#69#76#95#76#73#70#84#68#79#87+
+  #78#44#32#47#47#32#50#53#54#10#32#32#80#65#78#69#76#95#79#80#69#78#68#79#79+
+  #82#44#32#47#47#32#53#49#50#10#32#32#80#65#78#69#76#95#67#76#79#83#69#68#79+
+  #79#82#44#32#47#47#32#49#48#50#52#10#32#32#80#65#78#69#76#95#66#76#79#67#75+
+  #77#79#78#44#32#47#47#32#50#48#52#56#10#32#32#80#65#78#69#76#95#76#73#70#84+
+  #76#69#70#84#44#32#47#47#32#52#48#57#54#10#32#32#80#65#78#69#76#95#76#73#70+
+  #84#82#73#71#72#84#44#32#47#47#32#56#49#57#50#10#125#10#10#98#105#116#115+
+  #101#116#32#80#97#110#101#108#70#108#97#103#32#123#10#32#32#80#65#78#69#76+
+  #95#70#76#65#71#95#78#79#78#69#32#61#32#48#44#32#47#47#32#48#10#32#32#80#65+
+  #78#69#76#95#70#76#65#71#95#66#76#69#78#68#73#78#71#44#32#47#47#32#49#10#32+
+  #32#80#65#78#69#76#95#70#76#65#71#95#72#73#68#69#44#32#47#47#32#50#10#32#32+
+  #80#65#78#69#76#95#70#76#65#71#95#87#65#84#69#82#84#69#88#84#85#82#69#83#44+
+  #32#47#47#32#52#10#125#10#10#101#110#117#109#32#69#102#102#101#99#116#65#99+
+  #116#105#111#110#32#123#10#32#32#69#70#70#69#67#84#95#78#79#78#69#44#32#47+
+  #47#32#48#10#32#32#69#70#70#69#67#84#95#84#69#76#69#80#79#82#84#44#32#47#47+
+  #32#49#10#32#32#69#70#70#69#67#84#95#82#69#83#80#65#87#78#44#32#47#47#32#50+
+  #10#32#32#69#70#70#69#67#84#95#70#73#82#69#44#32#47#47#32#51#10#125#10#10+
+  #101#110#117#109#32#73#116#101#109#32#123#10#32#32#73#84#69#77#95#78#79#78+
+  #69#44#32#47#47#32#48#10#32#32#73#84#69#77#95#77#69#68#75#73#84#95#83#77#65+
+  #76#76#44#32#47#47#32#49#10#32#32#73#84#69#77#95#77#69#68#75#73#84#95#76#65+
+  #82#71#69#44#32#47#47#32#50#10#32#32#73#84#69#77#95#77#69#68#75#73#84#95#66+
+  #76#65#67#75#44#32#47#47#32#51#10#32#32#73#84#69#77#95#65#82#77#79#82#95#71+
+  #82#69#69#78#44#32#47#47#32#52#10#32#32#73#84#69#77#95#65#82#77#79#82#95#66+
+  #76#85#69#44#32#47#47#32#53#10#32#32#73#84#69#77#95#83#80#72#69#82#69#95#66+
+  #76#85#69#44#32#47#47#32#54#10#32#32#73#84#69#77#95#83#80#72#69#82#69#95#87+
+  #72#73#84#69#44#32#47#47#32#55#10#32#32#73#84#69#77#95#83#85#73#84#44#32#47+
+  #47#32#56#10#32#32#73#84#69#77#95#79#88#89#71#69#78#44#32#47#47#32#57#10#32+
+  #32#73#84#69#77#95#73#78#86#85#76#44#32#47#47#32#49#48#10#32#32#73#84#69#77+
+  #95#87#69#65#80#79#78#95#83#65#87#44#32#47#47#32#49#49#10#32#32#73#84#69#77+
+  #95#87#69#65#80#79#78#95#83#72#79#84#71#85#78#49#44#32#47#47#32#49#50#10#32+
+  #32#73#84#69#77#95#87#69#65#80#79#78#95#83#72#79#84#71#85#78#50#44#32#47#47+
+  #32#49#51#10#32#32#73#84#69#77#95#87#69#65#80#79#78#95#67#72#65#73#78#71#85+
+  #78#44#32#47#47#32#49#52#10#32#32#73#84#69#77#95#87#69#65#80#79#78#95#82#79+
+  #67#75#69#84#76#65#85#78#67#72#69#82#44#32#47#47#32#49#53#10#32#32#73#84#69+
+  #77#95#87#69#65#80#79#78#95#80#76#65#83#77#65#44#32#47#47#32#49#54#10#32#32+
+  #73#84#69#77#95#87#69#65#80#79#78#95#66#70#71#44#32#47#47#32#49#55#10#32#32+
+  #73#84#69#77#95#87#69#65#80#79#78#95#83#85#80#69#82#80#85#76#69#77#69#84#44+
+  #32#47#47#32#49#56#10#32#32#73#84#69#77#95#65#77#77#79#95#66#85#76#76#69#84+
+  #83#44#32#47#47#32#49#57#10#32#32#73#84#69#77#95#65#77#77#79#95#66#85#76#76+
+  #69#84#83#95#66#79#88#44#32#47#47#32#50#48#10#32#32#73#84#69#77#95#65#77#77+
+  #79#95#83#72#69#76#76#83#44#32#47#47#32#50#49#10#32#32#73#84#69#77#95#65#77+
+  #77#79#95#83#72#69#76#76#83#95#66#79#88#44#32#47#47#32#50#50#10#32#32#73#84+
+  #69#77#95#65#77#77#79#95#82#79#67#75#69#84#44#32#47#47#32#50#51#10#32#32#73+
+  #84#69#77#95#65#77#77#79#95#82#79#67#75#69#84#95#66#79#88#44#32#47#47#32#50+
+  #52#10#32#32#73#84#69#77#95#65#77#77#79#95#67#69#76#76#44#32#47#47#32#50#53+
+  #10#32#32#73#84#69#77#95#65#77#77#79#95#67#69#76#76#95#66#73#71#44#32#47#47+
+  #32#50#54#10#32#32#73#84#69#77#95#65#77#77#79#95#66#65#67#75#80#65#67#75#44+
+  #32#47#47#32#50#55#10#32#32#73#84#69#77#95#75#69#89#95#82#69#68#44#32#47#47+
+  #32#50#56#10#32#32#73#84#69#77#95#75#69#89#95#71#82#69#69#78#44#32#47#47#32+
+  #50#57#10#32#32#73#84#69#77#95#75#69#89#95#66#76#85#69#44#32#47#47#32#51#48+
+  #10#32#32#73#84#69#77#95#87#69#65#80#79#78#95#75#65#83#84#69#84#44#32#47#47+
+  #32#51#49#10#32#32#73#84#69#77#95#87#69#65#80#79#78#95#80#73#83#84#79#76#44+
+  #32#47#47#32#51#50#10#32#32#73#84#69#77#95#66#79#84#84#76#69#44#32#47#47#32+
+  #51#51#10#32#32#73#84#69#77#95#72#69#76#77#69#84#44#32#47#47#32#51#52#10#32+
+  #32#73#84#69#77#95#74#69#84#80#65#67#75#44#32#47#47#32#51#53#10#32#32#73#84+
+  #69#77#95#73#78#86#73#83#44#32#47#47#32#51#54#10#32#32#73#84#69#77#95#87#69+
+  #65#80#79#78#95#70#76#65#77#69#84#72#82#79#87#69#82#44#32#47#47#32#51#55#10+
+  #32#32#73#84#69#77#95#65#77#77#79#95#70#85#69#76#67#65#78#44#32#47#47#32#51+
+  #56#10#32#32#47#47#10#32#32#73#84#69#77#95#77#65#88#32#61#32#77#65#88#44#32+
+  #47#47#32#115#116#111#114#101#32#116#104#101#32#108#97#115#116#32#105#116+
+  #101#109#39#115#32#105#100#32#105#110#32#104#101#114#101#32#117#115#101#32+
+  #116#104#105#115#32#105#110#32#102#111#114#32#108#111#111#112#115#10#125#10+
+  #10#98#105#116#115#101#116#32#73#116#101#109#79#112#116#105#111#110#32#123+
+  #10#32#32#73#84#69#77#95#79#80#84#73#79#78#95#78#79#78#69#32#61#32#48#44#32+
+  #47#47#32#48#10#32#32#73#84#69#77#95#79#80#84#73#79#78#95#79#78#76#89#68#77+
+  #44#32#47#47#32#49#10#32#32#73#84#69#77#95#79#80#84#73#79#78#95#70#65#76#76+
+  #44#32#47#47#32#50#10#125#10#10#101#110#117#109#32#65#114#101#97#84#121#112+
+  #101#32#123#10#32#32#65#82#69#65#95#78#79#78#69#44#32#47#47#32#48#10#32#32+
+  #65#82#69#65#95#80#76#65#89#69#82#80#79#73#78#84#49#44#32#47#47#32#49#10#32+
+  #32#65#82#69#65#95#80#76#65#89#69#82#80#79#73#78#84#50#44#32#47#47#32#50#10+
+  #32#32#65#82#69#65#95#68#77#80#79#73#78#84#44#32#47#47#32#51#10#32#32#65#82+
+  #69#65#95#82#69#68#70#76#65#71#44#32#47#47#32#52#10#32#32#65#82#69#65#95#66+
+  #76#85#69#70#76#65#71#44#32#47#47#32#53#10#32#32#65#82#69#65#95#68#79#77#70+
+  #76#65#71#44#32#47#47#32#54#10#32#32#65#82#69#65#95#82#69#68#84#69#65#77#80+
+  #79#73#78#84#44#32#47#47#32#55#10#32#32#65#82#69#65#95#66#76#85#69#84#69#65+
+  #77#80#79#73#78#84#44#32#47#47#32#56#10#125#10#10#101#110#117#109#32#77#111+
+  #110#115#116#101#114#32#123#10#32#32#77#79#78#83#84#69#82#95#78#79#78#69#44+
+  #32#47#47#32#48#10#32#32#77#79#78#83#84#69#82#95#68#69#77#79#78#44#32#47#47+
+  #32#49#10#32#32#77#79#78#83#84#69#82#95#73#77#80#44#32#47#47#32#50#10#32#32+
+  #77#79#78#83#84#69#82#95#90#79#77#66#89#44#32#47#47#32#51#10#32#32#77#79#78+
+  #83#84#69#82#95#83#69#82#71#44#32#47#47#32#52#10#32#32#77#79#78#83#84#69#82+
+  #95#67#89#66#69#82#44#32#47#47#32#53#10#32#32#77#79#78#83#84#69#82#95#67#71+
+  #85#78#44#32#47#47#32#54#10#32#32#77#79#78#83#84#69#82#95#66#65#82#79#78#44+
+  #32#47#47#32#55#10#32#32#77#79#78#83#84#69#82#95#75#78#73#71#72#84#44#32#47+
+  #47#32#56#10#32#32#77#79#78#83#84#69#82#95#67#65#67#79#44#32#47#47#32#57#10+
+  #32#32#77#79#78#83#84#69#82#95#83#79#85#76#44#32#47#47#32#49#48#10#32#32#77+
+  #79#78#83#84#69#82#95#80#65#73#78#44#32#47#47#32#49#49#10#32#32#77#79#78#83+
+  #84#69#82#95#83#80#73#68#69#82#44#32#47#47#32#49#50#10#32#32#77#79#78#83#84+
+  #69#82#95#66#83#80#44#32#47#47#32#49#51#10#32#32#77#79#78#83#84#69#82#95#77+
+  #65#78#67#85#66#44#32#47#47#32#49#52#10#32#32#77#79#78#83#84#69#82#95#83#75+
+  #69#76#44#32#47#47#32#49#53#10#32#32#77#79#78#83#84#69#82#95#86#73#76#69#44+
+  #32#47#47#32#49#54#10#32#32#77#79#78#83#84#69#82#95#70#73#83#72#44#32#47#47+
+  #32#49#55#10#32#32#77#79#78#83#84#69#82#95#66#65#82#82#69#76#44#32#47#47#32+
+  #49#56#10#32#32#77#79#78#83#84#69#82#95#82#79#66#79#44#32#47#47#32#49#57#10+
+  #32#32#77#79#78#83#84#69#82#95#77#65#78#44#32#47#47#32#50#48#10#125#10#10+
+  #101#110#117#109#32#84#114#105#103#103#101#114#83#104#111#116#32#123#10#32+
+  #32#84#82#73#71#71#69#82#95#83#72#79#84#95#80#73#83#84#79#76#44#32#47#47#32+
+  #48#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#66#85#76#76#69#84#44#32+
+  #47#47#32#49#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#83#72#79#84#71+
+  #85#78#44#32#47#47#32#50#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#83+
+  #83#71#44#32#47#47#32#51#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#73+
+  #77#80#44#32#47#47#32#52#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#80+
+  #76#65#83#77#65#44#32#47#47#32#53#10#32#32#84#82#73#71#71#69#82#95#83#72#79+
+  #84#95#83#80#73#68#69#82#44#32#47#47#32#54#10#32#32#84#82#73#71#71#69#82#95+
+  #83#72#79#84#95#67#65#67#79#44#32#47#47#32#55#10#32#32#84#82#73#71#71#69#82+
+  #95#83#72#79#84#95#66#65#82#79#78#44#32#47#47#32#56#10#32#32#84#82#73#71#71+
+  #69#82#95#83#72#79#84#95#77#65#78#67#85#66#44#32#47#47#32#57#10#32#32#84#82+
+  #73#71#71#69#82#95#83#72#79#84#95#82#69#86#44#32#47#47#32#49#48#10#32#32#84+
+  #82#73#71#71#69#82#95#83#72#79#84#95#82#79#67#75#69#84#44#32#47#47#32#49#49+
+  #10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#66#70#71#44#32#47#47#32#49+
+  #50#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#69#88#80#76#44#32#47#47+
+  #32#49#51#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#66#70#71#69#88#80+
+  #76#44#32#47#47#32#49#52#10#32#32#47#47#10#32#32#84#82#73#71#71#69#82#95#83+
+  #72#79#84#95#77#65#88#32#61#32#77#65#88#44#10#125#10#10#101#110#117#109#32+
+  #84#114#105#103#103#101#114#83#104#111#116#84#97#114#103#101#116#32#123#10+
+  #32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#84#65#82#71#69#84#95#78#79#78+
+  #69#44#32#47#47#32#48#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#84#65+
+  #82#71#69#84#95#77#79#78#44#32#47#47#32#49#10#32#32#84#82#73#71#71#69#82#95+
+  #83#72#79#84#95#84#65#82#71#69#84#95#80#76#82#44#32#47#47#32#50#10#32#32#84+
+  #82#73#71#71#69#82#95#83#72#79#84#95#84#65#82#71#69#84#95#82#69#68#44#32#47+
+  #47#32#51#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#84#65#82#71#69#84+
+  #95#66#76#85#69#44#32#47#47#32#52#10#32#32#84#82#73#71#71#69#82#95#83#72#79+
+  #84#95#84#65#82#71#69#84#95#77#79#78#80#76#82#44#32#47#47#32#53#10#32#32#84+
+  #82#73#71#71#69#82#95#83#72#79#84#95#84#65#82#71#69#84#95#80#76#82#77#79#78+
+  #44#32#47#47#32#54#10#125#10#10#101#110#117#109#32#84#114#105#103#103#101+
+  #114#83#104#111#116#65#105#109#32#123#10#32#32#84#82#73#71#71#69#82#95#83#72+
+  #79#84#95#65#73#77#95#68#69#70#65#85#76#84#44#32#47#47#32#48#10#32#32#84#82+
+  #73#71#71#69#82#95#83#72#79#84#95#65#73#77#95#65#76#76#77#65#80#44#32#47#47+
+  #32#49#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#65#73#77#95#84#82#65+
+  #67#69#44#32#47#47#32#50#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#65+
+  #73#77#95#84#82#65#67#69#65#76#76#44#32#47#47#32#51#10#125#10#10#101#110#117+
+  #109#32#84#114#105#103#103#101#114#69#102#102#101#99#116#32#123#10#32#32#84+
+  #82#73#71#71#69#82#95#69#70#70#69#67#84#95#80#65#82#84#73#67#76#69#44#32#47+
+  #47#32#48#10#32#32#84#82#73#71#71#69#82#95#69#70#70#69#67#84#95#65#78#73#77+
+  #65#84#73#79#78#44#32#47#47#32#49#10#125#10#10#101#110#117#109#32#84#114#105+
+  #103#103#101#114#69#102#102#101#99#116#84#121#112#101#32#123#10#32#32#84#82+
+  #73#71#71#69#82#95#69#70#70#69#67#84#95#83#76#73#81#85#73#68#44#32#47#47#32+
+  #48#10#32#32#84#82#73#71#71#69#82#95#69#70#70#69#67#84#95#76#76#73#81#85#73+
+  #68#44#32#47#47#32#49#10#32#32#84#82#73#71#71#69#82#95#69#70#70#69#67#84#95+
+  #68#76#73#81#85#73#68#44#32#47#47#32#50#10#32#32#84#82#73#71#71#69#82#95#69+
+  #70#70#69#67#84#95#66#76#79#79#68#44#32#47#47#32#51#10#32#32#84#82#73#71#71+
+  #69#82#95#69#70#70#69#67#84#95#83#80#65#82#75#44#32#47#47#32#52#10#32#32#84+
+  #82#73#71#71#69#82#95#69#70#70#69#67#84#95#66#85#66#66#76#69#44#32#47#47#32+
+  #53#10#32#32#84#82#73#71#71#69#82#95#69#70#70#69#67#84#95#77#65#88#32#61#32+
+  #77#65#88#44#10#125#10#10#101#110#117#109#32#84#114#105#103#103#101#114#69+
+  #102#102#101#99#116#80#111#115#32#123#10#32#32#84#82#73#71#71#69#82#95#69#70+
+  #70#69#67#84#95#80#79#83#95#67#69#78#84#69#82#44#32#47#47#32#48#10#32#32#84+
+  #82#73#71#71#69#82#95#69#70#70#69#67#84#95#80#79#83#95#65#82#69#65#44#32#47+
+  #47#32#49#10#125#10#10#98#105#116#115#101#116#32#65#99#116#105#118#97#116+
+  #101#84#121#112#101#32#123#10#32#32#65#67#84#73#86#65#84#69#95#78#79#78#69+
+  #32#61#32#48#44#32#47#47#32#48#10#32#32#65#67#84#73#86#65#84#69#95#80#76#65+
+  #89#69#82#67#79#76#76#73#68#69#44#32#47#47#32#49#10#32#32#65#67#84#73#86#65+
+  #84#69#95#77#79#78#83#84#69#82#67#79#76#76#73#68#69#44#32#47#47#32#50#10#32+
+  #32#65#67#84#73#86#65#84#69#95#80#76#65#89#69#82#80#82#69#83#83#44#32#47#47+
+  #32#52#10#32#32#65#67#84#73#86#65#84#69#95#77#79#78#83#84#69#82#80#82#69#83+
+  #83#44#32#47#47#32#56#10#32#32#65#67#84#73#86#65#84#69#95#83#72#79#84#44#32+
+  #47#47#32#49#54#10#32#32#65#67#84#73#86#65#84#69#95#78#79#77#79#78#83#84#69+
+  #82#44#32#47#47#32#51#50#10#32#32#65#67#84#73#86#65#84#69#95#67#85#83#84#79+
+  #77#32#61#32#50#53#53#44#32#47#47#32#110#111#116#101#32#116#104#97#116#32#34+
+  #100#105#114#101#99#116#32#97#115#115#105#103#110#34#32#102#105#101#108#100+
+  #32#100#111#101#115#110#39#116#32#97#102#102#101#99#116#32#98#105#116#32#99+
+  #111#117#110#116#101#114#10#125#10#10#98#105#116#115#101#116#32#75#101#121+
+  #32#123#10#32#32#75#69#89#95#78#79#78#69#32#61#32#48#44#32#47#47#32#48#10#32+
+  #32#75#69#89#95#82#69#68#44#32#47#47#32#49#10#32#32#75#69#89#95#71#82#69#69+
+  #78#44#32#47#47#32#50#10#32#32#75#69#89#95#66#76#85#69#44#32#47#47#32#52#10+
+  #32#32#75#69#89#95#82#69#68#84#69#65#77#44#32#47#47#32#56#10#32#32#75#69#89+
+  #95#66#76#85#69#84#69#65#77#44#32#47#47#32#49#54#10#125#10#10#10#47#47#47#47+
+  #47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47+
+  #47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47+
+  #47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47+
+  #47#10#47#47#32#118#97#114#105#111#117#115#32#116#114#105#103#103#101#114+
+  #115#10#84#114#105#103#103#101#114#68#97#116#97#32#102#111#114#32#84#82#73+
+  #71#71#69#82#95#69#88#73#84#32#123#10#32#32#77#97#112#78#97#109#101#32#105+
+  #115#32#34#109#97#112#34#32#116#121#112#101#32#99#104#97#114#91#49#54#93#32+
+  #111#102#102#115#101#116#32#48#59#10#125#10#10#84#114#105#103#103#101#114#68+
+  #97#116#97#32#102#111#114#32#84#82#73#71#71#69#82#95#84#69#76#69#80#79#82#84+
+  #32#123#10#32#32#84#97#114#103#101#116#80#111#105#110#116#32#105#115#32#34+
+  #116#97#114#103#101#116#34#32#116#121#112#101#32#112#111#105#110#116#32#111+
+  #102#102#115#101#116#32#48#59#10#32#32#100#50#100#95#116#101#108#101#112#111+
+  #114#116#32#105#115#32#34#100#50#100#34#32#116#121#112#101#32#98#111#111#108+
+  #32#111#102#102#115#101#116#32#56#32#100#101#102#97#117#108#116#32#102#97+
+  #108#115#101#32#111#109#105#116#100#101#102#97#117#108#116#59#10#32#32#115+
+  #105#108#101#110#116#95#116#101#108#101#112#111#114#116#32#105#115#32#34#115+
+  #105#108#101#110#116#34#32#116#121#112#101#32#98#111#111#108#32#111#102#102+
+  #115#101#116#32#57#32#100#101#102#97#117#108#116#32#102#97#108#115#101#32+
+  #111#109#105#116#100#101#102#97#117#108#116#59#10#32#32#84#108#112#68#105+
+  #114#32#105#115#32#34#100#105#114#101#99#116#105#111#110#34#32#116#121#112+
+  #101#32#117#98#121#116#101#32#111#102#102#115#101#116#32#49#48#32#101#110+
+  #117#109#32#68#105#114#84#121#112#101#32#100#101#102#97#117#108#116#32#68#73+
+  #82#95#76#69#70#84#32#111#109#105#116#100#101#102#97#117#108#116#59#10#125+
+  #10#10#84#114#105#103#103#101#114#68#97#116#97#32#102#111#114#32#40#84#82#73+
+  #71#71#69#82#95#79#80#69#78#68#79#79#82#44#32#84#82#73#71#71#69#82#95#67#76+
+  #79#83#69#68#79#79#82#44#32#84#82#73#71#71#69#82#95#68#79#79#82#44#32#84#82+
+  #73#71#71#69#82#95#68#79#79#82#53#44#32#84#82#73#71#71#69#82#95#67#76#79#83+
+  #69#84#82#65#80#44#32#84#82#73#71#71#69#82#95#84#82#65#80#44#32#84#82#73#71+
+  #71#69#82#95#76#73#70#84#85#80#44#32#84#82#73#71#71#69#82#95#76#73#70#84#68+
+  #79#87#78#44#32#84#82#73#71#71#69#82#95#76#73#70#84#41#32#123#10#32#32#80#97+
+  #110#101#108#73#68#32#105#115#32#34#112#97#110#101#108#105#100#34#32#116#121+
+  #112#101#32#105#110#116#32#111#102#102#115#101#116#32#48#32#112#97#110#101+
+  #108#59#10#32#32#78#111#83#111#117#110#100#32#105#115#32#34#115#105#108#101+
+  #110#116#34#32#116#121#112#101#32#98#111#111#108#32#111#102#102#115#101#116+
+  #32#52#32#100#101#102#97#117#108#116#32#102#97#108#115#101#32#111#109#105+
+  #116#100#101#102#97#117#108#116#59#10#32#32#100#50#100#95#100#111#111#114+
+  #115#32#105#115#32#34#100#50#100#34#32#116#121#112#101#32#98#111#111#108#32+
+  #111#102#102#115#101#116#32#53#32#100#101#102#97#117#108#116#32#102#97#108+
+  #115#101#32#111#109#105#116#100#101#102#97#117#108#116#59#10#125#10#10#84+
+  #114#105#103#103#101#114#68#97#116#97#32#102#111#114#32#40#84#82#73#71#71#69+
+  #82#95#80#82#69#83#83#44#32#84#82#73#71#71#69#82#95#79#78#44#32#84#82#73#71+
+  #71#69#82#95#79#70#70#44#32#84#82#73#71#71#69#82#95#79#78#79#70#70#41#32#123+
+  #10#32#32#47#47#116#88#32#105#115#32#34#116#120#34#32#116#121#112#101#32#105+
+  #110#116#32#111#102#102#115#101#116#32#48#59#10#32#32#47#47#116#89#32#105+
+  #115#32#34#116#121#34#32#116#121#112#101#32#105#110#116#32#111#102#102#115+
+  #101#116#32#52#59#10#32#32#80#111#115#32#105#115#32#34#112#111#115#105#116+
+  #105#111#110#34#32#116#121#112#101#32#112#111#105#110#116#32#111#102#102#115+
+  #101#116#32#48#32#97#115#32#116#120#121#59#10#32#32#47#47#116#87#105#100#116+
+  #104#32#105#115#32#34#119#105#100#116#104#34#32#116#121#112#101#32#117#115+
+  #104#111#114#116#32#111#102#102#115#101#116#32#56#59#10#32#32#47#47#116#72+
+  #101#105#103#104#116#32#105#115#32#34#104#101#105#103#104#116#34#32#116#121+
+  #112#101#32#117#115#104#111#114#116#32#111#102#102#115#101#116#32#49#48#59+
+  #10#32#32#83#105#122#101#32#105#115#32#34#115#105#122#101#34#32#116#121#112+
+  #101#32#115#105#122#101#32#111#102#102#115#101#116#32#56#32#97#115#32#116+
+  #119#104#59#10#32#32#87#97#105#116#32#105#115#32#34#119#97#105#116#34#32#116+
+  #121#112#101#32#117#115#104#111#114#116#32#111#102#102#115#101#116#32#49#50+
+  #59#10#32#32#67#111#117#110#116#32#105#115#32#34#99#111#117#110#116#34#32+
+  #116#121#112#101#32#117#115#104#111#114#116#32#111#102#102#115#101#116#32#49+
+  #52#59#10#32#32#77#111#110#115#116#101#114#73#68#32#105#115#32#34#109#111+
+  #110#115#116#101#114#105#100#34#32#116#121#112#101#32#105#110#116#32#111#102+
+  #102#115#101#116#32#49#54#32#109#111#110#115#116#101#114#59#10#32#32#69#120+
+  #116#82#97#110#100#111#109#32#105#115#32#34#101#120#116#114#97#110#100#111+
+  #109#34#32#116#121#112#101#32#98#111#111#108#32#111#102#102#115#101#116#32+
+  #50#48#59#10#125#10#10#84#114#105#103#103#101#114#68#97#116#97#32#102#111+
+  #114#32#84#82#73#71#71#69#82#95#83#69#67#82#69#84#32#123#10#125#10#10#84#114+
+  #105#103#103#101#114#68#97#116#97#32#102#111#114#32#84#82#73#71#71#69#82#95+
+  #84#69#88#84#85#82#69#32#123#10#32#32#65#99#116#105#118#97#116#101#79#110#99+
+  #101#32#105#115#32#34#97#99#116#105#118#97#116#101#111#110#99#101#34#32#116+
+  #121#112#101#32#98#111#111#108#32#111#102#102#115#101#116#32#48#59#10#32#32+
+  #65#110#105#109#79#110#99#101#32#105#115#32#34#97#110#105#109#97#116#101#111+
+  #110#99#101#34#32#116#121#112#101#32#98#111#111#108#32#111#102#102#115#101+
+  #116#32#49#59#10#125#10#10#84#114#105#103#103#101#114#68#97#116#97#32#102+
+  #111#114#32#84#82#73#71#71#69#82#95#83#79#85#78#68#32#123#10#32#32#83#111+
+  #117#110#100#78#97#109#101#32#105#115#32#34#115#111#117#110#100#110#97#109+
+  #101#34#32#116#121#112#101#32#99#104#97#114#91#54#52#93#32#111#102#102#115+
+  #101#116#32#48#59#10#32#32#86#111#108#117#109#101#32#105#115#32#34#118#111+
+  #108#117#109#101#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102+
+  #115#101#116#32#54#52#59#10#32#32#80#97#110#32#105#115#32#34#112#97#110#34+
+  #32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101#116#32#54+
+  #53#59#10#32#32#76#111#99#97#108#32#105#115#32#34#108#111#99#97#108#34#32+
+  #116#121#112#101#32#98#111#111#108#32#111#102#102#115#101#116#32#54#54#59#10+
+  #32#32#80#108#97#121#67#111#117#110#116#32#105#115#32#34#112#108#97#121#99+
+  #111#117#110#116#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102+
+  #115#101#116#32#54#55#59#10#32#32#83#111#117#110#100#83#119#105#116#99#104+
+  #32#105#115#32#34#115#111#117#110#100#115#119#105#116#99#104#34#32#116#121+
+  #112#101#32#98#111#111#108#32#111#102#102#115#101#116#32#54#56#59#10#125#10+
+  #10#84#114#105#103#103#101#114#68#97#116#97#32#102#111#114#32#84#82#73#71#71+
+  #69#82#95#83#80#65#87#78#77#79#78#83#84#69#82#32#123#10#32#32#77#111#110#80+
+  #111#115#32#105#115#32#34#112#111#115#105#116#105#111#110#34#32#116#121#112+
+  #101#32#112#111#105#110#116#32#111#102#102#115#101#116#32#48#59#10#32#32#77+
+  #111#110#84#121#112#101#32#105#115#32#34#116#121#112#101#34#32#116#121#112+
+  #101#32#117#98#121#116#101#32#111#102#102#115#101#116#32#56#59#10#32#32#77+
+  #111#110#72#101#97#108#116#104#32#105#115#32#34#104#101#97#108#116#104#34#32+
+  #116#121#112#101#32#105#110#116#32#111#102#102#115#101#116#32#49#50#59#10#32+
+  #32#77#111#110#68#105#114#32#105#115#32#34#100#105#114#101#99#116#105#111+
+  #110#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101#116+
+  #32#49#54#32#101#110#117#109#32#68#105#114#84#121#112#101#59#10#32#32#77#111+
+  #110#65#99#116#105#118#101#32#105#115#32#34#97#99#116#105#118#101#34#32#116+
+  #121#112#101#32#98#111#111#108#32#111#102#102#115#101#116#32#49#55#59#10#32+
+  #32#77#111#110#67#111#117#110#116#32#105#115#32#34#99#111#117#110#116#34#32+
+  #116#121#112#101#32#105#110#116#32#111#102#102#115#101#116#32#50#48#59#10#32+
+  #32#77#111#110#69#102#102#101#99#116#32#105#115#32#34#101#102#102#101#99#116+
+  #34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101#116#32+
+  #50#52#59#10#32#32#77#111#110#77#97#120#32#105#115#32#34#109#97#120#34#32+
+  #116#121#112#101#32#117#115#104#111#114#116#32#111#102#102#115#101#116#32#50+
+  #54#59#10#32#32#77#111#110#68#101#108#97#121#32#105#115#32#34#100#101#108#97+
+  #121#34#32#116#121#112#101#32#117#115#104#111#114#116#32#111#102#102#115#101+
+  #116#32#50#56#59#10#32#32#77#111#110#66#101#104#97#118#32#105#115#32#34#98+
+  #101#104#97#118#105#111#117#114#34#32#116#121#112#101#32#117#98#121#116#101+
+  #32#111#102#102#115#101#116#32#51#48#59#10#125#10#10#84#114#105#103#103#101+
+  #114#68#97#116#97#32#102#111#114#32#84#82#73#71#71#69#82#95#83#80#65#87#78+
+  #73#84#69#77#32#123#10#32#32#73#116#101#109#80#111#115#32#105#115#32#34#112+
+  #111#115#105#116#105#111#110#34#32#116#121#112#101#32#112#111#105#110#116#32+
+  #111#102#102#115#101#116#32#48#59#10#32#32#73#116#101#109#84#121#112#101#32+
+  #105#115#32#34#116#121#112#101#34#32#116#121#112#101#32#117#98#121#116#101+
+  #32#111#102#102#115#101#116#32#56#59#10#32#32#73#116#101#109#70#97#108#108+
+  #115#32#105#115#32#34#103#114#97#118#105#116#121#34#32#116#121#112#101#32#98+
+  #111#111#108#32#111#102#102#115#101#116#32#57#59#10#32#32#73#116#101#109#79+
+  #110#108#121#68#77#32#105#115#32#34#100#109#111#110#108#121#34#32#116#121+
+  #112#101#32#98#111#111#108#32#111#102#102#115#101#116#32#49#48#59#10#32#32+
+  #73#116#101#109#67#111#117#110#116#32#105#115#32#34#99#111#117#110#116#34#32+
+  #116#121#112#101#32#105#110#116#32#111#102#102#115#101#116#32#49#50#59#10#32+
+  #32#73#116#101#109#69#102#102#101#99#116#32#105#115#32#34#101#102#102#101#99+
+  #116#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101#116+
+  #32#49#54#59#10#32#32#73#116#101#109#77#97#120#32#105#115#32#34#109#97#120+
+  #34#32#116#121#112#101#32#117#115#104#111#114#116#32#111#102#102#115#101#116+
+  #32#49#56#59#10#32#32#73#116#101#109#68#101#108#97#121#32#105#115#32#34#100+
+  #101#108#97#121#34#32#116#121#112#101#32#117#115#104#111#114#116#32#111#102+
+  #102#115#101#116#32#50#48#59#10#125#10#10#84#114#105#103#103#101#114#68#97+
+  #116#97#32#102#111#114#32#84#82#73#71#71#69#82#95#77#85#83#73#67#32#123#10+
+  #32#32#77#117#115#105#99#78#97#109#101#32#105#115#32#34#110#97#109#101#34#32+
+  #116#121#112#101#32#99#104#97#114#91#54#52#93#32#111#102#102#115#101#116#32+
+  #48#59#10#32#32#77#117#115#105#99#65#99#116#105#111#110#32#105#115#32#34#97+
+  #99#116#105#111#110#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102+
+  #102#115#101#116#32#54#52#59#10#125#10#10#84#114#105#103#103#101#114#68#97+
+  #116#97#32#102#111#114#32#84#82#73#71#71#69#82#95#80#85#83#72#32#123#10#32+
+  #32#80#117#115#104#65#110#103#108#101#32#105#115#32#34#97#110#103#108#101#34+
+  #32#116#121#112#101#32#117#115#104#111#114#116#32#111#102#102#115#101#116#32+
+  #48#59#10#32#32#80#117#115#104#70#111#114#99#101#32#105#115#32#34#102#111+
+  #114#99#101#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115+
+  #101#116#32#50#59#10#32#32#82#101#115#101#116#86#101#108#32#105#115#32#34+
+  #114#101#115#101#116#118#101#108#111#99#105#116#121#34#32#116#121#112#101#32+
+  #98#111#111#108#32#111#102#102#115#101#116#32#51#59#10#125#10#10#84#114#105+
+  #103#103#101#114#68#97#116#97#32#102#111#114#32#84#82#73#71#71#69#82#95#83+
+  #67#79#82#69#32#123#10#32#32#83#99#111#114#101#65#99#116#105#111#110#32#105+
+  #115#32#34#97#99#116#105#111#110#34#32#116#121#112#101#32#117#98#121#116#101+
+  #32#111#102#102#115#101#116#32#48#59#10#32#32#83#99#111#114#101#67#111#117+
+  #110#116#32#105#115#32#34#99#111#117#110#116#34#32#116#121#112#101#32#117#98+
+  #121#116#101#32#111#102#102#115#101#116#32#49#59#10#32#32#83#99#111#114#101+
+  #84#101#97#109#32#105#115#32#34#116#101#97#109#34#32#116#121#112#101#32#117+
+  #98#121#116#101#32#111#102#102#115#101#116#32#50#59#10#32#32#83#99#111#114+
+  #101#67#111#110#32#105#115#32#34#99#111#110#115#111#108#101#34#32#116#121+
+  #112#101#32#98#111#111#108#32#111#102#102#115#101#116#32#51#59#10#32#32#83+
+  #99#111#114#101#77#115#103#32#105#115#32#34#109#101#115#115#97#103#101#34#32+
+  #116#121#112#101#32#98#111#111#108#32#111#102#102#115#101#116#32#52#59#10+
+  #125#10#10#84#114#105#103#103#101#114#68#97#116#97#32#102#111#114#32#84#82+
+  #73#71#71#69#82#95#77#69#83#83#65#71#69#32#123#10#32#32#77#101#115#115#97+
+  #103#101#75#105#110#100#32#105#115#32#34#107#105#110#100#34#32#116#121#112+
+  #101#32#117#98#121#116#101#32#111#102#102#115#101#116#32#48#59#10#32#32#77+
+  #101#115#115#97#103#101#83#101#110#100#84#111#32#105#115#32#34#115#101#110+
+  #100#116#111#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115+
+  #101#116#32#49#59#10#32#32#77#101#115#115#97#103#101#84#101#120#116#32#105+
+  #115#32#34#116#101#120#116#34#32#116#121#112#101#32#99#104#97#114#91#49#48+
+  #48#93#32#111#102#102#115#101#116#32#50#59#10#32#32#77#101#115#115#97#103+
+  #101#84#105#109#101#32#105#115#32#34#116#105#109#101#34#32#116#121#112#101+
+  #32#117#115#104#111#114#116#32#111#102#102#115#101#116#32#49#48#50#59#10#125+
+  #10#10#84#114#105#103#103#101#114#68#97#116#97#32#102#111#114#32#84#82#73#71+
+  #71#69#82#95#68#65#77#65#71#69#32#123#10#32#32#68#97#109#97#103#101#86#97+
+  #108#117#101#32#105#115#32#34#97#109#111#117#110#116#34#32#116#121#112#101+
+  #32#117#115#104#111#114#116#32#111#102#102#115#101#116#32#48#59#10#32#32#68+
+  #97#109#97#103#101#73#110#116#101#114#118#97#108#32#105#115#32#34#105#110+
+  #116#101#114#118#97#108#34#32#116#121#112#101#32#117#115#104#111#114#116#32+
+  #111#102#102#115#101#116#32#50#59#10#125#10#10#84#114#105#103#103#101#114#68+
+  #97#116#97#32#102#111#114#32#84#82#73#71#71#69#82#95#72#69#65#76#84#72#32+
+  #123#10#32#32#72#101#97#108#86#97#108#117#101#32#105#115#32#34#97#109#111+
+  #117#110#116#34#32#116#121#112#101#32#117#115#104#111#114#116#32#111#102#102+
+  #115#101#116#32#48#59#10#32#32#72#101#97#108#73#110#116#101#114#118#97#108+
+  #32#105#115#32#34#105#110#116#101#114#118#97#108#34#32#116#121#112#101#32+
+  #117#115#104#111#114#116#32#111#102#102#115#101#116#32#50#59#10#32#32#72#101+
+  #97#108#77#97#120#32#105#115#32#34#109#97#120#34#32#116#121#112#101#32#98+
+  #111#111#108#32#111#102#102#115#101#116#32#52#59#10#32#32#72#101#97#108#83+
+  #105#108#101#110#116#32#105#115#32#34#115#105#108#101#110#116#34#32#116#121+
+  #112#101#32#98#111#111#108#32#111#102#102#115#101#116#32#53#59#10#125#10#10+
+  #84#114#105#103#103#101#114#68#97#116#97#32#102#111#114#32#84#82#73#71#71#69+
+  #82#95#83#72#79#84#32#123#10#32#32#83#104#111#116#80#111#115#32#105#115#32+
+  #34#112#111#115#105#116#105#111#110#34#32#116#121#112#101#32#112#111#105#110+
+  #116#32#111#102#102#115#101#116#32#48#59#10#32#32#83#104#111#116#84#121#112+
+  #101#32#105#115#32#34#116#121#112#101#34#32#116#121#112#101#32#117#98#121+
+  #116#101#32#111#102#102#115#101#116#32#56#32#101#110#117#109#32#84#114#105+
+  #103#103#101#114#83#104#111#116#59#10#32#32#83#104#111#116#84#97#114#103#101+
+  #116#32#105#115#32#34#116#97#114#103#101#116#34#32#116#121#112#101#32#117#98+
+  #121#116#101#32#111#102#102#115#101#116#32#57#32#101#110#117#109#32#84#114+
+  #105#103#103#101#114#83#104#111#116#84#97#114#103#101#116#59#10#32#32#83#104+
+  #111#116#83#111#117#110#100#32#105#115#32#34#115#105#108#101#110#116#34#32+
+  #116#121#112#101#32#110#101#103#98#111#111#108#32#111#102#102#115#101#116#32+
+  #49#48#59#32#47#47#32#110#101#103#98#111#111#108#33#10#32#32#83#104#111#116+
+  #65#105#109#32#105#115#32#34#97#105#109#34#32#116#121#112#101#32#98#121#116+
+  #101#32#111#102#102#115#101#116#32#49#49#59#10#32#32#83#104#111#116#80#97+
+  #110#101#108#73#68#32#105#115#32#34#112#97#110#101#108#105#100#34#32#116#121+
+  #112#101#32#105#110#116#32#111#102#102#115#101#116#32#49#50#59#10#32#32#83+
+  #104#111#116#73#110#116#83#105#103#104#116#32#105#115#32#34#115#105#103#104+
+  #116#34#32#116#121#112#101#32#117#115#104#111#114#116#32#111#102#102#115#101+
+  #116#32#49#54#59#10#32#32#83#104#111#116#65#110#103#108#101#32#105#115#32#34+
+  #97#110#103#108#101#34#32#116#121#112#101#32#117#115#104#111#114#116#32#111+
+  #102#102#115#101#116#32#49#56#59#10#32#32#83#104#111#116#87#97#105#116#32+
+  #105#115#32#34#119#97#105#116#34#32#116#121#112#101#32#117#115#104#111#114+
+  #116#32#111#102#102#115#101#116#32#50#48#59#10#32#32#83#104#111#116#65#99#99+
+  #117#114#97#99#121#32#105#115#32#34#97#99#99#117#114#97#99#121#34#32#116#121+
+  #112#101#32#117#115#104#111#114#116#32#111#102#102#115#101#116#32#50#50#59+
+  #10#32#32#83#104#111#116#65#109#109#111#32#105#115#32#34#97#109#109#111#34+
+  #32#116#121#112#101#32#117#115#104#111#114#116#32#111#102#102#115#101#116#32+
+  #50#52#59#10#32#32#83#104#111#116#73#110#116#82#101#108#111#97#100#32#105+
+  #115#32#34#114#101#108#111#97#100#34#32#116#121#112#101#32#117#115#104#111+
+  #114#116#32#111#102#102#115#101#116#32#50#54#59#10#125#10#10#84#114#105#103+
+  #103#101#114#68#97#116#97#32#102#111#114#32#84#82#73#71#71#69#82#95#69#70#70+
+  #69#67#84#32#123#10#32#32#70#88#67#111#117#110#116#32#105#115#32#34#99#111+
+  #117#110#116#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115+
+  #101#116#32#48#59#10#32#32#70#88#84#121#112#101#32#105#115#32#34#116#121#112+
+  #101#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101#116+
+  #32#49#59#10#32#32#70#88#83#117#98#84#121#112#101#32#105#115#32#34#115#117+
+  #98#116#121#112#101#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102+
+  #102#115#101#116#32#50#59#10#32#32#70#88#67#111#108#111#114#82#32#105#115#32+
+  #34#99#111#108#111#114#114#34#32#116#121#112#101#32#117#98#121#116#101#32+
+  #111#102#102#115#101#116#32#51#59#10#32#32#70#88#67#111#108#111#114#71#32+
+  #105#115#32#34#99#111#108#111#114#103#34#32#116#121#112#101#32#117#98#121+
+  #116#101#32#111#102#102#115#101#116#32#52#59#10#32#32#70#88#67#111#108#111+
+  #114#66#32#105#115#32#34#99#111#108#111#114#98#34#32#116#121#112#101#32#117+
+  #98#121#116#101#32#111#102#102#115#101#116#32#53#59#10#32#32#70#88#80#111+
+  #115#32#105#115#32#34#112#111#115#105#116#105#111#110#34#32#116#121#112#101+
+  #32#117#98#121#116#101#32#111#102#102#115#101#116#32#54#59#10#32#32#70#88#87+
+  #97#105#116#32#105#115#32#34#119#97#105#116#34#32#116#121#112#101#32#117#115+
+  #104#111#114#116#32#111#102#102#115#101#116#32#56#59#10#32#32#70#88#86#101+
+  #108#88#32#105#115#32#34#118#101#108#120#34#32#116#121#112#101#32#98#121#116+
+  #101#32#111#102#102#115#101#116#32#49#48#59#10#32#32#70#88#86#101#108#89#32+
+  #105#115#32#34#118#101#108#121#34#32#116#121#112#101#32#98#121#116#101#32+
+  #111#102#102#115#101#116#32#49#49#59#10#32#32#70#88#83#112#114#101#97#100#76+
+  #32#105#115#32#34#115#112#114#101#97#100#108#34#32#116#121#112#101#32#117#98+
+  #121#116#101#32#111#102#102#115#101#116#32#49#50#59#10#32#32#70#88#83#112+
+  #114#101#97#100#82#32#105#115#32#34#115#112#114#101#97#100#114#34#32#116#121+
+  #112#101#32#117#98#121#116#101#32#111#102#102#115#101#116#32#49#51#59#10#32+
+  #32#70#88#83#112#114#101#97#100#85#32#105#115#32#34#115#112#114#101#97#100+
+  #117#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101#116+
+  #32#49#52#59#10#32#32#70#88#83#112#114#101#97#100#68#32#105#115#32#34#115+
+  #112#114#101#97#100#100#34#32#116#121#112#101#32#117#98#121#116#101#32#111+
+  #102#102#115#101#116#32#49#53#59#10#125#10
+;
\ No newline at end of file
index d93b48d58bf87449d3b2b8356176eb8f26dee0a3..db3a64fe7de8c6d1b20d16f2c3a58ab9ee103385 100644 (file)
@@ -486,7 +486,7 @@ TriggerData for TRIGGER_SHOT {
   ShotType is "type" type ubyte offset 8 enum TriggerShot;
   ShotTarget is "target" type ubyte offset 9 enum TriggerShotTarget;
   ShotSound is "silent" type negbool offset 10; // negbool!
-  ShotAllMap is "allmap" type bool offset 11;
+  ShotAim is "aim" type byte offset 11;
   ShotPanelID is "panelid" type int offset 12;
   ShotIntSight is "sight" type ushort offset 16;
   ShotAngle is "angle" type ushort offset 18;
diff --git a/src/shared/mapstructio.inc b/src/shared/mapstructio.inc
deleted file mode 100644 (file)
index 68b46ac..0000000
+++ /dev/null
@@ -1,685 +0,0 @@
-procedure getBytesAt (var dest; const buf; ofs, len: Integer);
-begin
-  Move((PChar(@buf)+ofs)^, dest, len);
-end;
-
-procedure getWordAt (var dest; const buf; ofs: Integer);
-type PWord = ^Word; PByte = ^Byte;
-var
-  p: PByte;
-  d: PWord;
-begin
-  p := PByte(@buf); Inc(p, ofs);
-  d := PWord(@dest);
-  d^ := p^;
-  Inc(p);
-  d^ := (d^) or ((p^) shl 8);
-end;
-
-procedure getIntAt (var dest; const buf; ofs: Integer);
-type PInt = ^LongWord; PByte = ^Byte;
-var
-  p: PByte;
-  d: PInt;
-begin
-  p := PByte(@buf); Inc(p, ofs);
-  d := PInt(@dest);
-  d^ := p^;
-  Inc(p);
-  d^ := (d^) or ((p^) shl 8);
-  Inc(p);
-  d^ := (d^) or ((p^) shl 16);
-  Inc(p);
-  d^ := (d^) or ((p^) shl 24);
-end;
-
-procedure putBytesAt (var buf; ofs: Integer; const src; len: Integer);
-begin
-  Move(src, (PChar(@buf)+ofs)^, len);
-end;
-
-procedure putWordAt (var buf; ofs: Integer; const src);
-type PWord = ^Word; PByte = ^Byte;
-var
-  p: PByte;
-  d: PWord;
-begin
-  p := PByte(PChar(@buf)+ofs);
-  d := PWord(@src);
-  p^ := (d^) and $ff;
-  Inc(p);
-  p^ := ((d^) shr 8) and $ff;
-end;
-
-procedure putIntAt (var buf; ofs: Integer; const src);
-type PInt = ^LongWord; PByte = ^Byte;
-var
-  p: PByte;
-  d: PInt;
-begin
-  p := PByte(PChar(@buf)+ofs);
-  d := PInt(@src);
-  p^ := (d^) and $ff;
-  Inc(p);
-  p^ := ((d^) shr 8) and $ff;
-  Inc(p);
-  p^ := ((d^) shr 16) and $ff;
-  Inc(p);
-  p^ := ((d^) shr 24) and $ff;
-end;
-
-procedure mb_Read_TriggerData (var tr: TTriggerData; ttype: Integer; const buf; bufsize: Integer);
-  procedure xreadExit ();
-  begin
-    getBytesAt(tr.MapName, buf, 0, 16);
-  end;
-
-  procedure xreadTeleport ();
-  begin
-    getIntAt(tr.TargetPoint.x, buf, 0);
-    getIntAt(tr.TargetPoint.y, buf, 4);
-    getBytesAt(tr.d2d_teleport, buf, 8, 1);
-    getBytesAt(tr.silent_teleport, buf, 9, 1);
-    getBytesAt(tr.TlpDir, buf, 10, 1);
-  end;
-
-  procedure xreadOpendoor ();
-  begin
-    getIntAt(tr.PanelID, buf, 0);
-    getBytesAt(tr.NoSound, buf, 4, 1);
-    getBytesAt(tr.d2d_doors, buf, 5, 1);
-  end;
-
-  procedure xreadPress ();
-  begin
-    getIntAt(tr.tX, buf, 0);
-    getIntAt(tr.tY, buf, 4);
-    getWordAt(tr.tWidth, buf, 8);
-    getWordAt(tr.tHeight, buf, 10);
-    getWordAt(tr.Wait, buf, 12);
-    getWordAt(tr.Count, buf, 14);
-    getIntAt(tr.MonsterID, buf, 16);
-    getBytesAt(tr.ExtRandom, buf, 20, 1);
-  end;
-
-  procedure xreadSecret ();
-  begin
-  end;
-
-  procedure xreadTexture ();
-  begin
-    getBytesAt(tr.ActivateOnce, buf, 0, 1);
-    getBytesAt(tr.AnimOnce, buf, 1, 1);
-  end;
-
-  procedure xreadSound ();
-  begin
-    getBytesAt(tr.SoundName, buf, 0, 64);
-    getBytesAt(tr.Volume, buf, 64, 1);
-    getBytesAt(tr.Pan, buf, 65, 1);
-    getBytesAt(tr.Local, buf, 66, 1);
-    getBytesAt(tr.PlayCount, buf, 67, 1);
-    getBytesAt(tr.SoundSwitch, buf, 68, 1);
-  end;
-
-  procedure xreadSpawnmonster ();
-  begin
-    getIntAt(tr.MonPos.x, buf, 0);
-    getIntAt(tr.MonPos.y, buf, 4);
-    getBytesAt(tr.MonType, buf, 8, 1);
-    getIntAt(tr.MonHealth, buf, 12);
-    getBytesAt(tr.MonDir, buf, 16, 1);
-    getBytesAt(tr.MonActive, buf, 17, 1);
-    getIntAt(tr.MonCount, buf, 20);
-    getBytesAt(tr.MonEffect, buf, 24, 1);
-    getWordAt(tr.MonMax, buf, 26);
-    getWordAt(tr.MonDelay, buf, 28);
-    getBytesAt(tr.MonBehav, buf, 30, 1);
-  end;
-
-  procedure xreadSpawnitem ();
-  begin
-    getIntAt(tr.ItemPos.x, buf, 0);
-    getIntAt(tr.ItemPos.y, buf, 4);
-    getBytesAt(tr.ItemType, buf, 8, 1);
-    getBytesAt(tr.ItemFalls, buf, 9, 1);
-    getBytesAt(tr.ItemOnlyDM, buf, 10, 1);
-    getIntAt(tr.ItemCount, buf, 12);
-    getBytesAt(tr.ItemEffect, buf, 16, 1);
-    getWordAt(tr.ItemMax, buf, 18);
-    getWordAt(tr.ItemDelay, buf, 20);
-  end;
-
-  procedure xreadMusic ();
-  begin
-    getBytesAt(tr.MusicName, buf, 0, 64);
-    getBytesAt(tr.MusicAction, buf, 64, 1);
-  end;
-
-  procedure xreadPush ();
-  begin
-    getWordAt(tr.PushAngle, buf, 0);
-    getBytesAt(tr.PushForce, buf, 2, 1);
-    getBytesAt(tr.ResetVel, buf, 3, 1);
-  end;
-
-  procedure xreadScore ();
-  begin
-    getBytesAt(tr.ScoreAction, buf, 0, 1);
-    getBytesAt(tr.ScoreCount, buf, 1, 1);
-    getBytesAt(tr.ScoreTeam, buf, 2, 1);
-    getBytesAt(tr.ScoreCon, buf, 3, 1);
-    getBytesAt(tr.ScoreMsg, buf, 4, 1);
-  end;
-
-  procedure xreadMessage ();
-  begin
-    getBytesAt(tr.MessageKind, buf, 0, 1);
-    getBytesAt(tr.MessageSendTo, buf, 1, 1);
-    getBytesAt(tr.MessageText, buf, 2, 100);
-    getWordAt(tr.MessageTime, buf, 102);
-  end;
-
-  procedure xreadDamage ();
-  begin
-    getWordAt(tr.DamageValue, buf, 0);
-    getWordAt(tr.DamageInterval, buf, 2);
-  end;
-
-  procedure xreadHealth ();
-  begin
-    getWordAt(tr.HealValue, buf, 0);
-    getWordAt(tr.HealInterval, buf, 2);
-    getBytesAt(tr.HealMax, buf, 4, 1);
-    getBytesAt(tr.HealSilent, buf, 5, 1);
-  end;
-
-  procedure xreadShot ();
-  begin
-    getIntAt(tr.ShotPos.x, buf, 0);
-    getIntAt(tr.ShotPos.y, buf, 4);
-    getBytesAt(tr.ShotType, buf, 8, 1);
-    getBytesAt(tr.ShotTarget, buf, 9, 1);
-    getBytesAt(tr.ShotSound, buf, 10, 1);
-    getBytesAt(tr.ShotAim, buf, 11, 1);
-    getIntAt(tr.ShotPanelID, buf, 12);
-    getWordAt(tr.ShotIntSight, buf, 16);
-    getWordAt(tr.ShotAngle, buf, 18);
-    getWordAt(tr.ShotWait, buf, 20);
-    getWordAt(tr.ShotAccuracy, buf, 22);
-    getWordAt(tr.ShotAmmo, buf, 24);
-    getWordAt(tr.ShotIntReload, buf, 26);
-  end;
-
-  procedure xreadEffect ();
-  begin
-    getBytesAt(tr.FXCount, buf, 0, 1);
-    getBytesAt(tr.FXType, buf, 1, 1);
-    getBytesAt(tr.FXSubType, buf, 2, 1);
-    getBytesAt(tr.FXColorR, buf, 3, 1);
-    getBytesAt(tr.FXColorG, buf, 4, 1);
-    getBytesAt(tr.FXColorB, buf, 5, 1);
-    getBytesAt(tr.FXPos, buf, 6, 1);
-    getWordAt(tr.FXWait, buf, 8);
-    getBytesAt(tr.FXVelX, buf, 10, 1);
-    getBytesAt(tr.FXVelY, buf, 11, 1);
-    getBytesAt(tr.FXSpreadL, buf, 12, 1);
-    getBytesAt(tr.FXSpreadR, buf, 13, 1);
-    getBytesAt(tr.FXSpreadU, buf, 14, 1);
-    getBytesAt(tr.FXSpreadD, buf, 15, 1);
-  end;
-
-  procedure xreadScript ();
-  begin
-    getBytesAt(tr.SCRProc, buf, 0, 64);
-    getIntAt(tr.SCRArg, buf, 64);
-  end;
-
-begin
-  if (bufsize < 104) then raise Exception.Create('invalid buffer size in mb_Read_TriggerData');
-  if (ttype = TRIGGER_EXIT) then begin xreadExit(); exit; end;
-  if (ttype = TRIGGER_TELEPORT) then begin xreadTeleport(); exit; end;
-  if (ttype = TRIGGER_OPENDOOR) then begin xreadOpendoor(); exit; end;
-  if (ttype = TRIGGER_CLOSEDOOR) then begin xreadOpendoor(); exit; end;
-  if (ttype = TRIGGER_DOOR) then begin xreadOpendoor(); exit; end;
-  if (ttype = TRIGGER_DOOR5) then begin xreadOpendoor(); exit; end;
-  if (ttype = TRIGGER_CLOSETRAP) then begin xreadOpendoor(); exit; end;
-  if (ttype = TRIGGER_TRAP) then begin xreadOpendoor(); exit; end;
-  if (ttype = TRIGGER_LIFTUP) then begin xreadOpendoor(); exit; end;
-  if (ttype = TRIGGER_LIFTDOWN) then begin xreadOpendoor(); exit; end;
-  if (ttype = TRIGGER_LIFT) then begin xreadOpendoor(); exit; end;
-  if (ttype = TRIGGER_PRESS) then begin xreadPress(); exit; end;
-  if (ttype = TRIGGER_ON) then begin xreadPress(); exit; end;
-  if (ttype = TRIGGER_OFF) then begin xreadPress(); exit; end;
-  if (ttype = TRIGGER_ONOFF) then begin xreadPress(); exit; end;
-  if (ttype = TRIGGER_SECRET) then begin xreadSecret(); exit; end;
-  if (ttype = TRIGGER_TEXTURE) then begin xreadTexture(); exit; end;
-  if (ttype = TRIGGER_SOUND) then begin xreadSound(); exit; end;
-  if (ttype = TRIGGER_SPAWNMONSTER) then begin xreadSpawnmonster(); exit; end;
-  if (ttype = TRIGGER_SPAWNITEM) then begin xreadSpawnitem(); exit; end;
-  if (ttype = TRIGGER_MUSIC) then begin xreadMusic(); exit; end;
-  if (ttype = TRIGGER_PUSH) then begin xreadPush(); exit; end;
-  if (ttype = TRIGGER_SCORE) then begin xreadScore(); exit; end;
-  if (ttype = TRIGGER_MESSAGE) then begin xreadMessage(); exit; end;
-  if (ttype = TRIGGER_DAMAGE) then begin xreadDamage(); exit; end;
-  if (ttype = TRIGGER_HEALTH) then begin xreadHealth(); exit; end;
-  if (ttype = TRIGGER_SHOT) then begin xreadShot(); exit; end;
-  if (ttype = TRIGGER_EFFECT) then begin xreadEffect(); exit; end;
-  if (ttype = TRIGGER_SCRIPT) then begin xreadScript(); exit; end;
-  raise Exception.Create('invalid trigger type in mb_Read_TriggerData');
-end;
-
-
-procedure mb_Read_TMapHeaderRec_1 (var tr: TMapHeaderRec_1; const buf; bufsize: Integer);
-  procedure xreadTmapheaderrec_1 ();
-  begin
-    getBytesAt(tr.MapName, buf, 0, 32);
-    getBytesAt(tr.MapAuthor, buf, 32, 32);
-    getBytesAt(tr.MapDescription, buf, 64, 256);
-    getBytesAt(tr.MusicName, buf, 320, 64);
-    getBytesAt(tr.SkyName, buf, 384, 64);
-    getWordAt(tr.Width, buf, 448);
-    getWordAt(tr.Height, buf, 450);
-  end;
-
-begin
-  if (bufsize < 452) then raise Exception.Create('invalid buffer size in readTMapHeaderRec_1');
-  xreadTmapheaderrec_1();
-end;
-
-procedure mb_Read_TTextureRec_1 (var tr: TTextureRec_1; const buf; bufsize: Integer);
-  procedure xreadTtexturerec_1 ();
-  begin
-    getBytesAt(tr.Resource, buf, 0, 64);
-    getBytesAt(tr.Anim, buf, 64, 1);
-  end;
-
-begin
-  if (bufsize < 65) then raise Exception.Create('invalid buffer size in readTTextureRec_1');
-  xreadTtexturerec_1();
-end;
-
-procedure mb_Read_TPanelRec_1 (var tr: TPanelRec_1; const buf; bufsize: Integer);
-  procedure xreadTpanelrec_1 ();
-  begin
-    getIntAt(tr.X, buf, 0);
-    getIntAt(tr.Y, buf, 4);
-    getWordAt(tr.Width, buf, 8);
-    getWordAt(tr.Height, buf, 10);
-    getWordAt(tr.TextureNum, buf, 12);
-    getWordAt(tr.PanelType, buf, 14);
-    getBytesAt(tr.Alpha, buf, 16, 1);
-    getBytesAt(tr.Flags, buf, 17, 1);
-  end;
-
-begin
-  if (bufsize < 18) then raise Exception.Create('invalid buffer size in readTPanelRec_1');
-  xreadTpanelrec_1();
-end;
-
-procedure mb_Read_TItemRec_1 (var tr: TItemRec_1; const buf; bufsize: Integer);
-  procedure xreadTitemrec_1 ();
-  begin
-    getIntAt(tr.X, buf, 0);
-    getIntAt(tr.Y, buf, 4);
-    getBytesAt(tr.ItemType, buf, 8, 1);
-    getBytesAt(tr.Options, buf, 9, 1);
-  end;
-
-begin
-  if (bufsize < 10) then raise Exception.Create('invalid buffer size in readTItemRec_1');
-  xreadTitemrec_1();
-end;
-
-procedure mb_Read_TMonsterRec_1 (var tr: TMonsterRec_1; const buf; bufsize: Integer);
-  procedure xreadTmonsterrec_1 ();
-  begin
-    getIntAt(tr.X, buf, 0);
-    getIntAt(tr.Y, buf, 4);
-    getBytesAt(tr.MonsterType, buf, 8, 1);
-    getBytesAt(tr.Direction, buf, 9, 1);
-  end;
-
-begin
-  if (bufsize < 10) then raise Exception.Create('invalid buffer size in readTMonsterRec_1');
-  xreadTmonsterrec_1();
-end;
-
-procedure mb_Read_TAreaRec_1 (var tr: TAreaRec_1; const buf; bufsize: Integer);
-  procedure xreadTarearec_1 ();
-  begin
-    getIntAt(tr.X, buf, 0);
-    getIntAt(tr.Y, buf, 4);
-    getBytesAt(tr.AreaType, buf, 8, 1);
-    getBytesAt(tr.Direction, buf, 9, 1);
-  end;
-
-begin
-  if (bufsize < 10) then raise Exception.Create('invalid buffer size in readTAreaRec_1');
-  xreadTarearec_1();
-end;
-
-procedure mb_Read_TTriggerRec_1 (var tr: TTriggerRec_1; const buf; bufsize: Integer);
-  procedure xreadTtriggerrec_1 ();
-  begin
-    getIntAt(tr.X, buf, 0);
-    getIntAt(tr.Y, buf, 4);
-    getWordAt(tr.Width, buf, 8);
-    getWordAt(tr.Height, buf, 10);
-    getBytesAt(tr.Enabled, buf, 12, 1);
-    getIntAt(tr.TexturePanel, buf, 13);
-    getBytesAt(tr.TriggerType, buf, 17, 1);
-    getBytesAt(tr.ActivateType, buf, 18, 1);
-    getBytesAt(tr.Keys, buf, 19, 1);
-    getBytesAt(tr.DATA, buf, 20, 128);
-  end;
-
-begin
-  if (bufsize < 148) then raise Exception.Create('invalid buffer size in readTTriggerRec_1');
-  xreadTtriggerrec_1();
-end;
-
-procedure mb_Write_TriggerData (var buf; bufsize: Integer; ttype: Integer; var tr: TTriggerData);
-  procedure xwriteExit ();
-  begin
-    putBytesAt(buf, 0, tr.MapName, 16);
-  end;
-
-  procedure xwriteTeleport ();
-  begin
-    putIntAt(buf, 0, tr.TargetPoint.x);
-    putIntAt(buf, 4, tr.TargetPoint.y);
-    putBytesAt(buf, 8, tr.d2d_teleport, 1);
-    putBytesAt(buf, 9, tr.silent_teleport, 1);
-    putBytesAt(buf, 10, tr.TlpDir, 1);
-  end;
-
-  procedure xwriteOpendoor ();
-  begin
-    putIntAt(buf, 0, tr.PanelID);
-    putBytesAt(buf, 4, tr.NoSound, 1);
-    putBytesAt(buf, 5, tr.d2d_doors, 1);
-  end;
-
-  procedure xwritePress ();
-  begin
-    putIntAt(buf, 0, tr.tX);
-    putIntAt(buf, 4, tr.tY);
-    putWordAt(buf, 8, tr.tWidth);
-    putWordAt(buf, 10, tr.tHeight);
-    putWordAt(buf, 12, tr.Wait);
-    putWordAt(buf, 14, tr.Count);
-    putIntAt(buf, 16, tr.MonsterID);
-    putBytesAt(buf, 20, tr.ExtRandom, 1);
-  end;
-
-  procedure xwriteSecret ();
-  begin
-  end;
-
-  procedure xwriteTexture ();
-  begin
-    putBytesAt(buf, 0, tr.ActivateOnce, 1);
-    putBytesAt(buf, 1, tr.AnimOnce, 1);
-  end;
-
-  procedure xwriteSound ();
-  begin
-    putBytesAt(buf, 0, tr.SoundName, 64);
-    putBytesAt(buf, 64, tr.Volume, 1);
-    putBytesAt(buf, 65, tr.Pan, 1);
-    putBytesAt(buf, 66, tr.Local, 1);
-    putBytesAt(buf, 67, tr.PlayCount, 1);
-    putBytesAt(buf, 68, tr.SoundSwitch, 1);
-  end;
-
-  procedure xwriteSpawnmonster ();
-  begin
-    putIntAt(buf, 0, tr.MonPos.x);
-    putIntAt(buf, 4, tr.MonPos.y);
-    putBytesAt(buf, 8, tr.MonType, 1);
-    putIntAt(buf, 12, tr.MonHealth);
-    putBytesAt(buf, 16, tr.MonDir, 1);
-    putBytesAt(buf, 17, tr.MonActive, 1);
-    putIntAt(buf, 20, tr.MonCount);
-    putBytesAt(buf, 24, tr.MonEffect, 1);
-    putWordAt(buf, 26, tr.MonMax);
-    putWordAt(buf, 28, tr.MonDelay);
-    putBytesAt(buf, 30, tr.MonBehav, 1);
-  end;
-
-  procedure xwriteSpawnitem ();
-  begin
-    putIntAt(buf, 0, tr.ItemPos.x);
-    putIntAt(buf, 4, tr.ItemPos.y);
-    putBytesAt(buf, 8, tr.ItemType, 1);
-    putBytesAt(buf, 9, tr.ItemFalls, 1);
-    putBytesAt(buf, 10, tr.ItemOnlyDM, 1);
-    putIntAt(buf, 12, tr.ItemCount);
-    putBytesAt(buf, 16, tr.ItemEffect, 1);
-    putWordAt(buf, 18, tr.ItemMax);
-    putWordAt(buf, 20, tr.ItemDelay);
-  end;
-
-  procedure xwriteMusic ();
-  begin
-    putBytesAt(buf, 0, tr.MusicName, 64);
-    putBytesAt(buf, 64, tr.MusicAction, 1);
-  end;
-
-  procedure xwritePush ();
-  begin
-    putWordAt(buf, 0, tr.PushAngle);
-    putBytesAt(buf, 2, tr.PushForce, 1);
-    putBytesAt(buf, 3, tr.ResetVel, 1);
-  end;
-
-  procedure xwriteScore ();
-  begin
-    putBytesAt(buf, 0, tr.ScoreAction, 1);
-    putBytesAt(buf, 1, tr.ScoreCount, 1);
-    putBytesAt(buf, 2, tr.ScoreTeam, 1);
-    putBytesAt(buf, 3, tr.ScoreCon, 1);
-    putBytesAt(buf, 4, tr.ScoreMsg, 1);
-  end;
-
-  procedure xwriteMessage ();
-  begin
-    putBytesAt(buf, 0, tr.MessageKind, 1);
-    putBytesAt(buf, 1, tr.MessageSendTo, 1);
-    putBytesAt(buf, 2, tr.MessageText, 100);
-    putWordAt(buf, 102, tr.MessageTime);
-  end;
-
-  procedure xwriteDamage ();
-  begin
-    putWordAt(buf, 0, tr.DamageValue);
-    putWordAt(buf, 2, tr.DamageInterval);
-  end;
-
-  procedure xwriteHealth ();
-  begin
-    putWordAt(buf, 0, tr.HealValue);
-    putWordAt(buf, 2, tr.HealInterval);
-    putBytesAt(buf, 4, tr.HealMax, 1);
-    putBytesAt(buf, 5, tr.HealSilent, 1);
-  end;
-
-  procedure xwriteShot ();
-  begin
-    putIntAt(buf, 0, tr.ShotPos.x);
-    putIntAt(buf, 4, tr.ShotPos.y);
-    putBytesAt(buf, 8, tr.ShotType, 1);
-    putBytesAt(buf, 9, tr.ShotTarget, 1);
-    putBytesAt(buf, 10, tr.ShotSound, 1);
-    putBytesAt(buf, 11, tr.ShotAim, 1);
-    putIntAt(buf, 12, tr.ShotPanelID);
-    putWordAt(buf, 16, tr.ShotIntSight);
-    putWordAt(buf, 18, tr.ShotAngle);
-    putWordAt(buf, 20, tr.ShotWait);
-    putWordAt(buf, 22, tr.ShotAccuracy);
-    putWordAt(buf, 24, tr.ShotAmmo);
-    putWordAt(buf, 26, tr.ShotIntReload);
-  end;
-
-  procedure xwriteEffect ();
-  begin
-    putBytesAt(buf, 0, tr.FXCount, 1);
-    putBytesAt(buf, 1, tr.FXType, 1);
-    putBytesAt(buf, 2, tr.FXSubType, 1);
-    putBytesAt(buf, 3, tr.FXColorR, 1);
-    putBytesAt(buf, 4, tr.FXColorG, 1);
-    putBytesAt(buf, 5, tr.FXColorB, 1);
-    putBytesAt(buf, 6, tr.FXPos, 1);
-    putWordAt(buf, 8, tr.FXWait);
-    putBytesAt(buf, 10, tr.FXVelX, 1);
-    putBytesAt(buf, 11, tr.FXVelY, 1);
-    putBytesAt(buf, 12, tr.FXSpreadL, 1);
-    putBytesAt(buf, 13, tr.FXSpreadR, 1);
-    putBytesAt(buf, 14, tr.FXSpreadU, 1);
-    putBytesAt(buf, 15, tr.FXSpreadD, 1);
-  end;
-
-begin
-  if (bufsize < 104) then raise Exception.Create('invalid buffer size in mb_Write_TriggerData');
-  if (ttype = TRIGGER_EXIT) then begin xwriteExit(); exit; end;
-  if (ttype = TRIGGER_TELEPORT) then begin xwriteTeleport(); exit; end;
-  if (ttype = TRIGGER_OPENDOOR) then begin xwriteOpendoor(); exit; end;
-  if (ttype = TRIGGER_CLOSEDOOR) then begin xwriteOpendoor(); exit; end;
-  if (ttype = TRIGGER_DOOR) then begin xwriteOpendoor(); exit; end;
-  if (ttype = TRIGGER_DOOR5) then begin xwriteOpendoor(); exit; end;
-  if (ttype = TRIGGER_CLOSETRAP) then begin xwriteOpendoor(); exit; end;
-  if (ttype = TRIGGER_TRAP) then begin xwriteOpendoor(); exit; end;
-  if (ttype = TRIGGER_LIFTUP) then begin xwriteOpendoor(); exit; end;
-  if (ttype = TRIGGER_LIFTDOWN) then begin xwriteOpendoor(); exit; end;
-  if (ttype = TRIGGER_LIFT) then begin xwriteOpendoor(); exit; end;
-  if (ttype = TRIGGER_PRESS) then begin xwritePress(); exit; end;
-  if (ttype = TRIGGER_ON) then begin xwritePress(); exit; end;
-  if (ttype = TRIGGER_OFF) then begin xwritePress(); exit; end;
-  if (ttype = TRIGGER_ONOFF) then begin xwritePress(); exit; end;
-  if (ttype = TRIGGER_SECRET) then begin xwriteSecret(); exit; end;
-  if (ttype = TRIGGER_TEXTURE) then begin xwriteTexture(); exit; end;
-  if (ttype = TRIGGER_SOUND) then begin xwriteSound(); exit; end;
-  if (ttype = TRIGGER_SPAWNMONSTER) then begin xwriteSpawnmonster(); exit; end;
-  if (ttype = TRIGGER_SPAWNITEM) then begin xwriteSpawnitem(); exit; end;
-  if (ttype = TRIGGER_MUSIC) then begin xwriteMusic(); exit; end;
-  if (ttype = TRIGGER_PUSH) then begin xwritePush(); exit; end;
-  if (ttype = TRIGGER_SCORE) then begin xwriteScore(); exit; end;
-  if (ttype = TRIGGER_MESSAGE) then begin xwriteMessage(); exit; end;
-  if (ttype = TRIGGER_DAMAGE) then begin xwriteDamage(); exit; end;
-  if (ttype = TRIGGER_HEALTH) then begin xwriteHealth(); exit; end;
-  if (ttype = TRIGGER_SHOT) then begin xwriteShot(); exit; end;
-  if (ttype = TRIGGER_EFFECT) then begin xwriteEffect(); exit; end;
-  raise Exception.Create('invalid trigger type in mb_Write_TriggerData');
-end;
-
-
-procedure mb_Write_TMapHeaderRec_1 (var buf; bufsize: Integer; var tr: TMapHeaderRec_1);
-  procedure xwriteTmapheaderrec_1 ();
-  begin
-    putBytesAt(buf, 0, tr.MapName, 32);
-    putBytesAt(buf, 32, tr.MapAuthor, 32);
-    putBytesAt(buf, 64, tr.MapDescription, 256);
-    putBytesAt(buf, 320, tr.MusicName, 64);
-    putBytesAt(buf, 384, tr.SkyName, 64);
-    putWordAt(buf, 448, tr.Width);
-    putWordAt(buf, 450, tr.Height);
-  end;
-
-begin
-  if (bufsize < 452) then raise Exception.Create('invalid buffer size in writeTMapHeaderRec_1');
-  xwriteTmapheaderrec_1();
-end;
-
-procedure mb_Write_TTextureRec_1 (var buf; bufsize: Integer; var tr: TTextureRec_1);
-  procedure xwriteTtexturerec_1 ();
-  begin
-    putBytesAt(buf, 0, tr.Resource, 64);
-    putBytesAt(buf, 64, tr.Anim, 1);
-  end;
-
-begin
-  if (bufsize < 65) then raise Exception.Create('invalid buffer size in writeTTextureRec_1');
-  xwriteTtexturerec_1();
-end;
-
-procedure mb_Write_TPanelRec_1 (var buf; bufsize: Integer; var tr: TPanelRec_1);
-  procedure xwriteTpanelrec_1 ();
-  begin
-    putIntAt(buf, 0, tr.X);
-    putIntAt(buf, 4, tr.Y);
-    putWordAt(buf, 8, tr.Width);
-    putWordAt(buf, 10, tr.Height);
-    putWordAt(buf, 12, tr.TextureNum);
-    putWordAt(buf, 14, tr.PanelType);
-    putBytesAt(buf, 16, tr.Alpha, 1);
-    putBytesAt(buf, 17, tr.Flags, 1);
-  end;
-
-begin
-  if (bufsize < 18) then raise Exception.Create('invalid buffer size in writeTPanelRec_1');
-  xwriteTpanelrec_1();
-end;
-
-procedure mb_Write_TItemRec_1 (var buf; bufsize: Integer; var tr: TItemRec_1);
-  procedure xwriteTitemrec_1 ();
-  begin
-    putIntAt(buf, 0, tr.X);
-    putIntAt(buf, 4, tr.Y);
-    putBytesAt(buf, 8, tr.ItemType, 1);
-    putBytesAt(buf, 9, tr.Options, 1);
-  end;
-
-begin
-  if (bufsize < 10) then raise Exception.Create('invalid buffer size in writeTItemRec_1');
-  xwriteTitemrec_1();
-end;
-
-procedure mb_Write_TMonsterRec_1 (var buf; bufsize: Integer; var tr: TMonsterRec_1);
-  procedure xwriteTmonsterrec_1 ();
-  begin
-    putIntAt(buf, 0, tr.X);
-    putIntAt(buf, 4, tr.Y);
-    putBytesAt(buf, 8, tr.MonsterType, 1);
-    putBytesAt(buf, 9, tr.Direction, 1);
-  end;
-
-begin
-  if (bufsize < 10) then raise Exception.Create('invalid buffer size in writeTMonsterRec_1');
-  xwriteTmonsterrec_1();
-end;
-
-procedure mb_Write_TAreaRec_1 (var buf; bufsize: Integer; var tr: TAreaRec_1);
-  procedure xwriteTarearec_1 ();
-  begin
-    putIntAt(buf, 0, tr.X);
-    putIntAt(buf, 4, tr.Y);
-    putBytesAt(buf, 8, tr.AreaType, 1);
-    putBytesAt(buf, 9, tr.Direction, 1);
-  end;
-
-begin
-  if (bufsize < 10) then raise Exception.Create('invalid buffer size in writeTAreaRec_1');
-  xwriteTarearec_1();
-end;
-
-procedure mb_Write_TTriggerRec_1 (var buf; bufsize: Integer; var tr: TTriggerRec_1);
-  procedure xwriteTtriggerrec_1 ();
-  begin
-    putIntAt(buf, 0, tr.X);
-    putIntAt(buf, 4, tr.Y);
-    putWordAt(buf, 8, tr.Width);
-    putWordAt(buf, 10, tr.Height);
-    putBytesAt(buf, 12, tr.Enabled, 1);
-    putIntAt(buf, 13, tr.TexturePanel);
-    putBytesAt(buf, 17, tr.TriggerType, 1);
-    putBytesAt(buf, 18, tr.ActivateType, 1);
-    putBytesAt(buf, 19, tr.Keys, 1);
-    putBytesAt(buf, 20, tr.DATA, 128);
-  end;
-
-begin
-  if (bufsize < 148) then raise Exception.Create('invalid buffer size in writeTTriggerRec_1');
-  xwriteTtriggerrec_1();
-end;
-
diff --git a/src/shared/mapstructsizes.inc b/src/shared/mapstructsizes.inc
deleted file mode 100644 (file)
index e793c06..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-const
-  SizeOf_TMapHeaderRec_1 = 452;
-  SizeOf_TTextureRec_1 = 65;
-  SizeOf_TPanelRec_1 = 18;
-  SizeOf_TItemRec_1 = 10;
-  SizeOf_TMonsterRec_1 = 10;
-  SizeOf_TAreaRec_1 = 10;
-  SizeOf_TTriggerRec_1 = 148;
-
-procedure mb_Read_TriggerData (var tr: TTriggerData; ttype: Integer; const buf; bufsize: Integer);
-procedure mb_Write_TriggerData (var buf; bufsize: Integer; ttype: Integer; var tr: TTriggerData);
-procedure mb_Read_TMapHeaderRec_1 (var tr: TMapHeaderRec_1; const buf; bufsize: Integer);
-procedure mb_Write_TMapHeaderRec_1 (var buf; bufsize: Integer; var tr: TMapHeaderRec_1);
-procedure mb_Read_TTextureRec_1 (var tr: TTextureRec_1; const buf; bufsize: Integer);
-procedure mb_Write_TTextureRec_1 (var buf; bufsize: Integer; var tr: TTextureRec_1);
-procedure mb_Read_TPanelRec_1 (var tr: TPanelRec_1; const buf; bufsize: Integer);
-procedure mb_Write_TPanelRec_1 (var buf; bufsize: Integer; var tr: TPanelRec_1);
-procedure mb_Read_TItemRec_1 (var tr: TItemRec_1; const buf; bufsize: Integer);
-procedure mb_Write_TItemRec_1 (var buf; bufsize: Integer; var tr: TItemRec_1);
-procedure mb_Read_TMonsterRec_1 (var tr: TMonsterRec_1; const buf; bufsize: Integer);
-procedure mb_Write_TMonsterRec_1 (var buf; bufsize: Integer; var tr: TMonsterRec_1);
-procedure mb_Read_TAreaRec_1 (var tr: TAreaRec_1; const buf; bufsize: Integer);
-procedure mb_Write_TAreaRec_1 (var buf; bufsize: Integer; var tr: TAreaRec_1);
-procedure mb_Read_TTriggerRec_1 (var tr: TTriggerRec_1; const buf; bufsize: Integer);
-procedure mb_Write_TTriggerRec_1 (var buf; bufsize: Integer; var tr: TTriggerRec_1);
index 3830af240f6f924519c5704f81f1dc9683ab0dc5..8207f602fcac68605e3d9d58194b117ddb4cc65c 100644 (file)
@@ -76,7 +76,7 @@ var
 implementation
 
 uses
-  SysUtils, e_log, utils, MAPSTRUCT;
+  SysUtils, e_log, utils, MAPDEF;
 
 
 function findDiskWad (fname: AnsiString): AnsiString;
index 3a31a9663c9c96ef3e0bd3d3ba2d5c8603dc679f..f129dd035af96a9b8c12f84feec6bf58a35349b8 100644 (file)
@@ -45,9 +45,6 @@ type
       // TTrigData: array of mMaxDim bytes, but internally a record (mRecRef)
       // arrays of chars are pascal shortstrings (with counter in the first byte)
 
-      TDynFieldArray = array of TDynField;
-      TDynRecordArray = array of TDynRecord;
-
   private
     type
       TEBS = (TNone, TRec, TEnum, TBitSet);
@@ -102,6 +99,7 @@ type
     class function getTypeName (t: TType): AnsiString;
 
     function definition (): AnsiString;
+    function pasdef (): AnsiString;
 
     function clone (newOwner: TDynRecord=nil): TDynField;
 
@@ -129,6 +127,7 @@ type
     property ebs: TEBS read mEBS;
     property ebstype: TObject read mEBSType;
     property ebstypename: AnsiString read mEBSTypeName; // enum/bitset name
+    property list: TDynRecList read mRVal; // for list
 
     property x: Integer read mIVal;
     property w: Integer read mIVal;
@@ -172,6 +171,7 @@ type
     destructor Destroy (); override;
 
     function definition (): AnsiString;
+    function pasdef (): AnsiString;
 
     function clone (): TDynRecord;
 
@@ -181,11 +181,14 @@ type
     procedure parseBinValue (st: TStream; forceData: Boolean=false);
 
     procedure writeTo (wr: TTextWriter; putHeader: Boolean=true);
-    procedure writeBinTo (st: TStream; trigbufsz: Integer=-1);
+    procedure writeBinTo (st: TStream; trigbufsz: Integer=-1; onlyFields: Boolean=false);
 
     // find field with `TriggerType` type
     function trigTypeField (): TDynField;
 
+    // number of records of the given instance
+    function instanceCount (const typename: AnsiString): Integer;
+
   public
     property id: AnsiString read mId; // for map parser
     property pasname: AnsiString read mPasName;
@@ -196,9 +199,10 @@ type
     property field[const aname: AnsiString]: TDynField read getFieldByName;
     property isTrigData: Boolean read getIsTrigData;
     property isForTrig[const aname: AnsiString]: Boolean read getIsForTrig;
+    property headerType: TDynRecord read mHeaderRec;
+    property isHeader: Boolean read mHeader;
   end;
 
-
   TDynEBS = class
   private
     mOwner: TDynMapDef;
@@ -223,6 +227,7 @@ type
     destructor Destroy (); override;
 
     function definition (): AnsiString;
+    function pasdef (): AnsiString;
 
     // return empty string if not found
     function nameByValue (v: Integer): AnsiString;
@@ -254,6 +259,8 @@ type
     function findTrigFor (const aname: AnsiString): TDynRecord;
     function findEBSType (const aname: AnsiString): TDynEBS;
 
+    function pasdef (): AnsiString;
+
     // creates new header record
     function parseMap (pr: TTextParser): TDynRecord;
 
@@ -271,6 +278,10 @@ uses
   SysUtils;
 
 
+// ////////////////////////////////////////////////////////////////////////// //
+function StrEqu (const a, b: AnsiString): Boolean; inline; begin result := (a = b); end;
+
+
 // ////////////////////////////////////////////////////////////////////////// //
 constructor TDynField.Create (const aname: AnsiString; atype: TType);
 begin
@@ -535,6 +546,34 @@ begin
 end;
 
 
+function TDynField.pasdef (): AnsiString;
+begin
+  result := mPasName+': ';
+  case mType of
+    TType.TBool: result += 'Boolean;';
+    TType.TChar: if (mMaxDim > 0) then result += formatstrf('Char%d;', [mMaxDim]) else result += 'Char;';
+    TType.TByte: result += 'ShortInt;';
+    TType.TUByte: result += 'Byte;';
+    TType.TShort: result += 'SmallInt;';
+    TType.TUShort: result += 'Word;';
+    TType.TInt: result += 'LongInt;';
+    TType.TUInt: result += 'LongWord;';
+    TType.TString: result += 'AnsiString;';
+    TType.TPoint:
+           if mAsT then result := 'tX, tY: Integer;'
+      else if mSepPosSize then result := 'X, Y: Integer;'
+      else result += 'TDFPoint;';
+    TType.TSize:
+           if mAsT then result := 'tWidth, tHeight: Word;'
+      else if mSepPosSize then result := 'Width, Height: Word;'
+      else result += 'TSize;';
+    TType.TList: assert(false);
+    TType.TTrigData: result += formatstrf('Byte%d;', [mMaxDim]);
+    else raise Exception.Create('ketmar forgot to handle some field type');
+  end;
+end;
+
+
 procedure TDynField.parseDef (pr: TTextParser);
 var
   fldname: AnsiString;
@@ -753,17 +792,6 @@ begin
           exit;
         end;
         // record reference
-        if (mRecRef = nil) then
-        begin
-          // no ref, write -1
-          case mType of
-            TType.TByte, TType.TUByte: writeInt(st, Byte(-1));
-            TType.TShort, TType.TUShort: writeInt(st, SmallInt(-1));
-            TType.TInt, TType.TUInt: writeInt(st, Integer(-1));
-            else raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' cannot be written', [mEBSTypeName, mName]));
-          end;
-          exit;
-        end;
         case mType of
           TType.TByte: maxv := 127;
           TType.TUByte: maxv := 254;
@@ -774,13 +802,20 @@ begin
           else raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' cannot be written', [mEBSTypeName, mName]));
         end;
         // find record number
-        f := mOwner.findRecordNumByType(mEBSTypeName, mRecRef);
-        if (f < 0) then raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' not found in record list', [mEBSTypeName, mName]));
-        if (f > maxv) then raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' has too big index', [mEBSTypeName, mName]));
+        if (mRecRef <> nil) then
+        begin
+          f := mOwner.findRecordNumByType(mEBSTypeName, mRecRef);
+          if (f < 0) then raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' not found in record list', [mEBSTypeName, mName]));
+          if (f > maxv) then raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' has too big index', [mEBSTypeName, mName]));
+        end
+        else
+        begin
+          f := -1;
+        end;
         case mType of
           TType.TByte, TType.TUByte: writeInt(st, Byte(f));
           TType.TShort, TType.TUShort: writeInt(st, SmallInt(f));
-          TType.TInt, TType.TUInt: writeInt(st, Integer(f));
+          TType.TInt, TType.TUInt: writeInt(st, LongWord(f));
           else raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' cannot be written', [mEBSTypeName, mName]));
         end;
         exit;
@@ -1484,7 +1519,7 @@ begin
   result := 0;
   while (result < mFields.count) do
   begin
-    if (CompareText(aname, mFields[result].mName) = 0) then exit;
+    if StrEqu(aname, mFields[result].mName) then exit;
     Inc(result);
   end;
   result := -1;
@@ -1517,7 +1552,7 @@ var
   f: Integer;
 begin
   result := true;
-  for f := 0 to High(mTrigTypes) do if (CompareText(mTrigTypes[f], aname) = 0) then exit;
+  for f := 0 to High(mTrigTypes) do if StrEqu(mTrigTypes[f], aname) then exit;
   result := false;
 end;
 
@@ -1562,7 +1597,7 @@ begin
   begin
     for rec in fld.mRVal do
     begin
-      if (CompareText(rec.mId, aid) = 0) then begin result := rec; exit; end;
+      if StrEqu(rec.mId, aid) then begin result := rec; exit; end;
     end;
   end;
   // alas
@@ -1638,12 +1673,23 @@ begin
     if not (fld.mEBSType is TDynEBS) then continue;
     es := (fld.mEBSType as TDynEBS);
     assert(es <> nil);
-    if (CompareText(es.mName, 'TriggerType') = 0) then begin result := fld; exit; end;
+    if StrEqu(es.mName, 'TriggerType') then begin result := fld; exit; end;
   end;
   result := nil;
 end;
 
 
+// number of records of the given instance
+function TDynRecord.instanceCount (const typename: AnsiString): Integer;
+var
+  fld: TDynField;
+begin
+  result := 0;
+  fld := field[typename];
+  if (fld <> nil) and (fld.mType = fld.TType.TList) then result := fld.mRVal.count;
+end;
+
+
 procedure TDynRecord.parseDef (pr: TTextParser);
 var
   fld: TDynField;
@@ -1713,6 +1759,30 @@ begin
 end;
 
 
+function TDynRecord.pasdef (): AnsiString;
+var
+  fld: TDynField;
+begin
+  if isTrigData then
+  begin
+    assert(false);
+    result := '';
+  end
+  else
+  begin
+    // record
+    result := '  '+mPasName+' = packed record'#10;
+  end;
+  for fld in mFields do
+  begin
+    if fld.mInternal then continue;
+    if (fld.mBinOfs < 0) then continue;
+    result += '    '+fld.pasdef+#10;
+  end;
+  result += '  end;'#10;
+end;
+
+
 function TDynRecord.definition (): AnsiString;
 var
   f: Integer;
@@ -1812,7 +1882,7 @@ begin
         if (btype = 0) then break; // no more blocks
         readLongWord(st); // reserved
         bsize := readLongInt(st);
-        writeln('btype=', btype, '; bsize=', bsize);
+        //writeln('btype=', btype, '; bsize=', bsize);
         if (bsize < 0) or (bsize > $1fffffff) then raise Exception.Create(Format('block of type %d has invalid size %d', [btype, bsize]));
         if loaded[btype] then raise Exception.Create(Format('block of type %d already loaded', [btype]));
         loaded[btype] := true;
@@ -1820,7 +1890,7 @@ begin
         rect := nil;
         for rec in mOwner.recTypes do if (rec.mBinBlock = btype) then begin rect := rec; break; end;
         if (rect = nil) then raise Exception.Create(Format('block of type %d has no corresponding record', [btype]));
-        writeln('found type ''', rec.mName, ''' for block type ', btype);
+        //writeln('found type ''', rec.mName, ''' for block type ', btype);
         if (rec.mSize = 0) or ((bsize mod rec.mSize) <> 0) then raise Exception.Create(Format('block of type %d has invalid number of records', [btype]));
         // header?
         if (rect.mHeader) then
@@ -1867,7 +1937,7 @@ begin
     end;
 
     // read fields
-    if (CompareText(mName, 'TriggerData') = 0) then mSize := Integer(st.size-st.position);
+    if StrEqu(mName, 'TriggerData') then mSize := Integer(st.size-st.position);
     if (mSize < 1) then raise Exception.Create(Format('cannot read record of type ''%s'' with unknown size', [mName]));
     GetMem(buf, mSize);
     st.ReadBuffer(buf^, mSize);
@@ -1887,7 +1957,7 @@ begin
 end;
 
 
-procedure TDynRecord.writeBinTo (st: TStream; trigbufsz: Integer=-1);
+procedure TDynRecord.writeBinTo (st: TStream; trigbufsz: Integer=-1; onlyFields: Boolean=false);
 var
   fld: TDynField;
   rec, rv: TDynRecord;
@@ -1927,7 +1997,7 @@ begin
     end;
 
     // write block with normal fields
-    if mHeader then
+    if mHeader and not onlyFields then
     begin
       //writeln('writing header...');
       // signature and version
@@ -1942,7 +2012,7 @@ begin
     FreeMem(buf); buf := nil;
 
     // write other blocks, if any
-    if mHeader then
+    if mHeader and not onlyFields then
     begin
       // calculate blkmax
       blkmax := 0;
@@ -2089,7 +2159,7 @@ begin
             begin
               for rv in fld.mRVal do
               begin
-                if (Length(rv.mId) > 0) and (CompareText(rv.mId, rec.mId) = 0) then raise Exception.Create(Format('duplicate thing ''%s'' in record ''%s''', [fld.mName, mName]));
+                if (Length(rv.mId) > 0) and StrEqu(rv.mId, rec.mId) then raise Exception.Create(Format('duplicate thing ''%s'' in record ''%s''', [fld.mName, mName]));
               end;
             end;
           end;
@@ -2154,7 +2224,7 @@ begin
   result := 0;
   while (result < Length(mIds)) do
   begin
-    if (CompareText(aname, mIds[result]) = 0) then exit;
+    if StrEqu(aname, mIds[result]) then exit;
     Inc(result);
   end;
   result := -1;
@@ -2207,6 +2277,19 @@ begin
 end;
 
 
+function TDynEBS.pasdef (): AnsiString;
+var
+  f: Integer;
+begin
+  result := '// '+mName+#10'const'#10;
+  // fields
+  for f := 0 to High(mIds) do
+  begin
+    result += formatstrf('  %s = %d;'#10, [mIds[f], mVals[f]]);
+  end;
+end;
+
+
 function TDynEBS.nameByValue (v: Integer): AnsiString;
 var
   f: Integer;
@@ -2239,9 +2322,9 @@ begin
     idname := pr.expectId();
     for f := 0 to High(mIds) do
     begin
-      if (CompareText(mIds[f], idname) = 0) then raise Exception.Create(Format('duplicate field ''%s'' in enum/bitset ''%s''', [idname, mName]));
+      if StrEqu(mIds[f], idname) then raise Exception.Create(Format('duplicate field ''%s'' in enum/bitset ''%s''', [idname, mName]));
     end;
-    if (CompareText(mMaxName, idname) = 0) then raise Exception.Create(Format('duplicate field ''%s'' in enum/bitset ''%s''', [idname, mName]));
+    if StrEqu(mMaxName, idname) then raise Exception.Create(Format('duplicate field ''%s'' in enum/bitset ''%s''', [idname, mName]));
     skipAdd := false;
     hasV := false;
     v := cv;
@@ -2336,7 +2419,7 @@ var
 begin
   for rec in recTypes do
   begin
-    if (CompareText(rec.name, aname) = 0) then begin result := rec; exit; end;
+    if StrEqu(rec.name, aname) then begin result := rec; exit; end;
   end;
   result := nil;
 end;
@@ -2360,7 +2443,7 @@ var
 begin
   for ebs in ebsTypes do
   begin
-    if (CompareText(ebs.name, aname) = 0) then begin result := ebs; exit; end;
+    if StrEqu(ebs.name, aname) then begin result := ebs; exit; end;
   end;
   result := nil;
 end;
@@ -2448,7 +2531,7 @@ begin
     rec := TDynRecord.Create(pr);
     //writeln(dr.definition); writeln;
     if (findRecType(rec.name) <> nil) then begin rec.Free(); raise Exception.Create(Format('duplicate record ''%s''', [rec.name])); end;
-    if (hdr <> nil) and (CompareText(rec.name, hdr.name) = 0) then begin rec.Free(); raise Exception.Create(Format('duplicate record ''%s''', [rec.name])); end;
+    if (hdr <> nil) and StrEqu(rec.name, hdr.name) then begin rec.Free(); raise Exception.Create(Format('duplicate record ''%s''', [rec.name])); end;
     rec.mOwner := self;
     if rec.mHeader then
     begin
@@ -2519,4 +2602,51 @@ begin
 end;
 
 
+function TDynMapDef.pasdef (): AnsiString;
+var
+  ebs: TDynEBS;
+  rec: TDynRecord;
+  fld: TDynField;
+  needComma: Boolean;
+  tn: AnsiString;
+begin
+  result := '';
+  result += '// ////////////////////////////////////////////////////////////////////////// //'#10;
+  result += '// enums and bitsets'#10;
+  for ebs in ebsTypes do result += #10+ebs.pasdef();
+  result += #10#10'// ////////////////////////////////////////////////////////////////////////// //'#10;
+  result += '// records'#10'type'#10;
+  for rec in recTypes do
+  begin
+    if (rec.mSize < 1) then continue;
+    result += rec.pasdef();
+    result += #10;
+  end;
+  result += #10#10'// ////////////////////////////////////////////////////////////////////////// //'#10;
+  result += '// triggerdata'#10'type'#10;
+  result += '  TTriggerData = record'#10;
+  result += '    case Byte of'#10;
+  result += '      0: (Default: Byte128);'#10;
+  for rec in trigTypes do
+  begin
+    result += '      ';
+    needComma := false;
+    for tn in rec.mTrigTypes do
+    begin
+      if needComma then result += ', ' else needComma := true;
+      result += tn;
+    end;
+    result += ': ('#10;
+    for fld in rec.mFields do
+    begin
+      if fld.mInternal then continue;
+      if (fld.mBinOfs < 0) then continue;
+      result += '        '+fld.pasdef+#10;
+    end;
+    result += '      );'#10;
+  end;
+  result += '  end;'#10;
+end;
+
+
 end.
index d0f0d3af202bef33b10715f495e13db098ce7dd3..7263b7db60037eef69dba6c49ffa9b6cac5a3108 100644 (file)
@@ -177,6 +177,11 @@ uses
   SysUtils, utils;
 
 
+// ////////////////////////////////////////////////////////////////////////// //
+function StrEqu (const a, b: AnsiString): Boolean; inline; begin result := (a = b); end;
+
+
+// ////////////////////////////////////////////////////////////////////////// //
 var
   wc2shitmap: array[0..65535] of AnsiChar;
   wc2shitmapInited: Boolean = false;
@@ -528,7 +533,7 @@ end;
 
 procedure TTextParser.expectId (const aid: AnsiString);
 begin
-  if (mTokType <> TTId) or (CompareText(mTokStr, aid) <> 0) then raise Exception.Create('identifier '''+aid+''' expected');
+  if (mTokType <> TTId) or (not StrEqu(mTokStr, aid)) then raise Exception.Create('identifier '''+aid+''' expected');
   skipToken();
 end;
 
@@ -536,7 +541,7 @@ end;
 function TTextParser.eatId (const aid: AnsiString): Boolean;
 begin
   result := false;
-  if (mTokType <> TTId) or (CompareText(mTokStr, aid) <> 0) then exit;
+  if (mTokType <> TTId) or (not StrEqu(mTokStr, aid)) then exit;
   result := true;
   skipToken();
 end;
diff --git a/src/shared/zmapgen.dpr b/src/shared/zmapgen.dpr
new file mode 100644 (file)
index 0000000..e983e43
--- /dev/null
@@ -0,0 +1,53 @@
+{$INCLUDE a_modes.inc}
+{$M+}
+
+uses
+  SysUtils, Classes,
+  xparser in 'xparser.pas',
+  xdynrec in 'xdynrec.pas',
+  utils in 'utils.pas';
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+var
+  pr: TTextParser;
+  dfmapdef: TDynMapDef;
+  fo: TextFile;
+  st: TStream;
+  ch: AnsiChar;
+  wdt: Integer;
+  s: AnsiString;
+begin
+  writeln('parsing "mapdef.txt"...');
+  pr := TFileTextParser.Create('mapdef.txt');
+  try
+    dfmapdef := TDynMapDef.Create(pr);
+  except on e: Exception do
+    begin
+      writeln('ERROR at (', pr.line, ',', pr.col, '): ', e.message);
+      Halt(1);
+    end;
+  end;
+
+  writeln('writing "mapdef.inc"...');
+  AssignFile(fo, 'mapdef.inc');
+  Rewrite(fo);
+  write(fo, '// *** WARNING! ***'#10);
+  write(fo, '//   regenerate this part directly from "mapdef.txt" with ''zmapgen'', NEVER manually change anything here!'#10#10#10);
+  write(fo, dfmapdef.pasdef);
+
+  st := openDiskFileRO('mapdef.txt');
+  write(fo, #10#10'const defaultMapDef: AnsiString = ''''+'#10'  ');
+  wdt := 2;
+  while true do
+  begin
+    if (st.Read(ch, 1) <> 1) then break;
+    s := formatstrf('#%d', [Byte(ch)]);
+    if (wdt+Length(s) > 78) then begin wdt := 2; write(fo, '+'#10'  '); end;
+    write(fo, s);
+    Inc(wdt, Length(s));
+  end;
+  write(fo, #10';');
+
+  CloseFile(fo);
+end.