Reverse order of visual gears linked list
authorWuzzy <Wuzzy2@mail.ru>
Mon, 14 Jan 2019 00:34:56 +0100
changeset 14584 ab79cd4a7382
parent 14583 914f04315f21
child 14586 e54e41554529
Reverse order of visual gears linked list Now vgears will render in the order they have been added. Older visual gears are rendered earlier, so they are "behind" newer visual gears. This has been primarily done to fix the render order of speech bubbles (bug #287).
ChangeLog.txt
hedgewars/uVisualGears.pas
hedgewars/uVisualGearsList.pas
--- a/ChangeLog.txt	Mon Jan 14 17:59:32 2019 +0100
+++ b/ChangeLog.txt	Mon Jan 14 00:34:56 2019 +0100
@@ -42,6 +42,7 @@
 
 Graphics:
  + Show contour of flying saucer when in highly opaque water
+ * Fix speech bubbles overlapping in the wrong order
  * Fix wrong ice beam angle if it goes diagonally up out of map through world wrap
  * Fix double water splash when flying saucer drowns
 
--- a/hedgewars/uVisualGears.pas	Mon Jan 14 17:59:32 2019 +0100
+++ b/hedgewars/uVisualGears.pas	Mon Jan 14 00:34:56 2019 +0100
@@ -74,7 +74,7 @@
 
 for i:= 0 to 6 do
     begin
-    t:= VisualGearLayers[i];
+    t:= VisualGearLayersStart[i];
     while t <> nil do
         begin
         Gear:= t;
@@ -93,7 +93,7 @@
 for i:= 2 to 6 do
     if i <> 3 then
         begin
-        t:= VisualGearLayers[i];
+        t:= VisualGearLayersStart[i];
         while t <> nil do
             begin
             Gear:= t;
@@ -154,7 +154,7 @@
 case Layer of
     // this layer is very distant in the background when stereo
     0: begin
-        Gear:= VisualGearLayers[0];
+        Gear:= VisualGearLayersStart[0];
         while Gear <> nil do
             begin
             if Gear^.Tint <> $FFFFFFFF then Tint(Gear^.Tint);
@@ -189,7 +189,7 @@
        end;
     // this layer is on the land level (which is close but behind the screen plane) when stereo
     1: begin
-       Gear:= VisualGearLayers[1];
+       Gear:= VisualGearLayersStart[1];
        while Gear <> nil do
           begin
           if Gear^.Tint <> $FFFFFFFF then
@@ -248,7 +248,7 @@
        end;
     // this layer is on the screen plane (depth = 0) when stereo
     3: begin
-       Gear:= VisualGearLayers[3];
+       Gear:= VisualGearLayersStart[3];
        while Gear <> nil do
            begin
            tinted:= false;
@@ -307,7 +307,7 @@
        end;
     // this layer is outside the screen when stereo
     2: begin
-       Gear:= VisualGearLayers[2];
+       Gear:= VisualGearLayersStart[2];
        while Gear <> nil do
            begin
            tinted:= false;
@@ -382,7 +382,7 @@
        end;
      // this layer is half-way between the screen plane (depth = 0) when in stereo, and the land
      4: begin
-        Gear:= VisualGearLayers[4];
+        Gear:= VisualGearLayersStart[4];
         while Gear <> nil do
             begin
             if Gear^.Tint <> $FFFFFFFF then
@@ -408,7 +408,7 @@
         end;
      // this layer is on the screen plane (depth = 0) when stereo, but just behind the land
      5: begin
-        Gear:= VisualGearLayers[5];
+        Gear:= VisualGearLayersStart[5];
         while Gear <> nil do
             begin
             if Gear^.Tint <> $FFFFFFFF then
@@ -434,7 +434,7 @@
         end;
      // this layer is on the screen plane (depth = 0) when stereo, but just in front of the land
     6: begin
-        Gear:= VisualGearLayers[6];
+        Gear:= VisualGearLayersStart[6];
         while Gear <> nil do
             begin
             if Gear^.Tint <> $FFFFFFFF then
@@ -474,7 +474,7 @@
     exit;
 for i:= 0 to 6 do
     begin
-    vg:= VisualGearLayers[i];
+    vg:= VisualGearLayersStart[i];
     while vg <> nil do
         if vg^.Kind = vgtCloud then
             begin
@@ -514,7 +514,7 @@
     exit;
 for i:= 0 to 6 do
     begin
-    vg:= VisualGearLayers[i];
+    vg:= VisualGearLayersStart[i];
     while vg <> nil do
         if vg^.Kind = vgtFlake then
             begin
@@ -537,7 +537,10 @@
 begin
 VGCounter:= 0;
 for i:= 0 to 6 do
-    VisualGearLayers[i]:= nil;
+    begin
+    VisualGearLayersStart[i]:= nil;
+    VisualGearLayersEnd[i]:= nil;
+    end;
 end;
 
 procedure freeModule;
@@ -545,7 +548,7 @@
 begin
 VGCounter:= 0;
 for i:= 0 to 6 do
-    while VisualGearLayers[i] <> nil do DeleteVisualGear(VisualGearLayers[i]);
+    while VisualGearLayersStart[i] <> nil do DeleteVisualGear(VisualGearLayersStart[i]);
 end;
 
 end.
--- a/hedgewars/uVisualGearsList.pas	Mon Jan 14 17:59:32 2019 +0100
+++ b/hedgewars/uVisualGearsList.pas	Mon Jan 14 00:34:56 2019 +0100
@@ -33,7 +33,8 @@
     cExplFrameTicks = 110;
 
 var VGCounter: LongWord;
-    VisualGearLayers: array[0..6] of PVisualGear;
+    VisualGearLayersStart: array[0..6] of PVisualGear;
+    VisualGearLayersEnd: array[0..6] of PVisualGear;
 
 implementation
 uses uCollisions, uFloat, uVariables, uConsts, uTextures, uVisualGearsHandlers, uScript;
@@ -428,12 +429,15 @@
 
 if Layer <> -1 then gear^.Layer:= Layer;
 
-if VisualGearLayers[gear^.Layer] <> nil then
+if VisualGearLayersStart[gear^.Layer] = nil then
+    VisualGearLayersStart[gear^.Layer]:= gear;
+
+if VisualGearLayersEnd[gear^.Layer] <> nil then
     begin
-    VisualGearLayers[gear^.Layer]^.PrevGear:= gear;
-    gear^.NextGear:= VisualGearLayers[gear^.Layer]
+    VisualGearLayersEnd[gear^.Layer]^.NextGear:= gear;
+    gear^.PrevGear:= VisualGearLayersEnd[gear^.Layer]
     end;
-VisualGearLayers[gear^.Layer]:= gear;
+VisualGearLayersEnd[gear^.Layer]:= gear;
 
 AddVisualGear:= gear;
 ScriptCall('onVisualGearAdd', gear^.uid);
@@ -444,12 +448,19 @@
     ScriptCall('onVisualGearDelete', Gear^.uid);
     FreeAndNilTexture(Gear^.Tex);
 
-    if Gear^.NextGear <> nil then
-        Gear^.NextGear^.PrevGear:= Gear^.PrevGear;
+    if (Gear^.NextGear = nil) and (Gear^.PrevGear = nil) then
+        begin
+        VisualGearLayersStart[Gear^.Layer]:= nil;
+        VisualGearLayersEnd[Gear^.Layer]:= nil;
+        end;
     if Gear^.PrevGear <> nil then
         Gear^.PrevGear^.NextGear:= Gear^.NextGear
-    else
-        VisualGearLayers[Gear^.Layer]:= Gear^.NextGear;
+    else if Gear^.NextGear <> nil then
+        VisualGearLayersStart[Gear^.Layer]:= Gear^.NextGear;
+    if Gear^.NextGear <> nil then
+        Gear^.NextGear^.PrevGear:= Gear^.PrevGear
+    else if Gear^.PrevGear <> nil then
+        VisualGearLayersEnd[Gear^.Layer]:= Gear^.PrevGear;
 
     if lastVisualGearByUID = Gear then
         lastVisualGearByUID:= nil;
@@ -472,7 +483,7 @@
 // search in an order that is more likely to return layers they actually use.  Could perhaps track statistically AddVisualGear in uScript, since that is most likely the ones they want
 for i:= 2 to 5 do
     begin
-    vg:= VisualGearLayers[i mod 4];
+    vg:= VisualGearLayersStart[i mod 4];
     while vg <> nil do
         begin
         if vg^.uid = uid then