DEADSOFTWARE

AddResource: Fix non-ANSI encoding
[d2df-editor.git] / src / editor / f_main.pas
index d3193006eebd27184d3b0bc384de61a50d60962e..8bdab7d638cc7c829574a91ebb9c7a3bc960a1cd 100644 (file)
@@ -1,6 +1,6 @@
 unit f_main;
 
 unit f_main;
 
-{$MODE Delphi}
+{$INCLUDE ../shared/a_modes.inc}
 
 interface
 
 
 interface
 
@@ -8,10 +8,14 @@ uses
   LCLIntf, LCLType, LMessages, SysUtils, Variants, Classes, Graphics,
   Controls, Forms, Dialogs, ImgList, StdCtrls, Buttons,
   ComCtrls, ValEdit, Types, ToolWin, Menus, ExtCtrls,
   LCLIntf, LCLType, LMessages, SysUtils, Variants, Classes, Graphics,
   Controls, Forms, Dialogs, ImgList, StdCtrls, Buttons,
   ComCtrls, ValEdit, Types, ToolWin, Menus, ExtCtrls,
-  CheckLst, Grids;
+  CheckLst, Grids, OpenGLContext, utils, UTF8Process;
 
 type
 
 type
+
+  { TMainForm }
+
   TMainForm = class(TForm)
   TMainForm = class(TForm)
+    lLoad: TLabel;
   // Главное меню:
     MainMenu: TMainMenu;
   // "Файл":
   // Главное меню:
     MainMenu: TMainMenu;
   // "Файл":
@@ -77,6 +81,9 @@ type
 
   // Панель инструментов:
     MainToolBar: TToolBar;
 
   // Панель инструментов:
     MainToolBar: TToolBar;
+    pbLoad: TProgressBar;
+    pLoadProgress: TPanel;
+    RenderPanel: TOpenGLControl;
     tbNewMap: TToolButton;
     tbOpenMap: TToolButton;
     tbSaveMap: TToolButton;
     tbNewMap: TToolButton;
     tbOpenMap: TToolButton;
     tbSaveMap: TToolButton;
@@ -107,12 +114,6 @@ type
 
   // Панель карты:
     PanelMap: TPanel;
 
   // Панель карты:
     PanelMap: TPanel;
-  // Панель отображения карты:
-    RenderPanel: TPanel;
-  // Панель загрузки:
-    pLoadProgress: TPanel;
-    lLoad: TLabel;
-    pbLoad: TProgressBar;
   // Полосы прокрутки:
     sbHorizontal: TScrollBar;
     sbVertical: TScrollBar;
   // Полосы прокрутки:
     sbHorizontal: TScrollBar;
     sbVertical: TScrollBar;
@@ -206,9 +207,12 @@ type
     procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
     procedure FormResize(Sender: TObject);
     procedure lbTextureListClick(Sender: TObject);
     procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
     procedure FormResize(Sender: TObject);
     procedure lbTextureListClick(Sender: TObject);
+    procedure lbTextureListDrawItem(Control: TWinControl; Index: Integer;
+      ARect: TRect; State: TOwnerDrawState);
     procedure RenderPanelMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
     procedure RenderPanelMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
     procedure RenderPanelMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
     procedure RenderPanelMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
     procedure RenderPanelMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
     procedure RenderPanelMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
+    procedure RenderPanelPaint(Sender: TObject);
     procedure RenderPanelResize(Sender: TObject);
     procedure vleObjectPropertyEditButtonClick(Sender: TObject);
     procedure vleObjectPropertyGetPickList(Sender: TObject; const KeyName: String; Values: TStrings);
     procedure RenderPanelResize(Sender: TObject);
     procedure vleObjectPropertyEditButtonClick(Sender: TObject);
     procedure vleObjectPropertyGetPickList(Sender: TObject; const KeyName: String; Values: TStrings);
@@ -256,8 +260,6 @@ type
     procedure OnIdle(Sender: TObject; var Done: Boolean);
   public
     procedure RefreshRecentMenu();
     procedure OnIdle(Sender: TObject; var Done: Boolean);
   public
     procedure RefreshRecentMenu();
-    { procedure lbTextureListDrawItem(Control: TWinControl; Index: Integer;
-                                    Rect: TRect; State: TOwnerDrawState); }
   end;
 
 const
   end;
 
 const
@@ -321,14 +323,14 @@ procedure ChangeShownProperty(Name: String; NewValue: String);
 implementation
 
 uses
 implementation
 
 uses
-  f_options, e_graphics, e_log, dglOpenGL, Math,
+  f_options, e_graphics, e_log, GL, GLExt, Math,
   f_mapoptions, g_basic, f_about, f_mapoptimization,
   f_mapcheck, f_addresource_texture, g_textures,
   f_activationtype, f_keys, MAPWRITER, MAPSTRUCT,
   f_mapoptions, g_basic, f_about, f_mapoptimization,
   f_mapcheck, f_addresource_texture, g_textures,
   f_activationtype, f_keys, MAPWRITER, MAPSTRUCT,
-  MAPREADER, f_selectmap, f_savemap, WADEDITOR, MAPDEF,
+  MAPREADER, f_selectmap, f_savemap, WADEDITOR, WADSTRUCT, MAPDEF,
   g_map, f_saveminimap, f_addresource, CONFIG, f_packmap,
   f_addresource_sound, f_maptest, f_choosetype,
   g_map, f_saveminimap, f_addresource, CONFIG, f_packmap,
   f_addresource_sound, f_maptest, f_choosetype,
-  g_language, f_selectlang, ClipBrd, Windows;
+  g_language, f_selectlang, ClipBrd;
 
 const
   UNDO_DELETE_PANEL   = 1;
 
 const
   UNDO_DELETE_PANEL   = 1;
@@ -419,9 +421,8 @@ type
   TCopyRecArray = Array of TCopyRec;
 
 var
   TCopyRecArray = Array of TCopyRec;
 
 var
-  hDC: THandle;
-  hRC: THandle;
   gEditorFont: DWORD;
   gEditorFont: DWORD;
+  gDataLoaded: Boolean = False;
   ShowMap: Boolean = False;
   DrawRect: PRect = nil;
   SnapToGrid: Boolean = True;
   ShowMap: Boolean = False;
   DrawRect: PRect = nil;
   SnapToGrid: Boolean = True;
@@ -1460,7 +1461,13 @@ begin
                   MaxLength := 3;
                 end;
 
                   MaxLength := 3;
                 end;
 
-                with ItemProps[InsertRow(_lc[I_PROP_TR_SHOT_ALLMAP], BoolNames[Data.ShotAllMap], True)] do
+                case Data.ShotAim of
+                  1: str := _lc[I_PROP_TR_SHOT_AIM_1];
+                  2: str := _lc[I_PROP_TR_SHOT_AIM_2];
+                  3: str := _lc[I_PROP_TR_SHOT_AIM_3];
+                  else str := _lc[I_PROP_TR_SHOT_AIM_0];
+                end;
+                with ItemProps[InsertRow(_lc[I_PROP_TR_SHOT_AIM], str, True)-1] do
                 begin
                   EditStyle := esPickList;
                   ReadOnly := True;
                 begin
                   EditStyle := esPickList;
                   ReadOnly := True;
@@ -1788,6 +1795,7 @@ procedure FullClear();
 begin
   RemoveSelectFromObjects();
   ClearMap();
 begin
   RemoveSelectFromObjects();
   ClearMap();
