DEADSOFTWARE

gl: fix load textures on startup
[d2df-editor.git] / src / editor / f_main.pas
index 2bd2fc6bff2a770560fb6b3fad4685fe6ea8e50d..dfb9b75ef200377d2fbf27e5e7d780ac63f3acff 100644 (file)
@@ -2370,10 +2370,10 @@ begin
   Result := Res;
 end;
 
-procedure StringToCopyBuffer(Str: String; var CopyBuf: TCopyRecArray;
-  var pmin: TPoint);
+procedure StringToCopyBuffer(Str: String; var CopyBuf: TCopyRecArray; var pmin: TPoint);
 var
   i, j, t: Integer;
+  minArea, newArea, newX, newY: LongInt;
 
   function GetNext(): String;
   var
@@ -2416,6 +2416,7 @@ var
   end;
 
 begin
+  minArea := High(minArea);
   Str := Trim(Str);
 
   if GetNext() <> CLIPBOARD_SIG then
@@ -2426,8 +2427,7 @@ begin
   // Тип объекта:
     t := StrToIntDef(GetNext(), 0);
 
-    if (t < OBJECT_PANEL) or (t > OBJECT_TRIGGER) or
-       (GetNext() <> ';') then
+    if (t < OBJECT_PANEL) or (t > OBJECT_TRIGGER) or (GetNext() <> ';') then
     begin // Что-то не то => пропускаем:
       t := Pos(';', Str);
       Delete(Str, 1, t);
@@ -2453,13 +2453,14 @@ begin
             PanelType := StrToIntDef(GetNext(), PANEL_WALL);
             X := StrToIntDef(GetNext(), 0);
             Y := StrToIntDef(GetNext(), 0);
-            pmin.X := Min(X, pmin.X);
-            pmin.Y := Min(Y, pmin.Y);
             Width := StrToIntDef(GetNext(), 16);
             Height := StrToIntDef(GetNext(), 16);
             TextureName := GetNext();
             Alpha := StrToIntDef(GetNext(), 0);
             Blending := (GetNext() = '1');
+            newArea := X * Y - Width * Height;
+            newX := X;
+            newY := Y;
           end;
         end;
 
@@ -2469,10 +2470,11 @@ begin
           ItemType := StrToIntDef(GetNext(), ITEM_MEDKIT_SMALL);
           X := StrToIntDef(GetNext(), 0);
           Y := StrToIntDef(GetNext(), 0);
-          pmin.X := Min(X, pmin.X);
-          pmin.Y := Min(Y, pmin.Y);
           OnlyDM := (GetNext() = '1');
           Fall := (GetNext() = '1');
+          newArea := X * Y;
+          newX := X;
+          newY := Y;
         end;
 
       OBJECT_MONSTER:
@@ -2481,13 +2483,12 @@ begin
           MonsterType := StrToIntDef(GetNext(), MONSTER_DEMON);
           X := StrToIntDef(GetNext(), 0);
           Y := StrToIntDef(GetNext(), 0);
-          pmin.X := Min(X, pmin.X);
-          pmin.Y := Min(Y, pmin.Y);
-
-          if GetNext() = '1' then
-            Direction := D_LEFT
-          else
-            Direction := D_RIGHT;
+          if GetNext() = '1'
+            then Direction := D_LEFT
+            else Direction := D_RIGHT;
+          newArea := X * Y;
+          newX := X;
+          newY := Y;
         end;
 
       OBJECT_AREA:
@@ -2496,12 +2497,12 @@ begin
           AreaType := StrToIntDef(GetNext(), AREA_PLAYERPOINT1);
           X := StrToIntDef(GetNext(), 0);
           Y := StrToIntDef(GetNext(), 0);
-          pmin.X := Min(X, pmin.X);
-          pmin.Y := Min(Y, pmin.Y);
-          if GetNext() = '1' then
-            Direction := D_LEFT
-          else
-            Direction := D_RIGHT;
+          if GetNext() = '1'
+            then Direction := D_LEFT
+            else Direction := D_RIGHT;
+          newArea := X * Y;
+          newX := X;
+          newY := Y;
         end;
 
       OBJECT_TRIGGER:
@@ -2510,47 +2511,26 @@ begin
           TriggerType := StrToIntDef(GetNext(), TRIGGER_EXIT);
           X := StrToIntDef(GetNext(), 0);
           Y := StrToIntDef(GetNext(), 0);
