DEADSOFTWARE

gl: draw menu background
[d2df-sdl.git] / src / game / opengl / r_map.pas
index 1be9bbc1632a075034c504a8105d791278d31def..a35980d798eb0b9f5f301152f515435f31832a3f 100644 (file)
@@ -17,11 +17,19 @@ unit r_map;
 
 interface
 
-  uses g_panel, MAPDEF; // TPanel, TDFColor
+  uses g_panel, MAPDEF, binheap; // TPanel, TDFColor
+
+  procedure r_Map_Initialize;
+  procedure r_Map_Finalize;
+
+  procedure r_Map_Load;
+  procedure r_Map_Free;
 
   procedure r_Map_LoadTextures;
+  procedure r_Map_FreeTextures;
+
+  procedure r_Map_Update;
 
-  procedure r_Map_DrawBack (dx, dy: Integer);
   procedure r_Map_DrawPanels (PanelType: Word; hasAmbient: Boolean; constref ambColor: TDFColor); // unaccelerated
   procedure r_Map_CollectDrawPanels (x0, y0, wdt, hgt: Integer);
   procedure r_Map_DrawPanelShadowVolumes (lightX: Integer; lightY: Integer; radius: Integer);
@@ -30,13 +38,23 @@ interface
   procedure r_Panel_Draw (constref p: TPanel; hasAmbient: Boolean; constref ambColor: TDFColor);
   procedure r_Panel_DrawShadowVolume (constref p: TPanel; lightX, lightY: Integer; radius: Integer);
 
+  type
+    TBinHeapPanelDrawCmp = class
+      public
+        class function less (const a, b: TPanel): Boolean; inline;
+    end;
+
+    TBinHeapPanelDraw = specialize TBinaryHeapBase<TPanel, TBinHeapPanelDrawCmp>;
+
+  var
+    gDrawPanelList: TBinHeapPanelDraw = nil; // binary heap of all walls we have to render, populated by `g_Map_CollectDrawPanels()`
+
 implementation
 
   uses
     {$INCLUDE ../nogl/noGLuses.inc}
-    SysUtils, Classes, Math, utils,
-    e_log, wadreader, CONFIG,
-    r_graphics, r_animations, r_textures,
+    SysUtils, Classes, Math, e_log, wadreader, CONFIG, utils, g_language,
+    r_graphics, r_animations, r_textures, g_animations,
     g_base, g_basic, g_game, g_options,
     g_map
   ;
@@ -45,7 +63,39 @@ implementation
     RenTextures: array of record
       ID: DWORD;
       Width, Height: WORD;
+      Anim: Boolean;
     end;
+    FlagFrames: array [FLAG_RED..FLAG_BLUE] of DWORD;
+    FlagAnim: TAnimState;
+
+  class function TBinHeapPanelDrawCmp.less (const a, b: TPanel): Boolean; inline;
+  begin
+    if (a.tag < b.tag) then begin result := true; exit; end;
+    if (a.tag > b.tag) then begin result := false; exit; end;
+    result := (a.arrIdx < b.arrIdx);
+  end;
+
+  procedure r_Map_Initialize;
+  begin
+    FlagAnim := TAnimState.Create(True, 8, 5);
+  end;
+
+  procedure r_Map_Finalize;
+  begin
+    FlagAnim.Invalidate;
+  end;
+
+  procedure r_Map_Load;
+  begin
+    g_Frames_CreateWAD(@FlagFrames[FLAG_RED], 'FRAMES_FLAG_RED', GameWAD + ':TEXTURES\FLAGRED', 64, 64, 5, False);
+    g_Frames_CreateWAD(@FlagFrames[FLAG_BLUE], 'FRAMES_FLAG_BLUE', GameWAD + ':TEXTURES\FLAGBLUE', 64, 64, 5, False);
+  end;
+
+  procedure r_Map_Free;
+  begin
+    g_Frames_DeleteByName('FRAMES_FLAG_RED');
+    g_Frames_DeleteByName('FRAMES_FLAG_BLUE');
+  end;
 
   procedure r_Map_LoadTextures;
     const
@@ -68,9 +118,11 @@ implementation
       SetLength(RenTextures, n);
       for i := 0 to n - 1 do
       begin
+        // e_LogWritefln('r_Map_LoadTextures: -> [%s] :: [%s]', [Textures[i].FullName, Textures[i].TextureName]);
         RenTextures[i].ID := LongWord(TEXTURE_NONE);
         RenTextures[i].Width := 0;
         RenTextures[i].Height := 0;
+        RenTextures[i].Anim := False;
         case Textures[i].TextureName of
           TEXTURE_NAME_WATER: RenTextures[i].ID := LongWord(TEXTURE_SPECIAL_WATER);
           TEXTURE_NAME_ACID1: RenTextures[i].ID := LongWord(TEXTURE_SPECIAL_ACID1);
@@ -83,7 +135,7 @@ implementation
           begin
             if WAD.GetResource(ResName, ResData, ResLen, log) then
             begin
-              if Textures[i].Anim then
+              if IsWadData(ResData, ResLen) then
               begin
                 WADz := TWADFile.Create();
                 if WADz.ReadMemory(ResData, ResLen) then
@@ -106,7 +158,9 @@ implementation
                       begin
                         if WADz.GetResource('TEXTURES/' + TextureResource, ReszData, ReszLen) then
                         begin
-                          if not g_Frames_CreateMemory(@RenTextures[i].ID, '', ReszData, ReszLen, Width, Height, FramesCount, BackAnim) then
+                          if g_Frames_CreateMemory(@RenTextures[i].ID, '', ReszData, ReszLen, Width, Height, FramesCount, BackAnim) then
+                            RenTextures[i].Anim := True
+                          else
                             e_LogWritefln('r_Map_LoadTextures: failed to create frames object (%s)', [Textures[i].FullName]);
                           FreeMem(ReszData)
                         end