+  LoadSky(gMapInfo.SkyName);
   UndoBuffer := nil;
   slInvalidTextures.Clear();
   MapCheckForm.lbErrorList.Clear();
   UndoBuffer := nil;
   slInvalidTextures.Clear();
   MapCheckForm.lbErrorList.Clear();
@@ -1869,10 +1877,11 @@ end;
 
 function AddTexture(aWAD, aSection, aTex: String; silent: Boolean): Boolean;
 var
 
 function AddTexture(aWAD, aSection, aTex: String; silent: Boolean): Boolean;
 var
-  a: Integer;
+  a, FrameLen: Integer;
   ok: Boolean;
   FileName: String;
   ResourceName: String;
   ok: Boolean;
   FileName: String;
   ResourceName: String;
+  UResourceName: String;
   FullResourceName: String;
   SectionName: String;
   Data: Pointer;
   FullResourceName: String;
   SectionName: String;
   Data: Pointer;
@@ -1899,19 +1908,20 @@ begin
       end
     else
       begin // Внешний WAD
       end
     else
       begin // Внешний WAD
-        FileName := EditorDir+'wads\'+aWAD;
-        ResourceName := aWAD+':'+SectionName+'\'+aTex;
+        FileName := EditorDir+'wads/'+aWAD;
+        ResourceName := utf2win(aWAD)+':'+SectionName+'\'+aTex;
       end;
 
   ok := True;
       end;
 
   ok := True;
+  UResourceName := win2utf(ResourceName);
 
 // Есть ли уже такая текстура:
   for a := 0 to MainForm.lbTextureList.Items.Count-1 do
 
 // Есть ли уже такая текстура:
   for a := 0 to MainForm.lbTextureList.Items.Count-1 do
-    if ResourceName = MainForm.lbTextureList.Items[a] then
+    if UResourceName = MainForm.lbTextureList.Items[a] then
     begin
       if not silent then
         ErrorMessageBox(Format(_lc[I_MSG_TEXTURE_ALREADY],
     begin
       if not silent then
         ErrorMessageBox(Format(_lc[I_MSG_TEXTURE_ALREADY],
-                               [ResourceName]));
+                               [UResourceName]));
       ok := False;
     end;
 
       ok := False;
     end;
 
@@ -1920,7 +1930,7 @@ begin
   begin
     if not silent then
       ErrorMessageBox(Format(_lc[I_MSG_RES_NAME_64],
   begin
     if not silent then
       ErrorMessageBox(Format(_lc[I_MSG_RES_NAME_64],
-                             [ResourceName]));
+                             [UResourceName]));
     ok := False;
   end;
 
     ok := False;
   end;
 
@@ -1929,7 +1939,7 @@ begin
     a := -1;
     if aWAD = _lc[I_WAD_SPECIAL_TEXS] then
     begin
     a := -1;
     if aWAD = _lc[I_WAD_SPECIAL_TEXS] then
     begin
-      a := MainForm.lbTextureList.Items.Add(ResourceName);
+      a := MainForm.lbTextureList.Items.Add(UResourceName);
       if not silent then
         SelectTexture(a);
       Result := True;
       if not silent then
         SelectTexture(a);
       Result := True;
@@ -1940,15 +1950,15 @@ begin
 
     if IsAnim(FullResourceName) then
       begin // Аним. текстура
 
     if IsAnim(FullResourceName) then
       begin // Аним. текстура
-        GetFrame(FullResourceName, Data, Width, Height);
+        GetFrame(FullResourceName, Data, FrameLen, Width, Height);
 
 
-        if g_CreateTextureMemorySize(Data, ResourceName, 0, 0, Width, Height, 1) then
-          a := MainForm.lbTextureList.Items.Add(ResourceName);
+        if g_CreateTextureMemorySize(Data, FrameLen, ResourceName, 0, 0, Width, Height, 1) then
+          a := MainForm.lbTextureList.Items.Add(UResourceName);
       end
     else // Обычная текстура
       begin
         if g_CreateTextureWAD(ResourceName, FullResourceName) then
       end
     else // Обычная текстура
       begin
         if g_CreateTextureWAD(ResourceName, FullResourceName) then
-          a := MainForm.lbTextureList.Items.Add(ResourceName);
+          a := MainForm.lbTextureList.Items.Add(UResourceName);
       end;
     if (a > -1) and (not silent) then
       SelectTexture(a);
       end;
     if (a > -1) and (not silent) then
       SelectTexture(a);
@@ -2037,7 +2047,7 @@ begin
     lbTextureList.Sorted := True;
     lbTextureList.Sorted := False;
 
     lbTextureList.Sorted := True;
     lbTextureList.Sorted := False;
 
-    UpdateCaption(gMapInfo.Name, ExtractFileName(FileName), MapName);
+    UpdateCaption(win2utf(gMapInfo.Name), ExtractFileName(FileName), MapName);
   end;
 end;
 
   end;
 end;
 
@@ -2203,7 +2213,7 @@ end;
 function SelectedTexture(): String;
 begin
   if MainForm.lbTextureList.ItemIndex <> -1 then
 function SelectedTexture(): String;
 begin
   if MainForm.lbTextureList.ItemIndex <> -1 then
-    Result := MainForm.lbTextureList.Items[MainForm.lbTextureList.ItemIndex]
+    Result := utf2win(MainForm.lbTextureList.Items[MainForm.lbTextureList.ItemIndex])
   else
     Result := '';
 end;
   else
     Result := '';
 end;
@@ -2211,7 +2221,7 @@ end;
 function IsSpecialTextureSel(): Boolean;
 begin
   Result := (MainForm.lbTextureList.ItemIndex <> -1) and
 function IsSpecialTextureSel(): Boolean;
 begin
   Result := (MainForm.lbTextureList.ItemIndex <> -1) and
-            IsSpecialTexture(MainForm.lbTextureList.Items[MainForm.lbTextureList.ItemIndex]);
+            IsSpecialTexture(utf2win(MainForm.lbTextureList.Items[MainForm.lbTextureList.ItemIndex]));
 end;
 
 function CopyBufferToString(var CopyBuf: TCopyRecArray): String;
 end;
 
 function CopyBufferToString(var CopyBuf: TCopyRecArray): String;
@@ -2520,51 +2530,57 @@ begin
   OptionsForm.ShowModal();
 end;
 
   OptionsForm.ShowModal();
 end;
 
-procedure TMainForm.FormCreate(Sender: TObject);
+procedure LoadStdFont(cfgres, texture: string; var FontID: DWORD);
 var
 var
-  PixelFormat: GLuint;
-  pfd: TPIXELFORMATDESCRIPTOR;
+  cwdt, chgt: Byte;
+  spc: ShortInt;
+  ID: DWORD;
+  wad: TWADEditor_1;
+  cfgdata: Pointer;
+  cfglen: Integer;
   config: TConfig;
   config: TConfig;
-  i: Integer;
-  s: String;
 begin
 begin
