X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_animations.pas;h=0135b15ec0c2587fd2e734e3dacfaa98951e60a1;hb=0592c8529428165e2523e0cb054bff29e297777a;hp=1e9078e9320d52117e1b73aaf15371d3eaf7b22d;hpb=df1f12c26369a0d5e9e996583b30c9879570fe99;p=d2df-sdl.git diff --git a/src/game/g_animations.pas b/src/game/g_animations.pas index 1e9078e..0135b15 100644 --- a/src/game/g_animations.pas +++ b/src/game/g_animations.pas @@ -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.