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}
26 TLevelTexture
= record
27 TextureName
: AnsiString; // as stored in wad
28 FullName
: AnsiString; // full path to texture // !!! merge it with TextureName
29 framesCount
, speed
: Byte;
32 TLevelTextureArray
= array of TLevelTexture
;
34 TAnimationState
= class{$IFDEF USE_MEMPOOL}(TPoolObject
){$ENDIF}
36 mCounter
: Byte; // Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè
37 mSpeed
: Byte; // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè
38 mCurrentFrame
: Integer; // Òåêóùèé êàäð (íà÷èíàÿ ñ 0)
39 mLoop
: Boolean; // Ïåðåõîäèòü íà ïåðâûé êàäð ïîñëå ïîñëåäíåãî?
40 mEnabled
: Boolean; // Ðàáîòà ðàçðåøåíà?
41 mPlayed
: Boolean; // Ïðîèãðàíà âñÿ õîòÿ áû ðàç?
42 mMinLength
: Byte; // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ
43 mRevert
: Boolean; // Ñìåíà êàäðîâ îáðàòíàÿ?
48 constructor Create (aloop
: Boolean; aspeed
: Byte; len
: Integer);
49 destructor Destroy (); override;
55 procedure revert (r
: Boolean);
57 procedure saveState (st
: TStream
; mAlpha
: Byte; mBlending
: Boolean);
58 procedure loadState (st
: TStream
; out mAlpha
: Byte; out mBlending
: Boolean);
60 function totalFrames (): Integer; inline;
63 property played
: Boolean read mPlayed
;
64 property enabled
: Boolean read mEnabled
;
65 property isReverse
: Boolean read mRevert
;
66 property loop
: Boolean read mLoop write mLoop
;
67 property speed
: Byte read mSpeed write mSpeed
;
68 property minLength
: Byte read mMinLength write mMinLength
;
69 property currentFrame
: Integer read mCurrentFrame write mCurrentFrame
;
70 property currentCounter
: Byte read mCounter write mCounter
;
71 property counter
: Byte read mCounter
;
72 property length
: Integer read mLength
;
77 mCounter
: Byte; // Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè
78 mSpeed
: Byte; // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè
79 mCurrentFrame
: Integer; // Òåêóùèé êàäð (íà÷èíàÿ ñ 0)
80 mLoop
: Boolean; // Ïåðåõîäèòü íà ïåðâûé êàäð ïîñëå ïîñëåäíåãî?
81 mEnabled
: Boolean; // Ðàáîòà ðàçðåøåíà?
82 mPlayed
: Boolean; // Ïðîèãðàíà âñÿ õîòÿ áû ðàç?
83 mMinLength
: Byte; // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ
84 mRevert
: Boolean; // Ñìåíà êàäðîâ îáðàòíàÿ?
89 constructor Create (aloop
: Boolean; aspeed
: Byte; len
: Integer);
96 procedure revert (r
: Boolean);
98 procedure saveState (st
: TStream
; mAlpha
: Byte; mBlending
: Boolean);
99 procedure loadState (st
: TStream
; out mAlpha
: Byte; out mBlending
: Boolean);
101 function totalFrames (): Integer; inline;
102 function IsInvalid (): Boolean;
103 function IsValid (): Boolean;
106 property played
: Boolean read mPlayed
;
107 property enabled
: Boolean read mEnabled
;
108 property isReverse
: Boolean read mRevert
;
109 property loop
: Boolean read mLoop write mLoop
;
110 property speed
: Byte read mSpeed write mSpeed
;
111 property minLength
: Byte read mMinLength write mMinLength
;
112 property currentFrame
: Integer read mCurrentFrame write mCurrentFrame
;
113 property currentCounter
: Byte read mCounter write mCounter
;
114 property counter
: Byte read mCounter
;
115 property length
: Integer read mLength
;
121 g_game
, e_log
, g_basic
, g_console
, wadreader
,
122 g_language
, utils
, xstreams
;
124 constructor TAnimationState
.Create (aloop
: Boolean; aspeed
: Byte; len
: Integer);
137 destructor TAnimationState
.Destroy
;
142 procedure TAnimationState
.update
;
144 if (not mEnabled
) then exit
;
148 if (mCounter
>= mSpeed
) then
150 // Îæèäàíèå ìåæäó êàäðàìè çàêîí÷èëîñü
151 // Îáðàòíûé ïîðÿäîê êàäðîâ?
154 // Äîøëè äî êîíöà àíèìàöèè. Âîçìîæíî, æäåì åùå
155 if (mCurrentFrame
= 0) then
157 if (mLength
* mSpeed
+ mCounter
< mMinLength
) then exit
;
161 mPlayed
:= (mCurrentFrame
< 0);
163 // Ïîâòîðÿòü ëè àíèìàöèþ ïî êðóãó?
167 mCurrentFrame
:= mLength
- 1
176 // Ïðÿìîé ïîðÿäîê êàäðîâ
177 // Äîøëè äî êîíöà àíèìàöèè. Âîçìîæíî, æäåì åùå
178 if (mCurrentFrame
= mLength
- 1) then
180 if (mLength
* mSpeed
+ mCounter
< mMinLength
) then exit
;
184 mPlayed
:= (mCurrentFrame
> mLength
- 1);
186 // Ïîâòîðÿòü ëè àíèìàöèþ ïî êðóãó?
189 if mLoop
then mCurrentFrame
:= 0 else mCurrentFrame
-= 1;
197 procedure TAnimationState
.reset
;
200 mCurrentFrame
:= mLength
- 1
207 procedure TAnimationState
.disable
;
212 procedure TAnimationState
.enable
;
217 procedure TAnimationState
.revert (r
: Boolean);
223 function TAnimationState
.totalFrames (): Integer; inline;
228 procedure TAnimationState
.saveState (st
: TStream
; mAlpha
: Byte; mBlending
: Boolean);
230 if (st
= nil) then exit
;
232 utils
.writeSign(st
, 'ANIM');
233 utils
.writeInt(st
, Byte(0)); // version
234 // Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè
235 utils
.writeInt(st
, Byte(mCounter
));
237 utils
.writeInt(st
, LongInt(mCurrentFrame
));
238 // Ïðîèãðàíà ëè àíèìàöèÿ öåëèêîì
239 utils
.writeBool(st
, mPlayed
);
240 // Alpha-êàíàë âñåé òåêñòóðû
241 utils
.writeInt(st
, Byte(mAlpha
));
243 utils
.writeInt(st
, Byte(mBlending
));
244 // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè
245 utils
.writeInt(st
, Byte(mSpeed
));
246 // Çàöèêëåíà ëè àíèìàöèÿ
247 utils
.writeBool(st
, mLoop
);
249 utils
.writeBool(st
, mEnabled
);
250 // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ
251 utils
.writeInt(st
, Byte(mMinLength
));
252 // Îáðàòíûé ëè ïîðÿäîê êàäðîâ
253 utils
.writeBool(st
, mRevert
);
257 procedure TAnimationState
.loadState (st
: TStream
; out mAlpha
: Byte; out mBlending
: Boolean);
259 if (st
= nil) then exit
;
261 if not utils
.checkSign(st
, 'ANIM') then raise XStreamError
.Create('animation chunk expected');
262 if (utils
.readByte(st
) <> 0) then raise XStreamError
.Create('invalid animation chunk version');
263 // Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè
264 mCounter
:= utils
.readByte(st
);
266 mCurrentFrame
:= utils
.readLongInt(st
);
267 // Ïðîèãðàíà ëè àíèìàöèÿ öåëèêîì
268 mPlayed
:= utils
.readBool(st
);
269 // Alpha-êàíàë âñåé òåêñòóðû
270 mAlpha
:= utils
.readByte(st
);
272 mBlending
:= utils
.readBool(st
);
273 // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè
274 mSpeed
:= utils
.readByte(st
);
275 // Çàöèêëåíà ëè àíèìàöèÿ
276 mLoop
:= utils
.readBool(st
);
278 mEnabled
:= utils
.readBool(st
);
279 // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ
280 mMinLength
:= utils
.readByte(st
);
281 // Îáðàòíûé ëè ïîðÿäîê êàäðîâ
282 mRevert
:= utils
.readBool(st
);
288 constructor TAnimState
.Create (aloop
: Boolean; aspeed
: Byte; len
: Integer);
290 Self
:= Default(TAnimState
);
303 procedure TAnimState
.Invalidate
;
305 Self
:= Default(TAnimState
);
308 procedure TAnimState
.update
;
310 if (not mEnabled
) then exit
;
314 if (mCounter
>= mSpeed
) then
318 if (mCurrentFrame
= 0) then
320 if (mLength
* mSpeed
+ mCounter
< mMinLength
) then exit
;
324 mPlayed
:= (mCurrentFrame
< 0);
329 mCurrentFrame
:= mLength
- 1
338 if (mCurrentFrame
= mLength
- 1) then
340 if (mLength
* mSpeed
+ mCounter
< mMinLength
) then exit
;
344 mPlayed
:= (mCurrentFrame
> mLength
- 1);
348 if mLoop
then mCurrentFrame
:= 0 else mCurrentFrame
-= 1;
356 procedure TAnimState
.reset
;
359 mCurrentFrame
:= mLength
- 1
366 procedure TAnimState
.disable
;
371 procedure TAnimState
.enable
;
376 procedure TAnimState
.revert (r
: Boolean);
382 function TAnimState
.totalFrames (): Integer; inline;
387 function TAnimState
.IsInvalid (): Boolean;
389 result
:= mLength
<= 0
392 function TAnimState
.IsValid (): Boolean;
394 result
:= mLength
> 0
397 procedure TAnimState
.saveState (st
: TStream
; mAlpha
: Byte; mBlending
: Boolean);
399 if (st
= nil) then exit
;
401 utils
.writeSign(st
, 'ANIM');
402 utils
.writeInt(st
, Byte(0)); // version
403 utils
.writeInt(st
, Byte(mCounter
));
404 utils
.writeInt(st
, LongInt(mCurrentFrame
));
405 utils
.writeBool(st
, mPlayed
);
406 utils
.writeInt(st
, Byte(mAlpha
));
407 utils
.writeInt(st
, Byte(mBlending
));
408 utils
.writeInt(st
, Byte(mSpeed
));
409 utils
.writeBool(st
, mLoop
);
410 utils
.writeBool(st
, mEnabled
);
411 utils
.writeInt(st
, Byte(mMinLength
));
412 utils
.writeBool(st
, mRevert
);
416 procedure TAnimState
.loadState (st
: TStream
; out mAlpha
: Byte; out mBlending
: Boolean);
418 if (st
= nil) then exit
;
420 if not utils
.checkSign(st
, 'ANIM') then raise XStreamError
.Create('animation chunk expected');
421 if (utils
.readByte(st
) <> 0) then raise XStreamError
.Create('invalid animation chunk version');
422 mCounter
:= utils
.readByte(st
);
423 mCurrentFrame
:= utils
.readLongInt(st
);
424 mPlayed
:= utils
.readBool(st
);
425 mAlpha
:= utils
.readByte(st
);
426 mBlending
:= utils
.readBool(st
);
427 mSpeed
:= utils
.readByte(st
);
428 mLoop
:= utils
.readBool(st
);
429 mEnabled
:= utils
.readBool(st
);
430 mMinLength
:= utils
.readByte(st
);
431 mRevert
:= utils
.readBool(st
);