DEADSOFTWARE

map: fix free random memory address
[d2df-sdl.git] / src / game / g_map.pas
index d120dfcd6928f48bf7a3749c0cc5d36219bbfd96..85bffa627423e79bb74a14354eb8464edd4ac714 100644 (file)
@@ -20,7 +20,7 @@ interface
 
 uses
   SysUtils, Classes, mempool,
-  g_base, r_graphics, g_basic, MAPDEF, g_textures,
+  g_base, g_basic, MAPDEF,
   g_phys, utils, g_panel, g_grid, md5, binheap, xprofiler, xparser, xdynrec;
 
 type
@@ -31,6 +31,7 @@ type
     Author:        String;
     MusicName:     String;
     SkyName:       String;
+    SkyFullName:   String; // used by render
     Height:        Word;
     Width:         Word;
   end;
@@ -52,7 +53,6 @@ type
     State:       Byte;
     Count:       Integer;
     CaptureTime: LongWord;
-    Animation:   TAnimation;
     Direction:   TDirection;
     NeedSend:    Boolean;
   end;
@@ -152,6 +152,7 @@ const
   FLAG_RED  = 1;
   FLAG_BLUE = 2;
   FLAG_DOM  = 3;
+  FLAG_LAST = FLAG_DOM;
 
   FLAG_STATE_NONE     = 0;
   FLAG_STATE_NORMAL   = 1;
@@ -196,15 +197,6 @@ const
 
   GridDrawableMask = (GridTagBack or GridTagStep or GridTagWall or GridTagDoor or GridTagAcid1 or GridTagAcid2 or GridTagWater or GridTagFore);
 
-
-type
-  TBinHeapPanelDrawCmp = class
-  public
-    class function less (const a, b: TPanel): Boolean; inline;
-  end;
-
-  TBinHeapPanelDraw = specialize TBinaryHeapBase<TPanel, TBinHeapPanelDrawCmp>;
-
 var
   gWalls: TPanelArray;
   gRenderBackgrounds: TPanelArray;
@@ -216,18 +208,15 @@ var
   gFlags: array [FLAG_RED..FLAG_BLUE] of TFlag;
   //gDOMFlags: array of TFlag;
   gMapInfo: TMapInfo;
-  gBackSize: TDFPoint;
   gDoorMap: array of array of DWORD;
   gLiftMap: array of array of DWORD;
   gWADHash: TMD5Digest;
-  BackID:  DWORD = DWORD(-1);
   gExternalResources: array of TDiskFileInfo = nil;
   gMovingWallIds: array of Integer = nil;
 
   gdbg_map_use_accel_render: Boolean = true;
   gdbg_map_use_accel_coldet: Boolean = true;
   profMapCollision: TProfiler = nil; //WARNING: FOR DEBUGGING ONLY!
-  gDrawPanelList: TBinHeapPanelDraw = nil; // binary heap of all walls we have to render, populated by `g_Map_CollectDrawPanels()`
 
   gCurrentMap: TDynRecord = nil;
   gCurrentMapFileName: AnsiString = ''; // so we can skip texture reloading
@@ -248,13 +237,17 @@ var (* private state *)
 
 implementation
 
-uses
-  e_input, e_log, e_res, g_items, g_gfx, g_console,
-  g_weapons, g_game, g_sound, e_sound, CONFIG,
-  g_options, g_triggers, g_player, r_textures, r_animations,
-  Math, g_monsters, g_saveload, g_language, g_netmsg,
-  sfs, xstreams, hashtable, wadreader,
-  g_res_downloader;
+  uses
+    {$IFDEF ENABLE_GFX}
+      g_gfx,
+    {$ENDIF}
+    e_input, e_log, e_res, g_items, g_console,
+    g_weapons, g_game, g_sound, e_sound, CONFIG,
+    g_options, g_triggers, g_player,
+    Math, g_monsters, g_saveload, g_language, g_netmsg,
+    sfs, xstreams, hashtable, wadreader,
+    g_res_downloader
+  ;
 
 const
   FLAGRECT: TRectWH = (X:15; Y:12; Width:33; Height:52);
@@ -515,14 +508,6 @@ begin
   end;
 end;
 
-
-class function TBinHeapPanelDrawCmp.less (const a, b: TPanel): Boolean; inline;
-begin
-  if (a.tag < b.tag) then begin result := true; exit; end;
-  if (a.tag > b.tag) then begin result := false; exit; end;
-  result := (a.arrIdx < b.arrIdx);
-end;
-
 var
   TextNameHash: THashStrInt = nil; // key: texture name; value: index in `Textures`
   BadTextNameHash: THashStrInt = nil; // set; so we won't spam with non-existing texture messages
@@ -974,11 +959,10 @@ end;
   function CreateTexture (RecName: AnsiString; Map: String; log: Boolean): Integer;
     var
       HName: AnsiString;
