1 (* Copyright (C) Doom 2D: Forever Developers
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, version 3 of the License ONLY.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 {$INCLUDE ../shared/a_modes.inc}
22 {$IFDEF USE_MEMPOOL}mempool
,{$ENDIF}
23 g_base
, r_graphics
, MAPDEF
, ImagingTypes
, Imaging
, ImagingUtility
;
26 TLevelTexture
= record
27 textureName
: AnsiString;
30 false: (textureID
: LongWord);
31 true: (framesID
: LongWord; framesCount
: Byte; speed
: Byte);
34 TLevelTextureArray
= array of TLevelTexture
;
36 TAnimation
= class{$IFDEF USE_MEMPOOL}(TPoolObject
){$ENDIF}
41 mCounter
: Byte; // Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè
42 mSpeed
: Byte; // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè
43 mCurrentFrame
: Integer; // Òåêóùèé êàäð (íà÷èíàÿ ñ 0)
44 mLoop
: Boolean; // Ïåðåõîäèòü íà ïåðâûé êàäð ïîñëå ïîñëåäíåãî?
45 mEnabled
: Boolean; // Ðàáîòà ðàçðåøåíà?
46 mPlayed
: Boolean; // Ïðîèãðàíà âñÿ õîòÿ áû ðàç?
49 mMinLength
: Byte; // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ
50 mRevert
: Boolean; // Ñìåíà êàäðîâ îáðàòíàÿ?
53 constructor Create (aframesID
: LongWord; aloop
: Boolean; aspeed
: Byte);
54 destructor Destroy (); override;
60 procedure revert (r
: Boolean);
62 procedure saveState (st
: TStream
);
63 procedure loadState (st
: TStream
);
65 function totalFrames (): Integer; inline;
68 property played
: Boolean read mPlayed
;
69 property enabled
: Boolean read mEnabled
;
70 property isReverse
: Boolean read mRevert
;
71 property loop
: Boolean read mLoop write mLoop
;
72 property speed
: Byte read mSpeed write mSpeed
;
73 property minLength
: Byte read mMinLength write mMinLength
;
74 property currentFrame
: Integer read mCurrentFrame write mCurrentFrame
;
75 property currentCounter
: Byte read mCounter write mCounter
;
76 property counter
: Byte read mCounter
;
77 property blending
: Boolean read mBlending write mBlending
;
78 property alpha
: Byte read mAlpha write mAlpha
;
79 property framesId
: LongWord read mId
;
80 property width
: Word read mWidth
;
81 property height
: Word read mHeight
;
83 property id
: LongWord read mId
;
89 g_game
, e_log
, g_basic
, g_console
, wadreader
, r_animations
,
90 g_language
, utils
, xstreams
;
92 constructor TAnimation
.Create (aframesID
: LongWord; aloop
: Boolean; aspeed
: Byte);
94 if (aframesID
>= Length(framesArray
)) then
96 //raise Exception.Create('trying to create inexisting frame: something is very wrong here');
97 e_LogWritefln('trying to create inexisting frame %u of %u: something is very wrong here', [aframesID
, LongWord(Length(framesArray
))], TMsgType
.Warning
);
99 if (Length(framesArray
) = 0) then raise Exception
.Create('trying to create inexisting frame: something is very wrong here');
109 mWidth
:= framesArray
[mId
].FrameWidth
;
110 mHeight
:= framesArray
[mId
].FrameHeight
;
114 destructor TAnimation
.Destroy ();
120 procedure TAnimation
.update ();
122 if (not mEnabled
) then exit
;
126 if (mCounter
>= mSpeed
) then
128 // Îæèäàíèå ìåæäó êàäðàìè çàêîí÷èëîñü
129 // Îáðàòíûé ïîðÿäîê êàäðîâ?
132 // Äîøëè äî êîíöà àíèìàöèè. Âîçìîæíî, æäåì åùå
133 if (mCurrentFrame
= 0) then
135 if (Length(framesArray
[mId
].TexturesID
)*mSpeed
+mCounter
< mMinLength
) then exit
;
139 mPlayed
:= (mCurrentFrame
< 0);
141 // Ïîâòîðÿòü ëè àíèìàöèþ ïî êðóãó?
144 if mLoop
then mCurrentFrame
:= High(framesArray
[mId
].TexturesID
) else mCurrentFrame
+= 1;
151 // Ïðÿìîé ïîðÿäîê êàäðîâ
152 // Äîøëè äî êîíöà àíèìàöèè. Âîçìîæíî, æäåì åùå
153 if (mCurrentFrame
= High(framesArray
[mId
].TexturesID
)) then
155 if (Length(framesArray
[mId
].TexturesID
)*mSpeed
+mCounter
< mMinLength
) then exit
;
159 mPlayed
:= (mCurrentFrame
> High(framesArray
[mId
].TexturesID
));
161 // Ïîâòîðÿòü ëè àíèìàöèþ ïî êðóãó?
164 if mLoop
then mCurrentFrame
:= 0 else mCurrentFrame
-= 1;
173 procedure TAnimation
.reset ();
175 if mRevert
then mCurrentFrame
:= High(framesArray
[mId
].TexturesID
) else mCurrentFrame
:= 0;
181 procedure TAnimation
.disable (); begin mEnabled
:= false; end;
182 procedure TAnimation
.enable (); begin mEnabled
:= true; end;
185 function TAnimation
.totalFrames (): Integer; inline; begin result
:= Length(framesArray
[mId
].TexturesID
); end;
188 procedure TAnimation
.revert (r
: Boolean);
195 procedure TAnimation
.saveState (st
: TStream
);
197 if (st
= nil) then exit
;
199 utils
.writeSign(st
, 'ANIM');
200 utils
.writeInt(st
, Byte(0)); // version
201 // Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè
202 utils
.writeInt(st
, Byte(mCounter
));
204 utils
.writeInt(st
, LongInt(mCurrentFrame
));
205 // Ïðîèãðàíà ëè àíèìàöèÿ öåëèêîì
206 utils
.writeBool(st
, mPlayed
);
207 // Alpha-êàíàë âñåé òåêñòóðû
208 utils
.writeInt(st
, Byte(mAlpha
));
210 utils
.writeInt(st
, Byte(mBlending
));
211 // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè
212 utils
.writeInt(st
, Byte(mSpeed
));
213 // Çàöèêëåíà ëè àíèìàöèÿ
214 utils
.writeBool(st
, mLoop
);
216 utils
.writeBool(st
, mEnabled
);
217 // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ
218 utils
.writeInt(st
, Byte(mMinLength
));
219 // Îáðàòíûé ëè ïîðÿäîê êàäðîâ
220 utils
.writeBool(st
, mRevert
);
224 procedure TAnimation
.loadState (st
: TStream
);
226 if (st
= nil) then exit
;
228 if not utils
.checkSign(st
, 'ANIM') then raise XStreamError
.Create('animation chunk expected');
229 if (utils
.readByte(st
) <> 0) then raise XStreamError
.Create('invalid animation chunk version');
230 // Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè
231 mCounter
:= utils
.readByte(st
);
233 mCurrentFrame
:= utils
.readLongInt(st
);
234 // Ïðîèãðàíà ëè àíèìàöèÿ öåëèêîì
235 mPlayed
:= utils
.readBool(st
);
236 // Alpha-êàíàë âñåé òåêñòóðû
237 mAlpha
:= utils
.readByte(st
);
239 mBlending
:= utils
.readBool(st
);
240 // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè
241 mSpeed
:= utils
.readByte(st
);
242 // Çàöèêëåíà ëè àíèìàöèÿ
243 mLoop
:= utils
.readBool(st
);
245 mEnabled
:= utils
.readBool(st
);
246 // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ
247 mMinLength
:= utils
.readByte(st
);
248 // Îáðàòíûé ëè ïîðÿäîê êàäðîâ
249 mRevert
:= utils
.readBool(st
);