DEADSOFTWARE

render: use TAnimationState for projectiles
authorDeaDDooMER <deaddoomer@deadsoftware.ru>
Mon, 3 Jan 2022 19:19:39 +0000 (22:19 +0300)
committerDeaDDooMER <deaddoomer@deadsoftware.ru>
Fri, 9 Jun 2023 07:50:39 +0000 (10:50 +0300)
src/game/Doom2DF.lpr
src/game/g_textures.pas
src/game/g_weapons.pas
src/game/opengl/r_animations.pas
src/game/opengl/r_render.pas
src/game/opengl/r_weapons.pas

index d47b1b61049f2a1e9009a47de69a46a0a3894a0e..2b4fe158d53daa2ced428c06cd0449bad647e51d 100644 (file)
@@ -988,6 +988,7 @@ end;
     {$IFDEF ENABLE_HOLMES}
       InitHolmes;
     {$ENDIF}
+    r_Render_Load;
     g_Game_Init;
     {$IFNDEF HEADLESS}
       g_Menu_Init;
@@ -1007,6 +1008,7 @@ end;
       g_GUI_Destroy;
       g_Menu_Free;
     {$ENDIF}
+    r_Render_Free;
     {$IFDEF ENABLE_HOLMES}
       FreeHolmes;
     {$ENDIF}
index d12a9a24e4ba74789cfbe74fbaa0713e4b0c376f..acac0c61d3b8a87cc78bc9598d65d834ef6817c2 100644 (file)
@@ -33,6 +33,50 @@ type
 
   TLevelTextureArray = array of TLevelTexture;
 
+  TAnimationState = class{$IFDEF USE_MEMPOOL}(TPoolObject){$ENDIF}
+  private
+    mAlpha: Byte;
+    mBlending: Boolean;
+    mCounter: Byte; // Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè
+    mSpeed: Byte; // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè
+    mCurrentFrame: Integer; // Òåêóùèé êàäð (íà÷èíàÿ ñ 0)
+    mLoop: Boolean; // Ïåðåõîäèòü íà ïåðâûé êàäð ïîñëå ïîñëåäíåãî?
+    mEnabled: Boolean; // Ðàáîòà ðàçðåøåíà?
+    mPlayed: Boolean; // Ïðîèãðàíà âñÿ õîòÿ áû ðàç?
+    mMinLength: Byte; // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ
+    mRevert: Boolean; // Ñìåíà êàäðîâ îáðàòíàÿ?
+
+    mLength: Integer;
+
+  public
+    constructor Create (aloop: Boolean; aspeed: Byte; len: Integer);
+    destructor  Destroy (); override;
+
+    procedure reset ();
+    procedure update ();
+    procedure enable ();
+    procedure disable ();
+    procedure revert (r: Boolean);
+
+    procedure saveState (st: TStream);
+    procedure loadState (st: TStream);
+
+//    function totalFrames (): Integer; inline;
+
+  public
+    property played: Boolean read mPlayed;
+    property enabled: Boolean read mEnabled;
+    property isReverse: Boolean read mRevert;
+    property loop: Boolean read mLoop write mLoop;
+    property speed: Byte read mSpeed write mSpeed;
+    property minLength: Byte read mMinLength write mMinLength;
+    property currentFrame: Integer read mCurrentFrame write mCurrentFrame;
+    property currentCounter: Byte read mCounter write mCounter;
+    property counter: Byte read mCounter;
+    property blending: Boolean read mBlending write mBlending;
+    property alpha: Byte read mAlpha write mAlpha;
+  end;
+
   TAnimation = class{$IFDEF USE_MEMPOOL}(TPoolObject){$ENDIF}
   private
     mId: LongWord;
@@ -89,6 +133,171 @@ uses
   g_game, e_log, g_basic, g_console, wadreader, r_animations,
   g_language, utils, xstreams;
 