-      WAD, WADz: TWADFile;
+      WAD: TWADFile;
       WADName, ResName: String;
-      ResData, ReszData: Pointer;
-      ResLen, ReszLen: Integer;
-      cfg: TConfig;
+      ResData: Pointer;
+      ResLen: Integer;
       id: Integer;
   begin
     Result := -1;
@@ -1015,40 +999,13 @@ end;
           begin
             if WAD.GetResource(ResName, ResData, ResLen, log) then
             begin
-              if IsWadData(ResData, ResLen) then
-              begin
-                WADz := TWADFile.Create();
-                if WADz.ReadMemory(ResData, ResLen) then
-                begin
-                  if WADz.GetResource('TEXT/ANIM', ReszData, ReszLen) then
-                  begin
-                    cfg := TConfig.CreateMem(ReszData, ReszLen);
-                    if cfg <> nil then
-                    begin
-                      SetLength(Textures, Length(Textures) + 1);
-                      Textures[High(Textures)].TextureName := RecName;
-                      Textures[High(Textures)].FullName := WadName + ':' + ResName;
-                      Textures[High(Textures)].FramesCount := cfg.ReadInt('', 'framecount', 0);
-                      Textures[High(Textures)].Speed := cfg.ReadInt('', 'waitcount', 0);
-                      Result := High(Textures);
-                      TextNameHash.put(HName, result);
-                      cfg.Free;
-                    end;
-                    FreeMem(ReszData);
-                  end
-                end;
-                WADz.Free;
-              end
-              else
-              begin
-                SetLength(Textures, Length(Textures) + 1);
-                Textures[High(Textures)].FullName := WADName + ':' + ResName;
-                Textures[High(Textures)].TextureName := RecName;
-                Result := High(Textures);
-                TextNameHash.put(HName, result);
-              end;
+              SetLength(Textures, Length(Textures) + 1);
+              Textures[High(Textures)].FullName := WADName + ':' + ResName;
+              Textures[High(Textures)].TextureName := RecName;
+              Result := High(Textures);
+              TextNameHash.put(HName, result);
               FreeMem(ResData);
-            end
+            end;
           end;
           WAD.Free;
         end
@@ -1079,7 +1036,6 @@ end;
 procedure CreateArea(Area: TDynRecord);
 var
   a: Integer;
-  id: DWORD = 0;
 begin
   case Area.AreaType of
     AREA_DMPOINT, AREA_PLAYERPOINT1, AREA_PLAYERPOINT2,
@@ -1119,14 +1075,7 @@ begin
 
       with gFlags[a] do
       begin
-        case a of
-          FLAG_RED: g_Frames_Get(id, 'FRAMES_FLAG_RED');
-          FLAG_BLUE: g_Frames_Get(id, 'FRAMES_FLAG_BLUE');
-        end;
-
-        Animation := TAnimation.Create(id, True, 8);
         Obj.Rect := FLAGRECT;
-
         g_Map_ResetFlag(a);
       end;
     end;
@@ -1879,15 +1828,12 @@ begin
     //mapReader := nil;
 
     // Çàãðóçêà íåáà
+    gMapInfo.SkyFullName := '';
     if (gMapInfo.SkyName <> '') then
     begin
       e_WriteLog('  Loading sky: ' + gMapInfo.SkyName, TMsgType.Notify);
       g_Game_SetLoadingText(_lc[I_LOAD_SKY], 0, False);
-      s := e_GetResourcePath(WadDirs, gMapInfo.SkyName, g_ExtractWadName(Res));
-      if g_Texture_CreateWAD(BackID, s, gTextureFilter) then
-        g_Game_SetupScreenSize
-      else
-        g_FatalError(Format(_lc[I_GAME_ERROR_SKY], [s]))
+      gMapInfo.SkyFullName := e_GetResourcePath(WadDirs, gMapInfo.SkyName, g_ExtractWadName(Res));
     end;
 
     // Çàãðóçêà ìóçûêè
@@ -1912,8 +1858,10 @@ begin
     g_Weapon_Init();
     g_Monsters_Init();
 
-    // Åñëè íå LoadState, òî ñîçäàåì êàðòó ñòîëêíîâåíèé:
-    if not gLoadGameMode then g_GFX_Init();
+    {$IFDEF ENABLE_GFX}
+      // Åñëè íå LoadState, òî ñîçäàåì êàðòó ñòîëêíîâåíèé:
+      if not gLoadGameMode then g_GFX_Init();
+    {$ENDIF}
 
     // Ñáðîñ ëîêàëüíûõ ìàññèâîâ:
     mapTextureList := nil;
@@ -2091,7 +2039,9 @@ procedure g_Map_Free(freeTextures: Boolean=true);
   end;
 
 begin
