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 TAnimationState
= class{$IFDEF USE_MEMPOOL}(TPoolObject
){$ENDIF}
40 mCounter
: Byte; // Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè
41 mSpeed
: Byte; // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè
42 mCurrentFrame
: Integer; // Òåêóùèé êàäð (íà÷èíàÿ ñ 0)
43 mLoop
: Boolean; // Ïåðåõîäèòü íà ïåðâûé êàäð ïîñëå ïîñëåäíåãî?
44 mEnabled
: Boolean; // Ðàáîòà ðàçðåøåíà?
45 mPlayed
: Boolean; // Ïðîèãðàíà âñÿ õîòÿ áû ðàç?
46 mMinLength
: Byte; // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ
47 mRevert
: Boolean; // Ñìåíà êàäðîâ îáðàòíàÿ?
52 constructor Create (aloop
: Boolean; aspeed
: Byte; len
: Integer);
53 destructor Destroy (); override;
59 procedure revert (r
: Boolean);
61 procedure saveState (st
: TStream
);
62 procedure loadState (st
: TStream
);
64 function totalFrames (): Integer; inline;
67 property played
: Boolean read mPlayed
;
68 property enabled
: Boolean read mEnabled
;
69 property isReverse
: Boolean read mRevert
;
70 property loop
: Boolean read mLoop write mLoop
;
71 property speed
: Byte read mSpeed write mSpeed
;
72 property minLength
: Byte read mMinLength write mMinLength
;
73 property currentFrame
: Integer read mCurrentFrame write mCurrentFrame
;
74 property currentCounter
: Byte read mCounter write mCounter
;
75 property counter
: Byte read mCounter
;
76 property blending
: Boolean read mBlending write mBlending
;
77 property alpha
: Byte read mAlpha write mAlpha
;
80 TAnimation
= class{$IFDEF USE_MEMPOOL}(TPoolObject
){$ENDIF}
85 mCounter
: Byte; // Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè
86 mSpeed
: Byte; // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè
87 mCurrentFrame
: Integer; // Òåêóùèé êàäð (íà÷èíàÿ ñ 0)
88 mLoop
: Boolean; // Ïåðåõîäèòü íà ïåðâûé êàäð ïîñëå ïîñëåäíåãî?
89 mEnabled
: Boolean; // Ðàáîòà ðàçðåøåíà?
90 mPlayed
: Boolean; // Ïðîèãðàíà âñÿ õîòÿ áû ðàç?
93 mMinLength
: Byte; // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ
94 mRevert
: Boolean; // Ñìåíà êàäðîâ îáðàòíàÿ?
97 constructor Create (aframesID
: LongWord; aloop
: Boolean; aspeed
: Byte);
98 destructor Destroy (); override;
103 procedure disable ();
104 procedure revert (r
: Boolean);
106 procedure saveState (st
: TStream
);
107 procedure loadState (st
: TStream
);
109 function totalFrames (): Integer; inline;
112 property played
: Boolean read mPlayed
;
113 property enabled
: Boolean read mEnabled
;
114 property isReverse
: Boolean read mRevert
;
115 property loop
: Boolean read mLoop write mLoop
;
116 property speed
: Byte read mSpeed write mSpeed
;
117 property minLength
: Byte read mMinLength write mMinLength
;
118 property currentFrame
: Integer read mCurrentFrame write mCurrentFrame
;
119 property currentCounter
: Byte read mCounter write mCounter
;
120 property counter
: Byte read mCounter
;
121 property blending
: Boolean read mBlending write mBlending
;
122 property alpha
: Byte read mAlpha write mAlpha
;
123 property framesId
: LongWord read mId
;
124 property width
: Word read mWidth
;
125 property height
: Word read mHeight
;
127 property id
: LongWord read mId
;
133 g_game
, e_log
, g_basic
, g_console
, wadreader
, r_animations
,
134 g_language
, utils
, xstreams
;
139 constructor TAnimationState
.Create (aloop
: Boolean; aspeed
: Byte; len
: Integer);
153 destructor TAnimationState
.Destroy
;
158 procedure TAnimationState
.update
;
160 if (not mEnabled
) then exit
;
164 if (mCounter
>= mSpeed
) then
166 // Îæèäàíèå ìåæäó êàäðàìè çàêîí÷èëîñü
167 // Îáðàòíûé ïîðÿäîê êàäðîâ?
170 // Äîøëè äî êîíöà àíèìàöèè. Âîçìîæíî, æäåì åùå
171 if (mCurrentFrame
= 0) then
173 if (mLength
* mSpeed
+ mCounter
< mMinLength
) then exit
;
177 mPlayed
:= (mCurrentFrame
< 0);
179 // Ïîâòîðÿòü ëè àíèìàöèþ ïî êðóãó?
183 mCurrentFrame
:= mLength
- 1
192 // Ïðÿìîé ïîðÿäîê êàäðîâ
193 // Äîøëè äî êîíöà àíèìàöèè. Âîçìîæíî, æäåì åùå
194 if (mCurrentFrame
= mLength
- 1) then
196 if (mLength
* mSpeed
+ mCounter
< mMinLength
) then exit
;
200 mPlayed
:= (mCurrentFrame
> mLength
- 1);
202 // Ïîâòîðÿòü ëè àíèìàöèþ ïî êðóãó?
205 if mLoop
then mCurrentFrame
:= 0 else mCurrentFrame
-= 1;
213 procedure TAnimationState
.reset
;
216 mCurrentFrame
:= mLength
- 1
223 procedure TAnimationState
.disable
;
228 procedure TAnimationState
.enable
;
233 procedure TAnimationState
.revert (r
: Boolean);
239 function TAnimationState
.totalFrames (): Integer; inline;
244 procedure TAnimationState
.saveState (st
: TStream
);
246 if (st
= nil) then exit
;
248 utils
.writeSign(st
, 'ANIM');
249 utils
.writeInt(st
, Byte(0)); // version
250 // Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè
251 utils
.writeInt(st
, Byte(mCounter
));
253 utils
.writeInt(st
, LongInt(mCurrentFrame
));
254 // Ïðîèãðàíà ëè àíèìàöèÿ öåëèêîì
255 utils
.writeBool(st
, mPlayed
);
256 // Alpha-êàíàë âñåé òåêñòóðû
257 utils
.writeInt(st
, Byte(mAlpha
));
259 utils
.writeInt(st
, Byte(mBlending
));
260 // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè
261 utils
.writeInt(st
, Byte(mSpeed
));
262 // Çàöèêëåíà ëè àíèìàöèÿ
263 utils
.writeBool(st
, mLoop
);
265 utils
.writeBool(st
, mEnabled
);
266 // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ
267 utils
.writeInt(st
, Byte(mMinLength
));
268 // Îáðàòíûé ëè ïîðÿäîê êàäðîâ
269 utils
.writeBool(st
, mRevert
);
273 procedure TAnimationState
.loadState (st
: TStream
);
275 if (st
= nil) then exit
;
277 if not utils
.checkSign(st
, 'ANIM') then raise XStreamError
.Create('animation chunk expected');
278 if (utils
.readByte(st
) <> 0) then raise XStreamError
.Create('invalid animation chunk version');
279 // Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè
280 mCounter
:= utils
.readByte(st
);
282 mCurrentFrame
:= utils
.readLongInt(st
);
283 // Ïðîèãðàíà ëè àíèìàöèÿ öåëèêîì
284 mPlayed
:= utils
.readBool(st
);
285 // Alpha-êàíàë âñåé òåêñòóðû
286 mAlpha
:= utils
.readByte(st
);
288 mBlending
:= utils
.readBool(st
);
289 // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè
290 mSpeed
:= utils
.readByte(st
);
291 // Çàöèêëåíà ëè àíèìàöèÿ
292 mLoop
:= utils
.readBool(st
);
294 mEnabled
:= utils
.readBool(st
);
295 // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ
296 mMinLength
:= utils
.readByte(st
);
297 // Îáðàòíûé ëè ïîðÿäîê êàäðîâ
298 mRevert
:= utils
.readBool(st
);
306 constructor TAnimation
.Create (aframesID
: LongWord; aloop
: Boolean; aspeed
: Byte);
308 if (aframesID
>= Length(framesArray
)) then
310 //raise Exception.Create('trying to create inexisting frame: something is very wrong here');
311 e_LogWritefln('trying to create inexisting frame %u of %u: something is very wrong here', [aframesID
, LongWord(Length(framesArray
))], TMsgType
.Warning
);
313 if (Length(framesArray
) = 0) then raise Exception
.Create('trying to create inexisting frame: something is very wrong here');
323 mWidth
:= framesArray
[mId
].FrameWidth
;
324 mHeight
:= framesArray
[mId
].FrameHeight
;
328 destructor TAnimation
.Destroy ();
334 procedure TAnimation
.update ();
336 if (not mEnabled
) then exit
;
340 if (mCounter
>= mSpeed
) then
342 // Îæèäàíèå ìåæäó êàäðàìè çàêîí÷èëîñü
343 // Îáðàòíûé ïîðÿäîê êàäðîâ?
346 // Äîøëè äî êîíöà àíèìàöèè. Âîçìîæíî, æäåì åùå
347 if (mCurrentFrame
= 0) then
349 if (Length(framesArray
[mId
].TexturesID
)*mSpeed
+mCounter
< mMinLength
) then exit
;
353 mPlayed
:= (mCurrentFrame
< 0);
355 // Ïîâòîðÿòü ëè àíèìàöèþ ïî êðóãó?
358 if mLoop
then mCurrentFrame
:= High(framesArray
[mId
].TexturesID
) else mCurrentFrame
+= 1;
365 // Ïðÿìîé ïîðÿäîê êàäðîâ
366 // Äîøëè äî êîíöà àíèìàöèè. Âîçìîæíî, æäåì åùå
367 if (mCurrentFrame
= High(framesArray
[mId
].TexturesID
)) then
369 if (Length(framesArray
[mId
].TexturesID
)*mSpeed
+mCounter
< mMinLength
) then exit
;
373 mPlayed
:= (mCurrentFrame
> High(framesArray
[mId
].TexturesID
));
375 // Ïîâòîðÿòü ëè àíèìàöèþ ïî êðóãó?
378 if mLoop
then mCurrentFrame
:= 0 else mCurrentFrame
-= 1;
387 procedure TAnimation
.reset ();
389 if mRevert
then mCurrentFrame
:= High(framesArray
[mId
].TexturesID
) else mCurrentFrame
:= 0;
395 procedure TAnimation
.disable (); begin mEnabled
:= false; end;
396 procedure TAnimation
.enable (); begin mEnabled
:= true; end;
399 function TAnimation
.totalFrames (): Integer; inline; begin result
:= Length(framesArray
[mId
].TexturesID
); end;
402 procedure TAnimation
.revert (r
: Boolean);
409 procedure TAnimation
.saveState (st
: TStream
);
411 if (st
= nil) then exit
;
413 utils
.writeSign(st
, 'ANIM');
414 utils
.writeInt(st
, Byte(0)); // version
415 // Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè
416 utils
.writeInt(st
, Byte(mCounter
));
418 utils
.writeInt(st
, LongInt(mCurrentFrame
));
419 // Ïðîèãðàíà ëè àíèìàöèÿ öåëèêîì
420 utils
.writeBool(st
, mPlayed
);
421 // Alpha-êàíàë âñåé òåêñòóðû
422 utils
.writeInt(st
, Byte(mAlpha
));
424 utils
.writeInt(st
, Byte(mBlending
));
425 // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè
426 utils
.writeInt(st
, Byte(mSpeed
));
427 // Çàöèêëåíà ëè àíèìàöèÿ
428 utils
.writeBool(st
, mLoop
);
430 utils
.writeBool(st
, mEnabled
);
431 // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ
432 utils
.writeInt(st
, Byte(mMinLength
));
433 // Îáðàòíûé ëè ïîðÿäîê êàäðîâ
434 utils
.writeBool(st
, mRevert
);
438 procedure TAnimation
.loadState (st
: TStream
);
440 if (st
= nil) then exit
;
442 if not utils
.checkSign(st
, 'ANIM') then raise XStreamError
.Create('animation chunk expected');
443 if (utils
.readByte(st
) <> 0) then raise XStreamError
.Create('invalid animation chunk version');
444 // Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè
445 mCounter
:= utils
.readByte(st
);
447 mCurrentFrame
:= utils
.readLongInt(st
);
448 // Ïðîèãðàíà ëè àíèìàöèÿ öåëèêîì
449 mPlayed
:= utils
.readBool(st
);
450 // Alpha-êàíàë âñåé òåêñòóðû
451 mAlpha
:= utils
.readByte(st
);
453 mBlending
:= utils
.readBool(st
);
454 // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè
455 mSpeed
:= utils
.readByte(st
);
456 // Çàöèêëåíà ëè àíèìàöèÿ
457 mLoop
:= utils
.readBool(st
);
459 mEnabled
:= utils
.readBool(st
);
460 // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ
461 mMinLength
:= utils
.readByte(st
);
462 // Îáðàòíûé ëè ïîðÿäîê êàäðîâ
463 mRevert
:= utils
.readBool(st
);