DEADSOFTWARE

no more old-styled map structured; sadly, most triggers aren't working; also, save...
[d2df-sdl.git] / src / game / g_panel.pas
index b522ae2beb5c49b38a31e602f7227bd238f2ae3a..5eec8e780a546456cf85a75a25c04b6160b08b62 100644 (file)
@@ -1,9 +1,25 @@
+(* 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.
+ *
+ * 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_panel;
 
 interface
 
 uses
-  MAPSTRUCT, BinEditor, g_textures;
+  MAPDEF, BinEditor, g_textures, xdynrec;
 
 type
   TAddTextureArray = Array of
@@ -25,6 +41,11 @@ type
                             True:  (AnTex: TAnimation);
                         end;
 
+  private
+    function getx1 (): Integer; inline;
+    function gety1 (): Integer; inline;
+    function getvisvalid (): Boolean; inline;
+
   public
     FCurTexture:      Integer; // Íîìåð òåêóùåé òåêñòóðû
     FCurFrame:        Integer;
@@ -35,16 +56,21 @@ type
     SaveIt:           Boolean; // Ñîõðàíÿòü ïðè SaveState?
     Enabled:          Boolean;
     Door:             Boolean;
+    Moved:            Boolean;
     LiftType:         Byte;
     LastAnimLoop:     Byte;
+    arrIdx:           Integer; // index in one of internal arrays; sorry
+    tag:              Integer; // used in coldets and such; sorry
+    proxyId:          Integer; // proxy id in map grid (DO NOT USE!)
 
-    constructor Create(PanelRec: TPanelRec_1;
+    constructor Create(PanelRec: TDynRecord;
                        AddTextures: TAddTextureArray;
                        CurTex: Integer;
                        var Textures: TLevelTextureArray);
     destructor  Destroy(); override;
 
     procedure   Draw();
+    procedure   DrawShadowVolume(lightX: Integer; lightY: Integer; radius: Integer);
     procedure   Update();
     procedure   SetFrame(Frame: Integer; Count: Byte);
     procedure   NextTexture(AnimLoop: Byte = 0);
@@ -54,22 +80,29 @@ type
 
     procedure   SaveState(var Mem: TBinMemoryWriter);
     procedure   LoadState(var Mem: TBinMemoryReader);
+
+    property x0: Integer read X;
+    property y0: Integer read Y;
+    property x1: Integer read getx1; // inclusive!
+    property y1: Integer read gety1; // inclusive!
+    property visvalid: Boolean read getvisvalid; // panel is "visvalid" when it's width and height are positive
   end;
 
+  PPanel = ^TPanel;
   TPanelArray = Array of TPanel;
 
 implementation
 
 uses
-  g_basic, g_map, MAPDEF, g_game, e_graphics,
-  g_console, g_language;
+  SysUtils, g_basic, g_map, g_game, e_graphics,
+  g_console, g_language, e_log, GL;
 
 const
   PANEL_SIGNATURE = $4C4E4150; // 'PANL'
 
 { T P a n e l : }
 
-constructor TPanel.Create(PanelRec: TPanelRec_1;
+constructor TPanel.Create(PanelRec: TDynRecord;
                           AddTextures: TAddTextureArray;
                           CurTex: Integer;
                           var Textures: TLevelTextureArray);
@@ -85,6 +118,7 @@ begin
   FCurFrame := 0;
   FCurFrameCount := 0;
   LastAnimLoop := 0;
+  Moved := False;
 
 // Òèï ïàíåëè:
   PanelType := PanelRec.PanelType;
@@ -153,11 +187,11 @@ begin
 
     case PanelRec.PanelType of
       PANEL_WATER:
-        FTextureIDs[0].Tex := TEXTURE_SPECIAL_WATER;
+        FTextureIDs[0].Tex := LongWord(TEXTURE_SPECIAL_WATER);
       PANEL_ACID1:
-        FTextureIDs[0].Tex := TEXTURE_SPECIAL_ACID1;
+        FTextureIDs[0].Tex := LongWord(TEXTURE_SPECIAL_ACID1);
       PANEL_ACID2:
-        FTextureIDs[0].Tex := TEXTURE_SPECIAL_ACID2;
+        FTextureIDs[0].Tex := LongWord(TEXTURE_SPECIAL_ACID2);
     end;
 
     FCurTexture := 0;
@@ -197,7 +231,15 @@ begin
     SaveIt := True;
 
 // Åñëè íå ñïåöòåêñòóðà, òî çàäàåì ðàçìåðû:
-  if not g_Map_IsSpecialTexture(Textures[PanelRec.TextureNum].TextureName) then
+  if PanelRec.TextureNum > High(Textures) then
+  begin
+    e_WriteLog(Format('WTF?! PanelRec.TextureNum is out of limits! (%d : %d)', [PanelRec.TextureNum, High(Textures)]), MSG_FATALERROR);
+    FTextureWidth := 2;
+    FTextureHeight := 2;
+    FAlpha := 0;
+    FBlending := ByteBool(0);
+  end
+  else if not g_Map_IsSpecialTexture(Textures[PanelRec.TextureNum].TextureName) then
   begin
     FTextureWidth := Textures[PanelRec.TextureNum].Width;
     FTextureHeight := Textures[PanelRec.TextureNum].Height;
@@ -218,22 +260,25 @@ begin
   Inherited;
 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;
+
 procedure TPanel.Draw();
 var
   xx, yy: Integer;
   NoTextureID: DWORD;
   NW, NH: Word;
 begin
-  if Enabled and (FCurTexture >= 0) and
+  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_dbg_scale_05 or g_Collide(X, Y, Width, Height, sX, sY, sWidth, sHeight)) then
   begin
     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
             FTextureIDs[FCurTexture].AnTex.Draw(
@@ -243,16 +288,16 @@ begin
     else
       begin // Îáû÷íàÿ òåêñòóðà
         case FTextureIDs[FCurTexture].Tex of
-          TEXTURE_SPECIAL_WATER:
+          LongWord(TEXTURE_SPECIAL_WATER):
             e_DrawFillQuad(X, Y, X+Width-1, Y+Height-1,
                            0, 0, 255, 0, B_FILTER);
-          TEXTURE_SPECIAL_ACID1:
+          LongWord(TEXTURE_SPECIAL_ACID1):
             e_DrawFillQuad(X, Y, X+Width-1, Y+Height-1,
                            0, 128, 0, 0, B_FILTER);
-          TEXTURE_SPECIAL_ACID2:
+          LongWord(TEXTURE_SPECIAL_ACID2):
             e_DrawFillQuad(X, Y, X+Width-1, Y+Height-1,
                            128, 0, 0, 0, B_FILTER);
-          TEXTURE_NONE:
+          LongWord(TEXTURE_NONE):
             if g_Texture_Get('NOTEXTURE', NoTextureID) then
             begin
               e_GetTextureSize(NoTextureID, @NW, @NH);
@@ -282,6 +327,53 @@ begin
   end;
 end;
 
+procedure TPanel.DrawShadowVolume(lightX: Integer; lightY: Integer; radius: Integer);
+  procedure extrude (x: Integer; y: Integer);
+  begin
+    glVertex2i(x+(x-lightX)*500, y+(y-lightY)*500);
+    //e_WriteLog(Format('  : (%d,%d)', [x+(x-lightX)*300, y+(y-lightY)*300]), MSG_WARNING);
+  end;
+
+  procedure drawLine (x0: Integer; y0: Integer; x1: Integer; y1: Integer);
+  begin
+    // does this side facing the light?
+    if ((x1-x0)*(lightY-y0)-(lightX-x0)*(y1-y0) >= 0) then exit;
+    //e_WriteLog(Format('lightpan: (%d,%d)-(%d,%d)', [x0, y0, x1, y1]), MSG_WARNING);
+    // this edge is facing the light, extrude and draw it
+    glVertex2i(x0, y0);
+    glVertex2i(x1, y1);
+    extrude(x1, y1);
+    extrude(x0, y0);
+  end;
+
+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
+  begin
+    if not FTextureIDs[FCurTexture].Anim then
+    begin
+      case FTextureIDs[FCurTexture].Tex of
+        LongWord(TEXTURE_SPECIAL_WATER): exit;
+        LongWord(TEXTURE_SPECIAL_ACID1): exit;
+        LongWord(TEXTURE_SPECIAL_ACID2): exit;
+        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);
+
+    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
+    glEnd();
+  end;
+end;
+
 procedure TPanel.Update();
 begin
   if Enabled and (FCurTexture >= 0) and
@@ -356,7 +448,7 @@ begin
     else
       if AnimLoop = 2 then
         FTextureIDs[FCurTexture].AnTex.Loop := False;
-        
+
     FTextureIDs[FCurTexture].AnTex.Reset();
   end;
 
@@ -396,7 +488,7 @@ begin
     else
       if AnimLoop = 2 then
         FTextureIDs[FCurTexture].AnTex.Loop := False;
-        
+
     FTextureIDs[FCurTexture].AnTex.Reset();
   end;
 
@@ -405,7 +497,7 @@ end;
 
 function TPanel.GetTextureID(): DWORD;
 begin
-  Result := TEXTURE_NONE;
+  Result := LongWord(TEXTURE_NONE);
 
   if (FCurTexture >= 0) then
   begin
@@ -443,6 +535,9 @@ begin
   Mem.WriteByte(LiftType);
 // Íîìåð òåêóùåé òåêñòóðû:
   Mem.WriteInt(FCurTexture);
+// Êîîðäû
+  Mem.WriteInt(X);
+  Mem.WriteInt(Y);
 // Àíèìèðîâàííàÿ ëè òåêóùàÿ òåêñòóðà:
   if (FCurTexture >= 0) and (FTextureIDs[FCurTexture].Anim) then
     begin
@@ -478,6 +573,9 @@ begin
   Mem.ReadByte(LiftType);
 // Íîìåð òåêóùåé òåêñòóðû:
   Mem.ReadInt(FCurTexture);
+// Êîîðäû
+  Mem.ReadInt(X);
+  Mem.ReadInt(Y);
 // Àíèìèðîâàííàÿ ëè òåêóùàÿ òåêñòóðà:
   Mem.ReadBoolean(anim);
 // Åñëè äà - çàãðóæàåì àíèìàöèþ: