DEADSOFTWARE

render: fix animated textures
authorDeaDDooMER <deaddoomer@deadsoftware.ru>
Mon, 17 Jan 2022 16:38:24 +0000 (19:38 +0300)
committerDeaDDooMER <deaddoomer@deadsoftware.ru>
Mon, 17 Jan 2022 16:38:24 +0000 (19:38 +0300)
src/game/g_map.pas
src/game/g_panel.pas
src/game/g_textures.pas
src/game/opengl/r_map.pas

index de67ae2865933f34ed4f863a42b885e0ab98ad32..f53fd1500ec723ef7bdcfca6c93aa7c37dbfc24b 100644 (file)
@@ -873,7 +873,6 @@ begin
   SetLength(Textures, Length(Textures) + 1);
   Textures[High(Textures)].TextureName := RecName;
   Textures[High(Textures)].FullName := '';
-  Textures[High(Textures)].Anim := False;
   Result := High(Textures);
   TextNameHash.put(RecName, result);
 end;
@@ -971,154 +970,98 @@ begin
   addResToExternalResList(GetReplacementWad(g_ExtractWadName(map.SkyName)));
 end;
 
-
-function CreateTexture (RecName: AnsiString; Map: string; log: Boolean): Integer;
-var
-  WAD: TWADFile;
-  WADName, ResName: String;
-  ResData: Pointer;
-  ResLen: Integer;
-begin
-  RecName := toLowerCase1251(RecName);
-  if (TextNameHash = nil) then TextNameHash := THashStrInt.Create();
-  if TextNameHash.get(RecName, result) then
+  function CreateTexture (RecName: AnsiString; Map: String; log: Boolean): Integer;
+    var
+      HName: AnsiString;
+      WAD, WADz: TWADFile;
+      WADName, ResName: String;
+      ResData, ReszData: Pointer;
+      ResLen, ReszLen: Integer;
+      cfg: TConfig;
+      id: Integer;
   begin
-    // i found her!
-    //e_LogWritefln('texture ''%s'' already loaded (%s)', [RecName, result]);
-    exit;
-  end;
-
-  Result := -1;
-
-  if (BadTextNameHash <> nil) and BadTextNameHash.has(RecName) then
-    exit; // don't do it again and again
-
-  case RecName of
-    TEXTURE_NAME_WATER, TEXTURE_NAME_ACID1, TEXTURE_NAME_ACID2:
+    Result := -1;
+    HName := toLowerCase1251(RecName);
+    if (TextNameHash = nil) then
+      TextNameHash := THashStrInt.Create();
+    if TextNameHash.get(HName, Result) then
     begin
-      SetLength(Textures, Length(Textures) + 1);
-      Textures[High(Textures)].FullName := RecName;
-      Textures[High(Textures)].TextureName := RecName;
-      Textures[High(Textures)].Anim := False;
-      Result := High(Textures);
-      TextNameHash.put(RecName, result);
+      // e_LogWritefln('CreateTexture: found loaded %s', [Result]);
     end