-  Randomize();
+  cfglen := 0;
 
 
-  EditorDir := ExtractFilePath(Application.ExeName);
+  wad := TWADEditor_1.Create;
+  if wad.ReadFile(EditorDir+'data/Game.wad') then
+    wad.GetResource('FONTS', cfgres, cfgdata, cfglen);
+  wad.Free();
 
 
-  e_InitLog(EditorDir+'Editor.log', WM_NEWFILE);
+  if cfglen <> 0 then
+  begin
+    if not g_CreateTextureWAD('FONT_STD', EditorDir+'data/Game.wad:FONTS\'+texture) then
+      e_WriteLog('ERROR ERROR ERROR', MSG_WARNING);
 
 
-  e_WriteLog('Init OpenGL', MSG_NOTIFY);
+    config := TConfig.CreateMem(cfgdata, cfglen);
+    cwdt := Min(Max(config.ReadInt('FontMap', 'CharWidth', 0), 0), 255);
+    chgt := Min(Max(config.ReadInt('FontMap', 'CharHeight', 0), 0), 255);
+    spc := Min(Max(config.ReadInt('FontMap', 'Kerning', 0), -128), 127);
 
 
-  InitOpenGL();
-  hDC := GetDC(RenderPanel.Handle);
+    if g_GetTexture('FONT_STD', ID) then
+      e_TextureFontBuild(ID, FontID, cwdt, chgt, spc-2);
 
 
-  FillChar(pfd, SizeOf(pfd), 0);
-  with pfd do
-  begin
-    nSize := SizeOf(pfd);
-    nVersion := 1;
-    dwFlags := PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
-    dwLayerMask := PFD_MAIN_PLANE;
-    iPixelType := PFD_TYPE_RGBA;
-    cColorBits := 24;
-    cDepthBits := 32;
-    iLayerType := PFD_MAIN_PLANE;
-  end;
-  PixelFormat := ChoosePixelFormat (hDC, @pfd);
-  SetPixelFormat(hDC, PixelFormat, @pfd);
+    config.Free();
+  end
+  else
+    e_WriteLog('Could not load FONT_STD', MSG_WARNING);
 
 
-  hRC := wglCreateContext(hDC);
-  ActivateRenderingContext(hDC, hRC);
+  if cfglen <> 0 then FreeMem(cfgdata);
+end;
 
 
-  e_InitGL(False);
+procedure TMainForm.FormCreate(Sender: TObject);
+var
+  config: TConfig;
+  i: Integer;
+  s: String;
+begin
+  Randomize();
 
 
-  gEditorFont := e_SimpleFontCreate('Arial Cyr', 12, FW_BOLD, hDC);
+  EditorDir := ExtractFilePath(Application.ExeName);
 
 
-  slInvalidTextures := TStringList.Create;
+  e_InitLog(EditorDir+'Editor.log', WM_NEWFILE);
 
 
-  e_WriteLog('Loading data', MSG_NOTIFY);
-  LoadData();
+  slInvalidTextures := TStringList.Create;
 
   ShowLayer(LAYER_BACK, True);
   ShowLayer(LAYER_WALLS, True);
 
   ShowLayer(LAYER_BACK, True);
   ShowLayer(LAYER_WALLS, True);
@@ -2582,8 +2598,16 @@ begin
   OpenedMap := '';
   OpenedWAD := '';
 
   OpenedMap := '';
   OpenedWAD := '';
 
-  config := TConfig.CreateFile(EditorDir+'\Editor.cfg');
+  config := TConfig.CreateFile(EditorDir+'Editor.cfg');
 
 
+  if config.ReadInt('Editor', 'XPos', -1) = -1 then
+    Position := poDesktopCenter
+  else begin
+    Left := config.ReadInt('Editor', 'XPos', Left);
+    Top := config.ReadInt('Editor', 'YPos', Top);
+    Width := config.ReadInt('Editor', 'Width', Width);
+    Height := config.ReadInt('Editor', 'Height', Height);
+  end;
   if config.ReadBool('Editor', 'Maximize', False) then
     WindowState := wsMaximized;
   ShowMap := config.ReadBool('Editor', 'Minimap', False);
   if config.ReadBool('Editor', 'Maximize', False) then
     WindowState := wsMaximized;
   ShowMap := config.ReadBool('Editor', 'Minimap', False);
@@ -2657,18 +2681,22 @@ begin
   Application.OnIdle := OnIdle;
 end;
 
   Application.OnIdle := OnIdle;
 end;
 
+procedure PrintBlack(X, Y: Integer; Text: string; FontID: DWORD);
+begin
+  // NOTE: all the font printing routines assume CP1251
+  e_TextureFontPrintEx(X, Y, Text, FontID, 0, 0, 0, 1.0);
+end;
+
 procedure TMainForm.Draw();
 var
 procedure TMainForm.Draw();
 var
-  ps: TPaintStruct;
   x, y: Integer;
   a, b: Integer;
   x, y: Integer;
   a, b: Integer;
-  ID: DWORD;
+  ID, PID: DWORD;
   Width, Height: Word;
   Rect: TRectWH;
   ObjCount: Word;
   aX, aY, aX2, aY2, XX, ScaleSz: Integer;
 begin
   Width, Height: Word;
   Rect: TRectWH;
   ObjCount: Word;
   aX, aY, aX2, aY2, XX, ScaleSz: Integer;
 begin
-  BeginPaint(Handle, ps);
   e_BeginRender();
 
   e_Clear(GL_COLOR_BUFFER_BIT,
   e_BeginRender();
 
   e_Clear(GL_COLOR_BUFFER_BIT,
@@ -2735,10 +2763,9 @@ begin
     if not g_GetTexture(SelectedTexture(), ID) then
       g_GetTexture('NOTEXTURE', ID);
     g_GetTextureSizeByID(ID, Width, Height);
     if not g_GetTexture(SelectedTexture(), ID) then
       g_GetTexture('NOTEXTURE', ID);
     g_GetTextureSizeByID(ID, Width, Height);
-    e_DrawFillQuad(RenderPanel.Width-Width-2, RenderPanel.Height-Height-2,
-                   RenderPanel.Width-1, RenderPanel.Height-1,
-                   GetRValue(PreviewColor), GetGValue(PreviewColor), GetBValue(PreviewColor), 0);
-    e_Draw(ID, RenderPanel.Width-Width-1, RenderPanel.Height-Height-1, 0, True, False);
+    if g_GetTexture('PREVIEW', PID) then
+       e_DrawFill(PID, RenderPanel.Width-Width, RenderPanel.Height-Height, Width div 16 + 1, Height div 16 + 1, 0, True, False);
+    e_Draw(ID, RenderPanel.Width-Width, RenderPanel.Height-Height, 0, True, False);
   end;
 
 // Подсказка при выборе точки Телепорта:
   end;
 
 // Подсказка при выборе точки Телепорта:
@@ -2755,7 +2782,7 @@ begin
 
     e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 192, 192, 192, 127);
     e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 255, 255, 255);
 
     e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 192, 192, 192, 127);
     e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 255, 255, 255);
-    e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(_lc[I_HINT_TELEPORT]), gEditorFont, 0, 0, 0);
+    PrintBlack(MousePos.X+2, MousePos.Y+2, _glc[I_HINT_TELEPORT], gEditorFont);
   end;
 
 // Подсказка при выборе точки появления:
   end;
 
 // Подсказка при выборе точки появления:
@@ -2766,7 +2793,7 @@ begin
                0, 0, 255);
     e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 192, 192, 192, 127);
     e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 255, 255, 255);
                0, 0, 255);
     e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 192, 192, 192, 127);
     e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 255, 255, 255);
-    e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(_lc[I_HINT_SPAWN]), gEditorFont, 0, 0, 0);
+    PrintBlack(MousePos.X+2, MousePos.Y+2, _glc[I_HINT_SPAWN], gEditorFont);
   end;
 
 // Подсказка при выборе панели двери:
   end;
 
 // Подсказка при выборе панели двери:
@@ -2774,7 +2801,7 @@ begin
   begin
     e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 192, 192, 192, 127);
     e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 255, 255, 255);
   begin
     e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 192, 192, 192, 127);
     e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 255, 255, 255);
