X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_textures.pas;h=727e94ac7632e0b1e5b6e88e6f6a13f8876bfeb1;hb=b796b9f7b887de367bb71ccf5acdd3e39d82ebd2;hp=d12a9a24e4ba74789cfbe74fbaa0713e4b0c376f;hpb=3af68bc5a306b013ddb2a04c24543b6ec6e288af;p=d2df-sdl.git diff --git a/src/game/g_textures.pas b/src/game/g_textures.pas index d12a9a2..727e94a 100644 --- a/src/game/g_textures.pas +++ b/src/game/g_textures.pas @@ -24,15 +24,58 @@ uses 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; + TAnimationState = class{$IFDEF USE_MEMPOOL}(TPoolObject){$ENDIF} + private + mAlpha: Byte; + mBlending: Boolean; + 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); + destructor Destroy (); override; + + procedure reset (); + procedure update (); + procedure enable (); + procedure disable (); + procedure revert (r: Boolean); + + procedure saveState (st: TStream); + procedure loadState (st: TStream); + + function totalFrames (): Integer; 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 blending: Boolean read mBlending write mBlending; + property alpha: Byte read mAlpha write mAlpha; + property length: Integer read mLength; + end; + TAnimation = class{$IFDEF USE_MEMPOOL}(TPoolObject){$ENDIF} private mId: LongWord; @@ -89,6 +132,176 @@ uses g_game, e_log, g_basic, g_console, wadreader, r_animations, g_language, utils, xstreams; + + + +constructor TAnimationState.Create (aloop: Boolean; aspeed: Byte; len: Integer); +begin + assert(len >= 0); + mLength := len; + + mMinLength := 0; + mLoop := aloop; + mSpeed := aspeed; + mEnabled := true; + mCurrentFrame := 0; + mAlpha := 0; + mPlayed := false; +end; + +destructor TAnimationState.Destroy; +begin + inherited; +end; + +procedure TAnimationState.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 TAnimationState.reset; +begin + if mRevert then + mCurrentFrame := mLength - 1 + else + mCurrentFrame := 0; + mCounter := 0; + mPlayed := false +end; + +procedure TAnimationState.disable; +begin + mEnabled := false +end; + +procedure TAnimationState.enable; +begin + mEnabled := true +end; + +procedure TAnimationState.revert (r: Boolean); +begin + mRevert := r; + reset +end; + +function TAnimationState.totalFrames (): Integer; inline; +begin + result := mLength +end; + +procedure TAnimationState.saveState (st: TStream); +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); + // 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; + + +procedure TAnimationState.loadState (st: TStream); +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); + // 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; + + + + + + constructor TAnimation.Create (aframesID: LongWord; aloop: Boolean; aspeed: Byte); begin if (aframesID >= Length(framesArray)) then