+
+
+
+constructor TAnimationState.Create (aloop: Boolean; aspeed: Byte; len: Integer);
+begin
+  assert(len >= 0);
+  mLength := len;
+
+  mMinLength := 0;
+  mLoop := aloop;
+  mSpeed := aspeed;
+  mEnabled := true;
+  mCurrentFrame := 0;
+  mAlpha := 0;
+  mPlayed := false;
+end;
+
+destructor TAnimationState.Destroy;
+begin
+  inherited;
+end;
+
+procedure TAnimationState.update;
+begin
+  if (not mEnabled) then exit;
+
+  mCounter += 1;
+
+  if (mCounter >= mSpeed) then
+  begin
+    // Îæèäàíèå ìåæäó êàäðàìè çàêîí÷èëîñü
+    // Îáðàòíûé ïîðÿäîê êàäðîâ?
+    if mRevert then
+    begin
+      // Äîøëè äî êîíöà àíèìàöèè. Âîçìîæíî, æäåì åùå
+      if (mCurrentFrame = 0) then
+      begin
+        if (mLength * mSpeed + mCounter < mMinLength) then exit;
+      end;
+
+      mCurrentFrame -= 1;
+      mPlayed := (mCurrentFrame < 0);
+
+      // Ïîâòîðÿòü ëè àíèìàöèþ ïî êðóãó?
+      if mPlayed then
+      begin
+        if mLoop then
+          mCurrentFrame := mLength - 1
+        else
+          mCurrentFrame += 1
+      end;
+
+      mCounter := 0;
+    end
+    else
+    begin
+      // Ïðÿìîé ïîðÿäîê êàäðîâ
+      // Äîøëè äî êîíöà àíèìàöèè. Âîçìîæíî, æäåì åùå
+      if (mCurrentFrame = mLength - 1) then
+      begin
+        if (mLength * mSpeed + mCounter < mMinLength) then exit;
+      end;
+
+      mCurrentFrame += 1;
+      mPlayed := (mCurrentFrame > mLength - 1);
+
+      // Ïîâòîðÿòü ëè àíèìàöèþ ïî êðóãó?
+      if mPlayed then
+      begin
+        if mLoop then mCurrentFrame := 0 else mCurrentFrame -= 1;
+      end;
+
+      mCounter := 0;
+    end;
+  end;
+end;
+
+procedure TAnimationState.reset;
+begin
+  if mRevert then
+    mCurrentFrame := mLength - 1
+  else
+    mCurrentFrame := 0;
+  mCounter := 0;
+  mPlayed := false
+end;
+
+procedure TAnimationState.disable;
+begin
+  mEnabled := false
+end;
+
+procedure TAnimationState.enable;
+begin
+  mEnabled := true
+end;
+
+procedure TAnimationState.revert (r: Boolean);
+begin
+  mRevert := r;
+  reset
+end;
+
+procedure TAnimationState.saveState (st: TStream);
+begin
+  if (st = nil) then exit;
+
+  utils.writeSign(st, 'ANIM');
+  utils.writeInt(st, Byte(0)); // version
+  // Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè
+  utils.writeInt(st, Byte(mCounter));
+  // Òåêóùèé êàäð
+  utils.writeInt(st, LongInt(mCurrentFrame));
+  // Ïðîèãðàíà ëè àíèìàöèÿ öåëèêîì
+  utils.writeBool(st, mPlayed);
+  // Alpha-êàíàë âñåé òåêñòóðû
+  utils.writeInt(st, Byte(mAlpha));
+  // Ðàçìûòèå òåêñòóðû
+  utils.writeInt(st, Byte(mBlending));
+  // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè
+  utils.writeInt(st, Byte(mSpeed));
+  // Çàöèêëåíà ëè àíèìàöèÿ
+  utils.writeBool(st, mLoop);
+  // Âêëþ÷åíà ëè
+  utils.writeBool(st, mEnabled);
+  // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ
+  utils.writeInt(st, Byte(mMinLength));
+  // Îáðàòíûé ëè ïîðÿäîê êàäðîâ
+  utils.writeBool(st, mRevert);
+end;
+
+
+procedure TAnimationState.loadState (st: TStream);
+begin
+  if (st = nil) then exit;
+
+  if not utils.checkSign(st, 'ANIM') then raise XStreamError.Create('animation chunk expected');
+  if (utils.readByte(st) <> 0) then raise XStreamError.Create('invalid animation chunk version');
+  // Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè
+  mCounter := utils.readByte(st);
+  // Òåêóùèé êàäð
+  mCurrentFrame := utils.readLongInt(st);
+  // Ïðîèãðàíà ëè àíèìàöèÿ öåëèêîì
+  mPlayed := utils.readBool(st);
+  // Alpha-êàíàë âñåé òåêñòóðû
+  mAlpha := utils.readByte(st);
+  // Ðàçìûòèå òåêñòóðû
+  mBlending := utils.readBool(st);
+  // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè
+  mSpeed := utils.readByte(st);
+  // Çàöèêëåíà ëè àíèìàöèÿ
+  mLoop := utils.readBool(st);
+  // Âêëþ÷åíà ëè
+  mEnabled := utils.readBool(st);
+  // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ
+  mMinLength := utils.readByte(st);
+  // Îáðàòíûé ëè ïîðÿäîê êàäðîâ
+  mRevert := utils.readBool(st);
+end;
+
+
+
+
+
+
 constructor TAnimation.Create (aframesID: LongWord; aloop: Boolean; aspeed: Byte);
 begin
   if (aframesID >= Length(framesArray)) then
index 44d6a932ad94b7ddc1a22249f2fce0d7a5fdafe5..d2bb2dd451363d13a3b53a4b276bd49ee48d310f 100644 (file)
@@ -30,8 +30,7 @@ type
     SpawnerUID: Word;
     Triggers: DWArray;
     Obj: TObj;
-    Animation: TAnimation;
-    TextureID: DWORD;
+    Animation: TAnimationState;
     Timeout: DWORD;
     Stopped: Byte;
 
@@ -105,7 +104,6 @@ const
   WP_FIRST          = WEAPON_KASTET;
   WP_LAST           = WEAPON_FLAMETHROWER;
 
-
 var
   gwep_debug_fast_trace: Boolean = true;
 
@@ -562,7 +560,6 @@ end;
 function g_Weapon_CreateShot(I: Integer; ShotType: Byte; Spawner, TargetUID: Word; X, Y, XV, YV: Integer): LongWord;
 var
   find_id: DWord;
-  FramesID: DWORD = 0;
 begin
   if I < 0 then
     find_id := FindShot()
@@ -586,7 +583,6 @@ begin
         Animation := nil;
         Triggers := nil;
         ShotType := WEAPON_ROCKETLAUNCHER;
-        g_Texture_Get('TEXTURE_WEAPON_ROCKET', TextureID);
       end;
     end;
 
@@ -601,8 +597,7 @@ begin
 
         Triggers := nil;
         ShotType := WEAPON_PLASMA;
-        g_Frames_Get(FramesID, 'FRAMES_WEAPON_PLASMA');
-        Animation := TAnimation.Create(FramesID, True, 5);
+        Animation := TAnimationState.Create(True, 5, 2); // !!! put values into table
       end;
     end;
 
@@ -617,8 +612,7 @@ begin
 
         Triggers := nil;
         ShotType := WEAPON_BFG;
-        g_Frames_Get(FramesID, 'FRAMES_WEAPON_BFG');
-        Animation := TAnimation.Create(FramesID, True, 6);
+        Animation := TAnimationState.Create(True, 6, 2); // !!! put values into table
       end;
     end;
 
