From 3a76b7e2235c387754facfcccd6e4de45f36a460 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Mon, 17 Jan 2022 19:38:24 +0300 Subject: [PATCH] render: fix animated textures --- src/game/g_map.pas | 286 +++++++++++++------------------------- src/game/g_panel.pas | 3 +- src/game/g_textures.pas | 3 +- src/game/opengl/r_map.pas | 18 ++- 4 files changed, 106 insertions(+), 204 deletions(-) diff --git a/src/game/g_map.pas b/src/game/g_map.pas index de67ae2..f53fd15 100644 --- a/src/game/g_map.pas +++ b/src/game/g_map.pas @@ -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; diff --git a/src/game/g_panel.pas b/src/game/g_panel.pas index fa44292..382d6f9 100644 --- a/src/game/g_panel.pas +++ b/src/game/g_panel.pas @@ -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); diff --git a/src/game/g_textures.pas b/src/game/g_textures.pas index d35fc53..02fe5aa 100644 --- a/src/game/g_textures.pas +++ b/src/game/g_textures.pas @@ -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; diff --git a/src/game/opengl/r_map.pas b/src/game/opengl/r_map.pas index 7cb4263..50d06d0 100644 --- a/src/game/opengl/r_map.pas +++ b/src/game/opengl/r_map.pas @@ -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; -- 2.29.2