-    e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(_lc[I_HINT_PANEL_DOOR]), gEditorFont, 0, 0, 0);
+    PrintBlack(MousePos.X+2, MousePos.Y+2, _glc[I_HINT_PANEL_DOOR], gEditorFont);
   end;
 
 // Подсказка при выборе панели с текстурой:
   end;
 
 // Подсказка при выборе панели с текстурой:
@@ -2782,7 +2809,7 @@ begin
   begin
     e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+196, MousePos.Y+18, 192, 192, 192, 127);
     e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+196, MousePos.Y+18, 255, 255, 255);
   begin
     e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+196, MousePos.Y+18, 192, 192, 192, 127);
     e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+196, MousePos.Y+18, 255, 255, 255);
-    e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(_lc[I_HINT_PANEL_TEXTURE]), gEditorFont, 0, 0, 0);
+    PrintBlack(MousePos.X+2, MousePos.Y+2, _glc[I_HINT_PANEL_TEXTURE], gEditorFont);
   end;
 
 // Подсказка при выборе панели индикации выстрела:
   end;
 
 // Подсказка при выборе панели индикации выстрела:
@@ -2790,7 +2817,7 @@ begin
   begin
     e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+316, MousePos.Y+18, 192, 192, 192, 127);
     e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+316, MousePos.Y+18, 255, 255, 255);
   begin
     e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+316, MousePos.Y+18, 192, 192, 192, 127);
     e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+316, MousePos.Y+18, 255, 255, 255);
-    e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(_lc[I_HINT_PANEL_SHOT]), gEditorFont, 0, 0, 0);
+    PrintBlack(MousePos.X+2, MousePos.Y+2, _glc[I_HINT_PANEL_SHOT], gEditorFont);
   end;
 
 // Подсказка при выборе панели лифта:
   end;
 
 // Подсказка при выборе панели лифта:
@@ -2798,7 +2825,7 @@ begin
   begin
     e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 192, 192, 192, 127);
     e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 255, 255, 255);
   begin
     e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 192, 192, 192, 127);
     e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 255, 255, 255);
-    e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(_lc[I_HINT_PANEL_LIFT]), gEditorFont, 0, 0, 0);
+    PrintBlack(MousePos.X+2, MousePos.Y+2, _glc[I_HINT_PANEL_LIFT], gEditorFont);
   end;
 
 // Подсказка при выборе монстра:
   end;
 
 // Подсказка при выборе монстра:
@@ -2806,7 +2833,7 @@ begin
   begin
     e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+120, MousePos.Y+18, 192, 192, 192, 127);
     e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+120, MousePos.Y+18, 255, 255, 255);
   begin
     e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+120, MousePos.Y+18, 192, 192, 192, 127);
     e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+120, MousePos.Y+18, 255, 255, 255);
-    e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(_lc[I_HINT_MONSTER]), gEditorFont, 0, 0, 0);
+    PrintBlack(MousePos.X+2, MousePos.Y+2, _glc[I_HINT_MONSTER], gEditorFont);
   end;
 
 // Подсказка при выборе области воздействия:
   end;
 
 // Подсказка при выборе области воздействия:
@@ -2814,7 +2841,7 @@ begin
   begin
     e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+204, MousePos.Y+18, 192, 192, 192, 127);
     e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+204, MousePos.Y+18, 255, 255, 255);
   begin
     e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+204, MousePos.Y+18, 192, 192, 192, 127);
     e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+204, MousePos.Y+18, 255, 255, 255);
-    e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(_lc[I_HINT_EXT_AREA]), gEditorFont, 0, 0, 0);
+    PrintBlack(MousePos.X+2, MousePos.Y+2, _glc[I_HINT_EXT_AREA], gEditorFont);
   end;
 
 // Рисуем текстуры, если чертим панель:
   end;
 
 // Рисуем текстуры, если чертим панель:
@@ -2844,10 +2871,10 @@ begin
 
     if MouseAction in [MOUSEACTION_DRAWPANEL, MOUSEACTION_DRAWTRIGGER] then
       begin // Чертим новый
 
     if MouseAction in [MOUSEACTION_DRAWPANEL, MOUSEACTION_DRAWTRIGGER] then
       begin // Чертим новый
-        e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(Format(_lc[I_HINT_WIDTH],
-                          [Abs(MousePos.X-MouseLDownPos.X)])), gEditorFont, 0, 0, 0);
-        e_SimpleFontPrint(MousePos.X+8, MousePos.Y+28, PChar(Format(_lc[I_HINT_HEIGHT],
-                          [Abs(MousePos.Y-MouseLDownPos.Y)])), gEditorFont, 0, 0, 0);
+        PrintBlack(MousePos.X+2, MousePos.Y+2, Format(_glc[I_HINT_WIDTH],
+                          [Abs(MousePos.X-MouseLDownPos.X)]), gEditorFont);
+        PrintBlack(MousePos.X+2, MousePos.Y+14, Format(_glc[I_HINT_HEIGHT],
+                          [Abs(MousePos.Y-MouseLDownPos.Y)]), gEditorFont);
       end
     else // Растягиваем существующий
       if SelectedObjects[GetFirstSelected].ObjectType in [OBJECT_PANEL, OBJECT_TRIGGER] then
       end
     else // Растягиваем существующий
       if SelectedObjects[GetFirstSelected].ObjectType in [OBJECT_PANEL, OBJECT_TRIGGER] then
@@ -2863,10 +2890,10 @@ begin
             Height := gTriggers[SelectedObjects[GetFirstSelected].ID].Height;
           end;
 
             Height := gTriggers[SelectedObjects[GetFirstSelected].ID].Height;
           end;
 
-        e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(Format(_lc[I_HINT_WIDTH], [Width])),
-                          gEditorFont, 0, 0, 0);
-        e_SimpleFontPrint(MousePos.X+8, MousePos.Y+28, PChar(Format(_lc[I_HINT_HEIGHT], [Height])),
-                          gEditorFont, 0, 0, 0);
+        PrintBlack(MousePos.X+2, MousePos.Y+2, Format(_glc[I_HINT_WIDTH], [Width]),
+                          gEditorFont);
+        PrintBlack(MousePos.X+2, MousePos.Y+14, Format(_glc[I_HINT_HEIGHT], [Height]),
+                          gEditorFont);
       end;
   end;
 
       end;
   end;
 
@@ -2962,8 +2989,7 @@ begin
   end; // Мини-карта
 
   e_EndRender();
   end; // Мини-карта
 
   e_EndRender();
-  SwapBuffers(hDC);
-  EndPaint(Handle, ps);
+  RenderPanel.SwapBuffers();
 end;
 
 procedure TMainForm.FormResize(Sender: TObject);
 end;
 
 procedure TMainForm.FormResize(Sender: TObject);
@@ -3616,7 +3642,7 @@ begin
                   trigger.Key := Trigger.Key or KEY_BLUETEAM;
 
               // Параметры триггера:
                   trigger.Key := Trigger.Key or KEY_BLUETEAM;
 
               // Параметры триггера:
-                ZeroMemory(@trigger.Data.Default[0], 128);
+                FillByte(trigger.Data.Default[0], 128, 0);
 
                 case trigger.TriggerType of
                 // Переключаемая панель:
 
                 case trigger.TriggerType of
                 // Переключаемая панель:
@@ -3725,7 +3751,7 @@ begin
                       trigger.Data.ShotPanelID := -1;
                       trigger.Data.ShotTarget := 0;
                       trigger.Data.ShotIntSight := 0;
                       trigger.Data.ShotPanelID := -1;
                       trigger.Data.ShotTarget := 0;
                       trigger.Data.ShotIntSight := 0;