@@ -633,9 +627,7 @@ begin
 
         Triggers := nil;
         ShotType := WEAPON_FLAMETHROWER;
-        Animation := nil;
-        TextureID := 0;
-        g_Frames_Get(TextureID, 'FRAMES_FLAME');
+        // Animation := TAnimationState.Create(True, 6, 0); // drawed as gfx
       end;
     end;
 
@@ -650,8 +642,7 @@ begin
 
         Triggers := nil;
         ShotType := WEAPON_IMP_FIRE;
-        g_Frames_Get(FramesID, 'FRAMES_WEAPON_IMPFIRE');
-        Animation := TAnimation.Create(FramesID, True, 4);
+        Animation := TAnimationState.Create(True, 4, 2); // !!! put values into table
       end;
     end;
 
@@ -666,8 +657,7 @@ begin
 
         Triggers := nil;
         ShotType := WEAPON_CACO_FIRE;
-        g_Frames_Get(FramesID, 'FRAMES_WEAPON_CACOFIRE');
-        Animation := TAnimation.Create(FramesID, True, 4);
+        Animation := TAnimationState.Create(True, 4, 2); // !!! put values into table
       end;
     end;
 
@@ -682,8 +672,7 @@ begin
 
         Triggers := nil;
         ShotType := WEAPON_MANCUB_FIRE;
-        g_Frames_Get(FramesID, 'FRAMES_WEAPON_MANCUBFIRE');
-        Animation := TAnimation.Create(FramesID, True, 4);
+        Animation := TAnimationState.Create(True, 4, 2); // !!! put values into table
       end;
     end;
 
@@ -698,8 +687,7 @@ begin
 
         Triggers := nil;
         ShotType := WEAPON_BARON_FIRE;
-        g_Frames_Get(FramesID, 'FRAMES_WEAPON_BARONFIRE');
-        Animation := TAnimation.Create(FramesID, True, 4);
+        Animation := TAnimationState.Create(True, 4, 2); // !!! put values into table
       end;
     end;
 
@@ -714,8 +702,7 @@ begin
 
         Triggers := nil;
         ShotType := WEAPON_BSP_FIRE;
-        g_Frames_Get(FramesID, 'FRAMES_WEAPON_BSPFIRE');
-        Animation := TAnimation.Create(FramesID, True, 4);
+        Animation := TAnimationState.Create(True, 4, 2); // !!! put values into table
       end;
     end;
 
@@ -731,8 +718,7 @@ begin
         Triggers := nil;
         ShotType := WEAPON_SKEL_FIRE;
         target := TargetUID;
-        g_Frames_Get(FramesID, 'FRAMES_WEAPON_SKELFIRE');
-        Animation := TAnimation.Create(FramesID, True, 5);
+        Animation := TAnimationState.Create(True, 5, 2); // !!! put values into table
       end;
     end;
   end;
@@ -1151,28 +1137,6 @@ begin
   g_Sound_CreateWADEx('SOUND_PLAYER_SHELL1', GameWAD+':SOUNDS\SHELL1');
   g_Sound_CreateWADEx('SOUND_PLAYER_SHELL2', GameWAD+':SOUNDS\SHELL2');
 
-  g_Texture_CreateWADEx('TEXTURE_WEAPON_ROCKET', GameWAD+':TEXTURES\BROCKET');
-  g_Frames_CreateWAD(nil, 'FRAMES_WEAPON_SKELFIRE', GameWAD+':TEXTURES\BSKELFIRE', 64, 16, 2);
-  g_Frames_CreateWAD(nil, 'FRAMES_WEAPON_BFG', GameWAD+':TEXTURES\BBFG', 64, 64, 2);
-  g_Frames_CreateWAD(nil, 'FRAMES_WEAPON_PLASMA', GameWAD+':TEXTURES\BPLASMA', 16, 16, 2);
-  g_Frames_CreateWAD(nil, 'FRAMES_WEAPON_IMPFIRE', GameWAD+':TEXTURES\BIMPFIRE', 16, 16, 2);
-  g_Frames_CreateWAD(nil, 'FRAMES_WEAPON_BSPFIRE', GameWAD+':TEXTURES\BBSPFIRE', 16, 16, 2);
-  g_Frames_CreateWAD(nil, 'FRAMES_WEAPON_CACOFIRE', GameWAD+':TEXTURES\BCACOFIRE', 16, 16, 2);
-  g_Frames_CreateWAD(nil, 'FRAMES_WEAPON_BARONFIRE', GameWAD+':TEXTURES\BBARONFIRE', 64, 16, 2);
-  g_Frames_CreateWAD(nil, 'FRAMES_WEAPON_MANCUBFIRE', GameWAD+':TEXTURES\BMANCUBFIRE', 64, 32, 2);
-  g_Frames_CreateWAD(nil, 'FRAMES_EXPLODE_ROCKET', GameWAD+':TEXTURES\EROCKET', 128, 128, 6);
-  g_Frames_CreateWAD(nil, 'FRAMES_EXPLODE_SKELFIRE', GameWAD+':TEXTURES\ESKELFIRE', 64, 64, 3);
-  g_Frames_CreateWAD(nil, 'FRAMES_EXPLODE_BFG', GameWAD+':TEXTURES\EBFG', 128, 128, 6);
-  g_Frames_CreateWAD(nil, 'FRAMES_EXPLODE_IMPFIRE', GameWAD+':TEXTURES\EIMPFIRE', 64, 64, 3);
-  g_Frames_CreateWAD(nil, 'FRAMES_BFGHIT', GameWAD+':TEXTURES\BFGHIT', 64, 64, 4);
-  g_Frames_CreateWAD(nil, 'FRAMES_FIRE', GameWAD+':TEXTURES\FIRE', 64, 128, 8);
-  g_Frames_CreateWAD(nil, 'FRAMES_FLAME', GameWAD+':TEXTURES\FLAME', 32, 32, 11);
-  g_Frames_CreateWAD(nil, 'FRAMES_EXPLODE_PLASMA', GameWAD+':TEXTURES\EPLASMA', 32, 32, 4, True);
-  g_Frames_CreateWAD(nil, 'FRAMES_EXPLODE_BSPFIRE', GameWAD+':TEXTURES\EBSPFIRE', 32, 32, 5);
-  g_Frames_CreateWAD(nil, 'FRAMES_EXPLODE_CACOFIRE', GameWAD+':TEXTURES\ECACOFIRE', 64, 64, 3);
-  g_Frames_CreateWAD(nil, 'FRAMES_EXPLODE_BARONFIRE', GameWAD+':TEXTURES\EBARONFIRE', 64, 64, 3);
-  g_Frames_CreateWAD(nil, 'FRAMES_SMOKE', GameWAD+':TEXTURES\SMOKE', 32, 32, 10, False);
-
   g_Texture_CreateWADEx('TEXTURE_SHELL_BULLET', GameWAD+':TEXTURES\EBULLET');
   g_Texture_CreateWADEx('TEXTURE_SHELL_SHELL', GameWAD+':TEXTURES\ESHELL');
 
