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, either version 3 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 e_graphics
, BinEditor
, ImagingTypes
, Imaging
, ImagingUtility
;
25 TLevelTexture
= record
30 False: (TextureID
: DWORD
;);
31 True: (FramesID
: DWORD
;
36 TLevelTextureArray
= Array of TLevelTexture
;
38 TAnimation
= class(TObject
)
43 FCounter
: Byte; // Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè
44 FSpeed
: Byte; // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè
45 FCurrentFrame
: Integer; // Òåêóùèé êàäð (íà÷èíàÿ ñ 0)
46 FLoop
: Boolean; // Ïåðåõîäèòü íà ïåðâûé êàäð ïîñëå ïîñëåäíåãî?
47 FEnabled
: Boolean; // Ðàáîòà ðàçðåøåíà?
48 FPlayed
: Boolean; // Ïðîèãðàíà âñÿ õîòÿ áû ðàç?
51 FMinLength
: Byte; // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ
52 FRevert
: Boolean; // Ñìåíà êàäðîâ îáðàòíàÿ?
55 constructor Create(FramesID
: DWORD
; Loop
: Boolean; Speed
: Byte);
56 destructor Destroy(); override;
57 procedure Draw(X
, Y
: Integer; Mirror
: TMirrorType
);
58 procedure DrawEx(X
, Y
: Integer; Mirror
: TMirrorType
; RPoint
: TPoint
;
64 procedure Revert(r
: Boolean);
65 procedure SaveState(Var Mem
: TBinMemoryWriter
);
66 procedure LoadState(Var Mem
: TBinMemoryReader
);
67 function TotalFrames(): Integer;
69 property Played
: Boolean read FPlayed
;
70 property Enabled
: Boolean read FEnabled
;
71 property IsReverse
: Boolean read FRevert
;
72 property Loop
: Boolean read FLoop write FLoop
;
73 property Speed
: Byte read FSpeed write FSpeed
;
74 property MinLength
: Byte read FMinLength write FMinLength
;
75 property CurrentFrame
: Integer read FCurrentFrame write FCurrentFrame
;
76 property CurrentCounter
: Byte read FCounter write FCounter
;
77 property Counter
: Byte read FCounter
;
78 property Blending
: Boolean read FBlending write FBlending
;
79 property Alpha
: Byte read FAlpha write FAlpha
;
80 property FramesID
: DWORD read ID
;
81 property Width
: Word read FWidth
;
82 property Height
: Word read FHeight
;
85 function g_Texture_CreateWAD(var ID
: DWORD
; Resource
: String): Boolean;
86 function g_Texture_CreateFile(var ID
: DWORD
; FileName
: String): Boolean;
87 function g_Texture_CreateWADEx(TextureName
: ShortString; Resource
: String): Boolean;
88 function g_Texture_CreateFileEx(TextureName
: ShortString; FileName
: String): Boolean;
89 function g_Texture_Get(TextureName
: ShortString; var ID
: DWORD
): Boolean;
90 procedure g_Texture_Delete(TextureName
: ShortString);
91 procedure g_Texture_DeleteAll();
93 function g_CreateFramesImg (ia
: TDynImageDataArray
; ID
: PDWORD
; Name
: ShortString; BackAnimation
: Boolean = False): Boolean;
95 function g_Frames_CreateWAD(ID
: PDWORD
; Name
: ShortString; Resource
: String;
96 FWidth
, FHeight
, FCount
: Word; BackAnimation
: Boolean = False): Boolean;
97 function g_Frames_CreateFile(ID
: PDWORD
; Name
: ShortString; FileName
: String;
98 FWidth
, FHeight
, FCount
: Word; BackAnimation
: Boolean = False): Boolean;
99 function g_Frames_CreateMemory(ID
: PDWORD
; Name
: ShortString; pData
: Pointer; dataSize
: LongInt;
100 FWidth
, FHeight
, FCount
: Word; BackAnimation
: Boolean = False): Boolean;
101 //function g_Frames_CreateRevert(ID: PDWORD; Name: ShortString; Frames: string): Boolean;
102 function g_Frames_Get(var ID
: DWORD
; FramesName
: ShortString): Boolean;
103 function g_Frames_GetTexture(var ID
: DWORD
; FramesName
: ShortString; Frame
: Word): Boolean;
104 function g_Frames_Exists(FramesName
: String): Boolean;
105 procedure g_Frames_DeleteByName(FramesName
: ShortString);
106 procedure g_Frames_DeleteByID(ID
: DWORD
);
107 procedure g_Frames_DeleteAll();
109 procedure DumpTextureNames();
114 g_game
, e_log
, g_basic
, SysUtils
, g_console
, wadreader
,
125 TexturesID
: Array of DWORD
;
132 TexturesArray
: Array of _TTexture
= nil;
133 FramesArray
: Array of TFrames
= nil;
136 ANIM_SIGNATURE
= $4D494E41; // 'ANIM'
138 function FindTexture(): DWORD
;
142 if TexturesArray
<> nil then
143 for i
:= 0 to High(TexturesArray
) do
144 if TexturesArray
[i
].Name
= '' then
150 if TexturesArray
= nil then
152 SetLength(TexturesArray
, 8);
157 Result
:= High(TexturesArray
) + 1;
158 SetLength(TexturesArray
, Length(TexturesArray
) + 8);
162 function g_Texture_CreateWAD(var ID
: DWORD
; Resource
: String): Boolean;
166 TextureData
: Pointer;
167 ResourceLength
: Integer;
170 FileName
:= g_ExtractWadName(Resource
);
172 WAD
:= TWADFile
.Create
;
173 WAD
.ReadFile(FileName
);
175 if WAD
.GetResource(g_ExtractFilePathName(Resource
), TextureData
, ResourceLength
) then
177 if e_CreateTextureMem(TextureData
, ResourceLength
, ID
) then
180 FreeMem(TextureData
);
184 e_WriteLog(Format('Error loading texture %s', [Resource
]), MSG_WARNING
);
185 //e_WriteLog(Format('WAD Reader error: %s', [WAD.GetLastErrorStr]), MSG_WARNING);
190 function g_Texture_CreateFile(var ID
: DWORD
; FileName
: String): Boolean;
193 if not e_CreateTexture(FileName
, ID
) then
195 e_WriteLog(Format('Error loading texture %s', [FileName
]), MSG_WARNING
);
200 function g_Texture_CreateWADEx(TextureName
: ShortString; Resource
: String): Boolean;
204 TextureData
: Pointer;
206 ResourceLength
: Integer;
208 FileName
:= g_ExtractWadName(Resource
);
210 find_id
:= FindTexture();
212 WAD
:= TWADFile
.Create
;
213 WAD
.ReadFile(FileName
);
215 if WAD
.GetResource(g_ExtractFilePathName(Resource
), TextureData
, ResourceLength
) then
217 Result
:= e_CreateTextureMem(TextureData
, ResourceLength
, TexturesArray
[find_id
].ID
);
220 e_GetTextureSize(TexturesArray
[find_id
].ID
, @TexturesArray
[find_id
].Width
,
221 @TexturesArray
[find_id
].Height
);
222 TexturesArray
[find_id
].Name
:= LowerCase(TextureName
);
225 FreeMem(TextureData
);
229 e_WriteLog(Format('Error loading texture %s', [Resource
]), MSG_WARNING
);
230 //e_WriteLog(Format('WAD Reader error: %s', [WAD.GetLastErrorStr]), MSG_WARNING);
236 function g_Texture_CreateFileEx(TextureName
: ShortString; FileName
: String): Boolean;
240 find_id
:= FindTexture
;
242 Result
:= e_CreateTexture(FileName
, TexturesArray
[find_id
].ID
);
245 TexturesArray
[find_id
].Name
:= LowerCase(TextureName
);
246 e_GetTextureSize(TexturesArray
[find_id
].ID
, @TexturesArray
[find_id
].Width
,
247 @TexturesArray
[find_id
].Height
);
249 else e_WriteLog(Format('Error loading texture %s', [FileName
]), MSG_WARNING
);
252 function g_Texture_Get(TextureName
: ShortString; var ID
: DWORD
): Boolean;
258 if TexturesArray
= nil then Exit
;
260 if TextureName
= '' then Exit
;
262 TextureName
:= LowerCase(TextureName
);
264 for a
:= 0 to High(TexturesArray
) do
265 if TexturesArray
[a
].Name
= TextureName
then
267 ID
:= TexturesArray
[a
].ID
;
272 //if not Result then g_ConsoleAdd('Texture '+TextureName+' not found');
275 procedure g_Texture_Delete(TextureName
: ShortString);
279 if TexturesArray
= nil then Exit
;
281 TextureName
:= LowerCase(TextureName
);
283 for a
:= 0 to High(TexturesArray
) do
284 if TexturesArray
[a
].Name
= TextureName
then
286 e_DeleteTexture(TexturesArray
[a
].ID
);
287 TexturesArray
[a
].Name
:= '';
288 TexturesArray
[a
].ID
:= 0;
289 TexturesArray
[a
].Width
:= 0;
290 TexturesArray
[a
].Height
:= 0;
294 procedure g_Texture_DeleteAll();
298 if TexturesArray
= nil then Exit
;
300 for a
:= 0 to High(TexturesArray
) do
301 if TexturesArray
[a
].Name
<> '' then
302 e_DeleteTexture(TexturesArray
[a
].ID
);
304 TexturesArray
:= nil;
307 function FindFrame(): DWORD
;
311 if FramesArray
<> nil then
312 for i
:= 0 to High(FramesArray
) do
313 if FramesArray
[i
].TexturesID
= nil then
319 if FramesArray
= nil then
321 SetLength(FramesArray
, 64);
326 Result
:= High(FramesArray
) + 1;
327 SetLength(FramesArray
, Length(FramesArray
) + 64);
331 function g_Frames_CreateFile(ID
: PDWORD
; Name
: ShortString; FileName
: String;
332 FWidth
, FHeight
, FCount
: Word; BackAnimation
: Boolean = False): Boolean;
339 find_id
:= FindFrame
;
341 if FCount
<= 2 then BackAnimation
:= False;
343 if BackAnimation
then SetLength(FramesArray
[find_id
].TexturesID
, FCount
+FCount
-2)
344 else SetLength(FramesArray
[find_id
].TexturesID
, FCount
);
346 for a
:= 0 to FCount
-1 do
347 if not e_CreateTextureEx(FileName
, FramesArray
[find_id
].TexturesID
[a
],
348 a
*FWidth
, 0, FWidth
, FHeight
) then Exit
;
350 if BackAnimation
then
351 for a
:= 1 to FCount
-2 do
352 FramesArray
[find_id
].TexturesID
[FCount
+FCount
-2-a
] := FramesArray
[find_id
].TexturesID
[a
];
354 FramesArray
[find_id
].FrameWidth
:= FWidth
;
355 FramesArray
[find_id
].FrameHeight
:= FHeight
;
357 FramesArray
[find_id
].Name
:= LowerCase(Name
)
359 FramesArray
[find_id
].Name
:= '<noname>';
361 if ID
<> nil then ID
^ := find_id
;
366 function CreateFramesMem(pData
: Pointer; dataSize
: LongInt; ID
: PDWORD
; Name
: ShortString;
367 FWidth
, FHeight
, FCount
: Word; BackAnimation
: Boolean = False): Boolean;
374 find_id
:= FindFrame();
376 if FCount
<= 2 then BackAnimation
:= False;
378 if BackAnimation
then SetLength(FramesArray
[find_id
].TexturesID
, FCount
+FCount
-2)
379 else SetLength(FramesArray
[find_id
].TexturesID
, FCount
);
381 for a
:= 0 to FCount
-1 do
382 if not e_CreateTextureMemEx(pData
, dataSize
, FramesArray
[find_id
].TexturesID
[a
],
383 a
*FWidth
, 0, FWidth
, FHeight
) then
389 if BackAnimation
then
390 for a
:= 1 to FCount
-2 do
391 FramesArray
[find_id
].TexturesID
[FCount
+FCount
-2-a
] := FramesArray
[find_id
].TexturesID
[a
];
393 FramesArray
[find_id
].FrameWidth
:= FWidth
;
394 FramesArray
[find_id
].FrameHeight
:= FHeight
;
396 FramesArray
[find_id
].Name
:= LowerCase(Name
)
398 FramesArray
[find_id
].Name
:= '<noname>';
400 if ID
<> nil then ID
^ := find_id
;
405 function g_CreateFramesImg (ia
: TDynImageDataArray
; ID
: PDWORD
; Name
: ShortString; BackAnimation
: Boolean = False): Boolean;
411 find_id
:= FindFrame();
413 FCount
:= length(ia
);
415 //e_WriteLog(Format('+++ creating %d frames [%s]', [FCount, Name]), MSG_NOTIFY);
417 if FCount
< 1 then exit
;
418 if FCount
<= 2 then BackAnimation
:= False;
419 if BackAnimation
then
420 SetLength(FramesArray
[find_id
].TexturesID
, FCount
+FCount
-2)
422 SetLength(FramesArray
[find_id
].TexturesID
, FCount
);
424 //e_WriteLog(Format('+++ creating %d frames, %dx%d', [FCount, ia[0].width, ia[0].height]), MSG_NOTIFY);
426 for a
:= 0 to FCount
-1 do
428 if not e_CreateTextureImg(ia
[a
], FramesArray
[find_id
].TexturesID
[a
]) then exit
;
429 //e_WriteLog(Format('+++ frame %d, %dx%d', [a, ia[a].width, ia[a].height]), MSG_NOTIFY);
432 if BackAnimation
then
434 for a
:= 1 to FCount
-2 do
436 FramesArray
[find_id
].TexturesID
[FCount
+FCount
-2-a
] := FramesArray
[find_id
].TexturesID
[a
];
440 FramesArray
[find_id
].FrameWidth
:= ia
[0].width
;
441 FramesArray
[find_id
].FrameHeight
:= ia
[0].height
;
443 FramesArray
[find_id
].Name
:= LowerCase(Name
)
445 FramesArray
[find_id
].Name
:= '<noname>';
447 if ID
<> nil then ID
^ := find_id
;
452 function g_Frames_CreateWAD(ID
: PDWORD
; Name
: ShortString; Resource
: string;
453 FWidth
, FHeight
, FCount
: Word; BackAnimation
: Boolean = False): Boolean;
457 TextureData
: Pointer;
458 ResourceLength
: Integer;
462 FileName
:= g_ExtractWadName(Resource
);
464 WAD
:= TWADFile
.Create();
465 WAD
.ReadFile(FileName
);
467 if not WAD
.GetResource(g_ExtractFilePathName(Resource
), TextureData
, ResourceLength
) then
470 e_WriteLog(Format('Error loading texture %s', [Resource
]), MSG_WARNING
);
471 //e_WriteLog(Format('WAD Reader error: %s', [WAD.GetLastErrorStr]), MSG_WARNING);
475 if not CreateFramesMem(TextureData
, ResourceLength
, ID
, Name
, FWidth
, FHeight
, FCount
, BackAnimation
) then
486 function g_Frames_CreateMemory(ID
: PDWORD
; Name
: ShortString; pData
: Pointer; dataSize
: LongInt;
487 FWidth
, FHeight
, FCount
: Word; BackAnimation
: Boolean = False): Boolean;
489 Result
:= CreateFramesMem(pData
, dataSize
, ID
, Name
, FWidth
, FHeight
, FCount
, BackAnimation
);
492 {function g_Frames_CreateRevert(ID: PDWORD; Name: ShortString; Frames: string): Boolean;
499 if not g_Frames_Get(b, Frames) then Exit;
501 find_id := FindFrame();
503 FramesArray[find_id].Name := Name;
504 FramesArray[find_id].FrameWidth := FramesArray[b].FrameWidth;
505 FramesArray[find_id].FrameHeight := FramesArray[b].FrameHeight;
507 c := High(FramesArray[find_id].TexturesID);
510 FramesArray[find_id].TexturesID[a] := FramesArray[b].TexturesID[c-a];
515 procedure g_Frames_DeleteByName(FramesName
: ShortString);
520 if FramesArray
= nil then Exit
;
522 FramesName
:= LowerCase(FramesName
);
524 for a
:= 0 to High(FramesArray
) do
525 if FramesArray
[a
].Name
= FramesName
then
527 if FramesArray
[a
].TexturesID
<> nil then
528 for b
:= 0 to High(FramesArray
[a
].TexturesID
) do
529 e_DeleteTexture(FramesArray
[a
].TexturesID
[b
]);
530 FramesArray
[a
].TexturesID
:= nil;
531 FramesArray
[a
].Name
:= '';
532 FramesArray
[a
].FrameWidth
:= 0;
533 FramesArray
[a
].FrameHeight
:= 0;
537 procedure g_Frames_DeleteByID(ID
: DWORD
);
541 if FramesArray
= nil then Exit
;
543 if FramesArray
[ID
].TexturesID
<> nil then
544 for b
:= 0 to High(FramesArray
[ID
].TexturesID
) do
545 e_DeleteTexture(FramesArray
[ID
].TexturesID
[b
]);
546 FramesArray
[ID
].TexturesID
:= nil;
547 FramesArray
[ID
].Name
:= '';
548 FramesArray
[ID
].FrameWidth
:= 0;
549 FramesArray
[ID
].FrameHeight
:= 0;
552 procedure g_Frames_DeleteAll
;
557 if FramesArray
= nil then Exit
;
559 for a
:= 0 to High(FramesArray
) do
560 if FramesArray
[a
].TexturesID
<> nil then
562 for b
:= 0 to High(FramesArray
[a
].TexturesID
) do
563 e_DeleteTexture(FramesArray
[a
].TexturesID
[b
]);
564 FramesArray
[a
].TexturesID
:= nil;
565 FramesArray
[a
].Name
:= '';
566 FramesArray
[a
].FrameWidth
:= 0;
567 FramesArray
[a
].FrameHeight
:= 0;
573 function g_Frames_Get(var ID
: DWORD
; FramesName
: ShortString): Boolean;
579 if FramesArray
= nil then
582 FramesName
:= LowerCase(FramesName
);
584 for a
:= 0 to High(FramesArray
) do
585 if FramesArray
[a
].Name
= FramesName
then
593 g_FatalError(Format(_lc
[I_GAME_ERROR_FRAMES
], [FramesName
]));
596 function g_Frames_GetTexture(var ID
: DWORD
; FramesName
: ShortString; Frame
: Word): Boolean;
602 if FramesArray
= nil then
605 FramesName
:= LowerCase(FramesName
);
607 for a
:= 0 to High(FramesArray
) do
608 if FramesArray
[a
].Name
= FramesName
then
609 if Frame
<= High(FramesArray
[a
].TexturesID
) then
611 ID
:= FramesArray
[a
].TexturesID
[Frame
];
617 g_FatalError(Format(_lc
[I_GAME_ERROR_FRAMES
], [FramesName
]));
620 function g_Frames_Exists(FramesName
: string): Boolean;
626 if FramesArray
= nil then Exit
;
628 FramesName
:= LowerCase(FramesName
);
630 for a
:= 0 to High(FramesArray
) do
631 if FramesArray
[a
].Name
= FramesName
then
638 procedure DumpTextureNames();
642 e_WriteLog('BEGIN Textures:', MSG_NOTIFY
);
643 for i
:= 0 to High(TexturesArray
) do
644 e_WriteLog(' '+IntToStr(i
)+'. '+TexturesArray
[i
].Name
, MSG_NOTIFY
);
645 e_WriteLog('END Textures.', MSG_NOTIFY
);
647 e_WriteLog('BEGIN Frames:', MSG_NOTIFY
);
648 for i
:= 0 to High(FramesArray
) do
649 e_WriteLog(' '+IntToStr(i
)+'. '+FramesArray
[i
].Name
, MSG_NOTIFY
);
650 e_WriteLog('END Frames.', MSG_NOTIFY
);
655 constructor TAnimation
.Create(FramesID
: DWORD
; Loop
: Boolean; Speed
: Byte);
666 FWidth
:= FramesArray
[ID
].FrameWidth
;
667 FHeight
:= FramesArray
[ID
].FrameHeight
;
670 destructor TAnimation
.Destroy
;
675 procedure TAnimation
.Draw(X
, Y
: Integer; Mirror
: TMirrorType
);
680 e_DrawAdv(FramesArray
[ID
].TexturesID
[FCurrentFrame
], X
, Y
, FAlpha
,
681 True, FBlending
, 0, nil, Mirror
);
682 //e_DrawQuad(X, Y, X+FramesArray[ID].FrameWidth-1, Y+FramesArray[ID].FrameHeight-1, 0, 255, 0);
685 procedure TAnimation
.Update();
690 FCounter
:= FCounter
+ 1;
692 if FCounter
>= FSpeed
then
693 begin // Îæèäàíèå ìåæäó êàäðàìè çàêîí÷èëîñü
695 begin // Îáðàòíûé ïîðÿäîê êàäðîâ
696 // Äîøëè äî êîíöà àíèìàöèè. Âîçìîæíî, æäåì åùå:
697 if FCurrentFrame
= 0 then
698 if Length(FramesArray
[ID
].TexturesID
) * FSpeed
+
699 FCounter
< FMinLength
then
702 FCurrentFrame
:= FCurrentFrame
- 1;
703 FPlayed
:= FCurrentFrame
< 0;
705 // Ïîâòîðÿòü ëè àíèìàöèþ ïî êðóãó:
708 FCurrentFrame
:= High(FramesArray
[ID
].TexturesID
)
710 FCurrentFrame
:= FCurrentFrame
+ 1;
715 begin // Ïðÿìîé ïîðÿäîê êàäðîâ
716 // Äîøëè äî êîíöà àíèìàöèè. Âîçìîæíî, æäåì åùå:
717 if FCurrentFrame
= High(FramesArray
[ID
].TexturesID
) then
718 if Length(FramesArray
[ID
].TexturesID
) * FSpeed
+
719 FCounter
< FMinLength
then
722 FCurrentFrame
:= FCurrentFrame
+ 1;
723 FPlayed
:= (FCurrentFrame
> High(FramesArray
[ID
].TexturesID
));
725 // Ïîâòîðÿòü ëè àíèìàöèþ ïî êðóãó:
730 FCurrentFrame
:= FCurrentFrame
- 1;
737 procedure TAnimation
.Reset();
740 FCurrentFrame
:= High(FramesArray
[ID
].TexturesID
)
748 procedure TAnimation
.Disable
;
753 procedure TAnimation
.Enable
;
758 procedure TAnimation
.DrawEx(X
, Y
: Integer; Mirror
: TMirrorType
; RPoint
: TPoint
;
764 e_DrawAdv(FramesArray
[ID
].TexturesID
[FCurrentFrame
], X
, Y
, FAlpha
,
765 True, FBlending
, Angle
, @RPoint
, Mirror
);
768 function TAnimation
.TotalFrames(): Integer;
770 Result
:= Length(FramesArray
[ID
].TexturesID
);
773 procedure TAnimation
.Revert(r
: Boolean);
779 procedure TAnimation
.SaveState(Var Mem
: TBinMemoryWriter
);
786 // Ñèãíàòóðà àíèìàöèè:
787 sig
:= ANIM_SIGNATURE
; // 'ANIM'
789 // Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè:
790 Mem
.WriteByte(FCounter
);
792 Mem
.WriteInt(FCurrentFrame
);
793 // Ïðîèãðàíà ëè àíèìàöèÿ öåëèêîì:
794 Mem
.WriteBoolean(FPlayed
);
795 // Alpha-êàíàë âñåé òåêñòóðû:
796 Mem
.WriteByte(FAlpha
);
797 // Ðàçìûòèå òåêñòóðû:
798 Mem
.WriteBoolean(FBlending
);
799 // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè:
800 Mem
.WriteByte(FSpeed
);
801 // Çàöèêëåíà ëè àíèìàöèÿ:
802 Mem
.WriteBoolean(FLoop
);
804 Mem
.WriteBoolean(FEnabled
);
805 // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ:
806 Mem
.WriteByte(FMinLength
);
807 // Îáðàòíûé ëè ïîðÿäîê êàäðîâ:
808 Mem
.WriteBoolean(FRevert
);
811 procedure TAnimation
.LoadState(Var Mem
: TBinMemoryReader
);
818 // Ñèãíàòóðà àíèìàöèè:
820 if sig
<> ANIM_SIGNATURE
then // 'ANIM'
822 raise EBinSizeError
.Create('TAnimation.LoadState: Wrong Animation Signature');
824 // Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè:
825 Mem
.ReadByte(FCounter
);
827 Mem
.ReadInt(FCurrentFrame
);
828 // Ïðîèãðàíà ëè àíèìàöèÿ öåëèêîì:
829 Mem
.ReadBoolean(FPlayed
);
830 // Alpha-êàíàë âñåé òåêñòóðû:
831 Mem
.ReadByte(FAlpha
);
832 // Ðàçìûòèå òåêñòóðû:
833 Mem
.ReadBoolean(FBlending
);
834 // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè:
835 Mem
.ReadByte(FSpeed
);
836 // Çàöèêëåíà ëè àíèìàöèÿ:
837 Mem
.ReadBoolean(FLoop
);
839 Mem
.ReadBoolean(FEnabled
);
840 // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ:
841 Mem
.ReadByte(FMinLength
);
842 // Îáðàòíûé ëè ïîðÿäîê êàäðîâ:
843 Mem
.ReadBoolean(FRevert
);