-  g_GFX_Free();
+  {$IFDEF ENABLE_GFX}
+    g_GFX_Free;
+  {$ENDIF}
   g_Weapon_Free();
   g_Items_Free();
   g_Triggers_Free();
@@ -2147,14 +2097,6 @@ begin
   FreePanelArray(gBlockMon);
   gMovingWallIds := nil;
 
-  if BackID <> DWORD(-1) then
-  begin
-    gBackSize.X := 0;
-    gBackSize.Y := 0;
-    e_DeleteTexture(BackID);
-    BackID := DWORD(-1);
-  end;
-
   g_Game_StopAllSounds(False);
   gMusic.FreeSound();
   g_Sound_Delete(gMapInfo.MusicName);
@@ -2205,8 +2147,6 @@ begin
       begin
         with gFlags[a] do
         begin
-          if gFlags[a].Animation <> nil then gFlags[a].Animation.Update();
-
           Obj.oldX := Obj.X;
           Obj.oldY := Obj.Y;
 
@@ -2580,7 +2520,10 @@ begin
   if pan.Enabled and mapGrid.proxyEnabled[pan.proxyId] then exit;
 
   pan.Enabled := True;
-  g_Mark(pan.X, pan.Y, pan.Width, pan.Height, MARK_DOOR, true);
+
+  {$IFDEF ENABLE_GFX}
+    g_Mark(pan.X, pan.Y, pan.Width, pan.Height, MARK_DOOR, true);
+  {$ENDIF}
 
   mapGrid.proxyEnabled[pan.proxyId] := true;
   //if (pan.proxyId >= 0) then mapGrid.proxyEnabled[pan.proxyId] := true
@@ -2606,7 +2549,9 @@ begin
   if (not pan.Enabled) and (not mapGrid.proxyEnabled[pan.proxyId]) then exit;
 
   pan.Enabled := False;
-  g_Mark(pan.X, pan.Y, pan.Width, pan.Height, MARK_DOOR, false);
+  {$IFDEF ENABLE_GFX}
+    g_Mark(pan.X, pan.Y, pan.Width, pan.Height, MARK_DOOR, false);
+  {$ENDIF}
 
   mapGrid.proxyEnabled[pan.proxyId] := false;
   //if (pan.proxyId >= 0) then begin mapGrid.removeBody(pan.proxyId); pan.proxyId := -1; end;
@@ -2628,7 +2573,7 @@ begin
   tp := g_Map_PanelByGUID(pguid);
   if (tp = nil) then exit;
   tp.NextTexture(AnimLoop);
-  if g_Game_IsServer and g_Game_IsNet then MH_SEND_PanelTexture(pguid, AnimLoop);
+  if g_Game_IsServer and g_Game_IsNet then MH_SEND_PanelTexture(pguid);
 end;
 
 
@@ -2647,15 +2592,16 @@ begin
   begin
     LiftType := t;
 
-    g_Mark(X, Y, Width, Height, MARK_LIFT, false);
-    //TODO: make separate lift tags, and change tag here
-
-    case LiftType of
-      LIFTTYPE_UP:    g_Mark(X, Y, Width, Height, MARK_LIFTUP);
-      LIFTTYPE_DOWN:  g_Mark(X, Y, Width, Height, MARK_LIFTDOWN);
-      LIFTTYPE_LEFT:  g_Mark(X, Y, Width, Height, MARK_LIFTLEFT);
-      LIFTTYPE_RIGHT: g_Mark(X, Y, Width, Height, MARK_LIFTRIGHT);
-    end;
+    {$IFDEF ENABLE_GFX}
+      g_Mark(X, Y, Width, Height, MARK_LIFT, false);
+      //TODO: make separate lift tags, and change tag here
+      case LiftType of
+        LIFTTYPE_UP:    g_Mark(X, Y, Width, Height, MARK_LIFTUP);
+        LIFTTYPE_DOWN:  g_Mark(X, Y, Width, Height, MARK_LIFTDOWN);
+        LIFTTYPE_LEFT:  g_Mark(X, Y, Width, Height, MARK_LIFTLEFT);
+        LIFTTYPE_RIGHT: g_Mark(X, Y, Width, Height, MARK_LIFTRIGHT);
+      end;
+    {$ENDIF}
 
     //if g_Game_IsServer and g_Game_IsNet then MH_SEND_PanelState(pguid);
     // mark platform as interesting
@@ -2855,8 +2801,11 @@ begin
   loadPanels();
   ///// /////
 
-  // Îáíîâëÿåì êàðòó ñòîëêíîâåíèé è ñåòêó
-  g_GFX_Init();
+  {$IFDEF ENABLE_GFX}
+    // Îáíîâëÿåì êàðòó ñòîëêíîâåíèé è ñåòêó
+    g_GFX_Init();
+  {$ENDIF}
+
   //mapCreateGrid();
 
   ///// Çàãðóæàåì ìóçûêó: /////