@@ -1220,25 +1184,6 @@ begin
   g_Sound_Delete('SOUND_PLAYER_CASING2');
   g_Sound_Delete('SOUND_PLAYER_SHELL1');
   g_Sound_Delete('SOUND_PLAYER_SHELL2');
-
-  g_Texture_Delete('TEXTURE_WEAPON_ROCKET');
-  g_Frames_DeleteByName('FRAMES_WEAPON_BFG');
-  g_Frames_DeleteByName('FRAMES_WEAPON_PLASMA');
-  g_Frames_DeleteByName('FRAMES_WEAPON_IMPFIRE');
-  g_Frames_DeleteByName('FRAMES_WEAPON_BSPFIRE');
-  g_Frames_DeleteByName('FRAMES_WEAPON_CACOFIRE');
-  g_Frames_DeleteByName('FRAMES_WEAPON_MANCUBFIRE');
-  g_Frames_DeleteByName('FRAMES_EXPLODE_ROCKET');
-  g_Frames_DeleteByName('FRAMES_EXPLODE_BFG');
-  g_Frames_DeleteByName('FRAMES_EXPLODE_IMPFIRE');
-  g_Frames_DeleteByName('FRAMES_BFGHIT');
-  g_Frames_DeleteByName('FRAMES_FIRE');
-  g_Frames_DeleteByName('FRAMES_EXPLODE_PLASMA');
-  g_Frames_DeleteByName('FRAMES_EXPLODE_BSPFIRE');
-  g_Frames_DeleteByName('FRAMES_EXPLODE_CACOFIRE');
-  g_Frames_DeleteByName('FRAMES_SMOKE');
-  g_Frames_DeleteByName('FRAMES_WEAPON_BARONFIRE');
-  g_Frames_DeleteByName('FRAMES_EXPLODE_BARONFIRE');
 end;
 
 
@@ -1690,7 +1635,6 @@ begin
 
     Animation := nil;
     triggers := nil;
-    g_Texture_Get('TEXTURE_WEAPON_ROCKET', TextureID);
   end;
 
   Shots[find_id].SpawnerUID := SpawnerUID;
@@ -1702,7 +1646,7 @@ end;
 procedure g_Weapon_revf(x, y, xd, yd: Integer; SpawnerUID, TargetUID: Word;
   WID: Integer = -1; Silent: Boolean = False);
 var
-  find_id, FramesID: DWORD;
+  find_id: DWORD;
   dx, dy: Integer;
 begin
   if WID < 0 then
@@ -1729,8 +1673,7 @@ begin
 
     triggers := nil;
     target := TargetUID;
-    g_Frames_Get(FramesID, 'FRAMES_WEAPON_SKELFIRE');
-    Animation := TAnimation.Create(FramesID, True, 5);
+    Animation := TAnimationState.Create(True, 5, 2); // !!! put values into table
   end;
 
   Shots[find_id].SpawnerUID := SpawnerUID;
@@ -1742,7 +1685,7 @@ end;
 procedure g_Weapon_plasma(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1;
   Silent: Boolean = False; compat: Boolean = true);
 var
-  find_id, FramesID: DWORD;
+  find_id: DWORD;
   dx, dy: Integer;
 begin
   if WID < 0 then
@@ -1771,8 +1714,7 @@ begin
     throw(find_id, x+dx, y+dy, xd+dx, yd+dy, 16);
 
     triggers := nil;
-    g_Frames_Get(FramesID, 'FRAMES_WEAPON_PLASMA');
-    Animation := TAnimation.Create(FramesID, True, 5);
+    Animation := TAnimationState.Create(True, 5, 2); // !!! put values into table
   end;
 
   Shots[find_id].SpawnerUID := SpawnerUID;
@@ -1814,8 +1756,6 @@ begin
 
     triggers := nil;
     Animation := nil;
-    TextureID := 0;
-    g_Frames_Get(TextureID, 'FRAMES_FLAME');
   end;
 
   Shots[find_id].SpawnerUID := SpawnerUID;
@@ -1827,7 +1767,7 @@ end;
 procedure g_Weapon_ball1(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1;
   Silent: Boolean = False; compat: Boolean = true);
 var
-  find_id, FramesID: DWORD;
+  find_id: DWORD;
   dx, dy: Integer;
 begin
   if WID < 0 then
