X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_panel.pas;h=2681f1d43ec1e40e7b50712e0f3f7a5183c3c0ed;hb=d52e9d7b6bcc5c1846c82c3908a4688339e736f3;hp=58e7477c6f84d275e67384a718dd4e49a828dcf9;hpb=df1f12c26369a0d5e9e996583b30c9879570fe99;p=d2df-sdl.git diff --git a/src/game/g_panel.pas b/src/game/g_panel.pas index 58e7477..2681f1d 100644 --- a/src/game/g_panel.pas +++ b/src/game/g_panel.pas @@ -26,7 +26,6 @@ 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; @@ -37,7 +36,6 @@ type ATextureID = array of record Texture: Cardinal; // Textures[Texture] - AnTex: TAnimState; end; PPanel = ^TPanel; @@ -49,6 +47,8 @@ type FAlpha: Byte; FBlending: Boolean; FTextureIDs: ATextureID; + FAnimTime: LongWord; + FAnimLoop: Boolean; mMovingSpeed: TDFPoint; mMovingStart: TDFPoint; mMovingEnd: TDFPoint; @@ -96,9 +96,7 @@ type procedure setSizeEndY (v: Integer); inline; public - FCurTexture: Integer; // Íîìåð òåêóùåé òåêñòóðû - FCurFrame: Integer; - FCurFrameCount: Byte; + FCurTexture: Integer; // Номер текущей текстуры FX, FY: Integer; FOldX, FOldY: Integer; FWidth, FHeight: Word; @@ -123,7 +121,7 @@ type destructor Destroy(); override; procedure Update(); - procedure SetFrame(Frame: Integer; Count: Byte); + procedure SetFrame(StartTime: LongWord); procedure NextTexture(AnimLoop: Byte = 0); procedure SetTexture(ID: Integer; AnimLoop: Byte = 0); function GetTextureID(): Cardinal; @@ -196,10 +194,11 @@ type property isGLift: Boolean read getIsGLift; property isGBlockMon: Boolean read getIsGBlockMon; - (* private state *) property Alpha: Byte read FAlpha; property Blending: Boolean read FBlending; property TextureIDs: ATextureID read FTextureIDs; + property AnimTime: LongWord read FAnimTime; + property AnimLoop: Boolean read FAnimLoop; public property movingSpeed: TDFPoint read mMovingSpeed write mMovingSpeed; @@ -247,21 +246,25 @@ const { T P a n e l : } - function FindTextureByName (const name: String): Integer; - var i: Integer; + function GetSpecialTexture (const name: String): Integer; + (* HACK: get texture id, if not present -> insert it into list *) + (* required for older maps *) + var i, len: Integer; begin - Result := -1; + i := 0; len := 0; if Textures <> nil then begin - for i := 0 to High(Textures) do - begin - if Textures[i].TextureName = name then - begin - Result := i; - break; - end - end - end + len := Length(Textures); + while (i < len) and (Textures[i].TextureName <> name) do + Inc(i); + end; + if i >= len then + begin + i := len; + SetLength(Textures, len + 1); + Textures[i].TextureName := name; + end; + result := i; end; constructor TPanel.Create(PanelRec: TDynRecord; @@ -282,8 +285,6 @@ begin FOldH := Height; FAlpha := 0; FBlending := False; - FCurFrame := 0; - FCurFrameCount := 0; LastAnimLoop := 0; mapId := PanelRec.id; @@ -304,7 +305,7 @@ begin mNeedSend := false; -// Òèï ïàíåëè: +// Тип панели: PanelType := PanelRec.PanelType; Enabled := True; Door := False; @@ -320,14 +321,14 @@ begin PANEL_LIFTRIGHT: LiftType := LIFTTYPE_RIGHT; end; -// Íåâèäèìàÿ: +// Невидимая: if ByteBool(PanelRec.Flags and PANEL_FLAG_HIDE) then begin SetLength(FTextureIDs, 0); FCurTexture := -1; Exit; end; -// Ïàíåëè, íå èñïîëüçóþùèå òåêñòóðû: +// Панели, не использующие текстуры: if ByteBool(PanelType and (PANEL_LIFTUP or PANEL_LIFTDOWN or @@ -340,15 +341,15 @@ begin Exit; end; -// Åñëè ýòî æèäêîñòü áåç òåêñòóðû - ñïåöòåêñòóðó: +// Если это жидкость без текстуры - спецтекстуру: if WordBool(PanelType and (PANEL_WATER or PANEL_ACID1 or PANEL_ACID2)) and (not ByteBool(PanelRec.Flags and PANEL_FLAG_WATERTEXTURES)) then begin SetLength(FTextureIDs, 1); case PanelRec.PanelType of - PANEL_WATER: FTextureIDs[0].Texture := FindTextureByName(TEXTURE_NAME_WATER); - PANEL_ACID1: FTextureIDs[0].Texture := FindTextureByName(TEXTURE_NAME_ACID1); - PANEL_ACID2: FTextureIDs[0].Texture := FindTextureByName(TEXTURE_NAME_ACID2); + PANEL_WATER: FTextureIDs[0].Texture := GetSpecialTexture(TEXTURE_NAME_WATER); + PANEL_ACID1: FTextureIDs[0].Texture := GetSpecialTexture(TEXTURE_NAME_ACID1); + PANEL_ACID2: FTextureIDs[0].Texture := GetSpecialTexture(TEXTURE_NAME_ACID2); end; FCurTexture := 0; Exit; @@ -364,22 +365,19 @@ begin else FCurTexture := CurTex; - for i := 0 to Length(FTextureIDs)-1 do - begin + for i := 0 to Length(FTextureIDs) - 1 do FTextureIDs[i].Texture := AddTextures[i].Texture; - if Textures[AddTextures[i].Texture].FramesCount > 0 then - FTextureIDs[i].AnTex := TAnimState.Create(True, Textures[AddTextures[i].Texture].Speed, Textures[AddTextures[i].Texture].FramesCount) - else - FTextureIDs[i].AnTex.Invalidate; - end; -// Òåêñòóð íåñêîëüêî - íóæíî ñîõðàíÿòü òåêóùóþ: + FAnimTime := gTime; + FAnimLoop := true; + +// Текстур несколько - нужно сохранять текущую: //if Length(FTextureIDs) > 1 then SaveIt := True; if (PanelRec.TextureRec = nil) then tnum := -1 else tnum := PanelRec.tagInt; if (tnum < 0) then tnum := Length(Textures); -// Åñëè íå ñïåöòåêñòóðà, òî çàäàåì ðàçìåðû: +// Если не спецтекстура, то задаем размеры: if ({PanelRec.TextureNum}tnum > High(Textures)) then begin e_WriteLog(Format('WTF?! tnum is out of limits! (%d : %d)', [tnum, High(Textures)]), TMsgType.Warning); @@ -605,13 +603,6 @@ var begin if (not Enabled) or (Width < 1) or (Height < 1) then exit; - if (FCurTexture >= 0) and (FTextureIDs[FCurTexture].AnTex.IsValid()) and (FAlpha < 255) then - begin - FTextureIDs[FCurTexture].AnTex.Update(); - FCurFrame := FTextureIDs[FCurTexture].AnTex.CurrentFrame; - FCurFrameCount := FTextureIDs[FCurTexture].AnTex.CurrentCounter; - end; - if not g_dbgpan_mplat_active then exit; if (mOldMovingActive <> mMovingActive) then mNeedSend := true; @@ -867,34 +858,21 @@ begin end; end; - -procedure TPanel.SetFrame(Frame: Integer; Count: Byte); - - function ClampInt(X, A, B: Integer): Integer; + procedure TPanel.SetFrame (StartTime: LongWord); begin - Result := X; - if X < A then Result := A else if X > B then Result := B; + if Enabled and (FCurTexture >= 0) and (Width > 0) and (Height > 0) and (FAlpha < 255) then + FAnimTime := StartTime; end; -begin - if Enabled and (FCurTexture >= 0) and (FTextureIDs[FCurTexture].AnTex.IsValid()) and (Width > 0) and (Height > 0) and (FAlpha < 255) then - begin - FCurFrame := ClampInt(Frame, 0, FTextureIDs[FCurTexture].AnTex.TotalFrames - 1); - FCurFrameCount := Count; - FTextureIDs[FCurTexture].AnTex.CurrentFrame := FCurFrame; - FTextureIDs[FCurTexture].AnTex.CurrentCounter := FCurFrameCount; - end; -end; - procedure TPanel.NextTexture(AnimLoop: Byte = 0); begin Assert(FCurTexture >= -1, 'FCurTexture < -1'); -// Íåò òåêñòóð: +// Нет текстур: if Length(FTextureIDs) = 0 then FCurTexture := -1 else - // Òîëüêî îäíà òåêñòóðà: + // Только одна текстура: if Length(FTextureIDs) = 1 then begin if FCurTexture = 0 then @@ -903,23 +881,22 @@ begin FCurTexture := 0; end else - // Áîëüøå îäíîé òåêñòóðû: + // Больше одной текстуры: begin - // Ñëåäóþùàÿ: + // Следующая: Inc(FCurTexture); - // Ñëåäóþùåé íåò - âîçâðàò ê íà÷àëó: + // Следующей нет - возврат к началу: if FCurTexture >= Length(FTextureIDs) then FCurTexture := 0; end; -// Ïåðåêëþ÷èëèñü íà âèäèìóþ àíèì. òåêñòóðó: - if (FCurTexture >= 0) and FTextureIDs[FCurTexture].AnTex.IsValid() then + if FCurTexture >= 0 then begin - if AnimLoop = 1 then - FTextureIDs[FCurTexture].AnTex.Loop := True - else if AnimLoop = 2 then - FTextureIDs[FCurTexture].AnTex.Loop := False; - FTextureIDs[FCurTexture].AnTex.Reset(); + case AnimLoop of + 1: FAnimLoop := true; + 2: FAnimLoop := false; + end; + FAnimTime := gTime; end; LastAnimLoop := AnimLoop; @@ -930,14 +907,13 @@ begin if (ID >= -1) and (ID < Length(FTextureIDs)) then FCurTexture := ID; -// Ïåðåêëþ÷èëèñü íà âèäèìóþ àíèì. òåêñòóðó: - if (FCurTexture >= 0) and FTextureIDs[FCurTexture].AnTex.IsValid() then + if FCurTexture >= 0 then begin - if AnimLoop = 1 then - FTextureIDs[FCurTexture].AnTex.Loop := True - else if AnimLoop = 2 then - FTextureIDs[FCurTexture].AnTex.Loop := False; - FTextureIDs[FCurTexture].AnTex.Reset(); + case AnimLoop of + 1: FAnimLoop := true; + 2: FAnimLoop := false; + end; + FAnimTime := gTime; end; LastAnimLoop := AnimLoop; @@ -950,10 +926,13 @@ end; if (FCurTexture >= 0) then begin Texture := FTextureIDs[FCurTexture].Texture; - case Textures[Texture].TextureName of - TEXTURE_NAME_WATER: Result := DWORD(TEXTURE_SPECIAL_WATER); - TEXTURE_NAME_ACID1: Result := DWORD(TEXTURE_SPECIAL_ACID1); - TEXTURE_NAME_ACID2: Result := DWORD(TEXTURE_SPECIAL_ACID2); + if Texture >= 0 then + begin + case Textures[Texture].TextureName of (* TODO: optimize it *) + TEXTURE_NAME_WATER: Result := DWORD(TEXTURE_SPECIAL_WATER); + TEXTURE_NAME_ACID1: Result := DWORD(TEXTURE_SPECIAL_ACID1); + TEXTURE_NAME_ACID2: Result := DWORD(TEXTURE_SPECIAL_ACID2); + end end end end; @@ -961,9 +940,8 @@ end; function TPanel.GetTextureCount(): Integer; begin Result := Length(FTextureIDs); - if Enabled and (FCurTexture >= 0) then - if (FTextureIDs[FCurTexture].AnTex.IsValid()) and (Width > 0) and (Height > 0) and (FAlpha < 255) then - Result := Result + 100; + if Enabled and (FCurTexture >= 0) and (Width > 0) and (Height > 0) and (FAlpha < 255) then + Result := Result + 100; // ??? end; function TPanel.CanChangeTexture(): Boolean; @@ -975,30 +953,34 @@ const PAN_SAVE_VERSION = 1; procedure TPanel.SaveState (st: TStream); -var - anim: Boolean; + var anim: Boolean; stub: TAnimState; begin if (st = nil) then exit; - // Ñèãíàòóðà ïàíåëè + // Сигнатура панели utils.writeSign(st, 'PANL'); utils.writeInt(st, Byte(PAN_SAVE_VERSION)); - // Îòêðûòà/çàêðûòà, åñëè äâåðü + // Открыта/закрыта, если дверь utils.writeBool(st, FEnabled); - // Íàïðàâëåíèå ëèôòà, åñëè ëèôò + // Направление лифта, если лифт utils.writeInt(st, Byte(FLiftType)); - // Íîìåð òåêóùåé òåêñòóðû + // Номер текущей текстуры utils.writeInt(st, Integer(FCurTexture)); - // Êîîðäèíàòû è ðàçìåð + // Координаты и размер utils.writeInt(st, Integer(FX)); utils.writeInt(st, Integer(FY)); utils.writeInt(st, Word(FWidth)); utils.writeInt(st, Word(FHeight)); - // Àíèìèðîâàíà ëè òåêóùàÿ òåêñòóðà - anim := (FCurTexture >= 0) and (FTextureIDs[FCurTexture].AnTex.IsValid()); + // Анимирована ли текущая текстура + anim := FCurTexture >= 0; utils.writeBool(st, anim); - // Åñëè äà - ñîõðàíÿåì àíèìàöèþ - if anim then FTextureIDs[FCurTexture].AnTex.SaveState(st, FAlpha, FBlending); + // Если да - сохраняем анимацию + if anim then + begin + stub := TAnimState.Create(FAnimLoop, 1, 1); + stub.SaveState(st, FAlpha, FBlending); + stub.Invalidate; + end; // moving platform state utils.writeInt(st, Integer(mMovingSpeed.X)); @@ -1022,19 +1004,20 @@ end; procedure TPanel.LoadState (st: TStream); + var stub: TAnimState; begin if (st = nil) then exit; - // Ñèãíàòóðà ïàíåëè + // Сигнатура панели if not utils.checkSign(st, 'PANL') then raise XStreamError.create('wrong panel signature'); if (utils.readByte(st) <> PAN_SAVE_VERSION) then raise XStreamError.create('wrong panel version'); - // Îòêðûòà/çàêðûòà, åñëè äâåðü + // Открыта/закрыта, если дверь FEnabled := utils.readBool(st); - // Íàïðàâëåíèå ëèôòà, åñëè ëèôò + // Направление лифта, если лифт FLiftType := utils.readByte(st); - // Íîìåð òåêóùåé òåêñòóðû + // Номер текущей текстуры FCurTexture := utils.readLongInt(st); - // Êîîðäèíàòû è ðàçìåð + // Координаты и размер FX := utils.readLongInt(st); FY := utils.readLongInt(st); FOldX := FX; @@ -1043,12 +1026,14 @@ begin FHeight := utils.readWord(st); FOldW := FWidth; FOldH := FHeight; - // Àíèìèðîâàííàÿ ëè òåêóùàÿ òåêñòóðà + // Анимированная ли текущая текстура if utils.readBool(st) then begin - // Åñëè äà - çàãðóæàåì àíèìàöèþ - Assert((FCurTexture >= 0) and (FTextureIDs[FCurTexture].AnTex.IsValid()), 'TPanel.LoadState: No animation object'); - FTextureIDs[FCurTexture].AnTex.LoadState(st, FAlpha, FBlending); + // Если да - загружаем анимацию + Assert(FCurTexture >= 0, 'TPanel.LoadState: No animation object'); + stub := TAnimState.Create(FAnimLoop, 1, 1); + stub.LoadState(st, FAlpha, FBlending); + stub.Invalidate; end; // moving platform state