-          pmin.X := Min(X, pmin.X);
-          pmin.Y := Min(Y, pmin.Y);
           Width := StrToIntDef(GetNext(), 16);
           Height := StrToIntDef(GetNext(), 16);
           ActivateType := StrToIntDef(GetNext(), 0);
           Key := StrToIntDef(GetNext(), 0);
           Enabled := (GetNext() = '1');
           TexturePanel := StrToIntDef(GetNext(), 0);
-
-          for j := 0 to 127 do
-            Data.Default[j] := StrToIntDef(GetNext(), 0);
-
-          case TriggerType of
-            TRIGGER_TELEPORT:
-              begin
-                pmin.X := Min(Data.TargetPoint.X, pmin.X);
-                pmin.Y := Min(Data.TargetPoint.Y, pmin.Y);
-              end;
-            TRIGGER_PRESS, TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF:
-              begin
-                pmin.X := Min(Data.tX, pmin.X);
-                pmin.Y := Min(Data.tY, pmin.Y);
-              end;
-            TRIGGER_SPAWNMONSTER:
-              begin
-                pmin.X := Min(Data.MonPos.X, pmin.X);
-                pmin.Y := Min(Data.MonPos.Y, pmin.Y);
-              end;
-            TRIGGER_SPAWNITEM:
-              begin
-                pmin.X := Min(Data.ItemPos.X, pmin.X);
-                pmin.Y := Min(Data.ItemPos.Y, pmin.Y);
-              end;
-            TRIGGER_SHOT:
-              begin
-                pmin.X := Min(Data.ShotPos.X, pmin.X);
-                pmin.Y := Min(Data.ShotPos.Y, pmin.Y);
-              end;
-          end;
+          for j := 0 to 127
+            do Data.Default[j] := StrToIntDef(GetNext(), 0);
+          newArea := X * Y - Width * Height;
+          newX := X;
+          newY := Y;
         end;
     end;
+
+    if newArea < minArea then
+    begin
+      minArea := newArea;
+      pmin.X := newX;
+      pmin.Y := newY;
+    end;
   end;
 end;
 
@@ -2882,6 +2862,23 @@ begin
   e_TextureFontPrintEx(X, Y, Text, FontID, 0, 0, 0, 1.0);
 end;
 
+procedure InitGraphics;
+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;
+end;
+
 procedure TMainForm.Draw();
 var
   x, y: Integer;
@@ -2897,6 +2894,8 @@ begin
   Width := 0;
   Height := 0;
 