@@ -1856,8 +1796,7 @@ begin
     throw(find_id, x+dx, y+dy, xd+dx, yd+dy, 16);
 
     triggers := nil;
-    g_Frames_Get(FramesID, 'FRAMES_WEAPON_IMPFIRE');
-    Animation := TAnimation.Create(FramesID, True, 4);
+    Animation := TAnimationState.Create(True, 4, 2); // !!! put values into table
   end;
 
   Shots[find_id].SpawnerUID := SpawnerUID;
@@ -1869,7 +1808,7 @@ end;
 procedure g_Weapon_ball2(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1;
   Silent: Boolean = False; compat: Boolean = true);
 var
-  find_id, FramesID: DWORD;
+  find_id: DWORD;
   dx, dy: Integer;
 begin
   if WID < 0 then
@@ -1898,8 +1837,7 @@ begin
     throw(find_id, x+dx, y+dy, xd+dx, yd+dy, 16);
 
     triggers := nil;
-    g_Frames_Get(FramesID, 'FRAMES_WEAPON_CACOFIRE');
-    Animation := TAnimation.Create(FramesID, True, 4);
+    Animation := TAnimationState.Create(True, 4, 2); // !!! put values into table
   end;
 
   Shots[find_id].SpawnerUID := SpawnerUID;
@@ -1911,7 +1849,7 @@ end;
 procedure g_Weapon_ball7(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1;
   Silent: Boolean = False; compat: Boolean = true);
 var
-  find_id, FramesID: DWORD;
+  find_id: DWORD;
   dx, dy: Integer;
 begin
   if WID < 0 then
@@ -1927,7 +1865,7 @@ begin
   begin
     g_Obj_Init(@Obj);
 
-    Obj.Rect.Width := 16;
+    Obj.Rect.Width := 32;
     Obj.Rect.Height := 16;
 
     if compat then
@@ -1940,8 +1878,7 @@ begin
     throw(find_id, x+dx, y+dy, xd+dx, yd+dy, 16);
 
     triggers := nil;
-    g_Frames_Get(FramesID, 'FRAMES_WEAPON_BARONFIRE');
-    Animation := TAnimation.Create(FramesID, True, 4);
+    Animation := TAnimationState.Create(True, 4, 2); // !!! put values into table
   end;
 
   Shots[find_id].SpawnerUID := SpawnerUID;
@@ -1983,8 +1920,7 @@ begin
 
     triggers := nil;
 
-    g_Frames_Get(FramesID, 'FRAMES_WEAPON_BSPFIRE');
-    Animation := TAnimation.Create(FramesID, True, 4);
+    Animation := TAnimationState.Create(True, 4, 2); // !!! put values into table
   end;
 
   Shots[find_id].SpawnerUID := SpawnerUID;
@@ -1996,7 +1932,7 @@ end;
 procedure g_Weapon_manfire(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1;
   Silent: Boolean = False; compat: Boolean = true);
 var
-  find_id, FramesID: DWORD;
+  find_id: DWORD;
   dx, dy: Integer;
 begin
   if WID < 0 then
@@ -2026,8 +1962,7 @@ begin
 
     triggers := nil;
 
-    g_Frames_Get(FramesID, 'FRAMES_WEAPON_MANCUBFIRE');
-    Animation := TAnimation.Create(FramesID, True, 4);
+    Animation := TAnimationState.Create(True, 4, 2); // !!! put values into table
   end;
 
   Shots[find_id].SpawnerUID := SpawnerUID;
@@ -2039,7 +1974,7 @@ end;
 procedure g_Weapon_bfgshot(x, y, xd, yd: Integer; SpawnerUID: Word; WID: Integer = -1;
   Silent: Boolean = False; compat: Boolean = true);
 var
-  find_id, FramesID: DWORD;
+  find_id: DWORD;
   dx, dy: Integer;
 begin
   if WID < 0 then
@@ -2068,8 +2003,7 @@ begin
     throw(find_id, x+dx, y+dy, xd+dx, yd+dy, 16);
 
     triggers := nil;
-    g_Frames_Get(FramesID, 'FRAMES_WEAPON_BFG');
-    Animation := TAnimation.Create(FramesID, True, 6);
+    Animation := TAnimationState.Create(True, 6, 2); // !!! put values into table
   end;
 
   Shots[find_id].SpawnerUID := SpawnerUID;
@@ -2189,6 +2123,7 @@ var
   Anim: TAnimation;
   t: DWArray;
   st: Word;
+  TextureID: DWORD = DWORD(-1);
   s: String;
   o: TObj;
   spl: Boolean;
@@ -2267,6 +2202,8 @@ begin
       cx := Obj.X + (Obj.Rect.Width div 2);
       cy := Obj.Y + (Obj.Rect.Height div 2);
 
+      TextureID := DWORD(-1); // !!!
+
       case ShotType of
         WEAPON_ROCKETLAUNCHER, WEAPON_SKEL_FIRE: // Ðàêåòû è ñíàðÿäû Ñêåëåòà
           begin
@@ -2457,6 +2394,7 @@ begin
 
             if (gTime mod LongWord(tf) = 0) then
             begin
+              g_Frames_Get(TextureID, 'FRAMES_FLAME');
               Anim := TAnimation.Create(TextureID, False, 2 + Random(2));
               Anim.Alpha := 0;
               case Stopped of
@@ -2658,7 +2596,6 @@ end;
 procedure g_Weapon_LoadState (st: TStream);
 var
   count, tc, i, j: Integer;
-  dw: LongWord;
 begin
   if (st = nil) then exit;
 