-                      trigger.Data.ShotAllMap := False;
+                      trigger.Data.ShotAim := TRIGGER_SHOT_AIM_DEFAULT;
                       trigger.Data.ShotPos.X := trigger.X-64;
                       trigger.Data.ShotPos.Y := trigger.Y-64;
                       trigger.Data.ShotAngle := 0;
                       trigger.Data.ShotPos.X := trigger.X-64;
                       trigger.Data.ShotPos.Y := trigger.Y-64;
                       trigger.Data.ShotAngle := 0;
@@ -3837,6 +3863,11 @@ begin
     end;
 end;
 
     end;
 end;
 
+procedure TMainForm.RenderPanelPaint(Sender: TObject);
+begin
+  Draw();
+end;
+
 procedure TMainForm.RenderPanelMouseMove(Sender: TObject;
   Shift: TShiftState; X, Y: Integer);
 var
 procedure TMainForm.RenderPanelMouseMove(Sender: TObject;
   Shift: TShiftState; X, Y: Integer);
 var
@@ -3909,8 +3940,10 @@ begin
       begin
         if DrawRect = nil then
           New(DrawRect);
       begin
         if DrawRect = nil then
           New(DrawRect);
-        DrawRect.TopLeft := MouseRDownPos;
-        DrawRect.BottomRight := MousePos;
+        DrawRect.Top := MouseRDownPos.y;
+        DrawRect.Left := MouseRDownPos.x;
+        DrawRect.Bottom := MousePos.y;
+        DrawRect.Right := MousePos.x;
       end
     else
     // Двигаем выделенные объекты:
       end
     else
     // Двигаем выделенные объекты:
@@ -3959,8 +3992,10 @@ begin
       begin
         if DrawRect = nil then
           New(DrawRect);
       begin
         if DrawRect = nil then
           New(DrawRect);
-        DrawRect.TopLeft := MouseLDownPos;
-        DrawRect.BottomRight := MousePos;
+        DrawRect.Top := MouseLDownPos.y;
+        DrawRect.Left := MouseLDownPos.x;
+        DrawRect.Bottom := MousePos.y;
+        DrawRect.Right := MousePos.x;
       end
     else // Двигаем карту:
       if MouseAction = MOUSEACTION_MOVEMAP then
       end
     else // Двигаем карту:
       if MouseAction = MOUSEACTION_MOVEMAP then
@@ -3983,7 +4018,7 @@ begin
   CanClose := MessageBox(0, PChar(_lc[I_MSG_EXIT_PROMT]),
                          PChar(_lc[I_MSG_EXIT]),
                          MB_ICONQUESTION or MB_YESNO or
   CanClose := MessageBox(0, PChar(_lc[I_MSG_EXIT_PROMT]),
                          PChar(_lc[I_MSG_EXIT]),
                          MB_ICONQUESTION or MB_YESNO or
-                         MB_TASKMODAL or MB_DEFBUTTON1) = idYes;
+                         MB_DEFBUTTON1) = idYes;
 end;
 
 procedure TMainForm.aExitExecute(Sender: TObject);
 end;
 
 procedure TMainForm.aExitExecute(Sender: TObject);
@@ -3996,8 +4031,22 @@ var
   config: TConfig;
   i: Integer;
 begin
   config: TConfig;
   i: Integer;
 begin
-  config := TConfig.CreateFile(EditorDir+'\Editor.cfg');
+  config := TConfig.CreateFile(EditorDir+'Editor.cfg');
 
 
+  if WindowState <> wsMaximized then
+  begin
+    config.WriteInt('Editor', 'XPos', Left);
+    config.WriteInt('Editor', 'YPos', Top);
+    config.WriteInt('Editor', 'Width', Width);
+    config.WriteInt('Editor', 'Height', Height);
+  end
+  else
+  begin
+    config.WriteInt('Editor', 'XPos', RestoredLeft);
+    config.WriteInt('Editor', 'YPos', RestoredTop);
+    config.WriteInt('Editor', 'Width', RestoredWidth);
+    config.WriteInt('Editor', 'Height', RestoredHeight);
+  end;
   config.WriteBool('Editor', 'Maximize', WindowState = wsMaximized);
   config.WriteBool('Editor', 'Minimap', ShowMap);
   config.WriteInt('Editor', 'PanelProps', PanelProps.ClientWidth);
   config.WriteBool('Editor', 'Maximize', WindowState = wsMaximized);
   config.WriteBool('Editor', 'Minimap', ShowMap);
   config.WriteInt('Editor', 'PanelProps', PanelProps.ClientWidth);
@@ -4019,12 +4068,10 @@ begin
       config.WriteStr('RecentFiles', IntToStr(i+1), '');
   RecentFiles.Free();
 
       config.WriteStr('RecentFiles', IntToStr(i+1), '');
   RecentFiles.Free();
 
-  config.SaveFile(EditorDir+'\Editor.cfg');
+  config.SaveFile(EditorDir+'Editor.cfg');
   config.Free();
 
   slInvalidTextures.Free;
   config.Free();
 
   slInvalidTextures.Free;
-
-  wglDeleteContext(hRC);
 end;
 
 procedure TMainForm.RenderPanelResize(Sender: TObject);
 end;
 
 procedure TMainForm.RenderPanelResize(Sender: TObject);