@@ -147,6 +201,11 @@ implementation
     end
   end;
 
+  procedure r_Map_FreeTextures;
+  begin
+    // TODO
+  end;
+
 procedure dplClear ();
 begin
   if (gDrawPanelList = nil) then gDrawPanelList := TBinHeapPanelDraw.Create() else gDrawPanelList.clear();
@@ -206,55 +265,29 @@ begin
   it.release();
 end;
 
-procedure r_Map_DrawBack(dx, dy: Integer);
-begin
-  if gDrawBackGround and (BackID <> DWORD(-1)) then
-    e_DrawSize(BackID, dx, dy, 0, False, False, gBackSize.X, gBackSize.Y)
-  else
-    e_Clear(GL_COLOR_BUFFER_BIT, 0, 0, 0);
-end;
-
-procedure r_Map_DrawFlags();
-var
-  i, dx: Integer;
-  tx, ty: Integer;
-  Mirror: TMirrorType;
-begin
-  if gGameSettings.GameMode <> GM_CTF then
-    Exit;
-
-  for i := FLAG_RED to FLAG_BLUE do
-    with gFlags[i] do
-      if State <> FLAG_STATE_CAPTURED then
+  procedure r_Map_DrawFlags;
+    var i, dx, tx, ty: Integer; Mirror: TMirrorType; f: PFlag;
+  begin
+    if gGameSettings.GameMode = GM_CTF then
+    begin
+      for i := FLAG_RED to FLAG_BLUE do
       begin
-        if State = FLAG_STATE_NONE then
-          continue;
-
-        Obj.lerp(gLerpFactor, tx, ty);
-
-        if Direction = TDirection.D_LEFT then
-          begin
-            Mirror := TMirrorType.Horizontal;
-            dx := -1;
-          end
-        else
-          begin
-            Mirror := TMirrorType.None;
-            dx := 1;
-          end;
-
-        r_Animation_Draw(Animation, tx + dx, ty + 1, Mirror);
-
-        if g_debug_Frames then
+        f := @gFlags[i];
+        if not (f.State in [FLAG_STATE_NONE, FLAG_STATE_CAPTURED]) then
         begin
-          e_DrawQuad(Obj.X+Obj.Rect.X,
-                     Obj.Y+Obj.Rect.Y,
-                     Obj.X+Obj.Rect.X+Obj.Rect.Width-1,
-                     Obj.Y+Obj.Rect.Y+Obj.Rect.Height-1,
-                     0, 255, 0);
-        end;
-      end;
-end;
+          f.Obj.lerp(gLerpFactor, tx, ty);
+          if f.Direction = TDirection.D_LEFT then
+            Mirror :=  TMirrorType.Horizontal
+          else
+            Mirror := TMirrorType.None;
+          dx := IfThen(f.Direction = TDirection.D_LEFT, -1, +1);
+          r_AnimState_Draw(FlagFrames[i], FlagAnim, tx + dx, ty + 1, 0, Mirror, False);
+          if g_debug_Frames then
+            e_DrawQuad(tx + f.Obj.Rect.X, ty + f.Obj.Rect.Y, tx + f.Obj.Rect.X + f.Obj.Rect.Width - 1, ty + f.Obj.Rect.Y + f.Obj.Rect.Height - 1, 0, 255, 0)
+        end
+      end
+    end
+  end;
 
   procedure Panel_Lerp (p: TPanel; t: Single; out tX, tY, tW, tH: Integer);
   begin
@@ -281,17 +314,17 @@ end;
     begin
       Panel_Lerp(p, gLerpFactor, tx, ty, tw, th);
       Texture := p.TextureIDs[p.FCurTexture].Texture;
-      IsAnim := p.TextureIDs[p.FCurTexture].Anim;
+      IsAnim := RenTextures[Texture].Anim;
       if IsAnim then
       begin
-        if p.TextureIDs[p.FCurTexture].AnTex <> nil then
+        if p.TextureIDs[p.FCurTexture].AnTex.IsValid() then
         begin
           FramesID := RenTextures[Texture].ID;
           w := RenTextures[Texture].Width;
           h := RenTextures[Texture].Height;
           for xx := 0 to tw div w - 1 do
             for yy := 0 to th div h - 1 do
-              r_AnimationState_Draw(FramesID, p.TextureIDs[p.FCurTexture].AnTex, tx + xx * w, ty + yy * h, TMirrorType.None);
+              r_AnimState_Draw(FramesID, p.TextureIDs[p.FCurTexture].AnTex, tx + xx * w, ty + yy * h, p.Alpha, TMirrorType.None, p.Blending);
         end
       end
       else
@@ -356,9 +389,9 @@ end;
     if p.Enabled and (p.FCurTexture >= 0) and (p.Width > 0) and (p.Height > 0) and (p.Alpha < 255) {and g_Collide(X, Y, tw, th, sX, sY, sWidth, sHeight)} then
     begin
       Panel_Lerp(p, gLerpFactor, tx, ty, tw, th);
-      if not p.TextureIDs[p.FCurTexture].Anim then
+      Texture := p.TextureIDs[p.FCurTexture].Texture;
+      if not RenTextures[Texture].Anim then
       begin
-        Texture := p.TextureIDs[p.FCurTexture].Texture;
         case RenTextures[Texture].ID of
           LongWord(TEXTURE_SPECIAL_WATER): exit;
           LongWord(TEXTURE_SPECIAL_ACID1): exit;
@@ -380,4 +413,9 @@ end;
     end
   end;
 
+  procedure r_Map_Update;
+  begin
+    FlagAnim.Update
+  end;
+
 end.