+  InitGraphics();
+
   e_BeginRender();
 
   e_Clear(GL_COLOR_BUFFER_BIT,
@@ -3779,7 +3778,12 @@ begin
   if Button = mbMiddle then
     MouseMDown := False;
 
-  DrawRect := nil;
+  if DrawRect <> nil then
+  begin
+    Dispose(DrawRect);
+    DrawRect := nil;
+  end;
+
   ResizeType := RESIZETYPE_NONE;
   TextureID := 0;
 
@@ -4344,8 +4348,11 @@ begin
   end;
 
 // Клавиши мыши не зажаты:
-  if (not MouseRDown) and (not MouseLDown) then
+  if (not MouseRDown) and (not MouseLDown) and (DrawRect <> nil) then
+  begin
+    Dispose(DrawRect);
     DrawRect := nil;
+  end;
 
 // Строка состояния - координаты мыши:
   StatusBar.Panels[1].Text := Format('(%d:%d)',
@@ -5819,15 +5826,16 @@ begin
   h := High(CopyBuffer);
   RemoveSelectFromObjects();
 
-  if h > 0 then
+  if g_CollidePoint(
+    pmin.X, pmin.Y, -MapOffset.X-32, -MapOffset.Y-32, RenderPanel.Width, RenderPanel.Height) then
   begin
-    xadj := Floor((-pmin.X - MapOffset.X + 32) / DotStep) * DotStep;
-    yadj := Floor((-pmin.Y - MapOffset.Y + 32) / DotStep) * DotStep;
+    xadj := DotStep;
+    yadj := DotStep;
   end
   else
   begin
-    xadj := DotStep;
-    yadj := DotStep;
+    xadj := Floor((-pmin.X - MapOffset.X + 32) / DotStep) * DotStep;
+    yadj := Floor((-pmin.Y - MapOffset.Y + 32) / DotStep) * DotStep;
   end;
 
   for a := 0 to h do
@@ -6351,7 +6359,7 @@ begin
 
   g_ProcessResourceStr(OpenedMap, FileName, Section, Res);
 
-  SaveMap(FileName+':\'+Res);
+  SaveMap(FileName+':\'+Res, '');
 end;
 
 procedure TMainForm.aOpenMapExecute(Sender: TObject);
@@ -6607,35 +6615,59 @@ begin
 end;
 
 procedure TMainForm.aSaveMapAsExecute(Sender: TObject);
-var
-  idx: Integer;
+  var i, idx: Integer; list: TStringList; fmt: String;
 begin
-  SaveDialog.Filter := MsgFileFilterWad;
+  list := TStringList.Create();
 
-  if not SaveDialog.Execute() then
-    Exit;
-
-  SaveMapForm.GetMaps(SaveDialog.FileName, True);
+  // TODO: get loclized strings automatically from language files
+  SaveDialog.DefaultExt := '.dfz';
+  SaveDialog.FilterIndex := 1;
+  SaveDialog.Filter := '';
+  gWADEditorFactory.GetRegistredEditors(list);
+  for i := 0 to list.Count - 1 do
+  begin
+    if list[i] = 'DFZIP' then
+      SaveDialog.FilterIndex := i + 1;
 
-  if SaveMapForm.ShowModal() <> mrOK then
-    Exit;
+    if i <> 0 then
+      SaveDialog.Filter := SaveDialog.Filter + '|';
 
-  SaveDialog.InitialDir := ExtractFileDir(SaveDialog.FileName);
-  OpenedMap := SaveDialog.FileName+':\'+SaveMapForm.eMapName.Text;
-  OpenedWAD := SaveDialog.FileName;
+    if list[i] = 'DFWAD' then
+      SaveDialog.Filter := SaveDialog.Filter + MsgFileFilterSaveDFWAD
+    else if list[i] = 'DFZIP' then
+      SaveDialog.Filter := SaveDialog.Filter + MsgFileFilterSaveDFZIP
+    else
+      SaveDialog.Filter := SaveDialog.Filter + list[i] + '|*.*';
+  end;
 
-  idx := RecentFiles.IndexOf(OpenedMap);
-// Такая карта уже недавно открывалась:
-  if idx >= 0 then
-    RecentFiles.Delete(idx);
-  RecentFiles.Insert(0, OpenedMap);
-  RefreshRecentMenu;
+  if SaveDialog.Execute() then
+  begin
+    i := SaveDialog.FilterIndex - 1;
+    if (i >= 0) and (i < list.Count) then fmt := list[i] else fmt := '';
 
-  SaveMap(OpenedMap);
+    SaveMapForm.GetMaps(SaveDialog.FileName, True, fmt);
+    if SaveMapForm.ShowModal() = mrOK then
+    begin
+      SaveDialog.InitialDir := ExtractFileDir(SaveDialog.FileName);
+      OpenedMap := SaveDialog.FileName+':\'+SaveMapForm.eMapName.Text;
+      OpenedWAD := SaveDialog.FileName;
+
+      idx := RecentFiles.IndexOf(OpenedMap);
+      // Такая карта уже недавно открывалась:
+      if idx >= 0 then
+        RecentFiles.Delete(idx);
+      RecentFiles.Insert(0, OpenedMap);
+      RefreshRecentMenu;
+
+      SaveMap(OpenedMap, fmt);
+
+      gMapInfo.FileName := SaveDialog.FileName;
+      gMapInfo.MapName := SaveMapForm.eMapName.Text;
+      UpdateCaption(gMapInfo.Name, ExtractFileName(gMapInfo.FileName), gMapInfo.MapName);
+    end;
+  end;
 
-  gMapInfo.FileName := SaveDialog.FileName;
-  gMapInfo.MapName := SaveMapForm.eMapName.Text;
-  UpdateCaption(gMapInfo.Name, ExtractFileName(gMapInfo.FileName), gMapInfo.MapName);
+  list.Free();
 end;
 
 procedure TMainForm.aSelectAllExecute(Sender: TObject);
@@ -6684,20 +6716,6 @@ end;
 procedure TMainForm.OnIdle(Sender: TObject; var Done: Boolean);
   var f: AnsiString;
 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();
   if StartMap <> '' then
   begin
     f := StartMap;
@@ -6929,7 +6947,7 @@ begin
     newWad := newWad + '.wad'
   end;
   tempMap := newWAD + ':\' + TEST_MAP_NAME;
-  SaveMap(tempMap);
+  SaveMap(tempMap, '');
 
 // Опции игры:
   opt := 32 + 64;