-  else
-    WADName := GetReplacementWad(g_ExtractWadName(RecName));
-    if (WADName <> '') then
-      addResToExternalResList(WADName);
-    if WADName = '' then
-      WADName := Map;
-    ResName := g_ExtractFilePathName(RecName);
-
-    // !!! we have a better way to check that resource exists?
-    WAD := TWADFile.Create();
-    if WAD.ReadFile(WadName) and WAD.GetResource(ResName, ResData, ResLen, log) then
-    begin
-      FreeMem(ResData);
-      SetLength(Textures, Length(Textures) + 1);
-      Textures[High(Textures)].FullName := WADName + ':' + ResName;
-      Textures[High(Textures)].TextureName := RecName;
-      Textures[High(Textures)].Anim := False;
-      Result := High(Textures);
-      TextNameHash.put(RecName, result);
-    end;
-    WAD.Free;
-  end;
-end;
-
-
-function CreateAnimTexture(RecName: String; Map: string; log: Boolean): Integer;
-var
-  WAD: TWADFile;
-  TextureWAD: PChar = nil;
-  TextData: Pointer = nil;
-  cfg: TConfig = nil;
-  WADName: String;
-  ResLength: Integer;
-  f: Integer;
-begin
-  RecName := toLowerCase1251(RecName);
-  if (TextNameHash = nil) then TextNameHash := THashStrInt.Create();
-  if TextNameHash.get(RecName, result) then
-  begin
-    // i found her!
-    //e_LogWritefln('animated texture ''%s'' already loaded (%s)', [RecName, result]);
-    exit;
-  end;
-
-  result := -1;
-
-  //e_LogWritefln('*** Loading animated texture "%s"', [RecName]);
-
-  if (BadTextNameHash = nil) then BadTextNameHash := THashStrInt.Create();
-  if BadTextNameHash.get(RecName, f) then
-  begin
-    //e_WriteLog(Format('no animation texture %s (don''t worry)', [RecName]), MSG_NOTIFY);
-    exit;
-  end;
-
-  // ×èòàåì WAD-ðåñóðñ àíèì.òåêñòóðû èç WAD'à â ïàìÿòü:
-  WADName := GetReplacementWad(g_ExtractWadName(RecName));
-  if (WADName <> '') then addResToExternalResList(WADName);
-  if WADName = '' then WADName := Map; //WADName := GameDir+'/wads/'+WADName else
-
-  WAD := TWADFile.Create();
-  try
-    WAD.ReadFile(WADName);
-    if not WAD.GetResource(g_ExtractFilePathName(RecName), TextureWAD, ResLength, log) then
+    else
     begin
-      if (BadTextNameHash = nil) then BadTextNameHash := THashStrInt.Create();
-      if log and (not BadTextNameHash.get(RecName, f)) then
+      Result := -1;
+      if (BadTextNameHash = nil) or not BadTextNameHash.has(HName) then
       begin
-        e_WriteLog(Format('Error loading animation texture %s', [RecName]), TMsgType.Warning);
-        //e_WriteLog(Format('WAD Reader error: %s', [WAD.GetLastErrorStr]), MSG_WARNING);
+        case RecName of
+          TEXTURE_NAME_WATER, TEXTURE_NAME_ACID1, TEXTURE_NAME_ACID2:
+          begin
+            SetLength(Textures, Length(Textures) + 1);
+            Textures[High(Textures)].FullName := RecName;
+            Textures[High(Textures)].TextureName := RecName;
+            Result := High(Textures);
+            TextNameHash.put(RecName, result);
+          end
+        else
+          WADName := GetReplacementWad(g_ExtractWadName(RecName));
+          if (WADName <> '') then
+            addResToExternalResList(WADName);
+          if WADName = '' then
+            WADName := Map;
+          ResName := g_ExtractFilePathName(RecName);
+          WAD := TWADFile.Create();
+          if WAD.ReadFile(WadName) then
+          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;
+              FreeMem(ResData);
+            end
+          end;
+          WAD.Free;
+        end
       end;
-      BadTextNameHash.put(RecName, -1);
-      exit;
     end;
-    WAD.FreeWAD();
-
-    // íåò, ýòî ñóïåðìåí!
-    if not WAD.ReadMemory(TextureWAD, ResLength) then
+    if Result < 0 then
     begin
-      e_WriteLog(Format('Animated texture WAD file "%s" is invalid', [RecName]), TMsgType.Warning);
-      BadTextNameHash.put(RecName, -1);
-      exit;
-    end;
-
-    // ×èòàåì INI-ðåñóðñ àíèì. òåêñòóðû è çàïîìèíàåì åãî óñòàíîâêè:
-    if not WAD.GetResource('TEXT/ANIM', TextData, ResLength) then
-    begin
-      e_WriteLog(Format('Animated texture file "%s" has invalid INI', [RecName]), TMsgType.Warning);
-      BadTextNameHash.put(RecName, -1);
-      exit;
-    end;
-
-    WAD.Free();
-    WAD := nil;
-
-    cfg := TConfig.CreateMem(TextData, ResLength);
-    if cfg <> nil then
-    begin
-      SetLength(Textures, Length(Textures) + 1);
-      Textures[High(Textures)].TextureName := RecName;
-      Textures[High(Textures)].FullName := WadName + ':' + g_ExtractFilePathName(RecName);
-      Textures[High(Textures)].Anim := True;
-      Textures[High(Textures)].FramesCount := cfg.ReadInt('', 'framecount', 0);
-      Textures[High(Textures)].Speed := cfg.ReadInt('', 'waitcount', 0);
-      result := High(Textures);
-      TextNameHash.put(RecName, result);
-      cfg.Free();
-      cfg := nil;
-    end;
-  finally
-    WAD.Free();
-    cfg.Free();
-    if (TextureWAD <> nil) then FreeMem(TextureWAD);
-    if (TextData <> nil) then FreeMem(TextData);
+      if (BadTextNameHash = nil) then
+        BadTextNameHash := THashStrInt.Create();
+      if log and (not BadTextNameHash.get(HName, id)) then
+        e_WriteLog(Format('Error loading texture %s', [RecName]), TMsgType.Warning);
+      BadTextNameHash.put(HName, -1);
+    end
   end;
