index 5958e93b498f15d27a74e878e4850d32bb835942..16b0655a01dbcd0f81117770a592c9104fa1d027 100644 (file)
--- a/src/game/g_textures.pas
+++ b/src/game/g_textures.pas
-(* Copyright (C) DooM 2D:Forever Developers
+(* 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
*
* 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, either version 3 of the License, or
- * (at your option) any later version.
+ * 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
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
uses
SysUtils, Classes,
{$IFDEF USE_MEMPOOL}mempool,{$ENDIF}
uses
SysUtils, Classes,
{$IFDEF USE_MEMPOOL}mempool,{$ENDIF}
- e_graphics, MAPDEF, ImagingTypes, Imaging, ImagingUtility;
+ g_base, MAPDEF;
type
TLevelTexture = record
type
TLevelTexture = record
- textureName: AnsiString;
- width, height: Word;
- case anim: Boolean of
- false: (textureID: LongWord);
- true: (framesID: LongWord; 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;
end;
TLevelTextureArray = array of TLevelTexture;
- TAnimation = class{$IFDEF USE_MEMPOOL}(TPoolObject){$ENDIF}
+ TAnimationState = class{$IFDEF USE_MEMPOOL}(TPoolObject){$ENDIF}
private
private
- mId: LongWord;
- mAlpha: Byte;
- mBlending: Boolean;
mCounter: Byte; // Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè
mSpeed: Byte; // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè
mCurrentFrame: Integer; // Òåêóùèé êàäð (íà÷èíàÿ ñ 0)
mLoop: Boolean; // Ïåðåõîäèòü íà ïåðâûé êàäð ïîñëå ïîñëåäíåãî?
mEnabled: Boolean; // Ðàáîòà ðàçðåøåíà?
mPlayed: Boolean; // Ïðîèãðàíà âñÿ õîòÿ áû ðàç?
mCounter: Byte; // Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè
mSpeed: Byte; // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè
mCurrentFrame: Integer; // Òåêóùèé êàäð (íà÷èíàÿ ñ 0)
mLoop: Boolean; // Ïåðåõîäèòü íà ïåðâûé êàäð ïîñëå ïîñëåäíåãî?
mEnabled: Boolean; // Ðàáîòà ðàçðåøåíà?
mPlayed: Boolean; // Ïðîèãðàíà âñÿ õîòÿ áû ðàç?
- mHeight: Word;
- mWidth: Word;
mMinLength: Byte; // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ
mRevert: Boolean; // Ñìåíà êàäðîâ îáðàòíàÿ?
mMinLength: Byte; // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ
mRevert: Boolean; // Ñìåíà êàäðîâ îáðàòíàÿ?
+ mLength: Integer;
+
public
public
- constructor Create (aframesID: LongWord; aloop: Boolean; aspeed: Byte);
+ constructor Create (aloop: Boolean; aspeed: Byte; len: Integer);
destructor Destroy (); override;
destructor Destroy (); override;
- procedure draw (x, y: Integer; mirror: TMirrorType);
- procedure drawEx (x, y: Integer; mirror: TMirrorType; rpoint: TDFPoint; angle: SmallInt);
-
procedure reset ();
procedure update ();
procedure enable ();
procedure disable ();
procedure revert (r: Boolean);
procedure reset ();
procedure update ();
procedure enable ();
procedure disable ();
procedure revert (r: Boolean);
- procedure saveState (st: TStream);
- procedure loadState (st: TStream);
+ procedure saveState (st: TStream; mAlpha: Byte; mBlending: Boolean);
+ procedure loadState (st: TStream; out mAlpha: Byte; out mBlending: Boolean);
function totalFrames (): Integer; inline;
function totalFrames (): Integer; inline;
property currentFrame: Integer read mCurrentFrame write mCurrentFrame;
property currentCounter: Byte read mCounter write mCounter;
property counter: Byte read mCounter;
property currentFrame: Integer read mCurrentFrame write mCurrentFrame;
property currentCounter: Byte read mCounter write mCounter;
property counter: Byte read mCounter;
- property blending: Boolean read mBlending write mBlending;
- property alpha: Byte read mAlpha write mAlpha;
- property framesId: LongWord read mId;
- property width: Word read mWidth;
- property height: Word read mHeight;
+ property length: Integer read mLength;
end;
end;
+ TAnimState = record
+ private
+ mCounter: Byte; // Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè
+ mSpeed: Byte; // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè
+ mCurrentFrame: Integer; // Òåêóùèé êàäð (íà÷èíàÿ ñ 0)
+ mLoop: Boolean; // Ïåðåõîäèòü íà ïåðâûé êàäð ïîñëå ïîñëåäíåãî?
+ mEnabled: Boolean; // Ðàáîòà ðàçðåøåíà?
+ mPlayed: Boolean; // Ïðîèãðàíà âñÿ õîòÿ áû ðàç?
+ mMinLength: Byte; // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ
+ mRevert: Boolean; // Ñìåíà êàäðîâ îáðàòíàÿ?
-function g_Texture_CreateWAD (var ID: LongWord; const Resource: AnsiString): Boolean;
-function g_Texture_CreateFile (var ID: LongWord; const FileName: AnsiString): Boolean;
-function g_Texture_CreateWADEx (const textureName, Resource: AnsiString; const altrsrc: AnsiString=''): Boolean;
-function g_Texture_CreateFileEx (const textureName, FileName: AnsiString): Boolean;
-function g_Texture_Get (const textureName: AnsiString; var ID: LongWord): Boolean;
-procedure g_Texture_Delete (const textureName: AnsiString);
-procedure g_Texture_DeleteAll ();
+ mLength: Integer;
-function g_CreateFramesImg (ia: TDynImageDataArray; ID: PDWORD; const Name: AnsiString; BackAnimation: Boolean=false): Boolean;
+ public
+ constructor Create (aloop: Boolean; aspeed: Byte; len: Integer);
+ procedure Invalidate;
-function g_Frames_CreateWAD (ID: PDWORD; const Name, Resource: AnsiString; mWidth, mHeight, mCount: Word; BackAnimation: Boolean=false): Boolean;
-function g_Frames_CreateFile (ID: PDWORD; const Name, FileName: AnsiString; mWidth, mHeight, mCount: Word; BackAnimation: Boolean=false): Boolean;
-function g_Frames_CreateMemory (ID: PDWORD; const Name: AnsiString; pData: Pointer; dataSize: LongInt;
- mWidth, mHeight, mCount: Word; BackAnimation: Boolean=false): Boolean;
-function g_Frames_Dup (const NewName, OldName: AnsiString): Boolean;
-//function g_Frames_CreateRevert(ID: PDWORD; Name: ShortString; Frames: string): Boolean;
-function g_Frames_Get (out ID: LongWord; const FramesName: AnsiString): Boolean;
-function g_Frames_GetTexture (out ID: LongWord; const FramesName: AnsiString; Frame: Word): Boolean;
-function g_Frames_Exists (const FramesName: AnsiString): Boolean;
-procedure g_Frames_DeleteByName (const FramesName: AnsiString);
-procedure g_Frames_DeleteByID (ID: LongWord);
-procedure g_Frames_DeleteAll ();
+ procedure reset ();
+ procedure update ();
+ procedure enable ();
+ procedure disable ();
+ procedure revert (r: Boolean);
-procedure DumpTextureNames ();
+ procedure saveState (st: TStream; mAlpha: Byte; mBlending: Boolean);
+ procedure loadState (st: TStream; out mAlpha: Byte; out mBlending: Boolean);
-function g_Texture_Light (): Integer;
+ function totalFrames (): Integer; inline;
+ function IsInvalid (): Boolean;
+ function IsValid (): Boolean;
+ 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;
implementation
uses
g_game, e_log, g_basic, g_console, wadreader,
implementation
uses
g_game, e_log, g_basic, g_console, wadreader,
- g_language, GL, utils, xstreams;
-
-type
- _TTexture = record
- name: AnsiString;
- id: LongWord;
- width, height: Word;
- used: Boolean;
- end;
-
- TFrames = record
- texturesID: array of LongWord;
- name: AnsiString;
- frameWidth, frameHeight: Word;
- used: Boolean;
- end;
-
-var
- texturesArray: array of _TTexture = nil;
- framesArray: array of TFrames = nil;
-
+ g_language, utils, xstreams;
-const
- ANIM_SIGNATURE = $4D494E41; // 'ANIM'
-
-
-function allocTextureSlot (): LongWord;
-var
- f: integer;
+constructor TAnimationState.Create (aloop: Boolean; aspeed: Byte; len: Integer);
begin
begin
- for f := 0 to High(texturesArray) do
- begin
- if (not texturesArray[f].used) then
- begin
- result := f;
- exit;
- end;
- end;
+ assert(len >= 0);
+ mLength := len;
- result := Length(texturesArray);
- SetLength(texturesArray, result+64);
- for f := result to High(texturesArray) do
- begin
- with texturesArray[f] do
- begin
- name := '';
- id := 0;
- width := 0;
- height := 0;
- used := false;
- end;
- end;
+ mMinLength := 0;
+ mLoop := aloop;
+ mSpeed := aspeed;
+ mEnabled := true;
+ mCurrentFrame := 0;
+ mPlayed := false;
end;
end;
-
-function allocFrameSlot (): LongWord;
-var
- f: integer;
+destructor TAnimationState.Destroy;
begin
begin
- for f := 0 to High(framesArray) do
- begin
- if (not framesArray[f].used) then
- begin
- result := f;
- exit;
- end;
- end;
-
- result := Length(framesArray);
- SetLength(framesArray, result+64);
- for f := result to High(framesArray) do
- begin
- with framesArray[f] do
- begin
- texturesID := nil;
- name := '';
- frameWidth := 0;
- frameHeight := 0;
- used := false;
- end;
- end;
+ inherited;
end;
end;
-
-// ////////////////////////////////////////////////////////////////////////// //
-function g_Texture_CreateWAD (var ID: LongWord; const Resource: AnsiString): Boolean;
-var
- WAD: TWADFile;
- FileName: AnsiString;
- TextureData: Pointer;
- ResourceLength: Integer;
+procedure TAnimationState.update;
begin
begin
- result := false;
- FileName := g_ExtractWadName(Resource);
+ if (not mEnabled) then exit;
- WAD := TWADFile.Create;
- WAD.ReadFile(FileName);
+ mCounter += 1;
- if WAD.GetResource(g_ExtractFilePathName(Resource), TextureData, ResourceLength) then
+ if (mCounter >= mSpeed) then
begin
begin
- if e_CreateTextureMem(TextureData, ResourceLength, ID) then
- begin
- result := true;
- end
- else
+ // Îæèäàíèå ìåæäó êàäðàìè çàêîí÷èëîñü
+ // Îáðàòíûé ïîðÿäîê êàäðîâ?
+ if mRevert then
begin
begin
- FreeMem(TextureData);
- end;
- end
- else
- begin
- e_WriteLog(Format('Error loading texture %s', [Resource]), TMsgType.Warning);
- //e_WriteLog(Format('WAD Reader error: %s', [WAD.GetLastErrorStr]), MSG_WARNING);
- end;
- WAD.Free();
-end;
-
-
-function g_Texture_CreateFile (var ID: LongWord; const FileName: AnsiString): Boolean;
-begin
- result := true;
- if not e_CreateTexture(FileName, ID) then
- begin
- e_WriteLog(Format('Error loading texture %s', [FileName]), TMsgType.Warning);
- result := false;
- end;
-end;
-
-
-function texture_CreateWADExInternal (const textureName, Resource: AnsiString; showmsg: Boolean): Boolean;
-var
- WAD: TWADFile;
- FileName: AnsiString;
- TextureData: Pointer;
- find_id: LongWord;
- ResourceLength: Integer;
-begin
- FileName := g_ExtractWadName(Resource);
+ // Äîøëè äî êîíöà àíèìàöèè. Âîçìîæíî, æäåì åùå
+ if (mCurrentFrame = 0) then
+ begin
+ if (mLength * mSpeed + mCounter < mMinLength) then exit;
+ end;
- find_id := allocTextureSlot();
+ mCurrentFrame -= 1;
+ mPlayed := (mCurrentFrame < 0);
- WAD := TWADFile.Create;
- WAD.ReadFile(FileName);
+ // Ïîâòîðÿòü ëè àíèìàöèþ ïî êðóãó?
+ if mPlayed then
+ begin
+ if mLoop then
+ mCurrentFrame := mLength - 1
+ else
+ mCurrentFrame += 1
+ end;
- 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].used := true;
- texturesArray[find_id].Name := textureName;
+ mCounter := 0;
end
else
begin
end
else
begin
- FreeMem(TextureData);
- end;
- end
- else
- begin
- if showmsg then
- begin
- e_WriteLog(Format('Error loading texture %s', [Resource]), TMsgType.Warning);
- end;
- //e_WriteLog(Format('WAD Reader error: %s', [WAD.GetLastErrorStr]), MSG_WARNING);
- result := false;
- end;
- WAD.Free();
-end;
-
-
-function g_Texture_CreateWADEx (const textureName, Resource: AnsiString; const altrsrc: AnsiString=''): Boolean;
-begin
- if (Length(altrsrc) > 0) then
- begin
- result := texture_CreateWADExInternal(textureName, altrsrc, false);
- if result then exit;
- end;
- result := texture_CreateWADExInternal(textureName, Resource, true);
-end;
-
-
-function g_Texture_CreateFileEx (const textureName, FileName: AnsiString): Boolean;
-var
- find_id: LongWord;
-begin
- find_id := allocTextureSlot();
- result := e_CreateTexture(FileName, texturesArray[find_id].ID);
- if result then
- begin
- texturesArray[find_id].used := true;
- texturesArray[find_id].Name := 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]), TMsgType.Warning);
-end;
-
-
-function g_Texture_Get (const textureName: AnsiString; var id: LongWord): Boolean;
-var
- a: Integer;
-begin
- result := false;
- if (Length(texturesArray) = 0) or (Length(textureName) = 0) then exit;
- for a := 0 to High(texturesArray) do
- begin
- if (StrEquCI1251(texturesArray[a].name, textureName)) then
- begin
- id := texturesArray[a].id;
- result := true;
- break;
- end;
- end;
- //if not Result then g_ConsoleAdd('Texture '+TextureName+' not found');
-end;
-
-
-procedure g_Texture_Delete (const textureName: AnsiString);
-var
- a: Integer;
-begin
- if (Length(texturesArray) = 0) or (Length(textureName) = 0) then exit;
- for a := 0 to High(texturesArray) do
- begin
- if (StrEquCI1251(texturesArray[a].name, textureName)) then
- begin
- e_DeleteTexture(texturesArray[a].ID);
- texturesArray[a].used := false;
- texturesArray[a].name := '';
- texturesArray[a].id := 0;
- texturesArray[a].width := 0;
- texturesArray[a].height := 0;
- end;
- end;
-end;
-
-
-procedure g_Texture_DeleteAll ();
-var
- a: Integer;
-begin
- for a := 0 to High(texturesArray) do
- begin
- if (texturesArray[a].used) then e_DeleteTexture(texturesArray[a].ID);
- end;
- texturesArray := nil;
-end;
-
-
-function g_Frames_CreateFile (ID: PDWORD; const Name, FileName: AnsiString;
- mWidth, mHeight, mCount: Word; BackAnimation: Boolean = false): Boolean;
-var
- a: Integer;
- find_id: LongWord;
-begin
- result := false;
-
- find_id := allocFrameSlot();
-
- if (mCount <= 2) then BackAnimation := false;
-
- if BackAnimation then SetLength(framesArray[find_id].TexturesID, mCount+mCount-2)
- else SetLength(framesArray[find_id].TexturesID, mCount);
-
- for a := 0 to mCount-1 do
- begin
- if not e_CreateTextureEx(FileName, framesArray[find_id].TexturesID[a], a*mWidth, 0, mWidth, mHeight) then exit;
- end;
-
- if BackAnimation then
- begin
- for a := 1 to mCount-2 do framesArray[find_id].TexturesID[mCount+mCount-2-a] := framesArray[find_id].TexturesID[a];
- end;
-
- framesArray[find_id].used := true;
- framesArray[find_id].FrameWidth := mWidth;
- framesArray[find_id].FrameHeight := mHeight;
- if (Name <> '') then framesArray[find_id].Name := Name else framesArray[find_id].Name := '<noname>';
-
- if (ID <> nil) then ID^ := find_id;
-
- result := true;
-end;
-
-
-function CreateFramesMem (pData: Pointer; dataSize: LongInt; ID: PDWORD; Name: AnsiString;
- mWidth, mHeight, mCount: Word; BackAnimation: Boolean = false): Boolean;
-var
- find_id: LongWord;
- a: Integer;
-begin
- result := false;
-
- find_id := allocFrameSlot();
+ // Ïðÿìîé ïîðÿäîê êàäðîâ
+ // Äîøëè äî êîíöà àíèìàöèè. Âîçìîæíî, æäåì åùå
+ if (mCurrentFrame = mLength - 1) then
+ begin
+ if (mLength * mSpeed + mCounter < mMinLength) then exit;
+ end;
- if (mCount <= 2) then BackAnimation := false;
+ mCurrentFrame += 1;
+ mPlayed := (mCurrentFrame > mLength - 1);
- if BackAnimation then SetLength(framesArray[find_id].TexturesID, mCount+mCount-2)
- else SetLength(framesArray[find_id].TexturesID, mCount);
+ // Ïîâòîðÿòü ëè àíèìàöèþ ïî êðóãó?
+ if mPlayed then
+ begin
+ if mLoop then mCurrentFrame := 0 else mCurrentFrame -= 1;
+ end;
- for a := 0 to mCount-1 do
- if not e_CreateTextureMemEx(pData, dataSize, framesArray[find_id].TexturesID[a], a*mWidth, 0, mWidth, mHeight) then
- begin
- //!!!FreeMem(pData);
- exit;
+ mCounter := 0;
end;
end;
-
- if BackAnimation then
- begin
- for a := 1 to mCount-2 do framesArray[find_id].TexturesID[mCount+mCount-2-a] := framesArray[find_id].TexturesID[a];
end;
end;
-
- framesArray[find_id].used := true;
- framesArray[find_id].FrameWidth := mWidth;
- framesArray[find_id].FrameHeight := mHeight;
- if (Name <> '') then framesArray[find_id].Name := Name else framesArray[find_id].Name := '<noname>';
-
- if (ID <> nil) then ID^ := find_id;
-
- result := true;
end;
end;
-
-function g_CreateFramesImg (ia: TDynImageDataArray; ID: PDWORD; const Name: AnsiString; BackAnimation: Boolean = false): Boolean;
-var
- find_id: LongWord;
- a, mCount: Integer;
+procedure TAnimationState.reset;
begin
begin
- result := false;
- find_id := allocFrameSlot();
-
- mCount := Length(ia);
-
- //e_WriteLog(Format('+++ creating %d frames [%s]', [FCount, Name]), MSG_NOTIFY);
-
- if (mCount < 1) then exit;
- if (mCount <= 2) then BackAnimation := false;
-
- if BackAnimation then SetLength(framesArray[find_id].TexturesID, mCount+mCount-2)
- else SetLength(framesArray[find_id].TexturesID, mCount);
-
- //e_WriteLog(Format('+++ creating %d frames, %dx%d', [FCount, ia[0].width, ia[0].height]), MSG_NOTIFY);
-
- for a := 0 to mCount-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 mCount-2 do framesArray[find_id].TexturesID[mCount+mCount-2-a] := framesArray[find_id].TexturesID[a];
- end;
-
- framesArray[find_id].used := true;
- framesArray[find_id].FrameWidth := ia[0].width;
- framesArray[find_id].FrameHeight := ia[0].height;
- if (Name <> '') then framesArray[find_id].Name := Name else framesArray[find_id].Name := '<noname>';
-
- if (ID <> nil) then ID^ := find_id;
-
- result := true;
+ if mRevert then
+ mCurrentFrame := mLength - 1
+ else
+ mCurrentFrame := 0;
+ mCounter := 0;
+ mPlayed := false
end;
end;
-
-function g_Frames_CreateWAD (ID: PDWORD; const Name, Resource: AnsiString;
- mWidth, mHeight, mCount: Word; BackAnimation: Boolean=false): Boolean;
-var
- WAD: TWADFile;
- FileName: AnsiString;
- TextureData: Pointer;
- ResourceLength: Integer;
+procedure TAnimationState.disable;
begin
begin
- result := false;
-
- // models without "advanced" animations asks for "nothing" like this; don't spam log
- if (Length(Resource) > 0) and ((Resource[Length(Resource)] = '/') or (Resource[Length(Resource)] = '\')) then exit;
-
- 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]), TMsgType.Warning);
- //e_WriteLog(Format('WAD Reader error: %s', [WAD.GetLastErrorStr]), MSG_WARNING);
- exit;
- end;
-
- if not CreateFramesMem(TextureData, ResourceLength, ID, Name, mWidth, mHeight, mCount, BackAnimation) then
- begin
- WAD.Free();
- exit;
- end;
-
- WAD.Free();
-
- result := true;
+ mEnabled := false
end;
end;
-
-function g_Frames_CreateMemory (ID: PDWORD; const Name: AnsiString; pData: Pointer; dataSize: LongInt;
- mWidth, mHeight, mCount: Word; BackAnimation: Boolean = false): Boolean;
+procedure TAnimationState.enable;
begin
begin
- result := CreateFramesMem(pData, dataSize, ID, Name, mWidth, mHeight, mCount, BackAnimation);
+ mEnabled := true
end;
end;
-
-{function g_Frames_CreateRevert(ID: PDWORD; Name: ShortString; Frames: string): Boolean;
-var
- find_id, b: DWORD;
- a, c: Integer;
-begin
- Result := False;
-
- if not g_Frames_Get(b, Frames) then Exit;
-
- find_id := FindFrame();
-
- FramesArray[find_id].Name := Name;
- FramesArray[find_id].FrameWidth := FramesArray[b].FrameWidth;
- FramesArray[find_id].FrameHeight := FramesArray[b].FrameHeight;
-
- c := High(FramesArray[find_id].TexturesID);
-
- for a := 0 to c do
- FramesArray[find_id].TexturesID[a] := FramesArray[b].TexturesID[c-a];
-
- Result := True;
-end;}
-
-
-function g_Frames_Dup (const NewName, OldName: AnsiString): Boolean;
-var
- find_id, b: LongWord;
- a, c: Integer;
+procedure TAnimationState.revert (r: Boolean);
begin
begin
- result := false;
-
- if not g_Frames_Get(b, OldName) then exit;
-
- find_id := allocFrameSlot();
-
- framesArray[find_id].used := true;
- framesArray[find_id].Name := NewName;
- framesArray[find_id].FrameWidth := framesArray[b].FrameWidth;
- framesArray[find_id].FrameHeight := framesArray[b].FrameHeight;
-
- c := High(framesArray[b].TexturesID);
- SetLength(framesArray[find_id].TexturesID, c+1);
-
- for a := 0 to c do framesArray[find_id].TexturesID[a] := framesArray[b].TexturesID[a];
-
- result := true;
+ mRevert := r;
+ reset
end;
end;
-
-procedure g_Frames_DeleteByName (const FramesName: AnsiString);
-var
- a, b: Integer;
+function TAnimationState.totalFrames (): Integer; inline;
begin
begin
- if (Length(framesArray) = 0) then exit;
- for a := 0 to High(framesArray) do
- begin
- if (StrEquCI1251(framesArray[a].Name, FramesName)) then
- begin
- if framesArray[a].TexturesID <> nil then
- begin
- for b := 0 to High(framesArray[a].TexturesID) do e_DeleteTexture(framesArray[a].TexturesID[b]);
- end;
- framesArray[a].used := false;
- framesArray[a].TexturesID := nil;
- framesArray[a].Name := '';
- framesArray[a].FrameWidth := 0;
- framesArray[a].FrameHeight := 0;
- end;
- end;
+ result := mLength
end;
end;
-
-procedure g_Frames_DeleteByID (ID: LongWord);
-var
- b: Integer;
+procedure TAnimationState.saveState (st: TStream; mAlpha: Byte; mBlending: Boolean);
begin
begin
- if (Length(framesArray) = 0) then exit;
- if (framesArray[ID].TexturesID <> nil) then
- begin
- for b := 0 to High(framesArray[ID].TexturesID) do e_DeleteTexture(framesArray[ID].TexturesID[b]);
- end;
- framesArray[ID].used := false;
- framesArray[ID].TexturesID := nil;
- framesArray[ID].Name := '';
- framesArray[ID].FrameWidth := 0;
- framesArray[ID].FrameHeight := 0;
-end;
-
+ if (st = nil) then exit;
-procedure g_Frames_DeleteAll ();
-var
- a, b: Integer;
-begin
- for a := 0 to High(framesArray) do
- begin
- if (framesArray[a].used) then
- begin
- for b := 0 to High(framesArray[a].TexturesID) do e_DeleteTexture(framesArray[a].TexturesID[b]);
- end;
- framesArray[a].used := false;
- framesArray[a].TexturesID := nil;
- framesArray[a].Name := '';
- framesArray[a].FrameWidth := 0;
- framesArray[a].FrameHeight := 0;
- end;
- framesArray := nil;
+ 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;
end;
-function g_Frames_Get (out ID: LongWord; const FramesName: AnsiString): Boolean;
-var
- a: Integer;
+procedure TAnimationState.loadState (st: TStream; out mAlpha: Byte; out mBlending: Boolean);
begin
begin
- result := false;
- if (Length(framesArray) = 0) then exit;
- for a := 0 to High(framesArray) do
- begin
- if (StrEquCI1251(framesArray[a].Name, FramesName)) then
- begin
- ID := a;
- result := true;
- break;
- end;
- end;
- if not result then g_FatalError(Format(_lc[I_GAME_ERROR_FRAMES], [FramesName]));
-end;
-
+ if (st = nil) then exit;
-function g_Frames_GetTexture (out ID: LongWord; const FramesName: AnsiString; Frame: Word): Boolean;
-var
- a: Integer;
-begin
- result := false;
- if (Length(framesArray) = 0) then exit;
- for a := 0 to High(framesArray) do
- begin
- if (StrEquCI1251(framesArray[a].Name, FramesName)) then
- begin
- if (Frame < Length(framesArray[a].TexturesID)) then
- begin
- ID := framesArray[a].TexturesID[Frame];
- result := true;
- break;
- end;
- end;
- end;
- if not result then g_FatalError(Format(_lc[I_GAME_ERROR_FRAMES], [FramesName]));
+ 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;
end;
-function g_Frames_Exists (const FramesName: AnsiString): Boolean;
-var
- a: Integer;
-begin
- result := false;
- if (Length(framesArray) = 0) then exit;
- for a := 0 to High(framesArray) do
- begin
- if (StrEquCI1251(framesArray[a].Name, FramesName)) then
- begin
- result := true;
- exit;
- end;
- end;
-end;
-
+(* ------------- *)
-procedure DumpTextureNames ();
-var
- i: Integer;
+constructor TAnimState.Create (aloop: Boolean; aspeed: Byte; len: Integer);
begin
begin
- e_WriteLog('BEGIN Textures:', TMsgType.Notify);
- for i := 0 to High(texturesArray) do e_WriteLog(' '+IntToStr(i)+'. '+texturesArray[i].Name, TMsgType.Notify);
- e_WriteLog('END Textures.', TMsgType.Notify);
-
- e_WriteLog('BEGIN Frames:', TMsgType.Notify);
- for i := 0 to High(framesArray) do e_WriteLog(' '+IntToStr(i)+'. '+framesArray[i].Name, TMsgType.Notify);
- e_WriteLog('END Frames.', TMsgType.Notify);
-end;
-
+ Self := Default(TAnimState);
-{ TAnimation }
+ assert(len >= 0);
+ mLength := len;
-constructor TAnimation.Create (aframesID: LongWord; aloop: Boolean; aspeed: Byte);
-begin
- if (aframesID >= Length(framesArray)) then raise Exception.Create('trying to create inexisting frame: something is very wrong here');
- mId := aframesID;
mMinLength := 0;
mLoop := aloop;
mSpeed := aspeed;
mEnabled := true;
mCurrentFrame := 0;
mPlayed := false;
mMinLength := 0;
mLoop := aloop;
mSpeed := aspeed;
mEnabled := true;
mCurrentFrame := 0;
mPlayed := false;
- mAlpha := 0;
- mWidth := framesArray[mId].FrameWidth;
- mHeight := framesArray[mId].FrameHeight;
-end;
-
-
-destructor TAnimation.Destroy ();
-begin
- inherited;
end;
end;
-
-procedure TAnimation.draw (x, y: Integer; mirror: TMirrorType);
+procedure TAnimState.Invalidate;
begin
begin
- if (not mEnabled) then exit;
- e_DrawAdv(framesArray[mId].TexturesID[mCurrentFrame], x, y, mAlpha, true, mBlending, 0, nil, mirror);
- //e_DrawQuad(X, Y, X+FramesArray[ID].FrameWidth-1, Y+FramesArray[ID].FrameHeight-1, 0, 255, 0);
+ Self := Default(TAnimState);
end;
end;
-
-procedure TAnimation.update ();
+procedure TAnimState.update;
begin
if (not mEnabled) then exit;
begin
if (not mEnabled) then exit;
if (mCounter >= mSpeed) then
begin
if (mCounter >= mSpeed) then
begin
- // Îæèäàíèå ìåæäó êàäðàìè çàêîí÷èëîñü
- // Îáðàòíûé ïîðÿäîê êàäðîâ?
if mRevert then
begin
if mRevert then
begin
- // Äîøëè äî êîíöà àíèìàöèè. Âîçìîæíî, æäåì åùå
if (mCurrentFrame = 0) then
begin
if (mCurrentFrame = 0) then
begin
- if (Length(framesArray[mId].TexturesID)*mSpeed+mCounter < mMinLength) then exit;
+ if (mLength * mSpeed + mCounter < mMinLength) then exit;
end;
mCurrentFrame -= 1;
mPlayed := (mCurrentFrame < 0);
end;
mCurrentFrame -= 1;
mPlayed := (mCurrentFrame < 0);
- // Ïîâòîðÿòü ëè àíèìàöèþ ïî êðóãó?
if mPlayed then
begin
if mPlayed then
begin
- if mLoop then mCurrentFrame := High(framesArray[mId].TexturesID) else mCurrentFrame += 1;
+ if mLoop then
+ mCurrentFrame := mLength - 1
+ else
+ mCurrentFrame += 1
end;
mCounter := 0;
end
else
begin
end;
mCounter := 0;
end
else
begin
- // Ïðÿìîé ïîðÿäîê êàäðîâ
- // Äîøëè äî êîíöà àíèìàöèè. Âîçìîæíî, æäåì åùå
- if (mCurrentFrame = High(framesArray[mId].TexturesID)) then
+ if (mCurrentFrame = mLength - 1) then
begin
begin
- if (Length(framesArray[mId].TexturesID)*mSpeed+mCounter < mMinLength) then exit;
+ if (mLength * mSpeed + mCounter < mMinLength) then exit;
end;
mCurrentFrame += 1;
end;
mCurrentFrame += 1;
- mPlayed := (mCurrentFrame > High(framesArray[mId].TexturesID));
+ mPlayed := (mCurrentFrame > mLength - 1);
- // Ïîâòîðÿòü ëè àíèìàöèþ ïî êðóãó?
if mPlayed then
begin
if mLoop then mCurrentFrame := 0 else mCurrentFrame -= 1;
if mPlayed then
begin
if mLoop then mCurrentFrame := 0 else mCurrentFrame -= 1;
end;
end;
end;
end;
-
-procedure TAnimation.reset ();
+procedure TAnimState.reset;
begin
begin
- if mRevert then mCurrentFrame := High(framesArray[mId].TexturesID) else mCurrentFrame := 0;
+ if mRevert then
+ mCurrentFrame := mLength - 1
+ else
+ mCurrentFrame := 0;
mCounter := 0;
mCounter := 0;
- mPlayed := false;
+ mPlayed := false
end;
end;
-
-procedure TAnimation.disable (); begin mEnabled := false; end;
-procedure TAnimation.enable (); begin mEnabled := true; end;
-
-
-procedure TAnimation.drawEx (x, y: Integer; mirror: TMirrorType; rpoint: TDFPoint; angle: SmallInt);
+procedure TAnimState.disable;
begin
begin
- if (not mEnabled) then exit;
- e_DrawAdv(framesArray[mId].TexturesID[mCurrentFrame], x, y, mAlpha, true, mBlending, angle, @rpoint, mirror);
+ mEnabled := false
end;
end;
+procedure TAnimState.enable;
+begin
+ mEnabled := true
+end;
-function TAnimation.totalFrames (): Integer; inline; begin result := Length(framesArray[mId].TexturesID); end;
+procedure TAnimState.revert (r: Boolean);
+begin
+ mRevert := r;
+ reset
+end;
+function TAnimState.totalFrames (): Integer; inline;
+begin
+ result := mLength
+end;
-procedure TAnimation.revert (r: Boolean);
+function TAnimState.IsInvalid (): Boolean;
begin
begin
- mRevert := r;
- reset();
+ result := mLength <= 0
end;
end;
+function TAnimState.IsValid (): Boolean;
+begin
+ result := mLength > 0
+end;
-procedure TAnimation.saveState (st: TStream);
+procedure TAnimState.saveState (st: TStream; mAlpha: Byte; mBlending: Boolean);
begin
if (st = nil) then exit;
utils.writeSign(st, 'ANIM');
utils.writeInt(st, Byte(0)); // version
begin
if (st = nil) then exit;
utils.writeSign(st, 'ANIM');
utils.writeInt(st, Byte(0)); // version
- // Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè
utils.writeInt(st, Byte(mCounter));
utils.writeInt(st, Byte(mCounter));
- // Òåêóùèé êàäð
utils.writeInt(st, LongInt(mCurrentFrame));
utils.writeInt(st, LongInt(mCurrentFrame));
- // Ïðîèãðàíà ëè àíèìàöèÿ öåëèêîì
utils.writeBool(st, mPlayed);
utils.writeBool(st, mPlayed);
- // Alpha-êàíàë âñåé òåêñòóðû
utils.writeInt(st, Byte(mAlpha));
utils.writeInt(st, Byte(mAlpha));
- // Ðàçìûòèå òåêñòóðû
utils.writeInt(st, Byte(mBlending));
utils.writeInt(st, Byte(mBlending));
- // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè
utils.writeInt(st, Byte(mSpeed));
utils.writeInt(st, Byte(mSpeed));
- // Çàöèêëåíà ëè àíèìàöèÿ
utils.writeBool(st, mLoop);
utils.writeBool(st, mLoop);
- // Âêëþ÷åíà ëè
utils.writeBool(st, mEnabled);
utils.writeBool(st, mEnabled);
- // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ
utils.writeInt(st, Byte(mMinLength));
utils.writeInt(st, Byte(mMinLength));
- // Îáðàòíûé ëè ïîðÿäîê êàäðîâ
utils.writeBool(st, mRevert);
end;
utils.writeBool(st, mRevert);
end;
-procedure TAnimation.loadState (st: TStream);
+procedure TAnimState.loadState (st: TStream; out mAlpha: Byte; out mBlending: Boolean);
begin
if (st = nil) then exit;
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');
begin
if (st = nil) then exit;
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);
mCounter := utils.readByte(st);
- // Òåêóùèé êàäð
mCurrentFrame := utils.readLongInt(st);
mCurrentFrame := utils.readLongInt(st);
- // Ïðîèãðàíà ëè àíèìàöèÿ öåëèêîì
mPlayed := utils.readBool(st);
mPlayed := utils.readBool(st);
- // Alpha-êàíàë âñåé òåêñòóðû
mAlpha := utils.readByte(st);
mAlpha := utils.readByte(st);
- // Ðàçìûòèå òåêñòóðû
mBlending := utils.readBool(st);
mBlending := utils.readBool(st);
- // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè
mSpeed := utils.readByte(st);
mSpeed := utils.readByte(st);
- // Çàöèêëåíà ëè àíèìàöèÿ
mLoop := utils.readBool(st);
mLoop := utils.readBool(st);
- // Âêëþ÷åíà ëè
mEnabled := utils.readBool(st);
mEnabled := utils.readBool(st);
- // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ
mMinLength := utils.readByte(st);
mMinLength := utils.readByte(st);
- // Îáðàòíûé ëè ïîðÿäîê êàäðîâ
mRevert := utils.readBool(st);
end;
mRevert := utils.readBool(st);
end;
-// ////////////////////////////////////////////////////////////////////////// //
-var
- ltexid: GLuint = 0;
-
-function g_Texture_Light (): Integer;
-const
- Radius: Integer = 128;
-var
- tex, tpp: PByte;
- x, y, a: Integer;
- dist: Double;
-begin
- if ltexid = 0 then
- begin
- GetMem(tex, (Radius*2)*(Radius*2)*4);
- tpp := tex;
- for y := 0 to Radius*2-1 do
- begin
- for x := 0 to Radius*2-1 do
- begin
- dist := 1.0-sqrt((x-Radius)*(x-Radius)+(y-Radius)*(y-Radius))/Radius;
- if (dist < 0) then
- begin
- tpp^ := 0; Inc(tpp);
- tpp^ := 0; Inc(tpp);
- tpp^ := 0; Inc(tpp);
- tpp^ := 0; Inc(tpp);
- end
- else
- begin
- //tc.setPixel(x, y, Color(cast(int)(dist*255), cast(int)(dist*255), cast(int)(dist*255)));
- if (dist > 0.5) then dist := 0.5;
- a := round(dist*255);
- if (a < 0) then a := 0 else if (a > 255) then a := 255;
- tpp^ := 255; Inc(tpp);
- tpp^ := 255; Inc(tpp);
- tpp^ := 255; Inc(tpp);
- tpp^ := Byte(a); Inc(tpp);
- end;
- end;
- end;
-
- glGenTextures(1, @ltexid);
- //if (tid == 0) assert(0, "VGL: can't create screen texture");
-
- glBindTexture(GL_TEXTURE_2D, ltexid);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- //GLfloat[4] bclr = 0.0;
- //glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, bclr.ptr);
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Radius*2, Radius*2, 0, GL_RGBA{gltt}, GL_UNSIGNED_BYTE, tex);
- end;
-
- result := ltexid;
-end;
-
-
end.
end.