@@ -4043,7 +4090,7 @@ begin
   while (Pos(':\', ResName) > 0) do
     Delete(ResName, 1, Pos(':\', ResName) + 1);
 
   while (Pos(':\', ResName) > 0) do
     Delete(ResName, 1, Pos(':\', ResName) + 1);
 
-  UpdateCaption(gMapInfo.Name, ExtractFileName(OpenedWAD), ResName);
+  UpdateCaption(win2utf(gMapInfo.Name), ExtractFileName(OpenedWAD), ResName);
 end;
 
 procedure TMainForm.aAboutExecute(Sender: TObject);
 end;
 
 procedure TMainForm.aAboutExecute(Sender: TObject);
@@ -4264,11 +4311,11 @@ begin
       begin
         AddSoundForm.OKFunction := nil;
         AddSoundForm.lbResourcesList.MultiSelect := False;
       begin
         AddSoundForm.OKFunction := nil;
         AddSoundForm.lbResourcesList.MultiSelect := False;
-        AddSoundForm.SetResource := vleObjectProperty.Cells[1, i];
+        AddSoundForm.SetResource := utf2win(vleObjectProperty.Cells[1, i]);
 
         if (AddSoundForm.ShowModal() = mrOk) then
         begin
 
         if (AddSoundForm.ShowModal() = mrOk) then
         begin
-          vleObjectProperty.Cells[1, i] := AddSoundForm.ResourceName;
+          vleObjectProperty.Cells[1, i] := win2utf(AddSoundForm.ResourceName);
           bApplyProperty.Click();
         end;
         Exit;
           bApplyProperty.Click();
         end;
         Exit;
@@ -4330,6 +4377,27 @@ begin
     end;
 end;
 
     end;
 end;
 
+procedure TMainForm.lbTextureListDrawItem(Control: TWinControl; Index: Integer;
+  ARect: TRect; State: TOwnerDrawState);
+begin
+  with Control as TListBox do
+  begin
+    if LCLType.odSelected in State then
+    begin
+      Canvas.Brush.Color := clHighlight;
+      Canvas.Font.Color := clHighlightText;
+    end else
+      if (Items <> nil) and (Index >= 0) then
+        if slInvalidTextures.IndexOf(Items[Index]) > -1 then
+        begin
+          Canvas.Brush.Color := clRed;
+          Canvas.Font.Color := clWhite;
+        end;
+    Canvas.FillRect(ARect);
+    Canvas.TextRect(ARect, ARect.Left, ARect.Top, Items[Index]);
+  end;
+end;
+
 procedure TMainForm.vleObjectPropertyGetPickList(Sender: TObject;
   const KeyName: String; Values: TStrings);
 begin
 procedure TMainForm.vleObjectPropertyGetPickList(Sender: TObject;
   const KeyName: String; Values: TStrings);
 begin
@@ -4399,6 +4467,13 @@ begin
         Values.Add(_lc[I_PROP_TR_SHOT_TO_5]);
         Values.Add(_lc[I_PROP_TR_SHOT_TO_6]);
       end
         Values.Add(_lc[I_PROP_TR_SHOT_TO_5]);
         Values.Add(_lc[I_PROP_TR_SHOT_TO_6]);
       end
+    else if KeyName = _lc[I_PROP_TR_SHOT_AIM] then
+      begin
+        Values.Add(_lc[I_PROP_TR_SHOT_AIM_0]);
+        Values.Add(_lc[I_PROP_TR_SHOT_AIM_1]);
+        Values.Add(_lc[I_PROP_TR_SHOT_AIM_2]);
+        Values.Add(_lc[I_PROP_TR_SHOT_AIM_3]);
+      end
     else if (KeyName = _lc[I_PROP_PANEL_BLEND]) or
             (KeyName = _lc[I_PROP_DM_ONLY]) or
             (KeyName = _lc[I_PROP_ITEM_FALLS]) or
     else if (KeyName = _lc[I_PROP_PANEL_BLEND]) or
             (KeyName = _lc[I_PROP_DM_ONLY]) or
             (KeyName = _lc[I_PROP_ITEM_FALLS]) or
@@ -4416,7 +4491,6 @@ begin
             (KeyName = _lc[I_PROP_TR_SCORE_CON]) or
             (KeyName = _lc[I_PROP_TR_SCORE_MSG]) or
             (KeyName = _lc[I_PROP_TR_HEALTH_MAX]) or
             (KeyName = _lc[I_PROP_TR_SCORE_CON]) or
             (KeyName = _lc[I_PROP_TR_SCORE_MSG]) or
             (KeyName = _lc[I_PROP_TR_HEALTH_MAX]) or
-            (KeyName = _lc[I_PROP_TR_SHOT_ALLMAP]) or
             (KeyName = _lc[I_PROP_TR_SHOT_SOUND]) or
             (KeyName = _lc[I_PROP_TR_EFFECT_CENTER]) then
       begin
             (KeyName = _lc[I_PROP_TR_SHOT_SOUND]) or
             (KeyName = _lc[I_PROP_TR_EFFECT_CENTER]) then
       begin
@@ -4632,9 +4706,9 @@ begin
             TRIGGER_EXIT:
               begin
                 s := vleObjectProperty.Values[_lc[I_PROP_TR_NEXT_MAP]];
             TRIGGER_EXIT:
               begin
                 s := vleObjectProperty.Values[_lc[I_PROP_TR_NEXT_MAP]];
-                ZeroMemory(@Data.MapName[0], 16);
+                FillByte(Data.MapName[0], 16, 0);
                 if s <> '' then
                 if s <> '' then
-                  CopyMemory(@Data.MapName[0], @s[1], Min(Length(s), 16));
+                  Move(Data.MapName[0], s[1], Min(Length(s), 16));
               end;
 
             TRIGGER_TEXTURE:
               end;
 
             TRIGGER_TEXTURE:
@@ -4671,9 +4745,9 @@ begin
             TRIGGER_SOUND:
               begin
                 s := vleObjectProperty.Values[_lc[I_PROP_TR_SOUND_NAME]];
             TRIGGER_SOUND:
               begin
                 s := vleObjectProperty.Values[_lc[I_PROP_TR_SOUND_NAME]];
-                ZeroMemory(@Data.SoundName[0], 64);
+                FillByte(Data.SoundName[0], 64, 0);
                 if s <> '' then
                 if s <> '' then
-                  CopyMemory(@Data.SoundName[0], @s[1], Min(Length(s), 64));
+                  Move(Data.SoundName[0], s[1], Min(Length(s), 64));
 
                 Data.Volume := Min(StrToIntDef(vleObjectProperty.Values[_lc[I_PROP_TR_SOUND_VOLUME]], 0), 255);
                 Data.Pan := Min(StrToIntDef(vleObjectProperty.Values[_lc[I_PROP_TR_SOUND_PAN]], 0), 255);
 
                 Data.Volume := Min(StrToIntDef(vleObjectProperty.Values[_lc[I_PROP_TR_SOUND_VOLUME]], 0), 255);
                 Data.Pan := Min(StrToIntDef(vleObjectProperty.Values[_lc[I_PROP_TR_SOUND_PAN]], 0), 255);
@@ -4725,9 +4799,9 @@ begin
             TRIGGER_MUSIC:
               begin
                 s := vleObjectProperty.Values[_lc[I_PROP_TR_MUSIC_NAME]];
             TRIGGER_MUSIC:
               begin
                 s := vleObjectProperty.Values[_lc[I_PROP_TR_MUSIC_NAME]];
-                ZeroMemory(@Data.MusicName[0], 64);
+                FillByte(Data.MusicName[0], 64, 0);
                 if s <> '' then
                 if s <> '' then
-                  CopyMemory(@Data.MusicName[0], @s[1], Min(Length(s), 64));
+                  Move(Data.MusicName[0], s[1], Min(Length(s), 64));
 
                 if vleObjectProperty.Values[_lc[I_PROP_TR_MUSIC_ACT]] = _lc[I_PROP_TR_MUSIC_ON] then
                   Data.MusicAction := 1
 
                 if vleObjectProperty.Values[_lc[I_PROP_TR_MUSIC_ACT]] = _lc[I_PROP_TR_MUSIC_ON] then
                   Data.MusicAction := 1
@@ -4785,9 +4859,9 @@ begin
                   Data.MessageSendTo := 5;
 
                 s := vleObjectProperty.Values[_lc[I_PROP_TR_MESSAGE_TEXT]];
                   Data.MessageSendTo := 5;
 
                 s := vleObjectProperty.Values[_lc[I_PROP_TR_MESSAGE_TEXT]];
-                ZeroMemory(@Data.MessageText[0], 100);
+                FillByte(Data.MessageText[0], 100, 0);
                 if s <> '' then
                 if s <> '' then
-                  CopyMemory(@Data.MessageText[0], @s[1], Min(Length(s), 100));
+                  Move(Data.MessageText[0], s[1], Min(Length(s), 100));
 
                 Data.MessageTime := Min(Max(
                   StrToIntDef(vleObjectProperty.Values[_lc[I_PROP_TR_MESSAGE_TIME]], 0), 0), 65535);
 
                 Data.MessageTime := Min(Max(
                   StrToIntDef(vleObjectProperty.Values[_lc[I_PROP_TR_MESSAGE_TIME]], 0), 0), 65535);
@@ -4830,7 +4904,13 @@ begin
                   Data.ShotTarget := 6;
                 Data.ShotIntSight := Min(Max(
                   StrToIntDef(vleObjectProperty.Values[_lc[I_PROP_TR_SHOT_SIGHT]], 0), 0), 65535);
                   Data.ShotTarget := 6;
                 Data.ShotIntSight := Min(Max(
                   StrToIntDef(vleObjectProperty.Values[_lc[I_PROP_TR_SHOT_SIGHT]], 0), 0), 65535);
-                Data.ShotAllMap := NameToBool(vleObjectProperty.Values[_lc[I_PROP_TR_SHOT_ALLMAP]]);
+                Data.ShotAim := 0;
+                if vleObjectProperty.Values[_lc[I_PROP_TR_SHOT_AIM]] = _lc[I_PROP_TR_SHOT_AIM_1] then
+                  Data.ShotAim := 1
+                else if vleObjectProperty.Values[_lc[I_PROP_TR_SHOT_AIM]] = _lc[I_PROP_TR_SHOT_AIM_2] then
+                  Data.ShotAim := 2
+                else if vleObjectProperty.Values[_lc[I_PROP_TR_SHOT_AIM]] = _lc[I_PROP_TR_SHOT_AIM_3] then
+                  Data.ShotAim := 3;
                 Data.ShotAngle := Min(
                   StrToIntDef(vleObjectProperty.Values[_lc[I_PROP_TR_SHOT_ANGLE]], 0), 360);
                 Data.ShotWait := Min(Max(
                 Data.ShotAngle := Min(
                   StrToIntDef(vleObjectProperty.Values[_lc[I_PROP_TR_SHOT_ANGLE]], 0), 360);
                 Data.ShotWait := Min(Max(
@@ -4915,7 +4995,7 @@ begin
                                 [SelectedTexture()])),
                 PChar(_lc[I_MSG_DEL_TEXTURE]),
                 MB_ICONQUESTION or MB_YESNO or
                                 [SelectedTexture()])),
                 PChar(_lc[I_MSG_DEL_TEXTURE]),
                 MB_ICONQUESTION or MB_YESNO or
-                MB_TASKMODAL or MB_DEFBUTTON1) <> idYes then
+                MB_DEFBUTTON1) <> idYes then
     Exit;
 
   if gPanels <> nil then
     Exit;
 
   if gPanels <> nil then
@@ -4940,7 +5020,7 @@ begin
   if (MessageBox(0, PChar(_lc[I_MSG_CLEAR_MAP_PROMT]),
                  PChar(_lc[I_MSG_CLEAR_MAP]),
                  MB_ICONQUESTION or MB_YESNO or
   if (MessageBox(0, PChar(_lc[I_MSG_CLEAR_MAP_PROMT]),
                  PChar(_lc[I_MSG_CLEAR_MAP]),
                  MB_ICONQUESTION or MB_YESNO or
-                 MB_TASKMODAL or MB_DEFBUTTON1) = mrYes) then
+                 MB_DEFBUTTON1) = mrYes) then
     FullClear();
 end;
 
     FullClear();
 end;
 
@@ -5247,8 +5327,8 @@ begin
                   begin
                     Panel^.TextureID := SpecialTextureID(Panel^.TextureName);
                     with MainForm.lbTextureList.Items do
                   begin
                     Panel^.TextureID := SpecialTextureID(Panel^.TextureName);
                     with MainForm.lbTextureList.Items do
-                      if IndexOf(Panel^.TextureName) = -1 then
-                        Add(Panel^.TextureName);
+                      if IndexOf(win2utf(Panel^.TextureName)) = -1 then
+                        Add(win2utf(Panel^.TextureName));
                   end;
               end;
 
                   end;
               end;
 
@@ -5409,11 +5489,11 @@ begin
     begin // Выбор файла звука/музыки:
       AddSoundForm.OKFunction := nil;
       AddSoundForm.lbResourcesList.MultiSelect := False;
     begin // Выбор файла звука/музыки:
       AddSoundForm.OKFunction := nil;
       AddSoundForm.lbResourcesList.MultiSelect := False;
-      AddSoundForm.SetResource := vleObjectProperty.Values[Key];
+      AddSoundForm.SetResource := utf2win(vleObjectProperty.Values[Key]);
 
       if (AddSoundForm.ShowModal() = mrOk) then
       begin
 
       if (AddSoundForm.ShowModal() = mrOk) then
       begin
-        vleObjectProperty.Values[Key] := AddSoundForm.ResourceName;
+        vleObjectProperty.Values[Key] := utf2win(AddSoundForm.ResourceName);
         bApplyProperty.Click();
       end;
     end
         bApplyProperty.Click();
       end;
     end
@@ -5522,6 +5602,8 @@ begin
       lbTypeSelect.Items.Add(ItemToStr(ITEM_HELMET));
       lbTypeSelect.Items.Add(ItemToStr(ITEM_JETPACK));
       lbTypeSelect.Items.Add(ItemToStr(ITEM_INVIS));
       lbTypeSelect.Items.Add(ItemToStr(ITEM_HELMET));
       lbTypeSelect.Items.Add(ItemToStr(ITEM_JETPACK));
       lbTypeSelect.Items.Add(ItemToStr(ITEM_INVIS));
+      lbTypeSelect.Items.Add(ItemToStr(ITEM_WEAPON_FLAMETHROWER));
+      lbTypeSelect.Items.Add(ItemToStr(ITEM_AMMO_FUELCAN));
 
       b := StrToItem(Values[Key]);
       if b >= ITEM_BOTTLE then
 
       b := StrToItem(Values[Key]);
       if b >= ITEM_BOTTLE then
@@ -5715,9 +5797,9 @@ begin
       else gLanguage := LANGUAGE_RUSSIAN;
     end;
 
       else gLanguage := LANGUAGE_RUSSIAN;
     end;
 
-    config := TConfig.CreateFile(EditorDir+'\Editor.cfg');
+    config := TConfig.CreateFile(EditorDir+'Editor.cfg');
     config.WriteStr('Editor', 'Language', gLanguage);
     config.WriteStr('Editor', 'Language', gLanguage);
-    config.SaveFile(EditorDir+'\Editor.cfg');
+    config.SaveFile(EditorDir+'Editor.cfg');
     config.Free();
   end;
 
     config.Free();
   end;
 
@@ -5761,13 +5843,13 @@ begin
   begin
     str := SelectMapForm.lbMapList.Items[SelectMapForm.lbMapList.ItemIndex];
     MapName := '';
   begin
     str := SelectMapForm.lbMapList.Items[SelectMapForm.lbMapList.ItemIndex];
     MapName := '';
-    CopyMemory(@MapName[0], @str[1], Min(16, Length(str)));
+    Move(MapName[0], str[1], Min(16, Length(str)));
 
     if MessageBox(0, PChar(Format(_lc[I_MSG_DELETE_MAP_PROMT],
                            [MapName, OpenDialog.FileName])),
                   PChar(_lc[I_MSG_DELETE_MAP]),
                   MB_ICONQUESTION or MB_YESNO or
 
     if MessageBox(0, PChar(Format(_lc[I_MSG_DELETE_MAP_PROMT],
                            [MapName, OpenDialog.FileName])),
                   PChar(_lc[I_MSG_DELETE_MAP]),
                   MB_ICONQUESTION or MB_YESNO or
-                  MB_TASKMODAL or MB_DEFBUTTON2) <> mrYes then
+                  MB_DEFBUTTON2) <> mrYes then
       Exit;
 
     WAD.RemoveResource('', MapName);
       Exit;
 
     WAD.RemoveResource('', MapName);
@@ -5776,7 +5858,7 @@ begin
                                [MapName])),
                PChar(_lc[I_MSG_MAP_DELETED]),
                MB_ICONINFORMATION or MB_OK or
                                [MapName])),
                PChar(_lc[I_MSG_MAP_DELETED]),
                MB_ICONINFORMATION or MB_OK or
-               MB_TASKMODAL or MB_DEFBUTTON1);
+               MB_DEFBUTTON1);
 
     WAD.SaveTo(OpenDialog.FileName);
 
 
     WAD.SaveTo(OpenDialog.FileName);
 