-end;
 
 procedure CreateItem(Item: TDynRecord);
 begin
@@ -1443,7 +1386,7 @@ var
   FileName, mapResName, TexName, s: AnsiString;
   Data: Pointer;
   Len: Integer;
-  ok, isAnim: Boolean;
+  ok: Boolean;
   CurTex, ntn: Integer;
   rec, texrec: TDynRecord;
   pttit: PTRec;
@@ -1621,23 +1564,17 @@ begin
           else
           begin
             {$IF DEFINED(D2F_DEBUG_TXLOAD)}
-            e_LogWritefln('    Loading texture #%d: %s', [cnt, rec.Resource]);
+              e_LogWritefln('    Loading texture #%d: %s', [cnt, rec.Resource]);
             {$ENDIF}
-            //if g_Map_IsSpecialTexture(s) then e_WriteLog('      SPECIAL!', MSG_NOTIFY);
-            if rec.Anim then
-            begin
-              // Àíèìèðîâàííàÿ òåêñòóðà
-              ntn := CreateAnimTexture(rec.Resource, FileName, True);
-              if (ntn < 0) then g_SimpleError(Format(_lc[I_GAME_ERROR_TEXTURE_ANIM], [rec.Resource]));
-            end
-            else
+            ntn := CreateTexture(rec.Resource, FileName, True);
+            if ntn < 0 then
             begin
-              // Îáû÷íàÿ òåêñòóðà
-              ntn := CreateTexture(rec.Resource, FileName, True);
-              if (ntn < 0) then g_SimpleError(Format(_lc[I_GAME_ERROR_TEXTURE_SIMPLE], [rec.Resource]));
+              if rec.Anim then
+                g_SimpleError(Format(_lc[I_GAME_ERROR_TEXTURE_ANIM], [rec.Resource]))
+              else
+                g_SimpleError(Format(_lc[I_GAME_ERROR_TEXTURE_SIMPLE], [rec.Resource]));
+              ntn := CreateNullTexture(rec.Resource)
             end;
-            if (ntn < 0) then ntn := CreateNullTexture(rec.Resource);
-
             rec.tagInt := ntn; // remember texture number
           end;
           g_Game_StepLoading();
@@ -1777,39 +1714,7 @@ begin
 
               if (k = NNF_NAME_BEFORE) or (k = NNF_NAME_AFTER) then
               begin