@@ -2693,48 +2630,39 @@ begin
     Shots[i].Stopped := utils.readByte(st);
 
     // Óñòàíîâêà òåêñòóðû èëè àíèìàöèè
-    Shots[i].TextureID := DWORD(-1);
     Shots[i].Animation := nil;
 
     case Shots[i].ShotType of
       WEAPON_ROCKETLAUNCHER, WEAPON_SKEL_FIRE:
         begin
-          g_Texture_Get('TEXTURE_WEAPON_ROCKET', Shots[i].TextureID);
         end;
       WEAPON_PLASMA:
         begin
-          g_Frames_Get(dw, 'FRAMES_WEAPON_PLASMA');
-          Shots[i].Animation := TAnimation.Create(dw, True, 5);
+          Shots[i].Animation := TAnimationState.Create(True, 5, 2); // !!! put values into table
         end;
       WEAPON_BFG:
         begin
-          g_Frames_Get(dw, 'FRAMES_WEAPON_BFG');
-          Shots[i].Animation := TAnimation.Create(dw, True, 6);
+          Shots[i].Animation := TAnimationState.Create(True, 6, 2); // !!! put values into table
         end;
       WEAPON_IMP_FIRE:
         begin
-          g_Frames_Get(dw, 'FRAMES_WEAPON_IMPFIRE');
-          Shots[i].Animation := TAnimation.Create(dw, True, 4);
+          Shots[i].Animation := TAnimationState.Create(True, 4, 2); // !!! put values into table
         end;
       WEAPON_BSP_FIRE:
         begin
-          g_Frames_Get(dw, 'FRAMES_WEAPON_BSPFIRE');
-          Shots[i].Animation := TAnimation.Create(dw, True, 4);
+          Shots[i].Animation := TAnimationState.Create(True, 4, 2); // !!! put values into table
         end;
       WEAPON_CACO_FIRE:
         begin
-          g_Frames_Get(dw, 'FRAMES_WEAPON_CACOFIRE');
-          Shots[i].Animation := TAnimation.Create(dw, True, 4);
+          Shots[i].Animation := TAnimationState.Create(True, 4, 2); // !!! put values into table
         end;
       WEAPON_BARON_FIRE:
         begin
-          g_Frames_Get(dw, 'FRAMES_WEAPON_BARONFIRE');
-          Shots[i].Animation := TAnimation.Create(dw, True, 4);
+          Shots[i].Animation := TAnimationState.Create(True, 4, 2); // !!! put values into table
         end;
       WEAPON_MANCUB_FIRE:
         begin
-          g_Frames_Get(dw, 'FRAMES_WEAPON_MANCUBFIRE');
-          Shots[i].Animation := TAnimation.Create(dw, True, 4);
+          Shots[i].Animation := TAnimationState.Create(True, 4, 2); // !!! put values into table
         end;
     end;
   end;
@@ -2745,6 +2673,7 @@ var
   cx, cy: Integer;
   Anim: TAnimation;
   s: string;
+  TextureID: DWORD = DWORD(-1);
 begin
   if Shots = nil then
     Exit;
index 1b634051753716d481178091eaf2134a6bbe88bb..156869b82640047a1f888265e1c36887b932736a 100644 (file)
@@ -22,6 +22,9 @@ interface
   procedure r_Animation_Draw (t: TAnimation; x, y: Integer; mirror: TMirrorType);
   procedure r_Animation_DrawEx (t: TAnimation; x, y: Integer; mirror: TMirrorType; rpoint: TDFPoint; angle: SmallInt);
 
+  procedure r_AnimationState_Draw (TID: DWORD; t: TAnimationState; x, y: Integer; mirror: TMirrorType);
+  procedure r_AnimationState_DrawEx (FID: DWORD; t: TAnimationState; x, y: Integer; mirror: TMirrorType; rpoint: TDFPoint; angle: SmallInt);
+
   function g_CreateFramesImg (ia: TDynImageDataArray; ID: PDWORD; const Name: AnsiString; BackAnimation: Boolean = false): Boolean;
 
   function g_Frames_CreateWAD (ID: PDWORD; const Name, Resource: AnsiString; mWidth, mHeight, mCount: Word; BackAnimation: Boolean=false): Boolean;
@@ -68,6 +71,18 @@ implementation
       e_DrawAdv(framesArray[t.id].TexturesID[t.currentFrame], x, y, t.alpha, true, t.blending, angle, @rpoint, mirror)
   end;
 
+  procedure r_AnimationState_Draw (TID: DWORD; t: TAnimationState; x, y: Integer; mirror: TMirrorType);
+  begin
+    if t.enabled then
+      e_DrawAdv(framesArray[TID].TexturesID[t.currentFrame], x, y, t.alpha, true, t.blending, 0, nil, mirror)
+  end;
+
+  procedure r_AnimationState_DrawEx (FID: DWORD; t: TAnimationState; x, y: Integer; mirror: TMirrorType; rpoint: TDFPoint; angle: SmallInt);
+  begin
+    if t.enabled then
+      e_DrawAdv(framesArray[FID].TexturesID[t.currentFrame], x, y, t.alpha, true, t.blending, angle, @rpoint, mirror)
+  end;
+
 function allocFrameSlot (): LongWord;
 var
   f: integer;
index b768075d9dd1ecf0c84e12c92445f0f354e0dfa2..4db3f641a7f4376825cfdaa2881d1398fd4dbed0 100644 (file)
@@ -21,6 +21,9 @@ interface
   procedure r_Render_Finalize;
   procedure r_Render_Resize (w, h: Integer);
 
+  procedure r_Render_Load;
+  procedure r_Render_Free;
+
   procedure r_Render_Apply;
 
 implementation