@@ -5968,7 +6050,7 @@ begin
 
   gMapInfo.FileName := SaveDialog.FileName;
   gMapInfo.MapName := SaveMapForm.eMapName.Text;
 
   gMapInfo.FileName := SaveDialog.FileName;
   gMapInfo.MapName := SaveMapForm.eMapName.Text;
-  UpdateCaption(gMapInfo.Name, ExtractFileName(gMapInfo.FileName), gMapInfo.MapName);
+  UpdateCaption(win2utf(gMapInfo.Name), ExtractFileName(gMapInfo.FileName), gMapInfo.MapName);
 end;
 
 procedure TMainForm.aSelectAllExecute(Sender: TObject);
 end;
 
 procedure TMainForm.aSelectAllExecute(Sender: TObject);
@@ -6014,6 +6096,19 @@ end;
 
 procedure TMainForm.OnIdle(Sender: TObject; var Done: Boolean);
 begin
 
 procedure TMainForm.OnIdle(Sender: TObject; var Done: Boolean);
 begin
+  // FIXME: this is a shitty hack
+  if not gDataLoaded then
+  begin
+    e_WriteLog('Init OpenGL', MSG_NOTIFY);
+    e_InitGL();
+    e_WriteLog('Loading data', MSG_NOTIFY);
+    LoadStdFont('STDTXT', 'STDFONT', gEditorFont);
+    e_WriteLog('Loading more data', MSG_NOTIFY);
+    LoadData();
+    e_WriteLog('Loading even more data', MSG_NOTIFY);
+    gDataLoaded := True;
+    MainForm.FormResize(nil);
+  end;
   Draw();
 end;
 
   Draw();
 end;
 