-                // Ïðîáóåì äîáàâèòü íîâóþ òåêñòóðó
-                if texrec.Anim then
-                begin
-                  // Íà÷àëüíàÿ - àíèìèðîâàííàÿ, èùåì àíèìèðîâàííóþ
-                  isAnim := True;
-                  //e_LogWritefln('000: pannum=%s; TexName=[%s]; FileName=[%s]', [pannum, TexName, FileName]);
-                  ok := CreateAnimTexture(TexName, FileName, False) >= 0;
-                  //e_LogWritefln('001: pannum=%s; TexName=[%s]; FileName=[%s]', [pannum, TexName, FileName]);
-                  if not ok then
-                  begin
-                    // Íåò àíèìèðîâàííîé, èùåì îáû÷íóþ
-                    isAnim := False;
-                    //e_LogWritefln('002: pannum=%s; TexName=[%s]; FileName=[%s]', [pannum, TexName, FileName]);
-                    ok := CreateTexture(TexName, FileName, False) >= 0;
-                    //e_LogWritefln('003: pannum=%s; TexName=[%s]; FileName=[%s]', [pannum, TexName, FileName]);
-                  end;
-                end
-                else
-                begin
-                  // Íà÷àëüíàÿ - îáû÷íàÿ, èùåì îáû÷íóþ
-                  isAnim := False;
-                  //e_LogWritefln('004: pannum=%s; TexName=[%s]; FileName=[%s]', [pannum, TexName, FileName]);
-                  ok := CreateTexture(TexName, FileName, False) >= 0;
-                  //e_LogWritefln('005: pannum=%s; TexName=[%s]; FileName=[%s]', [pannum, TexName, FileName]);
-                  if not ok then
-                  begin
-                    // Íåò îáû÷íîé, èùåì àíèìèðîâàííóþ
-                    isAnim := True;
-                    //e_LogWritefln('006: pannum=%s; TexName=[%s]; FileName=[%s]', [pannum, TexName, FileName]);
-                    ok := CreateAnimTexture(TexName, FileName, False) >= 0;
-                    //e_LogWritefln('007: pannum=%s; TexName=[%s]; FileName=[%s]', [pannum, TexName, FileName]);
-                  end;
-                end;
+                ok := CreateTexture(TexName, FileName, False) >= 0;
 
                 // Îíà ñóùåñòâóåò. Çàíîñèì åå ID â ñïèñîê ïàíåëè
                 if ok then
@@ -1821,7 +1726,6 @@ begin
                     begin
                       SetLength(AddTextures, Length(AddTextures)+1);
                       AddTextures[High(AddTextures)].Texture := c;
-                      AddTextures[High(AddTextures)].Anim := isAnim;
                       break;
                     end;
                   end;
@@ -1830,7 +1734,6 @@ begin
                   begin
                     SetLength(AddTextures, Length(AddTextures)+1);
                     AddTextures[High(AddTextures)].Texture := c;
-                    AddTextures[High(AddTextures)].Anim := isAnim;
                   end;
                 end;
               end
@@ -1841,7 +1744,6 @@ begin
                   // Çàíîñèì òåêóùóþ òåêñòóðó íà ñâîå ìåñòî
                   SetLength(AddTextures, Length(AddTextures)+1);
                   AddTextures[High(AddTextures)].Texture := rec.tagInt; // internal texture number, not map index
-                  AddTextures[High(AddTextures)].Anim := texrec.Anim;
                   CurTex := High(AddTextures);
                   ok := true;
                 end
@@ -1861,8 +1763,6 @@ begin
           // Çàíîñèì òîëüêî òåêóùóþ òåêñòóðó
           SetLength(AddTextures, 1);
           AddTextures[0].Texture := rec.tagInt; // internal texture number, not map index
-          AddTextures[0].Anim := false;
-          if (texrec <> nil) then AddTextures[0].Anim := texrec.Anim;
           CurTex := 0;
         end;
 
index fa4429256576dd18b109dd5ddaf4fbfe9871ac28..382d6f9880159c3d1ac5db8a772878e56252d8d1 100644 (file)
@@ -25,7 +25,6 @@ uses
 type
   TAddTextureArray = array of record
     Texture: Cardinal; // Textures[Texture]
-    Anim: Boolean;
   end;
 
   ATextureID = array of record
@@ -334,7 +333,7 @@ begin
   for i := 0 to Length(FTextureIDs)-1 do
   begin
     FTextureIDs[i].Texture := AddTextures[i].Texture;
-    FTextureIDs[i].Anim := AddTextures[i].Anim;
+    FTextureIDs[i].Anim := Textures[AddTextures[i].Texture].FramesCount > 0;
     if FTextureIDs[i].Anim then
     begin // Àíèìèðîâàííàÿ òåêñòóðà
       FTextureIDs[i].AnTex := TAnimationState.Create(True, Textures[AddTextures[i].Texture].Speed, Textures[AddTextures[i].Texture].FramesCount);
index d35fc53be4c961ae19e62c0e973b206c1720d887..02fe5aad01a60530c126232a0679d05d4d87b173 100644 (file)
@@ -26,8 +26,7 @@ type
   TLevelTexture = record
     TextureName: AnsiString; // as stored in wad
     FullName: AnsiString; // full path to texture // !!! merge it with TextureName
