summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 7f582aa)
raw | patch | inline | side by side (parent: 7f582aa)
author | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Mon, 13 Jun 2022 16:03:33 +0000 (19:03 +0300) | ||
committer | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Fri, 9 Jun 2023 08:44:07 +0000 (11:44 +0300) |
22 files changed:
diff --git a/src/game/Doom2DF.lpr b/src/game/Doom2DF.lpr
index d5e43767143bf0f5fbe8c4df0f705948acc526f7..98c39b5d6c5b15c55b27976b3878433cdea94d66 100644 (file)
--- a/src/game/Doom2DF.lpr
+++ b/src/game/Doom2DF.lpr
g_playermodel in 'g_playermodel.pas',
g_saveload in 'g_saveload.pas',
g_sound in 'g_sound.pas',
- g_textures in 'g_textures.pas',
+ g_animations in 'g_animations.pas',
g_triggers in 'g_triggers.pas',
g_weapons in 'g_weapons.pas',
g_window in 'g_window.pas',
diff --git a/src/game/g_animations.pas b/src/game/g_animations.pas
--- /dev/null
@@ -0,0 +1,290 @@
+(* 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 <http://www.gnu.org/licenses/>.
+ *)
+{$INCLUDE ../shared/a_modes.inc}
+unit g_animations;
+
+interface
+
+ uses Classes;
+
+ type
+ TAnimState = record
+ private
+ mCounter: Byte; // delay counter (normally [0..mSpeed])
+ mSpeed: Byte; // delay between frames
+ mCurrentFrame: Integer; // current frame (normally [0..mLength - 1])
+ mLoop: Boolean; // looped animation
+ mEnabled: Boolean; // allow update state
+ mPlayed: Boolean; // anmation played at least once
+ mMinLength: Byte; // delay at animation end
+ mRevert: Boolean; // reverse play
+ mLength: Integer; // total frames (normally mLength > 0)
+
+ public
+ constructor Create (aloop: Boolean; aspeed: Byte; len: Integer);
+ procedure Invalidate;
+
+ procedure Reset;
+ procedure Update;
+ procedure Enable;
+ procedure Disable;
+ procedure Revert (r: Boolean);
+
+ procedure SaveState (st: TStream; mAlpha: Byte; mBlending: Boolean);
+ procedure LoadState (st: TStream; out mAlpha: Byte; out mBlending: Boolean);
+
+ function TotalFrames (): Integer; inline;
+ function IsInvalid (): Boolean; inline;
+ function IsValid (): Boolean; inline;
+
+ 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;
+
+ type
+ TAnimInfo = record
+ loop: Boolean; (* loop animation normalization *)
+ delay: Byte; (* delay between frames [1..255] *)
+ frames: Word; (* number of frames in animation stream [1..65535] *)
+ back: Boolean; (* back animation normalization *)
+ end;
+
+ function g_Anim_GetTotalFrames (const a: TAnimInfo): LongWord;
+ function g_Anim_GetTotalTime (const a: TAnimInfo): LongWord;
+ function g_Anim_GetCountByTime (const a: TAnimInfo; time: LongWord): LongInt;
+ procedure g_Anim_GetFrameByTime (const a: TAnimInfo; time: LongWord; out count, frame: LongInt);
+ procedure g_Anim_GetState (const anim: TAnimInfo; time: LongWord; out state: TAnimState);
+
+implementation
+
+ uses Math, utils, xstreams;
+
+ constructor TAnimState.Create (aloop: Boolean; aspeed: Byte; len: Integer);
+ begin
+ ASSERT(len >= 0);
+
+ self := Default(TAnimState);
+ self.mLength := len;
+ self.mMinLength := 0;
+ self.mLoop := aloop;
+ self.mSpeed := aspeed;
+ self.mEnabled := true;
+ self.mCurrentFrame := 0;
+ self.mPlayed := false;
+ end;
+
+ procedure TAnimState.Invalidate;
+ begin
+ self := Default(TAnimState);
+ end;
+
+ procedure TAnimState.Update;
+ begin
+ ASSERT(self.IsValid());
+ if self.mEnabled then
+ begin
+ INC(self.mCounter);
+ if self.mCounter >= self.mSpeed then
+ begin
+ if self.mRevert then
+ begin
+ if (self.mCurrentFrame <> 0) or (mLength * mSpeed + mCounter >= mMinLength) then
+ begin
+ DEC(self.mCurrentFrame);
+ self.mPlayed := self.mCurrentFrame < 0;
+ if self.mPlayed then
+ begin
+ if self.mLoop then self.mCurrentFrame := self.mLength - 1 else INC(self.mCurrentFrame);
+ end;
+ self.mCounter := 0;
+ end;
+ end
+ else
+ begin
+ if (self.mCurrentFrame <> self.mLength - 1) or (mLength * mSpeed + mCounter >= mMinLength) then
+ begin
+ INC(self.mCurrentFrame);
+ self.mPlayed := self.mCurrentFrame > self.mLength - 1;
+ if self.mPlayed then
+ begin
+ if self.mLoop then self.mCurrentFrame := 0 else DEC(self.mCurrentFrame);
+ end;
+ self.mCounter := 0;
+ end;
+ end;
+ end;
+ end;
+ end;
+
+ procedure TAnimState.Reset;
+ begin
+ ASSERT(self.IsValid());
+ if self.mRevert then self.mCurrentFrame := self.mLength - 1 else self.mCurrentFrame := 0;
+ self.mCounter := 0;
+ self.mPlayed := false;
+ end;
+
+ procedure TAnimState.Disable;
+ begin
+ ASSERT(self.IsValid());
+ self.mEnabled := false;
+ end;
+
+ procedure TAnimState.Enable;
+ begin
+ ASSERT(self.IsValid());
+ self.mEnabled := true;
+ end;
+
+ procedure TAnimState.revert (r: Boolean);
+ begin
+ ASSERT(self.IsValid());
+ self.mRevert := r;
+ self.Reset;
+ end;
+
+ function TAnimState.TotalFrames (): Integer;
+ begin
+ ASSERT(self.IsValid());
+ result := self.mLength;
+ end;
+
+ function TAnimState.IsInvalid (): Boolean;
+ begin
+ result := self.mLength <= 0
+ end;
+
+ function TAnimState.IsValid (): Boolean;
+ begin
+ result := self.mLength > 0;
+ end;
+
+ procedure TAnimState.SaveState (st: TStream; mAlpha: Byte; mBlending: Boolean);
+ begin
+ if st <> nil then
+ begin
+ 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;
+ end;
+
+ procedure TAnimState.LoadState (st: TStream; out mAlpha: Byte; out mBlending: Boolean);
+ begin
+ if st <> nil then
+ begin
+ if utils.checkSign(st, 'ANIM') = false 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;
+ end;
+
+ function g_Anim_GetTotalFrames (const a: TAnimInfo): LongWord;
+ begin
+ ASSERT(a.frames > 0);
+ ASSERT(a.delay > 0);
+ if a.back then result := MAX(1, a.frames * 2 - 2) else result := a.frames;
+ end;
+
+ function g_Anim_GetTotalTime (const a: TAnimInfo): LongWord;
+ begin
+ ASSERT(a.frames > 0);
+ ASSERT(a.delay > 0);
+ result := g_Anim_GetTotalFrames(a) * a.delay;
+ end;
+
+ function g_Anim_GetCountByTime (const a: TAnimInfo; time: LongWord): LongInt;
+ var n, f, t: LongWord;
+ begin
+ ASSERT(a.frames > 0);
+ ASSERT(a.delay > 0);
+ n := g_Anim_GetTotalFrames(a);
+ t := g_Anim_GetTotalTime(a);
+ f := n * time div t;
+ if a.loop then result := f div n
+ else if f >= n then result := 1
+ else result := 0;
+ end;
+
+ procedure g_Anim_GetFrameByTime (const a: TAnimInfo; time: LongWord; out count, frame: LongInt);
+ var n, f, t: LongWord;
+ begin
+ ASSERT(a.frames > 0);
+ ASSERT(a.delay > 0);
+ (* 1. Get total number frames for one animation cycle *)
+ n := g_Anim_GetTotalFrames(a);
+ (* 2. Get time for one animation cycle *)
+ t := g_Anim_GetTotalTime(a);
+ (* 3. Get frame for specified time *)
+ f := n * time div t;
+ (* 4. Get how many times is played *)
+ if a.loop then count := f div n
+ else if f >= n then count := 1
+ else count := 0;
+ (* 5. Normalize loop animation *)
+ if a.loop then f := f mod n else f := MIN(f, n - 1);
+ (* 6. Normalize back animation *)
+ if a.back and (f >= a.frames) then f := n - f;
+ frame := f;
+ end;
+
+ procedure g_Anim_GetState (const anim: TAnimInfo; time: LongWord; out state: TAnimState);
+ var count, frame: LongInt; a: TAnimInfo;
+ begin
+ ASSERT(anim.frames > 0);
+ ASSERT(anim.delay > 0);
+ a := anim;
+ if a.back then
+ begin
+ a.frames := MAX(1, a.frames * 2 - 2);
+ a.back := false;
+ end;
+ g_Anim_GetFrameByTime(a, time, count, frame);
+ state := TAnimState.Create(a.loop, a.delay, a.frames);
+ state.mCounter := time MOD a.delay;
+ state.mCurrentFrame := frame;
+ state.mPlayed := count >= 1;
+ end;
+
+end.
diff --git a/src/game/g_console.pas b/src/game/g_console.pas
index c9cc11e9859756a3b28e3f2788ffce0aaa5c5d0a..3005340534c6eec96e5553e1d1e7eef3eb3a51e9 100644 (file)
--- a/src/game/g_console.pas
+++ b/src/game/g_console.pas
{$IFDEF ENABLE_CORPSES}
g_corpses,
{$ENDIF}
- g_textures, e_input, g_game, g_player, g_items,
+ e_input, g_game, g_player, g_items,
SysUtils, g_basic, g_options, Math, e_res,
g_language, g_net, g_netmsg, e_log, conbuf, g_weapons,
Keyboard;
diff --git a/src/game/g_corpses.pas b/src/game/g_corpses.pas
index 8869e8a54af2729e10b705a7d7a0705a4e301578..b606a5ba9850a13046fa5cff7100045395261eb8 100644 (file)
--- a/src/game/g_corpses.pas
+++ b/src/game/g_corpses.pas
{$ENDIF}
Math,
utils, g_saveload, xstreams,
- g_game, g_textures, g_map
+ g_game, g_animations, g_map
;
var
diff --git a/src/game/g_gfx.pas b/src/game/g_gfx.pas
index 9cc665ccaadb5d2afe671d89739b86391f403d60..0be98e38498e8d47720d62c152186c5246530dd6 100644 (file)
--- a/src/game/g_gfx.pas
+++ b/src/game/g_gfx.pas
interface
-uses
- e_log, g_textures;
+uses e_log;
const
BLOOD_NORMAL = 0;
diff --git a/src/game/g_map.pas b/src/game/g_map.pas
index b7b3d45ff2a6eb5a94be530f54493d5e6f9be296..03c029f6404dad7c884a4647d9752216b9ab6482 100644 (file)
--- a/src/game/g_map.pas
+++ b/src/game/g_map.pas
uses
SysUtils, Classes, mempool,
- g_base, g_basic, MAPDEF, g_textures,
+ g_base, g_basic, MAPDEF,
g_phys, utils, g_panel, g_grid, md5, binheap, xprofiler, xparser, xdynrec;
type
index d6d65d32cf2a9c0ba220880097d42a020a0c3700..718921baf0934e810cc9db38725f7c7396b52692 100644 (file)
--- a/src/game/g_monsters.pas
+++ b/src/game/g_monsters.pas
SysUtils, Classes,
mempool,
MAPDEF,
- g_base, g_basic, g_phys, g_textures, g_grid,
+ g_base, g_basic, g_phys, g_animations, g_grid,
g_saveload, g_panel, xprofiler;
const
diff --git a/src/game/g_netmsg.pas b/src/game/g_netmsg.pas
index 85ff2706e0cec5dd1c46fe70249b55642e3acb3a..08fd9df69598dd87840cabd9fc700ec104c4b37b 100644 (file)
--- a/src/game/g_netmsg.pas
+++ b/src/game/g_netmsg.pas
g_corpses,
{$ENDIF}
Math, ENet, e_input, e_log, g_base, g_basic,
- g_textures, g_sound, g_console, g_options,
+ g_sound, g_console, g_options,
g_game, g_player, g_map, g_panel, g_items, g_weapons, g_phys,
g_language, g_monsters, g_netmaster, utils, wadreader, MAPDEF
;
diff --git a/src/game/g_panel.pas b/src/game/g_panel.pas
index 07bd4ec95d088c7413f41eb2f8254e3b9cf8a26b..58e7477c6f84d275e67384a718dd4e49a828dcf9 100644 (file)
--- a/src/game/g_panel.pas
+++ b/src/game/g_panel.pas
uses
SysUtils, Classes,
- MAPDEF, g_textures, xdynrec;
+ MAPDEF, g_animations, xdynrec;
type
+ TLevelTexture = record
+ TextureName: AnsiString; // as stored in wad
+ FullName: AnsiString; // full path to texture // !!! merge it with TextureName
+ framesCount, speed: Byte;
+ end;
+
+ TLevelTextureArray = array of TLevelTexture;
+
TAddTextureArray = array of record
Texture: Cardinal; // Textures[Texture]
end;
diff --git a/src/game/g_player.pas b/src/game/g_player.pas
index 312f186db0e7bca4cd4823bdcec36a7dd2592537..b3c8fecedec8c6e6a3e08f3e57fe83dea84837eb 100644 (file)
--- a/src/game/g_player.pas
+++ b/src/game/g_player.pas
uses
SysUtils, Classes,
{$IFDEF USE_MEMPOOL}mempool,{$ENDIF}
- g_base, g_playermodel, g_basic, g_textures,
+ g_base, g_playermodel, g_basic, g_animations,
g_weapons, g_phys, g_sound, g_saveload, MAPDEF,
g_panel;
index 4f4d709182bb491668c4f29f5de076ca4e0867e4..7a55bf758b8b9744c5a7883c43fbcb0659d23351 100644 (file)
interface
- uses MAPDEF, g_textures, g_base, g_basic, g_weapons, utils;
+ uses MAPDEF, g_animations, g_base, g_basic, g_weapons, utils;
const
A_STAND = 0;
type
TWeaponPoints = Array [WP_FIRST + 1..WP_LAST, A_STAND..A_LAST, TDirection.D_LEFT..TDirection.D_RIGHT] of Array of TDFPoint;
- TModelMatrix = Array [TDirection.D_LEFT..TDirection.D_RIGHT, A_STAND..A_LAST] of TAnimState;
-
TModelTextures = Array [TDirection.D_LEFT..TDirection.D_RIGHT, A_STAND..A_LAST] of record
Resource: String;
Mask: String;
{ TPlayerModel }
procedure TPlayerModel.ChangeAnimation (Animation: Byte; Force: Boolean = False);
- var once: Boolean; speed, count: Integer;
+ var loop: Boolean; speed, count: Integer;
begin
if not Force then
if FCurrentAnimation = Animation then
Exit;
FCurrentAnimation := Animation;
- once := FCurrentAnimation in [A_STAND, A_WALK];
+ loop := FCurrentAnimation in [A_STAND, A_WALK];
speed := PlayerModelsArray[FID].ModelSpeed[FCurrentAnimation];
count := PlayerModelsArray[FID].Anim[FDirection, FCurrentAnimation].Frames;
- FAnimState := TAnimState.Create(once, speed, count);
+ FAnimState := TAnimState.Create(loop, speed, count);
end;
destructor TPlayerModel.Destroy();
index 6c101a66d0fc65c148d18e7289dbd956a3718b46..f513f3af436b32fa27482cd5ab9eb6d00e783c36 100644 (file)
--- a/src/game/g_saveload.pas
+++ b/src/game/g_saveload.pas
interface
uses
- SysUtils, Classes, g_phys, g_textures;
+ SysUtils, Classes, g_phys;
function g_GetSaveName (n: Integer; out valid: Boolean): AnsiString;
diff --git a/src/game/g_textures.pas b/src/game/g_textures.pas
--- a/src/game/g_textures.pas
+++ /dev/null
@@ -1,230 +0,0 @@
-(* 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 <http://www.gnu.org/licenses/>.
- *)
-{$INCLUDE ../shared/a_modes.inc}
-unit g_textures;
-
-interface
-
-uses
- SysUtils, Classes,
- {$IFDEF USE_MEMPOOL}mempool,{$ENDIF}
- g_base, MAPDEF;
-
-type
- TLevelTexture = record
- TextureName: AnsiString; // as stored in wad
- FullName: AnsiString; // full path to texture // !!! merge it with TextureName
- framesCount, speed: Byte;
- end;
-
- TLevelTextureArray = array of TLevelTexture;
-
- TAnimState = record
- private
- mCounter: Byte; // Ñ÷åò÷èê îæèäàíèÿ ìåæäó êàäðàìè
- mSpeed: Byte; // Âðåìÿ îæèäàíèÿ ìåæäó êàäðàìè
- mCurrentFrame: Integer; // Òåêóùèé êàäð (íà÷èíàÿ ñ 0)
- mLoop: Boolean; // Ïåðåõîäèòü íà ïåðâûé êàäð ïîñëå ïîñëåäíåãî?
- mEnabled: Boolean; // Ðàáîòà ðàçðåøåíà?
- mPlayed: Boolean; // Ïðîèãðàíà âñÿ õîòÿ áû ðàç?
- mMinLength: Byte; // Îæèäàíèå ïîñëå ïðîèãðûâàíèÿ
- mRevert: Boolean; // Ñìåíà êàäðîâ îáðàòíàÿ?
-
- mLength: Integer;
-
- public
- constructor Create (aloop: Boolean; aspeed: Byte; len: Integer);
- procedure Invalidate;
-
- procedure reset ();
- procedure update ();
- procedure enable ();
- procedure disable ();
- procedure revert (r: Boolean);
-
- procedure saveState (st: TStream; mAlpha: Byte; mBlending: Boolean);
- procedure loadState (st: TStream; out mAlpha: Byte; out mBlending: Boolean);
-
- 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,
- g_language, utils, xstreams;
-
-constructor TAnimState.Create (aloop: Boolean; aspeed: Byte; len: Integer);
-begin
- Self := Default(TAnimState);
-
- assert(len >= 0);
- mLength := len;
-
- mMinLength := 0;
- mLoop := aloop;
- mSpeed := aspeed;
- mEnabled := true;
- mCurrentFrame := 0;
- mPlayed := false;
-end;
-
-procedure TAnimState.Invalidate;
-begin
- Self := Default(TAnimState);
-end;
-
-procedure TAnimState.update;
-begin
- if (not mEnabled) then exit;
-
- mCounter += 1;
-
- if (mCounter >= mSpeed) then
- begin
- if mRevert then
- begin
- if (mCurrentFrame = 0) then
- begin
- if (mLength * mSpeed + mCounter < mMinLength) then exit;
- end;
-
- mCurrentFrame -= 1;
- mPlayed := (mCurrentFrame < 0);
-
- if mPlayed then
- begin
- if mLoop then
- mCurrentFrame := mLength - 1
- else
- mCurrentFrame += 1
- end;
-
- mCounter := 0;
- end
- else
- begin
- if (mCurrentFrame = mLength - 1) then
- begin
- if (mLength * mSpeed + mCounter < mMinLength) then exit;
- end;
-
- mCurrentFrame += 1;
- mPlayed := (mCurrentFrame > mLength - 1);
-
- if mPlayed then
- begin
- if mLoop then mCurrentFrame := 0 else mCurrentFrame -= 1;
- end;
-
- mCounter := 0;
- end;
- end;
-end;
-
-procedure TAnimState.reset;
-begin
- if mRevert then
- mCurrentFrame := mLength - 1
- else
- mCurrentFrame := 0;
- mCounter := 0;
- mPlayed := false
-end;
-
-procedure TAnimState.disable;
-begin
- mEnabled := false
-end;
-
-procedure TAnimState.enable;
-begin
- mEnabled := true
-end;
-
-procedure TAnimState.revert (r: Boolean);
-begin
- mRevert := r;
- reset
-end;
-
-function TAnimState.totalFrames (): Integer; inline;
-begin
- result := mLength
-end;
-
-function TAnimState.IsInvalid (): Boolean;
-begin
- result := mLength <= 0
-end;
-
-function TAnimState.IsValid (): Boolean;
-begin
- result := mLength > 0
-end;
-
-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
- 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;
-
-
-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');
- 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;
-
-
-end.
diff --git a/src/game/g_weapons.pas b/src/game/g_weapons.pas
index 365396369efbf9ace4a41591da97b31889c6ce5c..2b38de319c037678141d76fbbd67259ceafaa92c 100644 (file)
--- a/src/game/g_weapons.pas
+++ b/src/game/g_weapons.pas
uses
SysUtils, Classes, mempool,
- g_textures, g_basic, g_phys, xprofiler;
+ g_animations, g_basic, g_phys, xprofiler;
type
index 26d15c7a087cd1d259e439e237ae4af28ed6f27d..76426d548f06a107cb6eb139ac19ccb91efd7334 100644 (file)
interface
- uses g_base, g_textures, MAPDEF, Imaging; // TMirrorType, TAnimationState, TDFPoint, TDynImageDataArray
+ uses g_base, g_animations, MAPDEF, Imaging; // TMirrorType, TAnimationState, TDFPoint, TDynImageDataArray
procedure r_AnimState_Draw (FID: DWORD; const t: TAnimState; x, y: Integer; alpha: Byte; mirror: TMirrorType; blending: Boolean);
procedure r_AnimState_DrawEx (FID: DWORD; const t: TAnimState; x, y: Integer; alpha: Byte; mirror: TMirrorType; blending: Boolean; rpoint: TDFPoint; angle: SmallInt);
index afdadd97d76198e4f20e8ebfaabe35ea02262811..1800c78fb5c82b2506d38191be7a70e62d081901 100644 (file)
SysUtils, Classes, Math,
utils,
g_base, r_graphics, g_options, r_animations,
- g_game, g_textures,
+ g_game, g_animations,
g_gfx
;
index 168d740e804bad69eb1aa0cb83fe64dd0aa6c2f0..d29ccc296a0eba8c1ca857ff580d9cf705b79f59 100644 (file)
uses
SysUtils, Classes, Math,
r_graphics, r_animations, r_textures,
- g_base, g_basic, g_game, g_options, g_textures,
+ g_base, g_basic, g_game, g_options, g_animations,
g_items
;
index 9a6235c8b1b3b1d153a39358ed001620d0a63cf8..a35980d798eb0b9f5f301152f515435f31832a3f 100644 (file)
uses
{$INCLUDE ../nogl/noGLuses.inc}
SysUtils, Classes, Math, e_log, wadreader, CONFIG, utils, g_language,
- r_graphics, r_animations, r_textures, g_textures,
+ r_graphics, r_animations, r_textures, g_animations,
g_base, g_basic, g_game, g_options,
g_map
;
index 5ab33e9ae2b3d14736634e423325f32508c0530f..aefbabbb9144cca15a9bf7a6a16fb91aaf61b59d 100644 (file)
MAPDEF, utils, e_log, wadreader,
ImagingTypes, Imaging, ImagingUtility,
r_graphics, g_options, r_animations, r_textures,
- g_basic, g_map, g_weapons, g_textures, g_player, g_phys, g_game
+ g_basic, g_map, g_weapons, g_animations, g_player, g_phys, g_game
;
const
index bdd60714db8713181a7d91a49bb096b56f687bcf..fbdae7e4ee8e09cdfd307dc29365d7b322f88149 100644 (file)
interface
uses
- g_textures,
+ g_animations,
r_textures
;
index 4f0621d452ac7f9abfde5904ecd0e3b48e94a13f..4ffd6e18345e203525615484b677c7390e090f50 100644 (file)
procedure r_Map_DrawPlayerModel (pm: TPlayerModel; x, y: Integer; alpha: Byte);
{$ENDIF}
-
procedure r_Map_Update;
procedure r_Map_Draw (x, y, w, h, camx, camy: Integer; player: TPlayer);
{$ENDIF}
e_log,
binheap, MAPDEF, utils,
- g_options, g_textures, g_basic, g_phys,
+ g_options, g_animations, g_basic, g_phys,
g_game, g_map, g_panel, g_items, g_monsters, g_weapons,
{$IFDEF ENABLE_CORPSES}
g_corpses,
ItemAnim: array [0..ITEM_LAST] of record
name: AnsiString;
w, h: Integer;
- d: Integer; // delay
- n: Integer; // count
- b: Boolean; // backanim
+ anim: TAnimInfo;
end = (
- (name: ''; w: 0; h: 0; d: 0; n: 0; b: False),
- (name: 'MED1'; w: 16; h: 16; d: 0; n: 1; b: False),
- (name: 'MED2'; w: 32; h: 32; d: 0; n: 1; b: False),
- (name: 'BMED'; w: 32; h: 32; d: 0; n: 1; b: False),
- (name: 'ARMORGREEN'; w: 32; h: 16; d: 20; n: 3; b: True),
- (name: 'ARMORBLUE'; w: 32; h: 16; d: 20; n: 3; b: True),
- (name: 'SBLUE'; w: 32; h: 32; d: 15; n: 4; b: True),
- (name: 'SWHITE'; w: 32; h: 32; d: 20; n: 4; b: True),
- (name: 'SUIT'; w: 32; h: 64; d: 0; n: 1; b: False),
- (name: 'OXYGEN'; w: 16; h: 32; d: 0; n: 1; b: False),
- (name: 'INVUL'; w: 32; h: 32; d: 20; n: 4; b: True),
- (name: 'SAW'; w: 64; h: 32; d: 0; n: 1; b: False),
- (name: 'SHOTGUN1'; w: 64; h: 16; d: 0; n: 1; b: False),
- (name: 'SHOTGUN2'; w: 64; h: 16; d: 0; n: 1; b: False),
- (name: 'MGUN'; w: 64; h: 16; d: 0; n: 1; b: False),
- (name: 'RLAUNCHER'; w: 64; h: 16; d: 0; n: 1; b: False),
- (name: 'PGUN'; w: 64; h: 16; d: 0; n: 1; b: False),
- (name: 'BFG'; w: 64; h: 64; d: 0; n: 1; b: False),
- (name: 'SPULEMET'; w: 64; h: 16; d: 0; n: 1; b: False),
- (name: 'CLIP'; w: 16; h: 16; d: 0; n: 1; b: False),
- (name: 'AMMO'; w: 32; h: 16; d: 0; n: 1; b: False),
- (name: 'SHELL1'; w: 16; h: 8; d: 0; n: 1; b: False),
- (name: 'SHELL2'; w: 32; h: 16; d: 0; n: 1; b: False),
- (name: 'ROCKET'; w: 16; h: 32; d: 0; n: 1; b: False),
- (name: 'ROCKETS'; w: 64; h: 32; d: 0; n: 1; b: False),
- (name: 'CELL'; w: 16; h: 16; d: 0; n: 1; b: False),
- (name: 'CELL2'; w: 32; h: 32; d: 0; n: 1; b: False),
- (name: 'BPACK'; w: 32; h: 32; d: 0; n: 1; b: False),
- (name: 'KEYR'; w: 16; h: 16; d: 0; n: 1; b: False),
- (name: 'KEYG'; w: 16; h: 16; d: 0; n: 1; b: False),
- (name: 'KEYB'; w: 16; h: 16; d: 0; n: 1; b: False),
- (name: 'KASTET'; w: 64; h: 32; d: 0; n: 1; b: False),
- (name: 'PISTOL'; w: 64; h: 16; d: 0; n: 1; b: False),
- (name: 'BOTTLE'; w: 16; h: 32; d: 20; n: 4; b: True),
- (name: 'HELMET'; w: 16; h: 16; d: 20; n: 4; b: True),
- (name: 'JETPACK'; w: 32; h: 32; d: 15; n: 3; b: True),
- (name: 'INVIS'; w: 32; h: 32; d: 20; n: 4; b: True),
- (name: 'FLAMETHROWER'; w: 64; h: 32; d: 0; n: 1; b: False),
- (name: 'FUELCAN'; w: 16; h: 32; d: 0; n: 1; b: False)
+ (name: 'NOTEXTURE'; w: 16; h: 16; anim: (loop: true; delay: 1; frames: 1; back: false)),
+ (name: 'MED1'; w: 16; h: 16; anim: (loop: true; delay: 1; frames: 1; back: false)),
+ (name: 'MED2'; w: 32; h: 32; anim: (loop: true; delay: 1; frames: 1; back: false)),
+ (name: 'BMED'; w: 32; h: 32; anim: (loop: true; delay: 1; frames: 1; back: false)),
+ (name: 'ARMORGREEN'; w: 32; h: 16; anim: (loop: true; delay: 20; frames: 3; back: true)),
+ (name: 'ARMORBLUE'; w: 32; h: 16; anim: (loop: true; delay: 20; frames: 3; back: true)),
+ (name: 'SBLUE'; w: 32; h: 32; anim: (loop: true; delay: 15; frames: 4; back: true)),
+ (name: 'SWHITE'; w: 32; h: 32; anim: (loop: true; delay: 20; frames: 4; back: true)),
+ (name: 'SUIT'; w: 32; h: 64; anim: (loop: true; delay: 1; frames: 1; back: false)),
+ (name: 'OXYGEN'; w: 16; h: 32; anim: (loop: true; delay: 1; frames: 1; back: false)),
+ (name: 'INVUL'; w: 32; h: 32; anim: (loop: true; delay: 20; frames: 4; back: true)),
+ (name: 'SAW'; w: 64; h: 32; anim: (loop: true; delay: 1; frames: 1; back: false)),
+ (name: 'SHOTGUN1'; w: 64; h: 16; anim: (loop: true; delay: 1; frames: 1; back: false)),
+ (name: 'SHOTGUN2'; w: 64; h: 16; anim: (loop: true; delay: 1; frames: 1; back: false)),
+ (name: 'MGUN'; w: 64; h: 16; anim: (loop: true; delay: 1; frames: 1; back: false)),
+ (name: 'RLAUNCHER'; w: 64; h: 16; anim: (loop: true; delay: 1; frames: 1; back: false)),
+ (name: 'PGUN'; w: 64; h: 16; anim: (loop: true; delay: 1; frames: 1; back: false)),
+ (name: 'BFG'; w: 64; h: 64; anim: (loop: true; delay: 1; frames: 1; back: false)),
+ (name: 'SPULEMET'; w: 64; h: 16; anim: (loop: true; delay: 1; frames: 1; back: false)),
+ (name: 'CLIP'; w: 16; h: 16; anim: (loop: true; delay: 1; frames: 1; back: false)),
+ (name: 'AMMO'; w: 32; h: 16; anim: (loop: true; delay: 1; frames: 1; back: false)),
+ (name: 'SHELL1'; w: 16; h: 8; anim: (loop: true; delay: 1; frames: 1; back: false)),
+ (name: 'SHELL2'; w: 32; h: 16; anim: (loop: true; delay: 1; frames: 1; back: false)),
+ (name: 'ROCKET'; w: 16; h: 32; anim: (loop: true; delay: 1; frames: 1; back: false)),
+ (name: 'ROCKETS'; w: 64; h: 32; anim: (loop: true; delay: 1; frames: 1; back: false)),
+ (name: 'CELL'; w: 16; h: 16; anim: (loop: true; delay: 1; frames: 1; back: false)),
+ (name: 'CELL2'; w: 32; h: 32; anim: (loop: true; delay: 1; frames: 1; back: false)),
+ (name: 'BPACK'; w: 32; h: 32; anim: (loop: true; delay: 1; frames: 1; back: false)),
+ (name: 'KEYR'; w: 16; h: 16; anim: (loop: true; delay: 1; frames: 1; back: false)),
+ (name: 'KEYG'; w: 16; h: 16; anim: (loop: true; delay: 1; frames: 1; back: false)),
+ (name: 'KEYB'; w: 16; h: 16; anim: (loop: true; delay: 1; frames: 1; back: false)),
+ (name: 'KASTET'; w: 64; h: 32; anim: (loop: true; delay: 1; frames: 1; back: false)),
+ (name: 'PISTOL'; w: 64; h: 16; anim: (loop: true; delay: 1; frames: 1; back: false)),
+ (name: 'BOTTLE'; w: 16; h: 32; anim: (loop: true; delay: 20; frames: 4; back: true)),
+ (name: 'HELMET'; w: 16; h: 16; anim: (loop: true; delay: 20; frames: 4; back: true)),
+ (name: 'JETPACK'; w: 32; h: 32; anim: (loop: true; delay: 15; frames: 3; back: true)),
+ (name: 'INVIS'; w: 32; h: 32; anim: (loop: true; delay: 20; frames: 4; back: true)),
+ (name: 'FLAMETHROWER'; w: 64; h: 32; anim: (loop: true; delay: 1; frames: 1; back: false)),
+ (name: 'FUELCAN'; w: 16; h: 32; anim: (loop: true; delay: 1; frames: 1; back: false))
);
{$IFDEF ENABLE_GFX}
GFXAnim: array [0..R_GFX_LAST] of record
name: AnsiString;
w, h: Integer;
- count: Integer;
- back: Boolean;
- speed: Integer;
- rspeed: Integer;
+ anim: TAnimInfo;
+ rdelay: Integer;
alpha: Integer;
end = (
- (name: ''; w: 0; h: 0; count: 0; back: false; speed: 0; rspeed: 0; alpha: 0),
- (name: 'TELEPORT'; w: 64; h: 64; count: 10; back: false; speed: 6; rspeed: 0; alpha: 0),
- (name: 'FLAME'; w: 32; h: 32; count: 11; back: false; speed: 3; rspeed: 0; alpha: 0),
- (name: 'EROCKET'; w: 128; h: 128; count: 6; back: false; speed: 6; rspeed: 0; alpha: 0),
- (name: 'EBFG'; w: 128; h: 128; count: 6; back: false; speed: 6; rspeed: 0; alpha: 0),
- (name: 'BFGHIT'; w: 64; h: 64; count: 4; back: false; speed: 4; rspeed: 0; alpha: 0),
- (name: 'FIRE'; w: 64; h: 128; count: 8; back: false; speed: 4; rspeed: 2; alpha: 0),
- (name: 'ITEMRESPAWN'; w: 32; h: 32; count: 5; back: true; speed: 4; rspeed: 0; alpha: 0),
- (name: 'SMOKE'; w: 32; h: 32; count: 10; back: false; speed: 3; rspeed: 0; alpha: 0),
- (name: 'ESKELFIRE'; w: 64; h: 64; count: 3; back: false; speed: 8; rspeed: 0; alpha: 0),
- (name: 'EPLASMA'; w: 32; h: 32; count: 4; back: true; speed: 3; rspeed: 0; alpha: 0),
- (name: 'EBSPFIRE'; w: 32; h: 32; count: 5; back: false; speed: 3; rspeed: 0; alpha: 0),
- (name: 'EIMPFIRE'; w: 64; h: 64; count: 3; back: false; speed: 6; rspeed: 0; alpha: 0),
- (name: 'ECACOFIRE'; w: 64; h: 64; count: 3; back: false; speed: 6; rspeed: 0; alpha: 0),
- (name: 'EBARONFIRE'; w: 64; h: 64; count: 3; back: false; speed: 6; rspeed: 0; alpha: 0),
- (name: 'TELEPORT'; w: 64; h: 64; count: 10; back: false; speed: 3; rspeed: 0; alpha: 0), // fast
- (name: 'SMOKE'; w: 32; h: 32; count: 10; back: false; speed: 3; rspeed: 0; alpha: 150), // transparent
- (name: 'FLAME'; w: 32; h: 32; count: 11; back: false; speed: 3; rspeed: 2; alpha: 0) // random
+ (name: ''; w: 0; h: 0; anim: (loop: false; delay: 0; frames: 0; back: false); rdelay: 0; alpha: 0),
+ (name: 'TELEPORT'; w: 64; h: 64; anim: (loop: false; delay: 6; frames: 10; back: false); rdelay: 0; alpha: 0),
+ (name: 'FLAME'; w: 32; h: 32; anim: (loop: false; delay: 3; frames: 11; back: false); rdelay: 0; alpha: 0),
+ (name: 'EROCKET'; w: 128; h: 128; anim: (loop: false; delay: 6; frames: 6; back: false); rdelay: 0; alpha: 0),
+ (name: 'EBFG'; w: 128; h: 128; anim: (loop: false; delay: 6; frames: 6; back: false); rdelay: 0; alpha: 0),
+ (name: 'BFGHIT'; w: 64; h: 64; anim: (loop: false; delay: 4; frames: 4; back: false); rdelay: 0; alpha: 0),
+ (name: 'FIRE'; w: 64; h: 128; anim: (loop: false; delay: 4; frames: 8; back: false); rdelay: 2; alpha: 0),
+ (name: 'ITEMRESPAWN'; w: 32; h: 32; anim: (loop: false; delay: 4; frames: 5; back: true); rdelay: 0; alpha: 0),
+ (name: 'SMOKE'; w: 32; h: 32; anim: (loop: false; delay: 3; frames: 10; back: false); rdelay: 0; alpha: 0),
+ (name: 'ESKELFIRE'; w: 64; h: 64; anim: (loop: false; delay: 8; frames: 3; back: false); rdelay: 0; alpha: 0),
+ (name: 'EPLASMA'; w: 32; h: 32; anim: (loop: false; delay: 3; frames: 4; back: true); rdelay: 0; alpha: 0),
+ (name: 'EBSPFIRE'; w: 32; h: 32; anim: (loop: false; delay: 3; frames: 5; back: false); rdelay: 0; alpha: 0),
+ (name: 'EIMPFIRE'; w: 64; h: 64; anim: (loop: false; delay: 6; frames: 3; back: false); rdelay: 0; alpha: 0),
+ (name: 'ECACOFIRE'; w: 64; h: 64; anim: (loop: false; delay: 6; frames: 3; back: false); rdelay: 0; alpha: 0),
+ (name: 'EBARONFIRE'; w: 64; h: 64; anim: (loop: false; delay: 6; frames: 3; back: false); rdelay: 0; alpha: 0),
+ (name: 'TELEPORT'; w: 64; h: 64; anim: (loop: false; delay: 3; frames: 10; back: false); rdelay: 0; alpha: 0), // fast
+ (name: 'SMOKE'; w: 32; h: 32; anim: (loop: false; delay: 3; frames: 10; back: false); rdelay: 0; alpha: 150), // transparent
+ (name: 'FLAME'; w: 32; h: 32; anim: (loop: false; delay: 3; frames: 11; back: false); rdelay: 2; alpha: 0) // random
);
{$ENDIF}
);
{$ENDIF}
+ FlagAnim: TAnimInfo = (loop: true; delay: 8; frames: 5; back: false);
+
type
TBinHeapPanelDrawCmp = class
public
end;
Items: array [0..ITEM_LAST] of record
tex: TGLMultiTexture;
- anim: TAnimState;
+ frame: Integer;
end;
MonTextures: array [0..MONSTER_MAN] of TMonsterAnims;
WeapTextures: array [0..WP_LAST, 0..W_POS_LAST, 0..W_ACT_LAST] of TGLTexture;
end;
StubShotAnim: TAnimState; // TODO remove this hack
- FlagAnim: TAnimState;
+ FlagFrame: LongInt;
{$IFDEF ENABLE_SHELLS}
ShellTextures: array [0..SHELL_LAST] of TGLTexture;
GFXTextures: array [0..R_GFX_LAST] of TGLMultiTexture;
gfxlist: array of record
typ: Byte;
- alpha: Byte;
x, y: Integer;
oldX, oldY: Integer;
- anim: TAnimState;
+ anim: TAnimInfo;
+ time: LongWord;
+ frame: LongInt;
end = nil;
{$ENDIF}
procedure r_Map_Initialize;
begin
StubShotAnim := TAnimState.Create(true, 1, 1);
- FlagAnim := TAnimState.Create(true, 8, 5);
+ FlagFrame := 0;
plist := TBinHeapPanelDraw.Create();
end;
procedure r_Map_Finalize;
begin
plist.Free;
+ FlagFrame := 0;
StubShotAnim.Invalidate;
end;
// --------- items --------- //
for i := 0 to ITEM_LAST do
begin
- if ItemAnim[i].n > 0 then
- begin
- Items[i].tex := r_Textures_LoadMultiFromFileAndInfo(
- GameWAD + ':TEXTURES/' + ItemAnim[i].name,
- ItemAnim[i].w,
- ItemAnim[i].h,
- ItemAnim[i].n,
- ItemAnim[i].b,
- false
- );
- k := IfThen(ItemAnim[i].b, ItemAnim[i].n * 2 - 2, ItemAnim[i].n);
- Items[i].anim := TAnimState.Create(True, ItemAnim[i].d, k);
- end;
+ Items[i].tex := r_Textures_LoadMultiFromFileAndInfo(
+ GameWAD + ':TEXTURES/' + ItemAnim[i].name,
+ ItemAnim[i].w,
+ ItemAnim[i].h,
+ ItemAnim[i].anim.frames,
+ ItemAnim[i].anim.back,
+ false
+ );
+ Items[i].frame := 0;
end;
// --------- monsters --------- //
for i := MONSTER_DEMON to MONSTER_MAN do
// --------- gfx animations --------- //
{$IFDEF ENABLE_GFX}
for i := 1 to R_GFX_LAST do
- if GFXAnim[i].count > 0 then
- GFXTextures[i] := r_Textures_LoadMultiFromFileAndInfo(GameWad + ':TEXTURES/' + GFXAnim[i].name, GFXAnim[i].w, GFXAnim[i].h, GFXAnim[i].count, GFXAnim[i].back);
+ if GFXAnim[i].anim.frames > 0 then
+ GFXTextures[i] := r_Textures_LoadMultiFromFileAndInfo(GameWad + ':TEXTURES/' + GFXAnim[i].name, GFXAnim[i].w, GFXAnim[i].h, GFXAnim[i].anim.frames, GFXAnim[i].anim.back);
{$ENDIF}
// --------- shots --------- //
for i := 0 to WEAPON_LAST do
for i := 0 to ITEM_LAST do
begin
if Items[i].tex <> nil then
- begin
Items[i].tex.Free;
- Items[i].tex := nil;
- end;
- Items[i].anim.Invalidate;
+ Items[i].tex := nil;
end;
end;
end;
procedure r_Map_DrawItems (x, y, w, h: Integer; drop: Boolean);
- var i, fX, fY: Integer; it: PItem; t: TGLMultiTexture;
+ var i, fX, fY: Integer; it: PItem; t: TGLMultiTexture; tex: TGLTexture;
begin
if ggItems <> nil then
begin
if g_Collide(it.obj.x, it.obj.y, t.width, t.height, x, y, w, h) then
begin
it.obj.Lerp(gLerpFactor, fX, fY);
- r_Draw_MultiTextureRepeat(t, Items[it.ItemType].anim, fX, fY, t.width, t.height, false, 255, 255, 255, 255, false);
+ tex := t.GetTexture(Items[it.ItemType].frame);
+ r_Draw_TextureRepeat(tex, fX, fY, tex.width, tex.height, false, 255, 255, 255, 255, false);
end;
end;
end;
angle := PlayerModelsArray[pm.id].FlagAngle;
xx := PlayerModelsArray[pm.id].FlagPoint.X;
yy := PlayerModelsArray[pm.id].FlagPoint.Y;
- r_Draw_MultiTextureRepeatRotate(
- t,
- FlagAnim,
+ tex := t.GetTexture(FlagFrame);
+ r_Draw_TextureRepeatRotate(
+ tex,
x + IfThen(flip, 2 * FLAG_BASEPOINT.X - xx + 1, xx - 1) - FLAG_BASEPOINT.X,
y + yy - FLAG_BASEPOINT.Y + 1,
- t.width,
- t.height,
+ tex.width,
+ tex.height,
flip,
255, 255, 255, 255, false,
IfThen(flip, 64 - FLAG_BASEPOINT.X, FLAG_BASEPOINT.X),
i := 0;
if gfxlist <> nil then
begin
- while (i < Length(gfxlist)) and gfxlist[i].anim.IsValid() do
+ while (i < Length(gfxlist)) and (gfxlist[i].typ > 0) do
Inc(i);
if i >= Length(gfxlist) then
SetLength(gfxlist, Length(gfxlist) + 1)
else
SetLength(gfxlist, 1);
gfxlist[i].typ := R_GFX_NONE;
- gfxlist[i].anim.Invalidate;
result := i
end;
gfxlist[i].y := y;
gfxlist[i].oldX := x;
gfxlist[i].oldY := y;
- gfxlist[i].anim := TAnimState.Create(false, GFXAnim[typ].speed + Random(GFXAnim[typ].rspeed), GFXAnim[typ].count);
- gfxlist[i].anim.Reset();
- gfxlist[i].anim.Enable();
+ gfxlist[i].anim := GFXAnim[typ].anim;
+ gfxlist[i].time := gTime DIV GAME_TICK;
+ gfxlist[i].frame := 0;
+ INC(gfxlist[i].anim.delay, Random(GFXAnim[typ].rdelay));
end;
end;
end;
- procedure r_Map_UpdateGFX;
- var i: Integer;
+ procedure r_Map_UpdateGFX (tick: LongWord);
+ var i: Integer; count: LongInt;
begin
if gfxlist <> nil then
begin
for i := 0 to High(gfxlist) do
begin
- if gfxlist[i].anim.IsValid() then
+ if (gfxlist[i].typ > 0) and (tick >= gfxlist[i].time) then
begin
- gfxlist[i].oldX := gfxlist[i].x;
- gfxlist[i].oldY := gfxlist[i].y;
- case gfxlist[i].typ of
- R_GFX_FLAME, R_GFX_SMOKE:
- begin
- if Random(3) = 0 then
- gfxlist[i].x := gfxlist[i].x - 1 + Random(3);
- if Random(2) = 0 then
- gfxlist[i].y := gfxlist[i].y - Random(2);
+ g_Anim_GetFrameByTime(gfxlist[i].anim, tick - gfxlist[i].time, count, gfxlist[i].frame);
+ if count < 1 then
+ begin
+ gfxlist[i].oldX := gfxlist[i].x;
+ gfxlist[i].oldY := gfxlist[i].y;
+ case gfxlist[i].typ of
+ R_GFX_FLAME, R_GFX_SMOKE:
+ begin
+ if Random(3) = 0 then
+ gfxlist[i].x := gfxlist[i].x - 1 + Random(3);
+ if Random(2) = 0 then
+ gfxlist[i].y := gfxlist[i].y - Random(2);
+ end;
end;
- end;
- if gfxlist[i].anim.played then
- gfxlist[i].anim.Invalidate
+ end
else
- gfxlist[i].anim.Update
+ gfxlist[i].typ := R_GFX_NONE;
+ end;
+ end;
+ end;
+ end;
+
+ procedure r_Map_DrawGFX (x, y, w, h: Integer);
+ var i, fx, fy, typ: Integer; t: TGLMultiTexture; tex: TGLTexture;
+ begin
+ if gfxlist <> nil then
+ begin
+ for i := 0 to High(gfxlist) do
+ begin
+ if gfxlist[i].typ > 0 then
+ begin
+ typ := gfxlist[i].typ;
+ t := GFXTextures[typ];
+ if t <> nil then
+ begin
+ fx := nlerp(gfxlist[i].oldX, gfxlist[i].x, gLerpFactor);
+ fy := nlerp(gfxlist[i].oldY, gfxlist[i].y, gLerpFactor);
+ tex := t.GetTexture(gfxlist[i].frame);
+ r_Draw_TextureRepeat(tex, fx, fy, tex.width, tex.height, false, 255, 255, 255, 255 - GFXAnim[typ].alpha, false);
+ end;
end;
end;
end;
glDisable(GL_BLEND);
end;
end;
-
- procedure r_Map_DrawGFX (x, y, w, h: Integer);
- var i, fx, fy, typ: Integer; tex: TGLMultiTexture;
- begin
- if gfxlist <> nil then
- begin
- for i := 0 to High(gfxlist) do
- begin
- if gfxlist[i].anim.IsValid() then
- begin
- typ := gfxlist[i].typ;
- tex := GFXTextures[typ];
- if tex <> nil then
- begin
- fx := nlerp(gfxlist[i].oldX, gfxlist[i].x, gLerpFactor);
- fy := nlerp(gfxlist[i].oldY, gfxlist[i].y, gLerpFactor);
- r_Draw_MultiTextureRepeat(tex, gfxlist[i].anim, fx, fy, tex.width, tex.height, false, 255, 255, 255, 255 - GFXAnim[typ].alpha, false);
- end;
- end;
- end;
- end;
- end;
{$ENDIF}
procedure r_Map_DrawShots (x, y, w, h: Integer);
end;
procedure r_Map_DrawFlags (x, y, w, h: Integer);
- var i, dx, fx, fy: Integer; flip: Boolean; tex: TGLMultiTexture;
+ var i, dx, fx, fy: Integer; flip: Boolean; t: TGLMultiTexture; tex: TGLTexture;
begin
if gGameSettings.GameMode = GM_CTF then
begin
gFlags[i].Obj.Lerp(gLerpFactor, fx, fy);
flip := gFlags[i].Direction = TDirection.D_LEFT;
if flip then dx := -1 else dx := +1;
- tex := FlagTextures[i];
- r_Draw_MultiTextureRepeat(tex, FlagAnim, fx + dx, fy + 1, tex.width, tex.height, flip, 255, 255, 255, 255, false)
+ t := FlagTextures[i];
+ tex := t.GetTexture(FlagFrame);
+ r_Draw_TextureRepeat(tex, fx + dx, fy + 1, tex.width, tex.height, flip, 255, 255, 255, 255, false)
end;
end;
end;
end;
procedure r_Map_Update;
- var i: Integer;
+ var i, count, tick: LongInt;
begin
+ tick := gTime div GAME_TICK;
for i := 0 to ITEM_LAST do
- Items[i].anim.Update;
- r_Map_UpdateGFX;
- FlagAnim.Update;
+ g_Anim_GetFrameByTime(ItemAnim[i].anim, tick, count, Items[i].frame);
+ r_Map_UpdateGFX(tick);
+ g_Anim_GetFrameByTime(FlagAnim, tick, count, FlagFrame);
end;
end.
index fb65ab5fa3d8ac66951c9ce1795015a8627c648b..135141e69ca752e333f82730d8b9a251877df077 100644 (file)
procedure r_Render_DrawLoading (force: Boolean);
begin
+ // TODO draw loading screen
end;
end.