DEADSOFTWARE

panels: fix crash on liquid collision
[d2df-sdl.git] / src / game / g_animations.pas
index 1e9078e9320d52117e1b73aaf15371d3eaf7b22d..0135b15ec0c2587fd2e734e3dacfaa98951e60a1 100644 (file)
@@ -22,7 +22,7 @@ interface
   type
     TAnimState = record
       private
-        mCounter: Byte;         // delay counter (normally [0..mSpeed])
+        mCounter: Byte;         // delay counter (normally [0..mSpeed - 1])
         mSpeed: Byte;           // delay between frames
         mCurrentFrame: Integer; // current frame (normally [0..mLength - 1])
         mLoop: Boolean;         // looped animation
@@ -70,12 +70,17 @@ interface
       back: Boolean; (* back animation normalization *)
     end;
 
+
   function g_Anim_GetTotalFrames (const a: TAnimInfo): LongWord;
   function g_Anim_GetTotalTime (const a: TAnimInfo): LongWord;
   function g_Anim_GetCountByTime (const a: TAnimInfo; time: LongWord): LongInt;
   procedure g_Anim_GetFrameByTime (const a: TAnimInfo; time: LongWord; out count, frame: LongInt);
   procedure g_Anim_GetState (const anim: TAnimInfo; time: LongWord; out state: TAnimState);
 
+  procedure g_Anim_GetFrameFromState (const s: TAnimState; backanim: Boolean; out frame: LongInt);
+  procedure g_Anim_GetInterplatedFrameFromState (const s: TAnimState; newlength: LongInt; out frame: LongInt);
+  procedure g_Anim_GetTimeFromState (const s: TAnimState; out curtime, fulltime: LongInt);
+
 implementation
 
   uses Math, utils, xstreams;
@@ -287,4 +292,49 @@ implementation
     state.mPlayed := count >= 1;
   end;
 
+  procedure g_Anim_GetFrameFromState (const s: TAnimState; backanim: Boolean; out frame: LongInt);
+    var total: LongInt;
+  begin
+    ASSERT(s.length > 0);
+    frame := s.CurrentFrame mod s.length;
+    if backanim then
+    begin
+      total := (s.length + 1) div 2;
+      if frame >= total then
+        frame := s.length - frame - 1;
+    end;
+  end;
+
+  procedure g_Anim_GetInterplatedFrameFromState (const s: TAnimState; newlength: LongInt; out frame: LongInt);
+    var delay, curframe, curcount, fulltime, curtime, newtime: LongInt;
+  begin
+    ASSERT(s.length > 0);
+    ASSERT(newlength > 0);
+    (* 1. normalize state values *)
+    delay := MAX(1, s.speed);
+    curframe := MIN(MAX(s.CurrentFrame, 0), s.length - 1);
+    curcount := MIN(MAX(s.CurrentCounter, 0), delay - 1);
+    (* 2. calc current time (normalized) *)
+    fulltime := s.length * delay;
+    curtime := MIN(curframe * delay + curcount, fulltime);
+    (* 3. calc interpolated frame *)
+    newtime := curtime * newlength div s.length;
+    frame := newtime div delay;
+    ASSERT(frame >= 0);
+    ASSERT(frame < newlength);
+  end;
+
+  procedure g_Anim_GetTimeFromState (const s: TAnimState; out curtime, fulltime: LongInt);
+    var delay, curframe, curcount: LongInt;
+  begin
+    ASSERT(s.length > 0);
+    (* 1. normalize state values *)
+    delay := MAX(1, s.speed);
+    curframe := MIN(MAX(s.CurrentFrame, 0), s.length - 1);
+    curcount := MIN(MAX(s.CurrentCounter, 0), delay - 1);
+    (* 2. calc current time (normalized) *)
+    fulltime := s.length * delay;
+    curtime := MIN(curframe * delay + curcount, fulltime);
+  end;
+
 end.