X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;ds=sidebyside;f=src%2Fgame%2Fg_textures.pas;h=16b0655a01dbcd0f81117770a592c9104fa1d027;hb=483304f6afb4ad7d8b16624ce835cbae9a60bb3a;hp=613419e21e451e1f0793126bdbf9c67fe174eaf3;hpb=8b87c4d3552073bc1dd71381553fa9973adbe260;p=d2df-sdl.git
diff --git a/src/game/g_textures.pas b/src/game/g_textures.pas
index 613419e..16b0655 100644
--- a/src/game/g_textures.pas
+++ b/src/game/g_textures.pas
@@ -1,831 +1,435 @@
-{$MODE DELPHI}
+(* Copyright (C) Doom 2D: Forever Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License ONLY.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *)
+{$INCLUDE ../shared/a_modes.inc}
unit g_textures;
interface
uses
- e_graphics, BinEditor, ImagingTypes, Imaging, ImagingUtility;
+ SysUtils, Classes,
+ {$IFDEF USE_MEMPOOL}mempool,{$ENDIF}
+ g_base, MAPDEF;
-Type
+type
TLevelTexture = record
- TextureName: String;
- Width,
- Height: Word;
- case Anim: Boolean of
- False: (TextureID: DWORD;);
- True: (FramesID: DWORD;
- FramesCount: Byte;
- Speed: Byte);
+ TextureName: AnsiString; // as stored in wad
+ FullName: AnsiString; // full path to texture // !!! merge it with TextureName
+ framesCount, speed: Byte;
end;
- TLevelTextureArray = Array of TLevelTexture;
+ TLevelTextureArray = array of TLevelTexture;
- TAnimation = class(TObject)
+ TAnimationState = class{$IFDEF USE_MEMPOOL}(TPoolObject){$ENDIF}
private
- ID: DWORD;
- FAlpha: Byte;
- FBlending: Boolean;
- FCounter: Byte; // Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè
- FSpeed: Byte; // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè
- FCurrentFrame: Integer; // Òåêóùèé êàäð (íà÷èíàÿ ñ 0)
- FLoop: Boolean; // Ïåðåõîäèòü íà ïåðâûé êàäð ïîñëå ïîñëåäíåãî?
- FEnabled: Boolean; // Ðàáîòà ðàçðåøåíà?
- FPlayed: Boolean; // Ïðîèãðàíà âñÿ õîòÿ áû ðàç?
- FHeight: Word;
- FWidth: Word;
- FMinLength: Byte; // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ
- FRevert: Boolean; // Ñìåíà êàäðîâ îáðàòíàÿ?
+ mCounter: Byte; // Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè
+ mSpeed: Byte; // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè
+ mCurrentFrame: Integer; // Òåêóùèé êàäð (íà÷èíàÿ ñ 0)
+ mLoop: Boolean; // Ïåðåõîäèòü íà ïåðâûé êàäð ïîñëå ïîñëåäíåãî?
+ mEnabled: Boolean; // Ðàáîòà ðàçðåøåíà?
+ mPlayed: Boolean; // Ïðîèãðàíà âñÿ õîòÿ áû ðàç?
+ mMinLength: Byte; // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ
+ mRevert: Boolean; // Ñìåíà êàäðîâ îáðàòíàÿ?
+
+ mLength: Integer;
public
- constructor Create(FramesID: DWORD; Loop: Boolean; Speed: Byte);
- destructor Destroy(); override;
- procedure Draw(X, Y: Integer; Mirror: TMirrorType);
- procedure DrawEx(X, Y: Integer; Mirror: TMirrorType; RPoint: TPoint;
- Angle: SmallInt);
- procedure Reset();
- procedure Update();
- procedure Enable();
- procedure Disable();
- procedure Revert(r: Boolean);
- procedure SaveState(Var Mem: TBinMemoryWriter);
- procedure LoadState(Var Mem: TBinMemoryReader);
- function TotalFrames(): Integer;
-
- property Played: Boolean read FPlayed;
- property Enabled: Boolean read FEnabled;
- property IsReverse: Boolean read FRevert;
- property Loop: Boolean read FLoop write FLoop;
- property Speed: Byte read FSpeed write FSpeed;
- property MinLength: Byte read FMinLength write FMinLength;
- property CurrentFrame: Integer read FCurrentFrame write FCurrentFrame;
- property CurrentCounter: Byte read FCounter write FCounter;
- property Counter: Byte read FCounter;
- property Blending: Boolean read FBlending write FBlending;
- property Alpha: Byte read FAlpha write FAlpha;
- property FramesID: DWORD read ID;
- property Width: Word read FWidth;
- property Height: Word read FHeight;
- end;
+ constructor Create (aloop: Boolean; aspeed: Byte; len: Integer);
+ destructor Destroy (); override;
-function g_Texture_CreateWAD(var ID: DWORD; Resource: String): Boolean;
-function g_Texture_CreateFile(var ID: DWORD; FileName: String): Boolean;
-function g_Texture_CreateWADEx(TextureName: ShortString; Resource: String): Boolean;
-function g_Texture_CreateFileEx(TextureName: ShortString; FileName: String): Boolean;
-function g_Texture_Get(TextureName: ShortString; var ID: DWORD): Boolean;
-procedure g_Texture_Delete(TextureName: ShortString);
-procedure g_Texture_DeleteAll();
-
-function g_CreateFramesImg (ia: TDynImageDataArray; ID: PDWORD; Name: ShortString; BackAnimation: Boolean = False): Boolean;
-
-function g_Frames_CreateWAD(ID: PDWORD; Name: ShortString; Resource: String;
- FWidth, FHeight, FCount: Word; BackAnimation: Boolean = False): Boolean;
-function g_Frames_CreateFile(ID: PDWORD; Name: ShortString; FileName: String;
- FWidth, FHeight, FCount: Word; BackAnimation: Boolean = False): Boolean;
-function g_Frames_CreateMemory(ID: PDWORD; Name: ShortString; pData: Pointer; dataSize: LongInt;
- FWidth, FHeight, FCount: Word; BackAnimation: Boolean = False): Boolean;
-//function g_Frames_CreateRevert(ID: PDWORD; Name: ShortString; Frames: string): Boolean;
-function g_Frames_Get(var ID: DWORD; FramesName: ShortString): Boolean;
-function g_Frames_GetTexture(var ID: DWORD; FramesName: ShortString; Frame: Word): Boolean;
-function g_Frames_Exists(FramesName: String): Boolean;
-procedure g_Frames_DeleteByName(FramesName: ShortString);
-procedure g_Frames_DeleteByID(ID: DWORD);
-procedure g_Frames_DeleteAll();
-
-procedure DumpTextureNames();
+ procedure reset ();
+ procedure update ();
+ procedure enable ();
+ procedure disable ();
+ procedure revert (r: Boolean);
-implementation
+ procedure saveState (st: TStream; mAlpha: Byte; mBlending: Boolean);
+ procedure loadState (st: TStream; out mAlpha: Byte; out mBlending: Boolean);
-uses
- g_game, e_log, g_basic, SysUtils, g_console, wadreader,
- g_language;
+ function totalFrames (): Integer; inline;
-type
- _TTexture = record
- Name: ShortString;
- ID: DWORD;
- Width, Height: Word;
- end;
-
- TFrames = record
- TexturesID: Array of DWORD;
- Name: ShortString;
- FrameWidth,
- FrameHeight: Word;
+ public
+ property played: Boolean read mPlayed;
+ property enabled: Boolean read mEnabled;
+ property isReverse: Boolean read mRevert;
+ property loop: Boolean read mLoop write mLoop;
+ property speed: Byte read mSpeed write mSpeed;
+ property minLength: Byte read mMinLength write mMinLength;
+ property currentFrame: Integer read mCurrentFrame write mCurrentFrame;
+ property currentCounter: Byte read mCounter write mCounter;
+ property counter: Byte read mCounter;
+ property length: Integer read mLength;
end;
-var
- TexturesArray: Array of _TTexture = nil;
- FramesArray: Array of TFrames = nil;
+ TAnimState = record
+ private
+ mCounter: Byte; // Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè
+ mSpeed: Byte; // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè
+ mCurrentFrame: Integer; // Òåêóùèé êàäð (íà÷èíàÿ ñ 0)
+ mLoop: Boolean; // Ïåðåõîäèòü íà ïåðâûé êàäð ïîñëå ïîñëåäíåãî?
+ mEnabled: Boolean; // Ðàáîòà ðàçðåøåíà?
+ mPlayed: Boolean; // Ïðîèãðàíà âñÿ õîòÿ áû ðàç?
+ mMinLength: Byte; // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ
+ mRevert: Boolean; // Ñìåíà êàäðîâ îáðàòíàÿ?
-const
- ANIM_SIGNATURE = $4D494E41; // 'ANIM'
+ mLength: Integer;
-function FindTexture(): DWORD;
-var
- i: integer;
-begin
- if TexturesArray <> nil then
- for i := 0 to High(TexturesArray) do
- if TexturesArray[i].Name = '' then
- begin
- Result := i;
- Exit;
- end;
+ public
+ constructor Create (aloop: Boolean; aspeed: Byte; len: Integer);
+ procedure Invalidate;
- if TexturesArray = nil then
- begin
- SetLength(TexturesArray, 8);
- Result := 0;
- end
- else
- begin
- Result := High(TexturesArray) + 1;
- SetLength(TexturesArray, Length(TexturesArray) + 8);
- end;
-end;
+ procedure reset ();
+ procedure update ();
+ procedure enable ();
+ procedure disable ();
+ procedure revert (r: Boolean);
-function g_Texture_CreateWAD(var ID: DWORD; Resource: String): Boolean;
-var
- WAD: TWADFile;
- FileName: String;
- TextureData: Pointer;
- ResourceLength: Integer;
-begin
- Result := False;
- FileName := g_ExtractWadName(Resource);
+ procedure saveState (st: TStream; mAlpha: Byte; mBlending: Boolean);
+ procedure loadState (st: TStream; out mAlpha: Byte; out mBlending: Boolean);
- WAD := TWADFile.Create;
- WAD.ReadFile(FileName);
+ function totalFrames (): Integer; inline;
+ function IsInvalid (): Boolean;
+ function IsValid (): Boolean;
- if WAD.GetResource(g_ExtractFilePathName(Resource), TextureData, ResourceLength) then
- begin
- if e_CreateTextureMem(TextureData, ResourceLength, ID) then
- Result := True
- else
- FreeMem(TextureData);
- end
- else
- begin
- e_WriteLog(Format('Error loading texture %s', [Resource]), MSG_WARNING);
- //e_WriteLog(Format('WAD Reader error: %s', [WAD.GetLastErrorStr]), MSG_WARNING);
- end;
- WAD.Free();
-end;
-
-function g_Texture_CreateFile(var ID: DWORD; FileName: String): Boolean;
-begin
- Result := True;
- if not e_CreateTexture(FileName, ID) then
- begin
- e_WriteLog(Format('Error loading texture %s', [FileName]), MSG_WARNING);
- Result := False;
+ public
+ property played: Boolean read mPlayed;
+ property enabled: Boolean read mEnabled;
+ property isReverse: Boolean read mRevert;
+ property loop: Boolean read mLoop write mLoop;
+ property speed: Byte read mSpeed write mSpeed;
+ property minLength: Byte read mMinLength write mMinLength;
+ property currentFrame: Integer read mCurrentFrame write mCurrentFrame;
+ property currentCounter: Byte read mCounter write mCounter;
+ property counter: Byte read mCounter;
+ property length: Integer read mLength;
end;
-end;
-function g_Texture_CreateWADEx(TextureName: ShortString; Resource: String): Boolean;
-var
- WAD: TWADFile;
- FileName: String;
- TextureData: Pointer;
- find_id: DWORD;
- ResourceLength: Integer;
-begin
- FileName := g_ExtractWadName(Resource);
+implementation
- find_id := FindTexture();
+uses
+ g_game, e_log, g_basic, g_console, wadreader,
+ g_language, utils, xstreams;
- WAD := TWADFile.Create;
- WAD.ReadFile(FileName);
+constructor TAnimationState.Create (aloop: Boolean; aspeed: Byte; len: Integer);
+begin
+ assert(len >= 0);
+ mLength := len;
- if WAD.GetResource(g_ExtractFilePathName(Resource), TextureData, ResourceLength) then
- begin
- Result := e_CreateTextureMem(TextureData, ResourceLength, TexturesArray[find_id].ID);
- if Result then
- begin
- e_GetTextureSize(TexturesArray[find_id].ID, @TexturesArray[find_id].Width,
- @TexturesArray[find_id].Height);
- TexturesArray[find_id].Name := LowerCase(TextureName);
- end
- else
- FreeMem(TextureData);
- end
- else
- begin
- e_WriteLog(Format('Error loading texture %s', [Resource]), MSG_WARNING);
- //e_WriteLog(Format('WAD Reader error: %s', [WAD.GetLastErrorStr]), MSG_WARNING);
- Result := False;
- end;
- WAD.Free();
+ mMinLength := 0;
+ mLoop := aloop;
+ mSpeed := aspeed;
+ mEnabled := true;
+ mCurrentFrame := 0;
+ mPlayed := false;
end;
-function g_Texture_CreateFileEx(TextureName: ShortString; FileName: String): Boolean;
-var
- find_id: DWORD;
+destructor TAnimationState.Destroy;
begin
- find_id := FindTexture;
-
- Result := e_CreateTexture(FileName, TexturesArray[find_id].ID);
- if Result then
- begin
- TexturesArray[find_id].Name := LowerCase(TextureName);
- e_GetTextureSize(TexturesArray[find_id].ID, @TexturesArray[find_id].Width,
- @TexturesArray[find_id].Height);
- end
- else e_WriteLog(Format('Error loading texture %s', [FileName]), MSG_WARNING);
+ inherited;
end;
-function g_Texture_Get(TextureName: ShortString; var ID: DWORD): Boolean;
-var
- a: DWORD;
+procedure TAnimationState.update;
begin
- Result := False;
-
- if TexturesArray = nil then Exit;
+ if (not mEnabled) then exit;
- if TextureName = '' then Exit;
+ mCounter += 1;
- TextureName := LowerCase(TextureName);
-
- for a := 0 to High(TexturesArray) do
- if TexturesArray[a].Name = TextureName then
+ if (mCounter >= mSpeed) then
+ begin
+ // Îæèäàíèå ìåæäó êàäðàìè çàêîí÷èëîñü
+ // Îáðàòíûé ïîðÿäîê êàäðîâ?
+ if mRevert then
begin
- ID := TexturesArray[a].ID;
- Result := True;
- Break;
- end;
-
- //if not Result then g_ConsoleAdd('Texture '+TextureName+' not found');
-end;
+ // Äîøëè äî êîíöà àíèìàöèè. Âîçìîæíî, æäåì åùå
+ if (mCurrentFrame = 0) then
+ begin
+ if (mLength * mSpeed + mCounter < mMinLength) then exit;
+ end;
-procedure g_Texture_Delete(TextureName: ShortString);
-var
- a: DWORD;
-begin
- if TexturesArray = nil then Exit;
+ mCurrentFrame -= 1;
+ mPlayed := (mCurrentFrame < 0);
- TextureName := LowerCase(TextureName);
+ // Ïîâòîðÿòü ëè àíèìàöèþ ïî êðóãó?
+ if mPlayed then
+ begin
+ if mLoop then
+ mCurrentFrame := mLength - 1
+ else
+ mCurrentFrame += 1
+ end;
- for a := 0 to High(TexturesArray) do
- if TexturesArray[a].Name = TextureName then
+ mCounter := 0;
+ end
+ else
begin
- e_DeleteTexture(TexturesArray[a].ID);
- TexturesArray[a].Name := '';
- TexturesArray[a].ID := 0;
- TexturesArray[a].Width := 0;
- TexturesArray[a].Height := 0;
- end;
-end;
-
-procedure g_Texture_DeleteAll();
-var
- a: DWORD;
-begin
- if TexturesArray = nil then Exit;
+ // Ïðÿìîé ïîðÿäîê êàäðîâ
+ // Äîøëè äî êîíöà àíèìàöèè. Âîçìîæíî, æäåì åùå
+ if (mCurrentFrame = mLength - 1) then
+ begin
+ if (mLength * mSpeed + mCounter < mMinLength) then exit;
+ end;
- for a := 0 to High(TexturesArray) do
- if TexturesArray[a].Name <> '' then
- e_DeleteTexture(TexturesArray[a].ID);
+ mCurrentFrame += 1;
+ mPlayed := (mCurrentFrame > mLength - 1);
- TexturesArray := nil;
-end;
-
-function FindFrame(): DWORD;
-var
- i: integer;
-begin
- if FramesArray <> nil then
- for i := 0 to High(FramesArray) do
- if FramesArray[i].TexturesID = nil then
+ // Ïîâòîðÿòü ëè àíèìàöèþ ïî êðóãó?
+ if mPlayed then
begin
- Result := i;
- Exit;
+ if mLoop then mCurrentFrame := 0 else mCurrentFrame -= 1;
end;
- if FramesArray = nil then
- begin
- SetLength(FramesArray, 64);
- Result := 0;
- end
- else
- begin
- Result := High(FramesArray) + 1;
- SetLength(FramesArray, Length(FramesArray) + 64);
+ mCounter := 0;
+ end;
end;
end;
-function g_Frames_CreateFile(ID: PDWORD; Name: ShortString; FileName: String;
- FWidth, FHeight, FCount: Word; BackAnimation: Boolean = False): Boolean;
-var
- a: Integer;
- find_id: DWORD;
+procedure TAnimationState.reset;
begin
- Result := False;
-
- find_id := FindFrame;
-
- if FCount <= 2 then BackAnimation := False;
-
- if BackAnimation then SetLength(FramesArray[find_id].TexturesID, FCount+FCount-2)
- else SetLength(FramesArray[find_id].TexturesID, FCount);
-
- for a := 0 to FCount-1 do
- if not e_CreateTextureEx(FileName, FramesArray[find_id].TexturesID[a],
- a*FWidth, 0, FWidth, FHeight) then Exit;
-
- if BackAnimation then
- for a := 1 to FCount-2 do
- FramesArray[find_id].TexturesID[FCount+FCount-2-a] := FramesArray[find_id].TexturesID[a];
-
- FramesArray[find_id].FrameWidth := FWidth;
- FramesArray[find_id].FrameHeight := FHeight;
- if Name <> '' then
- FramesArray[find_id].Name := LowerCase(Name)
+ if mRevert then
+ mCurrentFrame := mLength - 1
else
- FramesArray[find_id].Name := '';
-
- if ID <> nil then ID^ := find_id;
-
- Result := True;
+ mCurrentFrame := 0;
+ mCounter := 0;
+ mPlayed := false
end;
-function CreateFramesMem(pData: Pointer; dataSize: LongInt; ID: PDWORD; Name: ShortString;
- FWidth, FHeight, FCount: Word; BackAnimation: Boolean = False): Boolean;
-var
- find_id: DWORD;
- a: Integer;
+procedure TAnimationState.disable;
begin
- Result := False;
-
- find_id := FindFrame();
-
- if FCount <= 2 then BackAnimation := False;
-
- if BackAnimation then SetLength(FramesArray[find_id].TexturesID, FCount+FCount-2)
- else SetLength(FramesArray[find_id].TexturesID, FCount);
-
- for a := 0 to FCount-1 do
- if not e_CreateTextureMemEx(pData, dataSize, FramesArray[find_id].TexturesID[a],
- a*FWidth, 0, FWidth, FHeight) then
- begin
- FreeMem(pData);
- Exit;
- end;
-
- if BackAnimation then
- for a := 1 to FCount-2 do
- FramesArray[find_id].TexturesID[FCount+FCount-2-a] := FramesArray[find_id].TexturesID[a];
-
- FramesArray[find_id].FrameWidth := FWidth;
- FramesArray[find_id].FrameHeight := FHeight;
- if Name <> '' then
- FramesArray[find_id].Name := LowerCase(Name)
- else
- FramesArray[find_id].Name := '';
-
- if ID <> nil then ID^ := find_id;
-
- Result := True;
+ mEnabled := false
end;
-function g_CreateFramesImg (ia: TDynImageDataArray; ID: PDWORD; Name: ShortString; BackAnimation: Boolean = False): Boolean;
-var
- find_id: DWORD;
- a, FCount: Integer;
+procedure TAnimationState.enable;
begin
- result := false;
- find_id := FindFrame();
-
- FCount := length(ia);
-
- //e_WriteLog(Format('+++ creating %d frames [%s]', [FCount, Name]), MSG_NOTIFY);
-
- if FCount < 1 then exit;
- if FCount <= 2 then BackAnimation := False;
- if BackAnimation then
- SetLength(FramesArray[find_id].TexturesID, FCount+FCount-2)
- else
- SetLength(FramesArray[find_id].TexturesID, FCount);
-
- //e_WriteLog(Format('+++ creating %d frames, %dx%d', [FCount, ia[0].width, ia[0].height]), MSG_NOTIFY);
-
- for a := 0 to FCount-1 do
- begin
- if not e_CreateTextureImg(ia[a], FramesArray[find_id].TexturesID[a]) then exit;
- //e_WriteLog(Format('+++ frame %d, %dx%d', [a, ia[a].width, ia[a].height]), MSG_NOTIFY);
- end;
-
- if BackAnimation then
- begin
- for a := 1 to FCount-2 do
- begin
- FramesArray[find_id].TexturesID[FCount+FCount-2-a] := FramesArray[find_id].TexturesID[a];
- end;
- end;
-
- FramesArray[find_id].FrameWidth := ia[0].width;
- FramesArray[find_id].FrameHeight := ia[0].height;
- if Name <> '' then
- FramesArray[find_id].Name := LowerCase(Name)
- else
- FramesArray[find_id].Name := '';
-
- if ID <> nil then ID^ := find_id;
-
- result := true;
+ mEnabled := true
end;
-function g_Frames_CreateWAD(ID: PDWORD; Name: ShortString; Resource: string;
- FWidth, FHeight, FCount: Word; BackAnimation: Boolean = False): Boolean;
-var
- WAD: TWADFile;
- FileName: string;
- TextureData: Pointer;
- ResourceLength: Integer;
+procedure TAnimationState.revert (r: Boolean);
begin
- Result := False;
-
- FileName := g_ExtractWadName(Resource);
-
- WAD := TWADFile.Create();
- WAD.ReadFile(FileName);
-
- if not WAD.GetResource(g_ExtractFilePathName(Resource), TextureData, ResourceLength) then
- begin
- WAD.Free();
- e_WriteLog(Format('Error loading texture %s', [Resource]), MSG_WARNING);
- //e_WriteLog(Format('WAD Reader error: %s', [WAD.GetLastErrorStr]), MSG_WARNING);
- Exit;
- end;
-
- if not CreateFramesMem(TextureData, ResourceLength, ID, Name, FWidth, FHeight, FCount, BackAnimation) then
- begin
- WAD.Free();
- Exit;
- end;
-
- WAD.Free();
-
- Result := True;
+ mRevert := r;
+ reset
end;
-function g_Frames_CreateMemory(ID: PDWORD; Name: ShortString; pData: Pointer; dataSize: LongInt;
- FWidth, FHeight, FCount: Word; BackAnimation: Boolean = False): Boolean;
+function TAnimationState.totalFrames (): Integer; inline;
begin
- Result := CreateFramesMem(pData, dataSize, ID, Name, FWidth, FHeight, FCount, BackAnimation);
+ result := mLength
end;
-{function g_Frames_CreateRevert(ID: PDWORD; Name: ShortString; Frames: string): Boolean;
-var
- find_id, b: DWORD;
- a, c: Integer;
+procedure TAnimationState.saveState (st: TStream; mAlpha: Byte; mBlending: Boolean);
begin
- Result := False;
+ if (st = nil) then exit;
- if not g_Frames_Get(b, Frames) then Exit;
+ utils.writeSign(st, 'ANIM');
+ utils.writeInt(st, Byte(0)); // version
+ // Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè
+ utils.writeInt(st, Byte(mCounter));
+ // Òåêóùèé êàäð
+ utils.writeInt(st, LongInt(mCurrentFrame));
+ // Ïðîèãðàíà ëè àíèìàöèÿ öåëèêîì
+ utils.writeBool(st, mPlayed);
+ // Alpha-êàíàë âñåé òåêñòóðû
+ utils.writeInt(st, Byte(mAlpha));
+ // Ðàçìûòèå òåêñòóðû
+ utils.writeInt(st, Byte(mBlending));
+ // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè
+ utils.writeInt(st, Byte(mSpeed));
+ // Çàöèêëåíà ëè àíèìàöèÿ
+ utils.writeBool(st, mLoop);
+ // Âêëþ÷åíà ëè
+ utils.writeBool(st, mEnabled);
+ // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ
+ utils.writeInt(st, Byte(mMinLength));
+ // Îáðàòíûé ëè ïîðÿäîê êàäðîâ
+ utils.writeBool(st, mRevert);
+end;
- find_id := FindFrame();
- FramesArray[find_id].Name := Name;
- FramesArray[find_id].FrameWidth := FramesArray[b].FrameWidth;
- FramesArray[find_id].FrameHeight := FramesArray[b].FrameHeight;
+procedure TAnimationState.loadState (st: TStream; out mAlpha: Byte; out mBlending: Boolean);
+begin
+ if (st = nil) then exit;
- c := High(FramesArray[find_id].TexturesID);
+ if not utils.checkSign(st, 'ANIM') then raise XStreamError.Create('animation chunk expected');
+ if (utils.readByte(st) <> 0) then raise XStreamError.Create('invalid animation chunk version');
+ // Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè
+ mCounter := utils.readByte(st);
+ // Òåêóùèé êàäð
+ mCurrentFrame := utils.readLongInt(st);
+ // Ïðîèãðàíà ëè àíèìàöèÿ öåëèêîì
+ mPlayed := utils.readBool(st);
+ // Alpha-êàíàë âñåé òåêñòóðû
+ mAlpha := utils.readByte(st);
+ // Ðàçìûòèå òåêñòóðû
+ mBlending := utils.readBool(st);
+ // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè
+ mSpeed := utils.readByte(st);
+ // Çàöèêëåíà ëè àíèìàöèÿ
+ mLoop := utils.readBool(st);
+ // Âêëþ÷åíà ëè
+ mEnabled := utils.readBool(st);
+ // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ
+ mMinLength := utils.readByte(st);
+ // Îáðàòíûé ëè ïîðÿäîê êàäðîâ
+ mRevert := utils.readBool(st);
+end;
- for a := 0 to c do
- FramesArray[find_id].TexturesID[a] := FramesArray[b].TexturesID[c-a];
- Result := True;
-end;}
+(* ------------- *)
-procedure g_Frames_DeleteByName(FramesName: ShortString);
-var
- a: DWORD;
- b: Integer;
+constructor TAnimState.Create (aloop: Boolean; aspeed: Byte; len: Integer);
begin
- if FramesArray = nil then Exit;
-
- FramesName := LowerCase(FramesName);
+ Self := Default(TAnimState);
- for a := 0 to High(FramesArray) do
- if FramesArray[a].Name = FramesName then
- begin
- if FramesArray[a].TexturesID <> nil then
- for b := 0 to High(FramesArray[a].TexturesID) do
- e_DeleteTexture(FramesArray[a].TexturesID[b]);
- FramesArray[a].TexturesID := nil;
- FramesArray[a].Name := '';
- FramesArray[a].FrameWidth := 0;
- FramesArray[a].FrameHeight := 0;
- end;
-end;
+ assert(len >= 0);
+ mLength := len;
-procedure g_Frames_DeleteByID(ID: DWORD);
-var
- b: Integer;
-begin
- if FramesArray = nil then Exit;
-
- if FramesArray[ID].TexturesID <> nil then
- for b := 0 to High(FramesArray[ID].TexturesID) do
- e_DeleteTexture(FramesArray[ID].TexturesID[b]);
- FramesArray[ID].TexturesID := nil;
- FramesArray[ID].Name := '';
- FramesArray[ID].FrameWidth := 0;
- FramesArray[ID].FrameHeight := 0;
+ mMinLength := 0;
+ mLoop := aloop;
+ mSpeed := aspeed;
+ mEnabled := true;
+ mCurrentFrame := 0;
+ mPlayed := false;
end;
-procedure g_Frames_DeleteAll;
-var
- a: DWORD;
- b: DWORD;
+procedure TAnimState.Invalidate;
begin
- if FramesArray = nil then Exit;
-
- for a := 0 to High(FramesArray) do
- if FramesArray[a].TexturesID <> nil then
- begin
- for b := 0 to High(FramesArray[a].TexturesID) do
- e_DeleteTexture(FramesArray[a].TexturesID[b]);
- FramesArray[a].TexturesID := nil;
- FramesArray[a].Name := '';
- FramesArray[a].FrameWidth := 0;
- FramesArray[a].FrameHeight := 0;
- end;
-
- FramesArray := nil;
+ Self := Default(TAnimState);
end;
-function g_Frames_Get(var ID: DWORD; FramesName: ShortString): Boolean;
-var
- a: DWORD;
+procedure TAnimState.update;
begin
- Result := False;
+ if (not mEnabled) then exit;
- if FramesArray = nil then
- Exit;
+ mCounter += 1;
- FramesName := LowerCase(FramesName);
-
- for a := 0 to High(FramesArray) do
- if FramesArray[a].Name = FramesName then
+ if (mCounter >= mSpeed) then
+ begin
+ if mRevert then
begin
- ID := a;
- Result := True;
- Break;
- end;
-
- if not Result then
- g_FatalError(Format(_lc[I_GAME_ERROR_FRAMES], [FramesName]));
-end;
-
-function g_Frames_GetTexture(var ID: DWORD; FramesName: ShortString; Frame: Word): Boolean;
-var
- a: DWORD;
-begin
- Result := False;
-
- if FramesArray = nil then
- Exit;
+ if (mCurrentFrame = 0) then
+ begin
+ if (mLength * mSpeed + mCounter < mMinLength) then exit;
+ end;
- FramesName := LowerCase(FramesName);
+ mCurrentFrame -= 1;
+ mPlayed := (mCurrentFrame < 0);
- for a := 0 to High(FramesArray) do
- if FramesArray[a].Name = FramesName then
- if Frame <= High(FramesArray[a].TexturesID) then
+ if mPlayed then
begin
- ID := FramesArray[a].TexturesID[Frame];
- Result := True;
- Break;
+ if mLoop then
+ mCurrentFrame := mLength - 1
+ else
+ mCurrentFrame += 1
end;
- if not Result then
- g_FatalError(Format(_lc[I_GAME_ERROR_FRAMES], [FramesName]));
-end;
-
-function g_Frames_Exists(FramesName: string): Boolean;
-var
- a: DWORD;
-begin
- Result := False;
+ mCounter := 0;
+ end
+ else
+ begin
+ if (mCurrentFrame = mLength - 1) then
+ begin
+ if (mLength * mSpeed + mCounter < mMinLength) then exit;
+ end;
- if FramesArray = nil then Exit;
+ mCurrentFrame += 1;
+ mPlayed := (mCurrentFrame > mLength - 1);
- FramesName := LowerCase(FramesName);
+ if mPlayed then
+ begin
+ if mLoop then mCurrentFrame := 0 else mCurrentFrame -= 1;
+ end;
- for a := 0 to High(FramesArray) do
- if FramesArray[a].Name = FramesName then
- begin
- Result := True;
- Exit;
+ mCounter := 0;
end;
+ end;
end;
-procedure DumpTextureNames();
-var
- i: Integer;
-begin
- e_WriteLog('BEGIN Textures:', MSG_NOTIFY);
- for i := 0 to High(TexturesArray) do
- e_WriteLog(' '+IntToStr(i)+'. '+TexturesArray[i].Name, MSG_NOTIFY);
- e_WriteLog('END Textures.', MSG_NOTIFY);
-
- e_WriteLog('BEGIN Frames:', MSG_NOTIFY);
- for i := 0 to High(FramesArray) do
- e_WriteLog(' '+IntToStr(i)+'. '+FramesArray[i].Name, MSG_NOTIFY);
- e_WriteLog('END Frames.', MSG_NOTIFY);
-end;
-
-{ TAnimation }
-
-constructor TAnimation.Create(FramesID: DWORD; Loop: Boolean; Speed: Byte);
+procedure TAnimState.reset;
begin
- ID := FramesID;
-
- FMinLength := 0;
- FLoop := Loop;
- FSpeed := Speed;
- FEnabled := True;
- FCurrentFrame := 0;
- FPlayed := False;
- FAlpha := 0;
- FWidth := FramesArray[ID].FrameWidth;
- FHeight := FramesArray[ID].FrameHeight;
+ if mRevert then
+ mCurrentFrame := mLength - 1
+ else
+ mCurrentFrame := 0;
+ mCounter := 0;
+ mPlayed := false
end;
-destructor TAnimation.Destroy;
+procedure TAnimState.disable;
begin
- inherited;
+ mEnabled := false
end;
-procedure TAnimation.Draw(X, Y: Integer; Mirror: TMirrorType);
+procedure TAnimState.enable;
begin
- if not FEnabled then
- Exit;
-
- e_DrawAdv(FramesArray[ID].TexturesID[FCurrentFrame], X, Y, FAlpha,
- True, FBlending, 0, nil, Mirror);
- //e_DrawQuad(X, Y, X+FramesArray[ID].FrameWidth-1, Y+FramesArray[ID].FrameHeight-1, 0, 255, 0);
+ mEnabled := true
end;
-procedure TAnimation.Update();
+procedure TAnimState.revert (r: Boolean);
begin
- if not FEnabled then
- Exit;
-
- FCounter := FCounter + 1;
-
- if FCounter >= FSpeed then
- begin // Îæèäàíèå ìåæäó êàäðàìè çàêîí÷èëîñü
- if FRevert then
- begin // Îáðàòíûé ïîðÿäîê êàäðîâ
- // Äîøëè äî êîíöà àíèìàöèè. Âîçìîæíî, æäåì åùå:
- if FCurrentFrame = 0 then
- if Length(FramesArray[ID].TexturesID) * FSpeed +
- FCounter < FMinLength then
- Exit;
-
- FCurrentFrame := FCurrentFrame - 1;
- FPlayed := FCurrentFrame < 0;
-
- // Ïîâòîðÿòü ëè àíèìàöèþ ïî êðóãó:
- if FPlayed then
- if FLoop then
- FCurrentFrame := High(FramesArray[ID].TexturesID)
- else
- FCurrentFrame := FCurrentFrame + 1;
-
- FCounter := 0;
- end
- else
- begin // Ïðÿìîé ïîðÿäîê êàäðîâ
- // Äîøëè äî êîíöà àíèìàöèè. Âîçìîæíî, æäåì åùå:
- if FCurrentFrame = High(FramesArray[ID].TexturesID) then
- if Length(FramesArray[ID].TexturesID) * FSpeed +
- FCounter < FMinLength then
- Exit;
-
- FCurrentFrame := FCurrentFrame + 1;
- FPlayed := (FCurrentFrame > High(FramesArray[ID].TexturesID));
-
- // Ïîâòîðÿòü ëè àíèìàöèþ ïî êðóãó:
- if FPlayed then
- if FLoop then
- FCurrentFrame := 0
- else
- FCurrentFrame := FCurrentFrame - 1;
-
- FCounter := 0;
- end;
- end;
+ mRevert := r;
+ reset
end;
-procedure TAnimation.Reset();
+function TAnimState.totalFrames (): Integer; inline;
begin
- if FRevert then
- FCurrentFrame := High(FramesArray[ID].TexturesID)
- else
- FCurrentFrame := 0;
-
- FCounter := 0;
- FPlayed := False;
+ result := mLength
end;
-procedure TAnimation.Disable;
+function TAnimState.IsInvalid (): Boolean;
begin
- FEnabled := False;
+ result := mLength <= 0
end;
-procedure TAnimation.Enable;
+function TAnimState.IsValid (): Boolean;
begin
- FEnabled := True;
+ result := mLength > 0
end;
-procedure TAnimation.DrawEx(X, Y: Integer; Mirror: TMirrorType; RPoint: TPoint;
- Angle: SmallInt);
+procedure TAnimState.saveState (st: TStream; mAlpha: Byte; mBlending: Boolean);
begin
- if not FEnabled then
- Exit;
+ if (st = nil) then exit;
- e_DrawAdv(FramesArray[ID].TexturesID[FCurrentFrame], X, Y, FAlpha,
- True, FBlending, Angle, @RPoint, Mirror);
+ utils.writeSign(st, 'ANIM');
+ utils.writeInt(st, Byte(0)); // version
+ utils.writeInt(st, Byte(mCounter));
+ utils.writeInt(st, LongInt(mCurrentFrame));
+ utils.writeBool(st, mPlayed);
+ utils.writeInt(st, Byte(mAlpha));
+ utils.writeInt(st, Byte(mBlending));
+ utils.writeInt(st, Byte(mSpeed));
+ utils.writeBool(st, mLoop);
+ utils.writeBool(st, mEnabled);
+ utils.writeInt(st, Byte(mMinLength));
+ utils.writeBool(st, mRevert);
end;
-function TAnimation.TotalFrames(): Integer;
-begin
- Result := Length(FramesArray[ID].TexturesID);
-end;
-procedure TAnimation.Revert(r: Boolean);
+procedure TAnimState.loadState (st: TStream; out mAlpha: Byte; out mBlending: Boolean);
begin
- FRevert := r;
- Reset();
-end;
+ if (st = nil) then exit;
-procedure TAnimation.SaveState(Var Mem: TBinMemoryWriter);
-var
- sig: DWORD;
-begin
- if Mem = nil then
- Exit;
-
-// Ñèãíàòóðà àíèìàöèè:
- sig := ANIM_SIGNATURE; // 'ANIM'
- Mem.WriteDWORD(sig);
-// Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè:
- Mem.WriteByte(FCounter);
-// Òåêóùèé êàäð:
- Mem.WriteInt(FCurrentFrame);
-// Ïðîèãðàíà ëè àíèìàöèÿ öåëèêîì:
- Mem.WriteBoolean(FPlayed);
-// Alpha-êàíàë âñåé òåêñòóðû:
- Mem.WriteByte(FAlpha);
-// Ðàçìûòèå òåêñòóðû:
- Mem.WriteBoolean(FBlending);
-// Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè:
- Mem.WriteByte(FSpeed);
-// Çàöèêëåíà ëè àíèìàöèÿ:
- Mem.WriteBoolean(FLoop);
-// Âêëþ÷åíà ëè:
- Mem.WriteBoolean(FEnabled);
-// Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ:
- Mem.WriteByte(FMinLength);
-// Îáðàòíûé ëè ïîðÿäîê êàäðîâ:
- Mem.WriteBoolean(FRevert);
+ if not utils.checkSign(st, 'ANIM') then raise XStreamError.Create('animation chunk expected');
+ if (utils.readByte(st) <> 0) then raise XStreamError.Create('invalid animation chunk version');
+ mCounter := utils.readByte(st);
+ mCurrentFrame := utils.readLongInt(st);
+ mPlayed := utils.readBool(st);
+ mAlpha := utils.readByte(st);
+ mBlending := utils.readBool(st);
+ mSpeed := utils.readByte(st);
+ mLoop := utils.readBool(st);
+ mEnabled := utils.readBool(st);
+ mMinLength := utils.readByte(st);
+ mRevert := utils.readBool(st);
end;
-procedure TAnimation.LoadState(Var Mem: TBinMemoryReader);
-var
- sig: DWORD;
-begin
- if Mem = nil then
- Exit;
-
-// Ñèãíàòóðà àíèìàöèè:
- Mem.ReadDWORD(sig);
- if sig <> ANIM_SIGNATURE then // 'ANIM'
- begin
- raise EBinSizeError.Create('TAnimation.LoadState: Wrong Animation Signature');
- end;
-// Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè:
- Mem.ReadByte(FCounter);
-// Òåêóùèé êàäð:
- Mem.ReadInt(FCurrentFrame);
-// Ïðîèãðàíà ëè àíèìàöèÿ öåëèêîì:
- Mem.ReadBoolean(FPlayed);
-// Alpha-êàíàë âñåé òåêñòóðû:
- Mem.ReadByte(FAlpha);
-// Ðàçìûòèå òåêñòóðû:
- Mem.ReadBoolean(FBlending);
-// Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè:
- Mem.ReadByte(FSpeed);
-// Çàöèêëåíà ëè àíèìàöèÿ:
- Mem.ReadBoolean(FLoop);
-// Âêëþ÷åíà ëè:
- Mem.ReadBoolean(FEnabled);
-// Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ:
- Mem.ReadByte(FMinLength);
-// Îáðàòíûé ëè ïîðÿäîê êàäðîâ:
- Mem.ReadBoolean(FRevert);
-end;
end.