X-Git-Url: http://deadsoftware.ru/gitweb?p=d2df-sdl.git;a=blobdiff_plain;f=src%2Fgame%2Fg_panel.pas;h=084f64db416a805fc917215dcf74c7c898994715;hp=2ff9af5648006d2650a0b4e5e101e781e03f3003;hb=0f3ace5126eeb6ef6c5dbdee5226e36dffe712d6;hpb=d7d166dc3cd287276202e862746208892c4cc89f diff --git a/src/game/g_panel.pas b/src/game/g_panel.pas index 2ff9af5..084f64d 100644 --- a/src/game/g_panel.pas +++ b/src/game/g_panel.pas @@ -1,9 +1,8 @@ -(* 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 - * 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 @@ -30,6 +29,7 @@ type Anim: Boolean; end; + PPanel = ^TPanel; TPanel = Class (TObject) private const @@ -97,7 +97,9 @@ type FCurFrame: Integer; FCurFrameCount: Byte; FX, FY: Integer; + FOldX, FOldY: Integer; FWidth, FHeight: Word; + FOldW, FOldH: Word; FPanelType: Word; FEnabled: Boolean; FDoor: Boolean; @@ -109,6 +111,7 @@ type tag: Integer; // used in coldets and such; sorry; see g_map.GridTagXXX proxyId: Integer; // proxy id in map grid (DO NOT USE!) mapId: AnsiString; // taken directly from map file; dunno why it is here + hasTexTrigger: Boolean; // HACK: true when there's a trigger than can change my texture constructor Create(PanelRec: TDynRecord; AddTextures: TAddTextureArray; @@ -124,6 +127,7 @@ type procedure SetTexture(ID: Integer; AnimLoop: Byte = 0); function GetTextureID(): Cardinal; function GetTextureCount(): Integer; + function CanChangeTexture(): Boolean; procedure SaveState (st: TStream); procedure LoadState (st: TStream); @@ -144,6 +148,8 @@ type function gncNeedSend (): Boolean; inline; procedure setDirty (); inline; // why `dirty`? 'cause i may introduce property `needSend` later + procedure lerp (t: Single; out tX, tY, tW, tH: Integer); + public property visvalid: Boolean read getvisvalid; // panel is "visvalid" when it's width and height are positive @@ -201,6 +207,12 @@ type TPanelArray = Array of TPanel; +const + LIFTTYPE_UP = 0; + LIFTTYPE_DOWN = 1; + LIFTTYPE_LEFT = 2; + LIFTTYPE_RIGHT = 3; + var g_dbgpan_mplat_active: Boolean = {$IF DEFINED(D2F_DEBUG)}true{$ELSE}true{$ENDIF}; g_dbgpan_mplat_step: Boolean = false; // one step, and stop @@ -209,8 +221,9 @@ var implementation uses + {$INCLUDE ../nogl/noGLuses.inc} e_texture, g_basic, g_map, g_game, g_gfx, e_graphics, g_weapons, g_triggers, - g_console, g_language, g_monsters, g_player, g_grid, e_log, GL, utils, xstreams; + g_console, g_language, g_monsters, g_player, g_grid, e_log, geom, utils, xstreams; const PANEL_SIGNATURE = $4C4E4150; // 'PANL' @@ -223,11 +236,16 @@ constructor TPanel.Create(PanelRec: TDynRecord; var Textures: TLevelTextureArray; aguid: Integer); var i: Integer; + tnum: Integer; begin X := PanelRec.X; Y := PanelRec.Y; + FOldX := X; + FOldY := Y; Width := PanelRec.Width; Height := PanelRec.Height; + FOldW := Width; + FOldH := Height; FAlpha := 0; FBlending := False; FCurFrame := 0; @@ -256,15 +274,16 @@ begin PanelType := PanelRec.PanelType; Enabled := True; Door := False; - LiftType := 0; + LiftType := LIFTTYPE_UP; + hasTexTrigger := False; case PanelType of PANEL_OPENDOOR: begin Enabled := False; Door := True; end; PANEL_CLOSEDOOR: Door := True; - PANEL_LIFTUP: LiftType := 0; //??? - PANEL_LIFTDOWN: LiftType := 1; - PANEL_LIFTLEFT: LiftType := 2; - PANEL_LIFTRIGHT: LiftType := 3; + PANEL_LIFTUP: LiftType := LIFTTYPE_UP; //??? + PANEL_LIFTDOWN: LiftType := LIFTTYPE_DOWN; + PANEL_LIFTLEFT: LiftType := LIFTTYPE_LEFT; + PANEL_LIFTRIGHT: LiftType := LIFTTYPE_RIGHT; end; // Íåâèäèìàÿ: @@ -337,19 +356,22 @@ begin // Òåêñòóð íåñêîëüêî - íóæíî ñîõðàíÿòü òåêóùóþ: //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 > High(Textures) then + if ({PanelRec.TextureNum}tnum > High(Textures)) then begin - e_WriteLog(Format('WTF?! PanelRec.TextureNum is out of limits! (%d : %d)', [PanelRec.TextureNum, High(Textures)]), TMsgType.Fatal); + e_WriteLog(Format('WTF?! tnum is out of limits! (%d : %d)', [tnum, High(Textures)]), TMsgType.Warning); FTextureWidth := 2; FTextureHeight := 2; FAlpha := 0; FBlending := ByteBool(0); end - else if not g_Map_IsSpecialTexture(Textures[PanelRec.TextureNum].TextureName) then + else if not g_Map_IsSpecialTexture(Textures[{PanelRec.TextureNum}tnum].TextureName) then begin - FTextureWidth := Textures[PanelRec.TextureNum].Width; - FTextureHeight := Textures[PanelRec.TextureNum].Height; + FTextureWidth := Textures[{PanelRec.TextureNum}tnum].Width; + FTextureHeight := Textures[{PanelRec.TextureNum}tnum].Height; FAlpha := PanelRec.Alpha; FBlending := ByteBool(PanelRec.Flags and PANEL_FLAG_BLENDING); end; @@ -367,6 +389,24 @@ begin Inherited; end; +procedure TPanel.lerp (t: Single; out tX, tY, tW, tH: Integer); +begin + if mMovingActive then + begin + tX := nlerp(FOldX, FX, t); + tY := nlerp(FOldY, FY, t); + tW := nlerp(FOldW, FWidth, t); + tH := nlerp(FOldH, FHeight, t); + end + else + begin + tX := FX; + tY := FY; + tW := FWidth; + tH := FHeight; + end; +end; + function TPanel.getx1 (): Integer; inline; begin result := X+Width-1; end; function TPanel.gety1 (): Integer; inline; begin result := Y+Height-1; end; function TPanel.getvisvalid (): Boolean; inline; begin result := (Width > 0) and (Height > 0); end; @@ -412,6 +452,7 @@ procedure TPanel.setDirty (); inline; begin mNeedSend := true; end; procedure TPanel.Draw (hasAmbient: Boolean; constref ambColor: TDFColor); var + tx, ty, tw, th: Integer; xx, yy: Integer; NoTextureID: DWORD; NW, NH: Word; @@ -420,45 +461,46 @@ begin (Width > 0) and (Height > 0) and (FAlpha < 255) {and g_Collide(X, Y, Width, Height, sX, sY, sWidth, sHeight)} then begin + lerp(gLerpFactor, tx, ty, tw, th); if FTextureIDs[FCurTexture].Anim then begin // Àíèìèðîâàííàÿ òåêñòóðà if FTextureIDs[FCurTexture].AnTex = nil then Exit; - for xx := 0 to (Width div FTextureWidth)-1 do - for yy := 0 to (Height div FTextureHeight)-1 do + for xx := 0 to (tw div FTextureWidth)-1 do + for yy := 0 to (th div FTextureHeight)-1 do FTextureIDs[FCurTexture].AnTex.Draw( - X + xx*FTextureWidth, - Y + yy*FTextureHeight, TMirrorType.None); + tx + xx*FTextureWidth, + ty + yy*FTextureHeight, TMirrorType.None); end else begin // Îáû÷íàÿ òåêñòóðà case FTextureIDs[FCurTexture].Tex of - LongWord(TEXTURE_SPECIAL_WATER): e_DrawFillQuad(X, Y, X+Width-1, Y+Height-1, 0, 0, 255, 0, TBlending.Filter); - LongWord(TEXTURE_SPECIAL_ACID1): e_DrawFillQuad(X, Y, X+Width-1, Y+Height-1, 0, 128, 0, 0, TBlending.Filter); - LongWord(TEXTURE_SPECIAL_ACID2): e_DrawFillQuad(X, Y, X+Width-1, Y+Height-1, 128, 0, 0, 0, TBlending.Filter); + LongWord(TEXTURE_SPECIAL_WATER): e_DrawFillQuad(tx, ty, tx+tw-1, ty+th-1, 0, 0, 255, 0, TBlending.Filter); + LongWord(TEXTURE_SPECIAL_ACID1): e_DrawFillQuad(tx, ty, tx+tw-1, ty+th-1, 0, 230, 0, 0, TBlending.Filter); + LongWord(TEXTURE_SPECIAL_ACID2): e_DrawFillQuad(tx, ty, tx+tw-1, ty+th-1, 230, 0, 0, 0, TBlending.Filter); LongWord(TEXTURE_NONE): if g_Texture_Get('NOTEXTURE', NoTextureID) then begin e_GetTextureSize(NoTextureID, @NW, @NH); - e_DrawFill(NoTextureID, X, Y, Width div NW, Height div NH, 0, False, False); + e_DrawFill(NoTextureID, tx, ty, tw div NW, th div NH, 0, False, False); end else begin - xx := X + (Width div 2); - yy := Y + (Height div 2); - e_DrawFillQuad(X, Y, xx, yy, 255, 0, 255, 0); - e_DrawFillQuad(xx, Y, X+Width-1, yy, 255, 255, 0, 0); - e_DrawFillQuad(X, yy, xx, Y+Height-1, 255, 255, 0, 0); - e_DrawFillQuad(xx, yy, X+Width-1, Y+Height-1, 255, 0, 255, 0); + xx := tx + (tw div 2); + yy := ty + (th div 2); + e_DrawFillQuad(tx, ty, xx, yy, 255, 0, 255, 0); + e_DrawFillQuad(xx, ty, tx+tw-1, yy, 255, 255, 0, 0); + e_DrawFillQuad(tx, yy, xx, ty+th-1, 255, 255, 0, 0); + e_DrawFillQuad(xx, yy, tx+tw-1, ty+th-1, 255, 0, 255, 0); end; else begin if not mMovingActive then - e_DrawFill(FTextureIDs[FCurTexture].Tex, X, Y, Width div FTextureWidth, Height div FTextureHeight, FAlpha, True, FBlending, hasAmbient) + e_DrawFill(FTextureIDs[FCurTexture].Tex, tx, ty, tw div FTextureWidth, th div FTextureHeight, FAlpha, True, FBlending, hasAmbient) else - e_DrawFillX(FTextureIDs[FCurTexture].Tex, X, Y, Width, Height, FAlpha, True, FBlending, g_dbg_scale, hasAmbient); - if hasAmbient then e_AmbientQuad(X, Y, Width, Height, ambColor.r, ambColor.g, ambColor.b, ambColor.a); + e_DrawFillX(FTextureIDs[FCurTexture].Tex, tx, ty, tw, th, FAlpha, True, FBlending, g_dbg_scale, hasAmbient); + if hasAmbient then e_AmbientQuad(tx, ty, tw, th, ambColor.r, ambColor.g, ambColor.b, ambColor.a); end; end; end; @@ -466,6 +508,9 @@ begin end; procedure TPanel.DrawShadowVolume(lightX: Integer; lightY: Integer; radius: Integer); +var + tx, ty, tw, th: Integer; + procedure extrude (x: Integer; y: Integer); begin glVertex2i(x+(x-lightX)*500, y+(y-lightY)*500); @@ -487,8 +532,9 @@ procedure TPanel.DrawShadowVolume(lightX: Integer; lightY: Integer; radius: Inte begin if radius < 4 then exit; if Enabled and (FCurTexture >= 0) and (Width > 0) and (Height > 0) and (FAlpha < 255) {and - g_Collide(X, Y, Width, Height, sX, sY, sWidth, sHeight)} then + g_Collide(X, Y, tw, th, sX, sY, sWidth, sHeight)} then begin + lerp(gLerpFactor, tx, ty, tw, th); if not FTextureIDs[FCurTexture].Anim then begin case FTextureIDs[FCurTexture].Tex of @@ -498,17 +544,17 @@ begin LongWord(TEXTURE_NONE): exit; end; end; - if (X+Width < lightX-radius) then exit; - if (Y+Height < lightY-radius) then exit; - if (X > lightX+radius) then exit; - if (Y > lightY+radius) then exit; - //e_DrawFill(FTextureIDs[FCurTexture].Tex, X, Y, Width div FTextureWidth, Height div FTextureHeight, FAlpha, True, FBlending); + if (tx+tw < lightX-radius) then exit; + if (ty+th < lightY-radius) then exit; + if (tx > lightX+radius) then exit; + if (ty > lightY+radius) then exit; + //e_DrawFill(FTextureIDs[FCurTexture].Tex, X, Y, tw div FTextureWidth, th div FTextureHeight, FAlpha, True, FBlending); glBegin(GL_QUADS); - drawLine(x, y, x+width, y); // top - drawLine(x+width, y, x+width, y+height); // right - drawLine(x+width, y+height, x, y+height); // bottom - drawLine(x, y+height, x, y); // left + drawLine(tx, ty, tx+tw, ty); // top + drawLine(tx+tw, ty, tx+tw, ty+th); // right + drawLine(tx+tw, ty+th, tx, ty+th); // bottom + drawLine(tx, ty+th, tx, ty); // left glEnd(); end; end; @@ -581,7 +627,7 @@ var begin if (ontop <> nil) then ontop^ := true; // yes, move with it; but skip steps (no need to process size change here, 'cause platform top cannot be changed with it) - mapGrid.traceBox(tex, tey, px, py, pw, ph, pdx, pdy, nil, (GridTagWall or GridTagDoor)); + mapGrid.traceBox(tex, tey, px, py, pw, ph, pdx, pdy, (GridTagWall or GridTagDoor)); end else begin @@ -609,7 +655,7 @@ var trtag := (GridTagWall or GridTagDoor); // if we're moving down, consider steps too if (szdy > 0) then trtag := trtag or GridTagStep; - mapGrid.traceBox(tex, tey, px, py, pw, ph, szdx, szdy, nil, trtag); + mapGrid.traceBox(tex, tey, px, py, pw, ph, szdx, szdy, trtag); end; end; end; @@ -628,7 +674,7 @@ var trtag := (GridTagWall or GridTagDoor); // if we're moving down, consider steps too if (pdy > 0) then trtag := trtag or GridTagStep; - mapGrid.traceBox(tex, tey, px, py, pw, ph, pdx, pdy, nil, trtag); + mapGrid.traceBox(tex, tey, px, py, pw, ph, pdx, pdy, trtag); end; end; end; @@ -829,8 +875,12 @@ begin end; // move panel + FOldX := X; + FOldY := Y; X := nx; Y := ny; + FOldW := FWidth; + FOldH := FHeight; FWidth := nw; FHeight := nh; positionChanged(); @@ -893,7 +943,7 @@ begin (FTextureIDs[FCurTexture].AnTex <> nil) and (Width > 0) and (Height > 0) and (FAlpha < 255) then begin - FCurFrame := ClampInt(Frame, 0, FTextureIDs[FCurTexture].AnTex.TotalFrames); + FCurFrame := ClampInt(Frame, 0, FTextureIDs[FCurTexture].AnTex.TotalFrames - 1); FCurFrameCount := Count; FTextureIDs[FCurTexture].AnTex.CurrentFrame := FCurFrame; FTextureIDs[FCurTexture].AnTex.CurrentCounter := FCurFrameCount; @@ -949,22 +999,8 @@ end; procedure TPanel.SetTexture(ID: Integer; AnimLoop: Byte = 0); begin -// Íåò òåêñòóð: - if Length(FTextureIDs) = 0 then - FCurTexture := -1 - else - // Òîëüêî îäíà òåêñòóðà: - if Length(FTextureIDs) = 1 then - begin - if (ID = 0) or (ID = -1) then - FCurTexture := ID; - end - else - // Áîëüøå îäíîé òåêñòóðû: - begin - if (ID >= -1) and (ID <= High(FTextureIDs)) then - FCurTexture := ID; - end; + if (ID >= -1) and (ID < Length(FTextureIDs)) then + FCurTexture := ID; // Ïåðåêëþ÷èëèñü íà âèäèìóþ àíèì. òåêñòóðó: if (FCurTexture >= 0) and FTextureIDs[FCurTexture].Anim then @@ -1010,6 +1046,10 @@ begin Result := Result + 100; end; +function TPanel.CanChangeTexture(): Boolean; +begin + Result := (GetTextureCount() > 1) or hasTexTrigger; +end; const PAN_SAVE_VERSION = 1; @@ -1085,8 +1125,12 @@ begin // Êîîðäèíàòû è ðàçìåð FX := utils.readLongInt(st); FY := utils.readLongInt(st); + FOldX := FX; + FOldY := FY; FWidth := utils.readWord(st); FHeight := utils.readWord(st); + FOldW := FWidth; + FOldH := FHeight; // Àíèìèðîâàííàÿ ëè òåêóùàÿ òåêñòóðà if utils.readBool(st) then begin