@@ -6044,6 +6139,8 @@ begin
 
   PreviewMode := not PreviewMode;
   (Sender as TMenuItem).Checked := PreviewMode;
 
   PreviewMode := not PreviewMode;
   (Sender as TMenuItem).Checked := PreviewMode;
+
+  FormResize(Self);
 end;
 
 procedure TMainForm.miLayer1Click(Sender: TObject);
 end;
 
 procedure TMainForm.miLayer1Click(Sender: TObject);
@@ -6176,21 +6273,33 @@ end;
 
 procedure TMainForm.miTestMapClick(Sender: TObject);
 var
 
 procedure TMainForm.miTestMapClick(Sender: TObject);
 var
-  cmd, mapWAD, mapToRun: String;
+  cmd, mapWAD, mapToRun, tempWAD: String;
   opt: LongWord;
   time: Integer;
   opt: LongWord;
   time: Integer;
-  lpMsgBuf: PChar;
+  proc: TProcessUTF8;
+  res: Boolean;
 begin
 begin
+  mapToRun := '';
+  if OpenedMap <> '' then
+  begin
+    // Указываем текущую карту для теста:
+    g_ProcessResourceStr(OpenedMap, @mapWAD, nil, @mapToRun);
+    mapToRun := mapWAD + ':\' + mapToRun;
+    mapToRun := ExtractRelativePath(ExtractFilePath(TestD2dExe) + 'maps/', mapToRun);
+  end;
   // Сохраняем временную карту:
   time := 0;
   repeat
   // Сохраняем временную карту:
   time := 0;
   repeat
-    mapWAD := ExtractFilePath(TestD2dExe) + Format('maps\temp%.4d.wad', [time]);
+    mapWAD := ExtractFilePath(TestD2dExe) + Format('maps/temp%.4d.wad', [time]);
     Inc(time);
   until not FileExists(mapWAD);
     Inc(time);
   until not FileExists(mapWAD);
-  mapToRun := mapWAD + ':\' + TEST_MAP_NAME;
-  SaveMap(mapToRun);
+  tempWAD := mapWAD + ':\' + TEST_MAP_NAME;
+  SaveMap(tempWAD);
 
 
-  mapToRun := ExtractRelativePath(ExtractFilePath(TestD2dExe) + 'maps\', mapToRun);
+  tempWAD := ExtractRelativePath(ExtractFilePath(TestD2dExe) + 'maps/', tempWAD);
+// Если карта не была открыта, указываем временную в качестве текущей:
+  if mapToRun = '' then
+    mapToRun := tempWAD;
 
 // Опции игры:
   opt := 32 + 64;
 
 // Опции игры:
   opt := 32 + 64;
@@ -6206,7 +6315,8 @@ begin
     opt := opt + 16;
 
 // Составляем командную строку:
     opt := opt + 16;
 
 // Составляем командную строку:
-  cmd := ' -map "' + mapToRun + '"';
+  cmd := '-map "' + mapToRun + '"';
+  cmd := cmd + ' -testmap "' + tempWAD + '"';
   cmd := cmd + ' -gm ' + TestGameMode;
   cmd := cmd + ' -limt ' + TestLimTime;
   cmd := cmd + ' -lims ' + TestLimScore;
   cmd := cmd + ' -gm ' + TestGameMode;
   cmd := cmd + ' -limt ' + TestLimTime;
   cmd := cmd + ' -lims ' + TestLimScore;
@@ -6216,19 +6326,29 @@ begin
     cmd := cmd + ' --close';
 
   cmd := cmd + ' --debug';
     cmd := cmd + ' --close';
 
   cmd := cmd + ' --debug';
-  cmd := cmd + ' --tempdelete';
 
 // Запускаем:
 
 // Запускаем:
-  Application.Minimize();
-  if ExecuteProcess(TestD2dExe, cmd) < 0 then
+  proc := TProcessUTF8.Create(nil);
+  proc.Executable := TestD2dExe;
+  proc.Parameters.Add(cmd);
+  res := True;
+  try
+    proc.Execute();
+  except
+    res := False;
+  end;
+  if res then
+  begin
+    Application.Minimize();
+    proc.WaitOnExit();
+  end;
+  if (not res) or (proc.ExitCode < 0) then
   begin
   begin
-    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM,
-                  nil, GetLastError(), LANG_SYSTEM_DEFAULT,
-                  @lpMsgBuf, 0, nil);
-    MessageBox(0, lpMsgBuf,
+    MessageBox(0, 'FIXME',
                PChar(_lc[I_MSG_EXEC_ERROR]),
                MB_OK or MB_ICONERROR);
   end;
                PChar(_lc[I_MSG_EXEC_ERROR]),
                MB_OK or MB_ICONERROR);
   end;
+  proc.Free();
 
   SysUtils.DeleteFile(mapWAD);
   Application.Restore();
 
   SysUtils.DeleteFile(mapWAD);
   Application.Restore();
@@ -6323,26 +6443,4 @@ begin
   end;
 end;
 
   end;
 end;
 
-{
-procedure TMainForm.lbTextureListDrawItem(Control: TWinControl; Index: Integer;
-      Rect: TRect; State: LCLType.TOwnerDrawState);
-begin
-  with Control as TListBox do
-  begin
-    if LCLType.odSelected in State then
-    begin
-      Canvas.Brush.Color := clHighlight;
-      Canvas.Font.Color := clHighlightText;
-    end else
-      if (Items <> nil) and (Index >= 0) then
-        if slInvalidTextures.IndexOf(Items[Index]) > -1 then
-        begin
-          Canvas.Brush.Color := clRed;
-          Canvas.Font.Color := clWhite;
-        end;
-    Canvas.FillRect(Rect);
-    Canvas.TextRect(Rect, Rect.Left, Rect.Top, Items[Index]);
-  end;
-end;
-}
 end.
 end.