@@ -30,7 +33,8 @@ implementation
     SysUtils, Classes, Math,
     e_log, g_system,
     g_game, g_options, g_console,
-    r_window, r_graphics, r_console, r_playermodel
+    r_window, r_graphics, r_console, r_playermodel,
+    r_weapons
   ;
 
   var
@@ -69,6 +73,16 @@ implementation
     end
   end;
 
+  procedure r_Render_Load;
+  begin
+    r_Weapon_Load;
+  end;
+
+  procedure r_Render_Free;
+  begin
+    r_Weapon_Free;
+  end;
+
   procedure r_Render_Initialize;
   begin
     if sys_SetDisplayMode(gRC_Width, gRC_Height, gBPP, gRC_FullScreen, gRC_Maximized) = False then
index 94d1d4ade21ae5e423c512a020269bc8d431763d..648ff507201165d6cdcd9ad20b5017dbd61b7b6b 100644 (file)
@@ -17,6 +17,8 @@ unit r_weapons;
 
 interface
 
+  procedure r_Weapon_Load;
+  procedure r_Weapon_Free;
   procedure r_Weapon_Draw;
 
 implementation
@@ -24,11 +26,103 @@ implementation
   uses
     SysUtils, Classes, Math,
     MAPDEF,
-    r_graphics, r_animations,
-    g_base, g_basic, g_game,
+    r_graphics, r_animations, r_textures,
+    g_base, g_basic, g_game, g_options,
     g_weapons
   ;
 
+  var
+    ShotTexture, ShotFrames: array [WEAPON_KASTET..WEAPON_SKEL_FIRE] of DWORD;
+
+  procedure r_Weapon_Load;
+  begin
+    g_Texture_CreateWADEx('TEXTURE_WEAPON_ROCKET', GameWAD+':TEXTURES\BROCKET');
+    g_Frames_CreateWAD(nil, 'FRAMES_WEAPON_SKELFIRE', GameWAD+':TEXTURES\BSKELFIRE', 64, 16, 2);
+    g_Frames_CreateWAD(nil, 'FRAMES_WEAPON_BFG', GameWAD+':TEXTURES\BBFG', 64, 64, 2);
+    g_Frames_CreateWAD(nil, 'FRAMES_WEAPON_PLASMA', GameWAD+':TEXTURES\BPLASMA', 16, 16, 2);
+    g_Frames_CreateWAD(nil, 'FRAMES_WEAPON_IMPFIRE', GameWAD+':TEXTURES\BIMPFIRE', 16, 16, 2);
+    g_Frames_CreateWAD(nil, 'FRAMES_WEAPON_BSPFIRE', GameWAD+':TEXTURES\BBSPFIRE', 16, 16, 2);
+    g_Frames_CreateWAD(nil, 'FRAMES_WEAPON_CACOFIRE', GameWAD+':TEXTURES\BCACOFIRE', 16, 16, 2);
+    g_Frames_CreateWAD(nil, 'FRAMES_WEAPON_BARONFIRE', GameWAD+':TEXTURES\BBARONFIRE', 64, 16, 2);
+    g_Frames_CreateWAD(nil, 'FRAMES_WEAPON_MANCUBFIRE', GameWAD+':TEXTURES\BMANCUBFIRE', 64, 32, 2);
+    g_Frames_CreateWAD(nil, 'FRAMES_EXPLODE_ROCKET', GameWAD+':TEXTURES\EROCKET', 128, 128, 6);
+    g_Frames_CreateWAD(nil, 'FRAMES_EXPLODE_SKELFIRE', GameWAD+':TEXTURES\ESKELFIRE', 64, 64, 3);
+    g_Frames_CreateWAD(nil, 'FRAMES_EXPLODE_BFG', GameWAD+':TEXTURES\EBFG', 128, 128, 6);
+    g_Frames_CreateWAD(nil, 'FRAMES_EXPLODE_IMPFIRE', GameWAD+':TEXTURES\EIMPFIRE', 64, 64, 3);
+    g_Frames_CreateWAD(nil, 'FRAMES_BFGHIT', GameWAD+':TEXTURES\BFGHIT', 64, 64, 4);
+    g_Frames_CreateWAD(nil, 'FRAMES_FIRE', GameWAD+':TEXTURES\FIRE', 64, 128, 8);
+    g_Frames_CreateWAD(nil, 'FRAMES_FLAME', GameWAD+':TEXTURES\FLAME', 32, 32, 11);
+    g_Frames_CreateWAD(nil, 'FRAMES_EXPLODE_PLASMA', GameWAD+':TEXTURES\EPLASMA', 32, 32, 4, True);
+    g_Frames_CreateWAD(nil, 'FRAMES_EXPLODE_BSPFIRE', GameWAD+':TEXTURES\EBSPFIRE', 32, 32, 5);
+    g_Frames_CreateWAD(nil, 'FRAMES_EXPLODE_CACOFIRE', GameWAD+':TEXTURES\ECACOFIRE', 64, 64, 3);
+    g_Frames_CreateWAD(nil, 'FRAMES_EXPLODE_BARONFIRE', GameWAD+':TEXTURES\EBARONFIRE', 64, 64, 3);
+    g_Frames_CreateWAD(nil, 'FRAMES_SMOKE', GameWAD+':TEXTURES\SMOKE', 32, 32, 10, False);
+
+    g_Texture_CreateWADEx('TEXTURE_SHELL_BULLET', GameWAD+':TEXTURES\EBULLET');
+    g_Texture_CreateWADEx('TEXTURE_SHELL_SHELL', GameWAD+':TEXTURES\ESHELL');
+
+    (* WEAPON_ROCKETLAUNCHER *)
+    g_Texture_Get('TEXTURE_WEAPON_ROCKET', ShotTexture[WEAPON_ROCKETLAUNCHER]);
+
+    (* WEAPON_PLASMA *)
+    g_Frames_Get(ShotFrames[WEAPON_PLASMA], 'FRAMES_WEAPON_PLASMA');
+    // Animation := TAnimation.Create(FramesID, True, 5);
+
+    (* WEAPON_BFG *)
+    g_Frames_Get(ShotFrames[WEAPON_BFG], 'FRAMES_WEAPON_BFG');
+    // Animation := TAnimation.Create(FramesID, True, 6);
+
+    (* WEAPON_FLAMETHROWER *)
+    //g_Frames_Get(ShotTexture[WEAPON_FLAMETHROWER], 'FRAMES_FLAME');
+    //g_Frames_Get(ShotFrames[WEAPON_FLAMETHROWER], 'FRAMES_FLAME');
+
+    (* WEAPON_IMP_FIRE *)
+    g_Frames_Get(ShotFrames[WEAPON_IMP_FIRE], 'FRAMES_WEAPON_IMPFIRE');
+    // Animation := TAnimation.Create(FramesID, True, 4);
+
+    (* WEAPON_CACO_FIRE *)
+    g_Frames_Get(ShotFrames[WEAPON_CACO_FIRE], 'FRAMES_WEAPON_CACOFIRE');
+    // Animation := TAnimation.Create(FramesID, True, 4);
+
+    (* WEAPON_MANCUB_FIRE *)
+    g_Frames_Get(ShotFrames[WEAPON_MANCUB_FIRE], 'FRAMES_WEAPON_MANCUBFIRE');
+    // Animation := TAnimation.Create(FramesID, True, 4);
+
+    (* WEAPON_BARON_FIRE *)
+    g_Frames_Get(ShotFrames[WEAPON_BARON_FIRE], 'FRAMES_WEAPON_BARONFIRE');
+    // Animation := TAnimation.Create(FramesID, True, 4);
+
+    (* WEAPON_BSP_FIRE *)
+    g_Frames_Get(ShotFrames[WEAPON_BSP_FIRE], 'FRAMES_WEAPON_BSPFIRE');
+    // Animation := TAnimation.Create(FramesID, True, 4);
+
+    (* WEAPON_SKEL_FIRE *)
+    g_Frames_Get(ShotFrames[WEAPON_SKEL_FIRE], 'FRAMES_WEAPON_SKELFIRE');
+    // Animation := TAnimation.Create(FramesID, True, 5);
+  end;
+
+  procedure r_Weapon_Free;
+  begin
+    g_Texture_Delete('TEXTURE_WEAPON_ROCKET');
+    g_Frames_DeleteByName('FRAMES_WEAPON_BFG');
+    g_Frames_DeleteByName('FRAMES_WEAPON_PLASMA');
+    g_Frames_DeleteByName('FRAMES_WEAPON_IMPFIRE');
+    g_Frames_DeleteByName('FRAMES_WEAPON_BSPFIRE');
+    g_Frames_DeleteByName('FRAMES_WEAPON_CACOFIRE');
+    g_Frames_DeleteByName('FRAMES_WEAPON_MANCUBFIRE');
+    g_Frames_DeleteByName('FRAMES_EXPLODE_ROCKET');
+    g_Frames_DeleteByName('FRAMES_EXPLODE_BFG');
+    g_Frames_DeleteByName('FRAMES_EXPLODE_IMPFIRE');
+    g_Frames_DeleteByName('FRAMES_BFGHIT');
+    g_Frames_DeleteByName('FRAMES_FIRE');
+    g_Frames_DeleteByName('FRAMES_EXPLODE_PLASMA');
+    g_Frames_DeleteByName('FRAMES_EXPLODE_BSPFIRE');
+    g_Frames_DeleteByName('FRAMES_EXPLODE_CACOFIRE');
+    g_Frames_DeleteByName('FRAMES_SMOKE');
+    g_Frames_DeleteByName('FRAMES_WEAPON_BARONFIRE');
+    g_Frames_DeleteByName('FRAMES_EXPLODE_BARONFIRE');
+  end;
+
   procedure r_Weapon_Draw;
     var i, fX, fY, xx, yy: Integer; a: SmallInt; p: TDFPoint;
   begin