-    case anim: Boolean of
-      true: (framesCount: Byte; speed: Byte);
+    framesCount, speed: Byte;
   end;
 
   TLevelTextureArray = array of TLevelTexture;
index 7cb4263764ba7b37031ecaff219eafb5541d224e..50d06d03c88d3cf55380a11864f44df446fb4754 100644 (file)
@@ -34,7 +34,7 @@ implementation
 
   uses
     {$INCLUDE ../nogl/noGLuses.inc}
-    SysUtils, Classes, Math, e_log, wadreader, CONFIG,
+    SysUtils, Classes, Math, e_log, wadreader, CONFIG, utils,
     r_graphics, r_animations, r_textures,
     g_base, g_basic, g_game, g_options,
     g_map
@@ -44,6 +44,7 @@ implementation
     RenTextures: array of record
       ID: DWORD;
       Width, Height: WORD;
+      Anim: Boolean;
     end;
 
   procedure r_Map_LoadTextures;
@@ -67,9 +68,11 @@ implementation
       SetLength(RenTextures, n);
       for i := 0 to n - 1 do
       begin
+        // e_LogWritefln('r_Map_LoadTextures: -> [%s] :: [%s]', [Textures[i].FullName, Textures[i].TextureName]);
         RenTextures[i].ID := LongWord(TEXTURE_NONE);
         RenTextures[i].Width := 0;
         RenTextures[i].Height := 0;
+        RenTextures[i].Anim := False;
         case Textures[i].TextureName of
           TEXTURE_NAME_WATER: RenTextures[i].ID := LongWord(TEXTURE_SPECIAL_WATER);
           TEXTURE_NAME_ACID1: RenTextures[i].ID := LongWord(TEXTURE_SPECIAL_ACID1);
@@ -82,7 +85,7 @@ implementation
           begin
             if WAD.GetResource(ResName, ResData, ResLen, log) then
             begin
-              if Textures[i].Anim then
+              if IsWadData(ResData, ResLen) then
               begin
                 WADz := TWADFile.Create();
                 if WADz.ReadMemory(ResData, ResLen) then
@@ -105,7 +108,9 @@ implementation
                       begin
                         if WADz.GetResource('TEXTURES/' + TextureResource, ReszData, ReszLen) then
                         begin
-                          if not g_Frames_CreateMemory(@RenTextures[i].ID, '', ReszData, ReszLen, Width, Height, FramesCount, BackAnim) then
+                          if g_Frames_CreateMemory(@RenTextures[i].ID, '', ReszData, ReszLen, Width, Height, FramesCount, BackAnim) then
+                            RenTextures[i].Anim := True
+                          else
                             e_LogWritefln('r_Map_LoadTextures: failed to create frames object (%s)', [Textures[i].FullName]);
                           FreeMem(ReszData)
                         end
@@ -258,7 +263,7 @@ end;
     if {p.Enabled and} (p.FCurTexture >= 0) and (p.Width > 0) and (p.Height > 0) and (p.Alpha < 255) {and g_Collide(X, Y, Width, Height, sX, sY, sWidth, sHeight)} then
     begin
       Texture := p.TextureIDs[p.FCurTexture].Texture;
-      IsAnim := p.TextureIDs[p.FCurTexture].Anim;
+      IsAnim := RenTextures[Texture].Anim;
       if IsAnim then
       begin
         if p.TextureIDs[p.FCurTexture].AnTex <> nil then
@@ -332,10 +337,9 @@ end;
     if radius < 4 then exit;
     if p.Enabled and (p.FCurTexture >= 0) and (p.Width > 0) and (p.Height > 0) and (p.Alpha < 255) {and g_Collide(X, Y, Width, Height, sX, sY, sWidth, sHeight)} then
     begin
-      if not p.TextureIDs[p.FCurTexture].Anim then
+      Texture := p.TextureIDs[p.FCurTexture].Texture;
+      if not RenTextures[Texture].Anim then
       begin
-        Texture := p.TextureIDs[p.FCurTexture].Texture;
-        // case Textures[Texture].TextureID of
         case RenTextures[Texture].ID of
           LongWord(TEXTURE_SPECIAL_WATER): exit;
           LongWord(TEXTURE_SPECIAL_ACID1): exit;