@@ -53,16 +147,16 @@ implementation
           if Animation <> nil then
           begin
             if Shots[i].ShotType in [WEAPON_BARON_FIRE, WEAPON_MANCUB_FIRE, WEAPON_SKEL_FIRE] then
-              r_Animation_DrawEx(Animation, fX, fY, TMirrorType.None, p, a)
+              r_AnimationState_DrawEx(ShotFrames[Shots[i].ShotType], Animation, fX, fY, TMirrorType.None, p, a)
             else
-              r_Animation_Draw(Animation, fX, fY, TMirrorType.None);
+              r_AnimationState_Draw(ShotFrames[Shots[i].ShotType], Animation, fX, fY, TMirrorType.None);
           end
-          else if TextureID <> 0 then
+          else if ShotTexture[Shots[i].ShotType] <> 0 then
           begin
             if (Shots[i].ShotType = WEAPON_ROCKETLAUNCHER) then
-              e_DrawAdv(TextureID, fX, fY, 0, True, False, a, @p, TMirrorType.None)
+              e_DrawAdv(ShotTexture[Shots[i].ShotType], fX, fY, 0, True, False, a, @p, TMirrorType.None)
             else if (Shots[i].ShotType <> WEAPON_FLAMETHROWER) then
-              e_Draw(TextureID, fX, fY, 0, True, False);
+              e_Draw(ShotTexture[Shots[i].ShotType], fX, fY, 0, True, False);
           end;
 
           if g_debug_Frames then