# HG changeset patch
# User koda
# Date 1277129304 -7200
# Node ID 0e968ba12a849cf6f5281455589e957287b4d455
# Parent  a8c673657b79f15ecb50c35dc5a9a8fe26528296# Parent  0ad90165fde0d965cf4b23f2ac82c7f4d6cde03a
memory management for openalbridge
added openalbridge as dependency of hwengine
usound formatted clearly

diff -r a8c673657b79 -r 0e968ba12a84 CMakeLists.txt
--- a/CMakeLists.txt	Fri Jun 18 14:45:05 2010 +0200
+++ b/CMakeLists.txt	Mon Jun 21 16:08:24 2010 +0200
@@ -15,10 +15,10 @@
 		FIND_PROGRAM(HGCOMMAND hg)
 		IF(HGCOMMAND)
 			exec_program(${HGCOMMAND} 
-				     ARGS identify ${CMAKE_CURRENT_SOURCE_DIR}
+				     ARGS identify -in ${CMAKE_CURRENT_SOURCE_DIR}
 				     OUTPUT_VARIABLE version_suffix
 				     )
-			STRING(REGEX REPLACE "(.*) +.*" "\\1" version_suffix ${version_suffix})
+			STRING(REGEX REPLACE "(.*) +(.*)" "\\2:\\1" version_suffix ${version_suffix})
 			MESSAGE(STATUS "Builing revision ${version_suffix}")
 			set(version_suffix ".${version_suffix}")
 #			#truncate to numbers only - trying to fix a problem described in http://www.hedgewars.org/node/2019
@@ -183,6 +183,7 @@
 endif(WITH_SERVER)
 
 add_subdirectory(hedgewars)
+add_subdirectory(misc/libopenalbridge)
 if(NOT BUILD_ENGINE_LIBRARY)
 	add_subdirectory(bin)
 	add_subdirectory(QTfrontend)
diff -r a8c673657b79 -r 0e968ba12a84 QTfrontend/about.cpp
--- a/QTfrontend/about.cpp	Fri Jun 18 14:45:05 2010 +0200
+++ b/QTfrontend/about.cpp	Mon Jun 21 16:08:24 2010 +0200
@@ -76,7 +76,7 @@
             "Mac OS X/iPhone port, OpenGL-ES conversion: Vittorio Giovara &lt;<a href=\"mailto:vittorio.giovara@gmail.com\">vittorio.giovara@gmail.com</a>&gt;<br>"
             "Gamepad and Lua integration, misc effects: Mario Liebisch &lt;<a href=\"mailto:mario.liebisch@googlemail.com\">mario.liebisch@googlemail.com</a>&gt;<br>"
             "Many engine improvements and graphics: Carlos Vives &lt;<a href=\"mailto:mail@carlosvives.es\">mail@carlosvives.es</a>&gt;<br>"
-            "Don't ask: Richard Karolyi &lt;<a href=\"mailto:sheepluva@ercatec.net\">sheepluva@ercatec.net</a>&gt;<br>"
+            "Few engine and frontend improvements: Richard Karolyi &lt;<a href=\"mailto:sheepluva@ercatec.net\">sheepluva@ercatec.net</a>&gt;<br>"
             "Maze maps: Henning K&uuml;hn &lt;<a href=\"mailto:prg@cooco.de\">prg@cooco.de</a>&gt;"
             "</p><h2>" +
 
diff -r a8c673657b79 -r 0e968ba12a84 hedgewars/CMakeLists.txt
--- a/hedgewars/CMakeLists.txt	Fri Jun 18 14:45:05 2010 +0200
+++ b/hedgewars/CMakeLists.txt	Mon Jun 21 16:08:24 2010 +0200
@@ -61,7 +61,7 @@
 	uMisc.pas
 	uRandom.pas
 	uScript.pas
-	uSHA.pas
+	adler32.pas
 	uSound.pas
 	uStats.pas
 	uStore.pas
@@ -76,6 +76,7 @@
 	SinTable.inc
 	options.inc
 	${CMAKE_CURRENT_BINARY_DIR}/config.inc
+	openalbridge
 	)
 
 if(BUILD_ENGINE_LIBRARY)
diff -r a8c673657b79 -r 0e968ba12a84 hedgewars/GSHandlers.inc
--- a/hedgewars/GSHandlers.inc	Fri Jun 18 14:45:05 2010 +0200
+++ b/hedgewars/GSHandlers.inc	Mon Jun 21 16:08:24 2010 +0200
@@ -812,7 +812,7 @@
         end;
 
         if CheckLandValue(hwRound(Gear^.X + Gear^.dX + SignAs(_6,Gear^.dX)), hwRound(Gear^.Y + _1_9)
-           , LAND_INDESTRUCTIBLE) then
+           , lfIndestructible) then
         begin
             Gear^.X := Gear^.X + Gear^.dX;
             Gear^.Y := Gear^.Y + _1_9;
@@ -922,11 +922,11 @@
             // why the call to HedgehogStep then a further increment of X?
             if (prevX = hwRound(HHGear^.X)) and
                CheckLandValue(hwRound(HHGear^.X + SignAs(_6, HHGear^.dX)), hwRound(HHGear^.Y),
-               LAND_INDESTRUCTIBLE) then HedgehogStep(HHGear);
+               lfIndestructible) then HedgehogStep(HHGear);
 
             if (prevX = hwRound(HHGear^.X)) and
                CheckLandValue(hwRound(HHGear^.X + SignAs(_6, HHGear^.dX)), hwRound(HHGear^.Y),
-               LAND_INDESTRUCTIBLE) then HHGear^.X := HHGear^.X + SignAs(_1, HHGear^.dX);
+               lfIndestructible) then HHGear^.X := HHGear^.X + SignAs(_1, HHGear^.dX);
             HHGear^.State := HHGear^.State or gstAttacking
         end;
 
@@ -936,7 +936,7 @@
             BTSteps := 0;
             if CheckLandValue(hwRound(HHGear^.X + Gear^.dX * (cHHRadius + cBlowTorchC) + SignAs(_6,
                Gear^.dX)), hwRound(HHGear^.Y + Gear^.dY * (cHHRadius + cBlowTorchC)),
-               LAND_INDESTRUCTIBLE) then
+               lfIndestructible) then
             begin
                 Gear^.X := HHGear^.X + Gear^.dX * (cHHRadius + cBlowTorchC);
                 Gear^.Y := HHGear^.Y + Gear^.dY * (cHHRadius + cBlowTorchC);
@@ -1795,7 +1795,7 @@
     end;
 
     if CheckLandValue(hwRound(HHGear^.X), hwRound(HHGear^.Y + HHGear^.dY + SignAs(_6,Gear^.dY)),
-       LAND_INDESTRUCTIBLE) then
+       lfIndestructible) then
         HHGear^.Y := HHGear^.Y + HHGear^.dY
 end;
 
@@ -2545,7 +2545,7 @@
        or (not TestCollisionYWithGear(Gear, hwSign(Gear^.dY))
        and not TestCollisionXWithGear(Gear, hwSign(Gear^.dX)))
 // CheckLandValue returns true if the type isn't matched
-       or not CheckLandValue(hwRound(Gear^.Y), hwRound(Gear^.X), LAND_INDESTRUCTIBLE) then
+       or not CheckLandValue(hwRound(Gear^.Y), hwRound(Gear^.X), lfIndestructible) then
     begin
         //out of time or exited ground
         StopSound(Gear^.SoundChannel);
diff -r a8c673657b79 -r 0e968ba12a84 hedgewars/adler32.pas
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hedgewars/adler32.pas	Mon Jun 21 16:08:24 2010 +0200
@@ -0,0 +1,152 @@
+unit Adler32;
+
+{ZLib - Adler32 checksum function}
+
+
+interface
+
+(*************************************************************************
+
+ DESCRIPTION     :  ZLib - Adler32 checksum function
+
+ REQUIREMENTS    :  TP5-7, D1-D7/D9-D10/D12, FPC, VP
+
+ EXTERNAL DATA   :  ---
+
+ MEMORY USAGE    :  ---
+
+ DISPLAY MODE    :  ---
+
+ REFERENCES      :  RFC 1950 (http://tools.ietf.org/html/rfc1950)
+
+
+ Version  Date      Author      Modification
+ -------  --------  -------     ------------------------------------------
+ 0.10     30.08.03  W.Ehrhardt  Initial version based on MD5 layout
+ 2.10     30.08.03  we          Common vers., XL versions for Win32
+ 2.20     27.09.03  we          FPC/go32v2
+ 2.30     05.10.03  we          STD.INC, TP5.0
+ 2.40     10.10.03  we          common version, english comments
+ 3.00     01.12.03  we          Common version 3.0
+ 3.01     22.05.05  we          Adler32UpdateXL (i,n: integer)
+ 3.02     17.12.05  we          Force $I- in Adler32File
+ 3.03     07.08.06  we          $ifdef BIT32: (const fname: shortstring...)
+ 3.04     10.02.07  we          Adler32File: no eof, XL and filemode via $ifdef
+ 3.05     04.07.07  we          BASM16: speed-up factor 15
+ 3.06     12.11.08  we          uses BTypes, Ptr2Inc and/or Str255
+ 3.07     25.04.09  we          updated RFC URL(s)
+ 3.08     19.07.09  we          D12 fix: assign with typecast string(fname)
+**************************************************************************)
+
+(*-------------------------------------------------------------------------
+ (C) Copyright 2002-2009 Wolfgang Ehrhardt
+
+ This software is provided 'as-is', without any express or implied warranty.
+ In no event will the authors be held liable for any damages arising from
+ the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+    claim that you wrote the original software. If you use this software in
+    a product, an acknowledgment in the product documentation would be
+    appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be
+    misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source distribution.
+----------------------------------------------------------------------------*)
+
+(*
+As per the license above, noting that this implementation of adler32 was stripped of everything we didn't need.
+That means no btypes, file loading, and the assembly version disabled.
+*)
+
+procedure Adler32Update(var adler: longint; Msg: pointer; Len: longint);
+
+implementation
+
+(*
+$ifdef BASM16
+
+procedure Adler32Update(var adler: longint; Msg: pointer; Len: longint);
+  //-update Adler32 with Msg data
+const
+  BASE = 65521; // max. prime < 65536 
+  NMAX =  5552; // max. n with 255n(n+1)/2 + (n+1)(BASE-1) < 2^32
+type
+  LH    = packed record
+            L,H: word;
+          end;
+var
+  s1,s2: longint;
+  n: integer;
+begin
+  s1 := LH(adler).L;
+  s2 := LH(adler).H;
+  while Len > 0 do begin
+    if Len<NMAX then n := Len else n := NMAX;
+    //BASM increases speed from about 52 cyc/byte to about 3.7 cyc/byte
+    asm
+                    mov  cx,[n]
+            db $66; mov  ax,word ptr [s1]
+            db $66; mov  di,word ptr [s2]
+                    les  si,[msg]
+      @@1:  db $66, $26, $0f, $b6, $1c      // movzx ebx,es:[si]
+                    inc  si
+            db $66; add  ax,bx              // inc(s1, pByte(Msg)^)
+            db $66; add  di,ax              // inc(s2, s1
+                    dec  cx
+                    jnz  @@1
+            db $66; sub  cx,cx
+                    mov  cx,BASE
+            db $66; sub  dx,dx
+            db $66; div  cx
+            db $66; mov  word ptr [s1],dx   // s1 := s1 mod BASE
+            db $66; sub  dx,dx
+            db $66; mov  ax,di
+            db $66; div  cx
+            db $66; mov  word ptr [s2],dx   // s2 := s2 mod BASE
+                    mov  word ptr [msg],si  // save offset for next chunk
+    end;
+    dec(len, n);
+  end;
+  LH(adler).L := word(s1);
+  LH(adler).H := word(s2);
+end;
+*)
+
+procedure Adler32Update(var adler: longint; Msg: pointer; Len: longint);
+  {-update Adler32 with Msg data}
+const
+  BASE = 65521; {max. prime < 65536 }
+  NMAX =  3854; {max. n with 255n(n+1)/2 + (n+1)(BASE-1) < 2^31}
+type
+  LH    = packed record
+            L,H: word;
+          end;
+var
+  s1,s2: longint;
+  i,n: integer;
+begin
+  s1 := LH(adler).L;
+  s2 := LH(adler).H;
+  while Len > 0 do begin
+    if Len<NMAX then n := Len else n := NMAX;
+    for i:=1 to n do begin
+      inc(s1, pByte(Msg)^);
+      inc(Msg);
+      inc(s2, s1);
+    end;
+    s1 := s1 mod BASE;
+    s2 := s2 mod BASE;
+    dec(len, n);
+  end;
+  LH(adler).L := word(s1);
+  LH(adler).H := word(s2);
+end;
+
+end.
diff -r a8c673657b79 -r 0e968ba12a84 hedgewars/uConsts.pas
--- a/hedgewars/uConsts.pas	Fri Jun 18 14:45:05 2010 +0200
+++ b/hedgewars/uConsts.pas	Mon Jun 21 16:08:24 2010 +0200
@@ -249,10 +249,11 @@
 {$ENDIF}
 
 // To allow these to layer, going to treat them as masks. The bottom byte is reserved for objects
-    LAND_BASIC          = $8000;  // white
-    LAND_INDESTRUCTIBLE = $4000;  // red
-    LAND_OBJECT         = $2000;  // no idea
-    LAND_DAMAGED        = $1000;  // no idea
+// TODO - set lfBasic for all solid land, ensure all uses of the flags can handle multiple flag bits
+    lfBasic          = $8000;  // white
+    lfIndestructible = $4000;  // red
+    lfObject         = $2000;  // no idea
+    lfDamaged        = $1000;  // no idea
 
     cMaxPower     = 1500;
     cMaxAngle     = 2048;
diff -r a8c673657b79 -r 0e968ba12a84 hedgewars/uLand.pas
--- a/hedgewars/uLand.pas	Fri Jun 18 14:45:05 2010 +0200
+++ b/hedgewars/uLand.pas	Mon Jun 21 16:08:24 2010 +0200
@@ -57,7 +57,7 @@
 function  LandBackPixel(x, y: LongInt): LongWord;
 
 implementation
-uses uConsole, uStore, uMisc, uRandom, uTeams, uLandObjects, uSHA, uIO, uLandTexture;
+uses uConsole, uStore, uMisc, uRandom, uTeams, uLandObjects, Adler32, uIO, uLandTexture;
 
 operator=(const a, b: direction) c: Boolean;
 begin
@@ -70,20 +70,13 @@
               end;
 
 procedure LogLandDigest;
-var ctx: TSHA1Context;
-    dig: TSHA1Digest;
-    s: shortstring;
+var s: shortstring;
+    adler: LongInt;
 begin
-{$HINTS OFF}
-SHA1Init(ctx);
-{$HINTS ON}
-SHA1UpdateLongwords(ctx, @Land, sizeof(Land));
-dig:= SHA1Final(ctx);
-s:='M{'+inttostr(dig[0])+':'
-       +inttostr(dig[1])+':'
-       +inttostr(dig[2])+':'
-       +inttostr(dig[3])+':'
-       +inttostr(dig[4])+'}';
+adler:= 1;
+Adler32Update(adler, @Land, sizeof(Land));
+s:= 'M'+inttostr(adler);
+
 CheckLandDigest(s);
 SendIPCRaw(@s[0], Length(s) + 1)
 end;
@@ -561,7 +554,7 @@
 begin
 for y:= 0 to LAND_HEIGHT - 1 do
     for x:= 0 to LAND_WIDTH - 1 do
-        Land[y, x]:= LAND_BASIC;
+        Land[y, x]:= lfBasic;
 
 {$HINTS OFF}
 SetPoints(Template, pa);
@@ -582,7 +575,7 @@
          with FillPoints^[i] do
               FillLand(x, y);
 
-DrawEdge(pa, LAND_BASIC);
+DrawEdge(pa, lfBasic);
 
 MaxHedgehogs:= Template.MaxHedgehogs;
 hasGirders:= Template.hasGirders;
@@ -605,8 +598,8 @@
             else
             begin
                if Land[y, x] = 0 then
-                   Land[y, x]:= LAND_BASIC
-               else if Land[y, x] = LAND_BASIC then
+                   Land[y, x]:= lfBasic
+               else if Land[y, x] = lfBasic then
                    Land[y, x]:= 0;
             end;
     end;
@@ -978,7 +971,7 @@
 
 for x := 0 to playWidth do
     for y := off_y to LAND_HEIGHT - 1 do
-        Land[y, x] := LAND_BASIC;
+        Land[y, x] := lfBasic;
 
 for y := 0 to num_cells_y - 1 do
     for x := 0 to num_cells_x - 1 do
@@ -1079,7 +1072,7 @@
 else
 begin
     x := 0;
-    while Land[cellsize div 2 + cellsize + off_y, x] = LAND_BASIC do
+    while Land[cellsize div 2 + cellsize + off_y, x] = lfBasic do
         x := x + 1;
     while Land[cellsize div 2 + cellsize + off_y, x] = 0 do
         x := x + 1;
@@ -1165,9 +1158,9 @@
                     if ((AMask and p^[x]) = 0) then  // Tiy was having trouble generating transparent black
                         Land[cpY + y, cpX + x]:= 0
                     else if p^[x] = (AMask or RMask) then
-                        Land[cpY + y, cpX + x]:= LAND_INDESTRUCTIBLE
+                        Land[cpY + y, cpX + x]:= lfIndestructible
                     else if p^[x] = $FFFFFFFF then
-                        Land[cpY + y, cpX + x]:= LAND_BASIC;
+                        Land[cpY + y, cpX + x]:= lfBasic;
                 end;
                 p:= @(p^[tmpsurf^.pitch div 4]);
             end;
@@ -1261,15 +1254,15 @@
     for y:= 0 to LAND_HEIGHT - 1 do
         for x:= 0 to LAND_WIDTH - 1 do
             if (y < topY) or (x < leftX) or (x > rightX) then
-                Land[y, x]:= LAND_INDESTRUCTIBLE;
+                Land[y, x]:= lfIndestructible;
     // experiment hardcoding cave
     // also try basing cave dimensions on map/template dimensions, if they exist
     for w:= 0 to 5 do // width of 3 allowed hogs to be knocked through with grenade
         begin
         for y:= topY to LAND_HEIGHT - 1 do
             begin
-            Land[y, leftX + w]:= LAND_INDESTRUCTIBLE;
-            Land[y, rightX - w]:= LAND_INDESTRUCTIBLE;
+            Land[y, leftX + w]:= lfIndestructible;
+            Land[y, rightX - w]:= lfIndestructible;
             if (y + w) mod 32 < 16 then
                 c:= AMask
             else
@@ -1285,7 +1278,7 @@
 
         for x:= leftX to rightX do
             begin
-            Land[topY + w, x]:= LAND_INDESTRUCTIBLE;
+            Land[topY + w, x]:= lfIndestructible;
             if (x + w) mod 32 < 16 then
                 c:= AMask
             else
diff -r a8c673657b79 -r 0e968ba12a84 hedgewars/uLandGraphics.pas
--- a/hedgewars/uLandGraphics.pas	Fri Jun 18 14:45:05 2010 +0200
+++ b/hedgewars/uLandGraphics.pas	Mon Jun 21 16:08:24 2010 +0200
@@ -46,19 +46,19 @@
 begin
 if ((y + dy) and LAND_HEIGHT_MASK) = 0 then
     for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do
-        if (Land[y + dy, i] and LAND_INDESTRUCTIBLE) = 0 then
+        if (Land[y + dy, i] and lfIndestructible) = 0 then
             Land[y + dy, i]:= Value;
 if ((y - dy) and LAND_HEIGHT_MASK) = 0 then
    for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do
-        if (Land[y - dy, i] and LAND_INDESTRUCTIBLE) = 0 then
+        if (Land[y - dy, i] and lfIndestructible) = 0 then
             Land[y - dy, i]:= Value;
 if ((y + dx) and LAND_HEIGHT_MASK) = 0 then
     for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do
-        if (Land[y + dx, i] and LAND_INDESTRUCTIBLE) = 0 then
+        if (Land[y + dx, i] and lfIndestructible) = 0 then
             Land[y + dx, i]:= Value;
 if ((y - dx) and LAND_HEIGHT_MASK) = 0 then
     for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do
-        if (Land[y - dx, i] and LAND_INDESTRUCTIBLE) = 0 then
+        if (Land[y - dx, i] and lfIndestructible) = 0 then
             Land[y - dx, i]:= Value;
 end;
 
@@ -145,7 +145,7 @@
 begin
 if ((y + dy) and LAND_HEIGHT_MASK) = 0 then
     for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do
-        if (not isMap and ((Land[y + dy, i] and LAND_INDESTRUCTIBLE) = 0)) or ((Land[y + dy, i] and LAND_BASIC) <> 0) then
+        if (not isMap and ((Land[y + dy, i] and lfIndestructible) = 0)) or ((Land[y + dy, i] and lfBasic) <> 0) then
 {$IFDEF DOWNSCALE}
             LandPixels[(y + dy) div 2, i div 2]:= 0;
 {$ELSE}
@@ -153,7 +153,7 @@
 {$ENDIF}
 if ((y - dy) and LAND_HEIGHT_MASK) = 0 then
     for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do
-        if (not isMap and ((Land[y - dy, i] and LAND_INDESTRUCTIBLE) = 0)) or ((Land[y - dy, i] and LAND_BASIC) <> 0) then
+        if (not isMap and ((Land[y - dy, i] and lfIndestructible) = 0)) or ((Land[y - dy, i] and lfBasic) <> 0) then
 {$IFDEF DOWNSCALE}
              LandPixels[(y - dy) div 2, i div 2]:= 0;
 {$ELSE}
@@ -161,7 +161,7 @@
 {$ENDIF}
 if ((y + dx) and LAND_HEIGHT_MASK) = 0 then
     for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do
-        if (not isMap and ((Land[y + dx, i] and LAND_INDESTRUCTIBLE) = 0)) or ((Land[y + dx, i] and LAND_BASIC) <> 0) then
+        if (not isMap and ((Land[y + dx, i] and lfIndestructible) = 0)) or ((Land[y + dx, i] and lfBasic) <> 0) then
 {$IFDEF DOWNSCALE}
             LandPixels[(y + dx) div 2, i div 2]:= 0;
 {$ELSE}
@@ -169,7 +169,7 @@
 {$ENDIF}
 if ((y - dx) and LAND_HEIGHT_MASK) = 0 then
     for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do
-        if (not isMap and ((Land[y - dx, i] and LAND_INDESTRUCTIBLE) = 0)) or ((Land[y - dx, i] and LAND_BASIC) <> 0) then
+        if (not isMap and ((Land[y - dx, i] and lfIndestructible) = 0)) or ((Land[y - dx, i] and lfBasic) <> 0) then
 {$IFDEF DOWNSCALE}
              LandPixels[(y - dx) div 2, i div 2]:= 0;
 {$ELSE}
@@ -182,7 +182,7 @@
 begin
 if ((y + dy) and LAND_HEIGHT_MASK) = 0 then
    for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do
-       if ((Land[y + dy, i] and LAND_BASIC) <> 0) then
+       if ((Land[y + dy, i] and lfBasic) <> 0) then
 {$IFDEF DOWNSCALE}
           LandPixels[(y + dy) div 2, i div 2]:= LandBackPixel(i, y + dy)
 {$ELSE}
@@ -190,13 +190,13 @@
 {$ENDIF}
        else
 {$IFDEF DOWNSCALE}
-          if (Land[y + dy, i] = LAND_OBJECT) then LandPixels[(y + dy) div 2, i div 2]:= 0;
+          if ((Land[y + dy, i] and lfObject) <> 0) then LandPixels[(y + dy) div 2, i div 2]:= 0;
 {$ELSE}
-          if (Land[y + dy, i] = LAND_OBJECT) then LandPixels[y + dy, i]:= 0;
+          if ((Land[y + dy, i] and lfObject) <> 0) then LandPixels[y + dy, i]:= 0;
 {$ENDIF}
 if ((y - dy) and LAND_HEIGHT_MASK) = 0 then
    for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do
-       if ((Land[y - dy, i] and LAND_BASIC) <> 0) then
+       if ((Land[y - dy, i] and lfBasic) <> 0) then
 {$IFDEF DOWNSCALE}
           LandPixels[(y - dy) div 2, i div 2]:= LandBackPixel(i, y - dy)
 {$ELSE}
@@ -204,13 +204,13 @@
 {$ENDIF}
        else
 {$IFDEF DOWNSCALE}
-          if (Land[y - dy, i] = LAND_OBJECT) then LandPixels[(y - dy) div 2, i div 2]:= 0;
+          if ((Land[y - dy, i] and lfObject) <> 0) then LandPixels[(y - dy) div 2, i div 2]:= 0;
 {$ELSE}
-          if (Land[y - dy, i] = LAND_OBJECT) then LandPixels[y - dy, i]:= 0;
+          if ((Land[y - dy, i] and lfObject) <> 0) then LandPixels[y - dy, i]:= 0;
 {$ENDIF}
 if ((y + dx) and LAND_HEIGHT_MASK) = 0 then
    for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do
-       if ((Land[y + dx, i] and LAND_BASIC) <> 0) then
+       if ((Land[y + dx, i] and lfBasic) <> 0) then
 {$IFDEF DOWNSCALE}
            LandPixels[(y + dx) div 2, i div 2]:= LandBackPixel(i, y + dx)
 {$ELSE}
@@ -218,13 +218,13 @@
 {$ENDIF}
        else
 {$IFDEF DOWNSCALE}
-          if (Land[y + dx, i] = LAND_OBJECT) then LandPixels[(y + dx) div 2, i div 2]:= 0;
+          if ((Land[y + dx, i] and lfObject) <> 0) then LandPixels[(y + dx) div 2, i div 2]:= 0;
 {$ELSE}
-          if (Land[y + dx, i] = LAND_OBJECT) then LandPixels[y + dx, i]:= 0;
+          if ((Land[y + dx, i] and lfObject) <> 0) then LandPixels[y + dx, i]:= 0;
 {$ENDIF}
 if ((y - dx) and LAND_HEIGHT_MASK) = 0 then
    for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do
-       if ((Land[y - dx, i] and LAND_BASIC) <> 0) then
+       if ((Land[y - dx, i] and lfBasic) <> 0) then
 {$IFDEF DOWNSCALE}
           LandPixels[(y - dx) div 2, i div 2]:= LandBackPixel(i, y - dx)
 {$ELSE}
@@ -232,9 +232,9 @@
 {$ENDIF}
        else
 {$IFDEF DOWNSCALE}
-          if (Land[y - dx, i] = LAND_OBJECT) then LandPixels[(y - dx) div 2, i div 2]:= 0;
+          if ((Land[y - dx, i] and lfObject) <> 0) then LandPixels[(y - dx) div 2, i div 2]:= 0;
 {$ELSE}
-          if (Land[y - dx, i] = LAND_OBJECT) then LandPixels[y - dx, i]:= 0;
+          if ((Land[y - dx, i] and lfObject) <> 0) then LandPixels[y - dx, i]:= 0;
 {$ENDIF}
 end;
 
@@ -243,53 +243,53 @@
 begin
 if ((y + dy) and LAND_HEIGHT_MASK) = 0 then
    for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do
-       if ((Land[y + dy, i] and LAND_BASIC) <> 0) or (Land[y + dy, i] = LAND_OBJECT) then
+       if ((Land[y + dy, i] and lfBasic) <> 0) or ((Land[y + dy, i] and lfObject) <> 0) then
           begin
 {$IFDEF DOWNSCALE}
           LandPixels[(y + dy) div 2, i div 2]:= cExplosionBorderColor;
 {$ELSE}
           LandPixels[y + dy, i]:= cExplosionBorderColor;
 {$ENDIF}
-          Land[y + dy, i]:= Land[y + dy, i] or LAND_DAMAGED;
+          Land[y + dy, i]:= Land[y + dy, i] or lfDamaged;
           Despeckle(i, y + dy);
           LandDirty[(y + dy) div 32, i div 32]:= 1;
           end;
 if ((y - dy) and LAND_HEIGHT_MASK) = 0 then
    for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do
-       if ((Land[y - dy, i] and LAND_BASIC) <> 0) or (Land[y - dy, i] = LAND_OBJECT) then
+       if ((Land[y - dy, i] and lfBasic) <> 0) or ((Land[y - dy, i] and lfObject) <> 0) then
           begin
 {$IFDEF DOWNSCALE}
           LandPixels[(y - dy) div 2, i div 2]:= cExplosionBorderColor;
 {$ELSE}
           LandPixels[y - dy, i]:= cExplosionBorderColor;
 {$ENDIF}
-          Land[y - dy, i]:= Land[y - dy, i] or LAND_DAMAGED;
+          Land[y - dy, i]:= Land[y - dy, i] or lfDamaged;
           Despeckle(i, y - dy);
           LandDirty[(y - dy) div 32, i div 32]:= 1;
           end;
 if ((y + dx) and LAND_HEIGHT_MASK) = 0 then
    for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do
-       if ((Land[y + dx, i] and LAND_BASIC) <> 0) or (Land[y + dx, i] = LAND_OBJECT) then
+       if ((Land[y + dx, i] and lfBasic) <> 0) or ((Land[y + dx, i] and lfObject) <> 0) then
            begin
 {$IFDEF DOWNSCALE}
            LandPixels[(y + dx) div 2, i div 2]:= cExplosionBorderColor;
 {$ELSE}
            LandPixels[y + dx, i]:= cExplosionBorderColor;
 {$ENDIF}
-           Land[y + dx, i]:= Land[y + dx, i] or LAND_DAMAGED;
+           Land[y + dx, i]:= Land[y + dx, i] or lfDamaged;
            Despeckle(i, y + dx);
            LandDirty[(y + dx) div 32, i div 32]:= 1;
            end;
 if ((y - dx) and LAND_HEIGHT_MASK) = 0 then
    for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do
-       if ((Land[y - dx, i] and LAND_BASIC) <> 0) or (Land[y - dx, i] = LAND_OBJECT) then
+       if ((Land[y - dx, i] and lfBasic) <> 0) or ((Land[y - dx, i] and lfObject) <> 0) then
           begin
 {$IFDEF DOWNSCALE}
           LandPixels[(y - dx) div 2, i div 2]:= cExplosionBorderColor;
 {$ELSE}
           LandPixels[y - dx, i]:= cExplosionBorderColor;
 {$ENDIF}
-          Land[y - dx, i]:= Land[y - dx, i] or LAND_DAMAGED;
+          Land[y - dx, i]:= Land[y - dx, i] or lfDamaged;
           Despeckle(i, y - dy);
           LandDirty[(y - dx) div 32, i div 32]:= 1;
           end;
@@ -377,13 +377,13 @@
     begin
     for ty:= max(y - Radius, 0) to min(y + Radius, LAND_HEIGHT) do
         for tx:= max(0, ar^[i].Left - Radius) to min(LAND_WIDTH, ar^[i].Right + Radius) do
-            if (Land[ty, tx] and LAND_BASIC) <> 0 then
+            if (Land[ty, tx] and lfBasic) <> 0 then
 {$IFDEF DOWNSCALE}
                 LandPixels[ty div 2, tx div 2]:= LandBackPixel(tx, ty)
 {$ELSE}
                 LandPixels[ty, tx]:= LandBackPixel(tx, ty)
 {$ENDIF}
-            else if Land[ty, tx] = LAND_OBJECT then
+            else if (Land[ty, tx] and lfObject) <> 0 then
 {$IFDEF DOWNSCALE}
                 LandPixels[ty div 2, tx div 2]:= 0;
 {$ELSE}
@@ -399,14 +399,14 @@
     begin
     for ty:= max(y - Radius, 0) to min(y + Radius, LAND_HEIGHT) do
         for tx:= max(0, ar^[i].Left - Radius) to min(LAND_WIDTH, ar^[i].Right + Radius) do
-            if ((Land[ty, tx] and LAND_BASIC) <> 0) or (Land[ty, tx] = LAND_OBJECT) then
+            if ((Land[ty, tx] and lfBasic) <> 0) or ((Land[ty, tx] and lfObject) <> 0) then
                 begin
 {$IFDEF DOWNSCALE}
                 LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor;
 {$ELSE}
                 LandPixels[ty, tx]:= cExplosionBorderColor;
 {$ENDIF}
-                Land[ty, tx]:= Land[ty, tx] or LAND_DAMAGED;
+                Land[ty, tx]:= Land[ty, tx] or lfDamaged;
                 LandDirty[(y + dy) shr 5, i shr 5]:= 1;
                 end;
     inc(y, dY)
@@ -443,10 +443,10 @@
     ty:= hwRound(Y);
     if ((ty and LAND_HEIGHT_MASK) = 0) and
        ((tx and LAND_WIDTH_MASK) = 0) and
-       (((Land[ty, tx] and LAND_BASIC) <> 0) or 
-       (Land[ty, tx] = LAND_OBJECT)) then
+       (((Land[ty, tx] and lfBasic) <> 0) or 
+       ((Land[ty, tx] and lfObject) <> 0)) then
         begin
-        Land[ty, tx]:= Land[ty, tx] or LAND_DAMAGED;
+        Land[ty, tx]:= Land[ty, tx] or lfDamaged;
 {$IFDEF DOWNSCALE}
         LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor
 {$ELSE}
@@ -470,10 +470,10 @@
     ty:= hwRound(Y);
     if ((ty and LAND_HEIGHT_MASK) = 0) and
        ((tx and LAND_WIDTH_MASK) = 0) and
-       (((Land[ty, tx] and LAND_BASIC) <> 0) or 
-       (Land[ty, tx] = LAND_OBJECT)) then
+       (((Land[ty, tx] and lfBasic) <> 0) or 
+       ((Land[ty, tx] and lfObject) <> 0)) then
         begin
-        Land[ty, tx]:= Land[ty, tx] or LAND_DAMAGED;
+        Land[ty, tx]:= Land[ty, tx] or lfDamaged;
 {$IFDEF DOWNSCALE}
         LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor
 {$ELSE}
@@ -489,15 +489,15 @@
         Y:= Y + dY;
         tx:= hwRound(X);
         ty:= hwRound(Y);
-        if ((ty and LAND_HEIGHT_MASK) = 0) and ((tx and LAND_WIDTH_MASK) = 0) and ((Land[ty, tx] and LAND_INDESTRUCTIBLE) = 0) then
+        if ((ty and LAND_HEIGHT_MASK) = 0) and ((tx and LAND_WIDTH_MASK) = 0) and ((Land[ty, tx] and lfIndestructible) = 0) then
             begin
-            if (Land[ty, tx] and LAND_BASIC) <> 0 then
+            if (Land[ty, tx] and lfBasic) <> 0 then
 {$IFDEF DOWNSCALE}
                 LandPixels[ty div 2, tx div 2]:= LandBackPixel(tx, ty)
 {$ELSE}
                 LandPixels[ty, tx]:= LandBackPixel(tx, ty)
 {$ENDIF}
-            else if Land[ty, tx] = LAND_OBJECT then
+            else if (Land[ty, tx] and lfObject) <> 0 then
 {$IFDEF DOWNSCALE}
                 LandPixels[ty div 2, tx div 2]:= 0;
 {$ELSE}
@@ -514,10 +514,10 @@
     ty:= hwRound(Y);
     if ((ty and LAND_HEIGHT_MASK) = 0) and
        ((tx and LAND_WIDTH_MASK) = 0) and
-       (((Land[ty, tx] and LAND_BASIC) <> 0) or 
-       (Land[ty, tx] = LAND_OBJECT)) then
+       (((Land[ty, tx] and lfBasic) <> 0) or 
+       ((Land[ty, tx] and lfObject) <> 0)) then
         begin
-        Land[ty, tx]:= Land[ty, tx] or LAND_DAMAGED;
+        Land[ty, tx]:= Land[ty, tx] or lfDamaged;
 {$IFDEF DOWNSCALE}
         LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor
 {$ELSE}
@@ -541,10 +541,10 @@
     ty:= hwRound(Y);
     if ((ty and LAND_HEIGHT_MASK) = 0) and
        ((tx and LAND_WIDTH_MASK) = 0) and
-       (((Land[ty, tx] and LAND_BASIC) <> 0) or 
-       (Land[ty, tx] = LAND_OBJECT)) then
+       (((Land[ty, tx] and lfBasic) <> 0) or 
+       ((Land[ty, tx] and lfObject) <> 0)) then
         begin
-        Land[ty, tx]:= Land[ty, tx] or LAND_DAMAGED;
+        Land[ty, tx]:= Land[ty, tx] or lfDamaged;
 {$IFDEF DOWNSCALE}
         LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor
 {$ELSE}
@@ -620,7 +620,7 @@
             for x:= 0 to Pred(w) do
                 if PLongword(@(p^[x * 4]))^ <> 0 then
                    begin
-                   Land[cpY + y, cpX + x]:= LAND_OBJECT;
+                   Land[cpY + y, cpX + x]:= lfObject;
 {$IFDEF DOWNSCALE}
                    LandPixels[(cpY + y) div 2, (cpX + x) div 2]:= PLongword(@(p^[x * 4]))^
 {$ELSE}
@@ -644,7 +644,7 @@
 function Despeckle(X, Y: LongInt): boolean;
 var nx, ny, i, j, c: LongInt;
 begin
-if (Land[Y, X] > 255) and ((Land[Y, X] and LAND_INDESTRUCTIBLE) = 0) and ((Land[Y, X] and LAND_DAMAGED) <> 0)then // check neighbours
+if ((Land[Y, X] and lfDamaged) <> 0) and ((Land[Y, X] and lfIndestructible) = 0) then // check neighbours
     begin
     c:= 0;
     for i:= -1 to 1 do
@@ -661,9 +661,9 @@
     if c < 4 then // 0-3 neighbours
         begin
 {$IFDEF DOWNSCALE}
-        if (Land[Y, X] and LAND_BASIC) <> 0 then LandPixels[Y div 2, X div 2]:= LandBackPixel(X, Y) else LandPixels[Y div 2, X div 2]:= 0;
+        if (Land[Y, X] and lfBasic) <> 0 then LandPixels[Y div 2, X div 2]:= LandBackPixel(X, Y) else LandPixels[Y div 2, X div 2]:= 0;
 {$ELSE}
-        if (Land[Y, X] and LAND_BASIC) <> 0 then LandPixels[Y, X]:= LandBackPixel(X, Y) else LandPixels[Y, X]:= 0;
+        if (Land[Y, X] and lfBasic) <> 0 then LandPixels[Y, X]:= LandBackPixel(X, Y) else LandPixels[Y, X]:= 0;
 {$ENDIF}
         Land[Y, X]:= 0;
         exit(true);
diff -r a8c673657b79 -r 0e968ba12a84 hedgewars/uLandObjects.pas
--- a/hedgewars/uLandObjects.pas	Fri Jun 18 14:45:05 2010 +0200
+++ b/hedgewars/uLandObjects.pas	Mon Jun 21 16:08:24 2010 +0200
@@ -93,7 +93,7 @@
             LandPixels[cpY + y, cpX + x]:= p^[x];
 {$ENDIF}
         if ((Land[cpY + y, cpX + x] and $FF00) = 0) and ((p^[x] and AMask) <> 0) then 
-            Land[cpY + y, cpX + x]:= LAND_OBJECT
+            Land[cpY + y, cpX + x]:= lfObject
         end;
     p:= @(p^[Image^.pitch shr 2])
     end;
@@ -211,23 +211,31 @@
 end;
 
 function CheckLand(rect: TSDL_Rect; dX, dY, Color: Longword): boolean;
-var i: LongInt;
+var tmpx, tmpx2, tmpy, tmpy2, bx, by: LongInt;
     bRes: boolean = true;
 begin
 inc(rect.x, dX);
 inc(rect.y, dY);
-i:= 0;
+bx:= rect.x + rect.w;
+by:= rect.y + rect.h;
 {$WARNINGS OFF}
-while (i <= rect.w) and bRes do
+tmpx:= rect.x;
+tmpx2:= bx;
+while (tmpx <= bx - rect.w div 2 - 1) and bRes do
       begin
-      bRes:= (Land[rect.y, rect.x + i] = Color) and (Land[rect.y + rect.h, rect.x + i] = Color);
-      inc(i)
+      bRes:= (Land[rect.y, tmpx] = Color) and (Land[by, tmpx] = Color) and
+             (Land[rect.y, tmpx2] = Color) and (Land[by, tmpx2] = Color);
+      inc(tmpx);
+      dec(tmpx2)
       end;
-i:= 0;
-while (i <= rect.h) and bRes do
+tmpy:= rect.y+1;
+tmpy2:= by-1;
+while (tmpy <= by - rect.h div 2 - 1) and bRes do
       begin
-      bRes:= (Land[rect.y + i, rect.x] = Color) and (Land[rect.y + i, rect.x + rect.w] = Color);
-      inc(i)
+      bRes:= (Land[tmpy, rect.x] = Color) and (Land[tmpy, bx] = Color) and
+             (Land[tmpy2, rect.x] = Color) and (Land[tmpy2, bx] = Color);
+      inc(tmpy);
+      dec(tmpy2)
       end;
 {$WARNINGS ON}
 CheckLand:= bRes;
@@ -238,7 +246,7 @@
     bRes: boolean;
 begin
 with Obj do
-     if CheckLand(inland, x, y, LAND_BASIC) then
+     if CheckLand(inland, x, y, lfBasic) then
         begin
         bRes:= true;
         i:= 1;
@@ -318,7 +326,7 @@
     repeat
         y:= 8;
         repeat
-            if CheckLand(r, x, y - 8, LAND_BASIC)
+            if CheckLand(r, x, y - 8, lfBasic)
             and not CheckIntersect(x, y, Width, Height) then
             begin
             ar[cnt].x:= x;
diff -r a8c673657b79 -r 0e968ba12a84 hedgewars/uSound.pas
--- a/hedgewars/uSound.pas	Fri Jun 18 14:45:05 2010 +0200
+++ b/hedgewars/uSound.pas	Mon Jun 21 16:08:24 2010 +0200
@@ -40,8 +40,8 @@
 procedure PlaySound(snd: TSound; keepPlaying: boolean);
 procedure PlaySound(snd: TSound; voicepack: PVoicepack);
 procedure PlaySound(snd: TSound; voicepack: PVoicepack; keepPlaying: boolean);
-function LoopSound(snd: TSound): LongInt;
-function LoopSound(snd: TSound; voicepack: PVoicepack): LongInt;
+function  LoopSound(snd: TSound): LongInt;
+function  LoopSound(snd: TSound; voicepack: PVoicepack): LongInt;
 procedure PlayMusic;
 procedure PauseMusic;
 procedure ResumeMusic;
@@ -65,14 +65,14 @@
 var i: Longword;
 begin
 i:= 0;
-while (voicepacks[i].name <> name) and (voicepacks[i].name <> '') do
+    while (voicepacks[i].name <> name) and (voicepacks[i].name <> '') do
     begin
-    inc(i);
-    TryDo(i <= cMaxTeams, 'Engine bug: AskForVoicepack i > cMaxTeams', true)
+        inc(i);
+        TryDo(i <= cMaxTeams, 'Engine bug: AskForVoicepack i > cMaxTeams', true)
     end;
 
-voicepacks[i].name:= name;
-AskForVoicepack:= @voicepacks[i]
+    voicepacks[i].name:= name;
+    AskForVoicepack:= @voicepacks[i]
 end;
 
 procedure InitSound;
@@ -110,22 +110,22 @@
 var i: TSound;
     t: Longword;
 begin
-for t:= 0 to cMaxTeams do
-    if voicepacks[t].name <> '' then
-        for i:= Low(TSound) to High(TSound) do
-            if voicepacks[t].chunks[i] <> nil then
-                Mix_FreeChunk(voicepacks[t].chunks[i]);
+    for t:= 0 to cMaxTeams do
+        if voicepacks[t].name <> '' then
+            for i:= Low(TSound) to High(TSound) do
+                if voicepacks[t].chunks[i] <> nil then
+                    Mix_FreeChunk(voicepacks[t].chunks[i]);
 
-if Mus <> nil then
-    Mix_FreeMusic(Mus);
+    if Mus <> nil then
+        Mix_FreeMusic(Mus);
 
 {$IFDEF SDL_MIXER_NEWER}
-// make sure all instances of sdl_mixer are unloaded before continuing
-while Mix_Init(0) <> 0 do
-    Mix_Quit();
+    // make sure all instances of sdl_mixer are unloaded before continuing
+    while Mix_Init(0) <> 0 do
+        Mix_Quit();
 {$ENDIF}    
 
-Mix_CloseAudio();
+    Mix_CloseAudio();
 end;
 
 procedure SoundLoad;
@@ -137,28 +137,28 @@
 
     defVoicepack:= AskForVoicepack('Default');
 
-for i:= Low(TSound) to High(TSound) do
-    if (Soundz[i].Path <> ptVoices) and (Soundz[i].FileName <> '') then
+    for i:= Low(TSound) to High(TSound) do
+        if (Soundz[i].Path <> ptVoices) and (Soundz[i].FileName <> '') then
         begin
-        s:= Pathz[Soundz[i].Path] + '/' + Soundz[i].FileName;
-        WriteToConsole(msgLoading + s + ' ');
-        defVoicepack^.chunks[i]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), 'rb'), 1);
-        TryDo(defVoicepack^.chunks[i] <> nil, msgFailed, true);
-        WriteLnToConsole(msgOK);
+            s:= Pathz[Soundz[i].Path] + '/' + Soundz[i].FileName;
+            WriteToConsole(msgLoading + s + ' ');
+            defVoicepack^.chunks[i]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), 'rb'), 1);
+            TryDo(defVoicepack^.chunks[i] <> nil, msgFailed, true);
+            WriteLnToConsole(msgOK);
         end;
 
-for t:= 0 to cMaxTeams do
-    if voicepacks[t].name <> '' then
-        for i:= Low(TSound) to High(TSound) do
-            if (Soundz[i].Path = ptVoices) and (Soundz[i].FileName <> '') then
+    for t:= 0 to cMaxTeams do
+        if voicepacks[t].name <> '' then
+            for i:= Low(TSound) to High(TSound) do
+                if (Soundz[i].Path = ptVoices) and (Soundz[i].FileName <> '') then
                 begin
-                s:= Pathz[Soundz[i].Path] + '/' + voicepacks[t].name + '/' + Soundz[i].FileName;
-                WriteToConsole(msgLoading + s + ' ');
-                voicepacks[t].chunks[i]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), 'rb'), 1);
-                if voicepacks[t].chunks[i] = nil then
-                    WriteLnToConsole(msgFailed)
-                else
-                    WriteLnToConsole(msgOK)
+                    s:= Pathz[Soundz[i].Path] + '/' + voicepacks[t].name + '/' + Soundz[i].FileName;
+                    WriteToConsole(msgLoading + s + ' ');
+                    voicepacks[t].chunks[i]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), 'rb'), 1);
+                    if voicepacks[t].chunks[i] = nil then
+                        WriteLnToConsole(msgFailed)
+                    else
+                        WriteLnToConsole(msgOK)
                 end;
 end;
 
@@ -179,15 +179,16 @@
 
 procedure PlaySound(snd: TSound; voicepack: PVoicepack; keepPlaying: boolean);
 begin
-if (not isSoundEnabled) or fastUntilLag then exit;
-
-if keepPlaying and (lastChan[snd] <> -1) and (Mix_Playing(lastChan[snd]) <> 0) then
-    exit;
+    if (not isSoundEnabled) or fastUntilLag then
+        exit;
 
-if (voicepack <> nil) and (voicepack^.chunks[snd] <> nil) then
-    lastChan[snd]:= Mix_PlayChannelTimed(-1, voicepack^.chunks[snd], 0, -1)
-else
-    lastChan[snd]:= Mix_PlayChannelTimed(-1, defVoicepack^.chunks[snd], 0, -1)
+    if keepPlaying and (lastChan[snd] <> -1) and (Mix_Playing(lastChan[snd]) <> 0) then
+        exit;
+
+    if (voicepack <> nil) and (voicepack^.chunks[snd] <> nil) then
+        lastChan[snd]:= Mix_PlayChannelTimed(-1, voicepack^.chunks[snd], 0, -1)
+    else
+        lastChan[snd]:= Mix_PlayChannelTimed(-1, defVoicepack^.chunks[snd], 0, -1)
 end;
 
 function LoopSound(snd: TSound): LongInt;
@@ -197,76 +198,79 @@
 
 function LoopSound(snd: TSound; voicepack: PVoicepack): LongInt;
 begin
-if (not isSoundEnabled) or fastUntilLag then
+    if (not isSoundEnabled) or fastUntilLag then
     begin
-    LoopSound:= -1;
-    exit
+        LoopSound:= -1;
+        exit
     end;
 
-if (voicepack <> nil) and (voicepack^.chunks[snd] <> nil) then
-    LoopSound:= Mix_PlayChannelTimed(-1, voicepack^.chunks[snd], -1, -1)
-else
-    LoopSound:= Mix_PlayChannelTimed(-1, defVoicepack^.chunks[snd], -1, -1)
+    if (voicepack <> nil) and (voicepack^.chunks[snd] <> nil) then
+        LoopSound:= Mix_PlayChannelTimed(-1, voicepack^.chunks[snd], -1, -1)
+    else
+        LoopSound:= Mix_PlayChannelTimed(-1, defVoicepack^.chunks[snd], -1, -1)
 end;
 
 procedure StopSound(snd: TSound);
 begin
-if not isSoundEnabled then exit;
-if (lastChan[snd] <> -1) and (Mix_Playing(lastChan[snd]) <> 0) then
+    if not isSoundEnabled then exit;
+    if (lastChan[snd] <> -1) and (Mix_Playing(lastChan[snd]) <> 0) then
     begin
-    Mix_HaltChannel(lastChan[snd]);
-    lastChan[snd]:= -1;
+        Mix_HaltChannel(lastChan[snd]);
+        lastChan[snd]:= -1;
     end;
 end;
 
 procedure StopSound(chn: LongInt);
 begin
-if not isSoundEnabled then exit;
-if (chn <> -1) and (Mix_Playing(chn) <> 0) then Mix_HaltChannel(chn);
+    if not isSoundEnabled then exit;
+
+    if (chn <> -1) and (Mix_Playing(chn) <> 0) then
+        Mix_HaltChannel(chn);
 end;
 
 procedure PlayMusic;
 var s: shortstring;
 begin
-if (not isSoundEnabled)
-    or (MusicFN = '')
-    or (not isMusicEnabled) then exit;
+    if (not isSoundEnabled) or (MusicFN = '') or (not isMusicEnabled) then
+        exit;
+
+    s:= PathPrefix + '/Music/' + MusicFN;
+    WriteToConsole(msgLoading + s + ' ');
 
-s:= PathPrefix + '/Music/' + MusicFN;
-WriteToConsole(msgLoading + s + ' ');
+    Mus:= Mix_LoadMUS(Str2PChar(s));
+    TryDo(Mus <> nil, msgFailed, false);
+    WriteLnToConsole(msgOK);
 
-Mus:= Mix_LoadMUS(Str2PChar(s));
-TryDo(Mus <> nil, msgFailed, false);
-WriteLnToConsole(msgOK);
-
-SDLTry(Mix_FadeInMusic(Mus, -1, 3000) <> -1, false)
+    SDLTry(Mix_FadeInMusic(Mus, -1, 3000) <> -1, false)
 end;
 
 function ChangeVolume(voldelta: LongInt): LongInt;
 begin
-if not isSoundEnabled then
-    exit(0);
+    if not isSoundEnabled then
+        exit(0);
 
-inc(Volume, voldelta);
-if Volume < 0 then Volume:= 0;
-Mix_Volume(-1, Volume);
-Volume:= Mix_Volume(-1, -1);
-if isMusicEnabled then Mix_VolumeMusic(Volume * 4 div 8);
-ChangeVolume:= Volume * 100 div MIX_MAX_VOLUME
+    inc(Volume, voldelta);
+    if Volume < 0 then Volume:= 0;
+    Mix_Volume(-1, Volume);
+    Volume:= Mix_Volume(-1, -1);
+    if isMusicEnabled then Mix_VolumeMusic(Volume * 4 div 8);
+    ChangeVolume:= Volume * 100 div MIX_MAX_VOLUME
 end;
 
 procedure PauseMusic;
 begin
-if (MusicFN = '') or (not isMusicEnabled) then exit;
+    if (MusicFN = '') or (not isMusicEnabled) then
+        exit;
 
-Mix_PauseMusic(Mus);
+    Mix_PauseMusic(Mus);
 end;
 
 procedure ResumeMusic;
 begin
-if (MusicFN = '') or (not isMusicEnabled) then exit;
+    if (MusicFN = '') or (not isMusicEnabled) then
+        exit;
 
-Mix_ResumeMusic(Mus);
+    Mix_ResumeMusic(Mus);
 end;
 
 procedure initModule;
diff -r a8c673657b79 -r 0e968ba12a84 misc/libopenalbridge/CMakeLists.txt
--- a/misc/libopenalbridge/CMakeLists.txt	Fri Jun 18 14:45:05 2010 +0200
+++ b/misc/libopenalbridge/CMakeLists.txt	Mon Jun 21 16:08:24 2010 +0200
@@ -7,9 +7,7 @@
 set(LIBRARY_OUTPUT_PATH ${EXECUTABLE_OUTPUT_PATH})
 
 #list of source files for libraries
-set(openal_src
-	openalbridge.c loaders.c wrappers.c errlib.c
-)
+set(openal_src openalbridge.c loaders.c wrappers.c commands.c)
 
 #build a static library for human systems
 set (build_type STATIC)
@@ -17,9 +15,7 @@
 #visualstudio and windows in general don't like static linking, so we're building the library in shared mode
 if(WIN32)
 #workaround for visualstudio (wants headers in the source list)
-	set(openal_src
-		openalbridge.h openalbridge_t.h loaders.h wrappers.h globals.h oggvorbis.h errlib.h ${openal_src}
-	)
+	set(openal_src *.h ${openal_src})
 #deps for the shared library
 	link_libraries(${VORBISFILE_LIBRARY})
 	link_libraries(${VORBIS_LIBRARY})
@@ -39,3 +35,8 @@
 #install it in the executable directory
 	install(TARGETS openalbridge DESTINATION bin)
 endif(WIN32)
+
+#type make openalbridge_test to get a small executable test
+add_executable(openalbridge_test "${hedgewars_SOURCE_DIR}/misc/libopenalbridge/tester.c")
+target_link_libraries(openalbridge_test openalbridge ${OPENAL_LIBRARY} ${OGGVORBIS_LIBRARIES})
+
diff -r a8c673657b79 -r 0e968ba12a84 misc/libopenalbridge/commands.c
--- a/misc/libopenalbridge/commands.c	Fri Jun 18 14:45:05 2010 +0200
+++ b/misc/libopenalbridge/commands.c	Mon Jun 21 16:08:24 2010 +0200
@@ -92,8 +92,6 @@
             fprintf(stderr,"(Bridge Warning) - failed to play sound %d\n", index);
             return;
         }
-        
-        the_sounds[index].stats++;
     }
 }
 
diff -r a8c673657b79 -r 0e968ba12a84 misc/libopenalbridge/openalbridge.c
--- a/misc/libopenalbridge/openalbridge.c	Fri Jun 18 14:45:05 2010 +0200
+++ b/misc/libopenalbridge/openalbridge.c	Mon Jun 21 16:08:24 2010 +0200
@@ -34,22 +34,14 @@
 
 // Initialize an OpenAL contex and allocate memory space for data and buffers
 // It can be called twice to increase the cache size
-int openal_init (int memorysize) {
+int openal_init (void) {
     ALCcontext *context;
     ALCdevice *device;
     int i;
         
     // reuse old context and resize the existing 
     if (openal_ready() == AL_TRUE) {
-        cache_size += memorysize;
-        fprintf(stderr,"(Bridge Info) - already initialized, resizing cache to %d\n", cache_size);
-        the_sounds = (al_sound_t *)Realloc (the_sounds, sizeof(al_sound_t) * cache_size);
-        for (i = cache_size - memorysize; i < cache_size; i++) {
-            the_sounds[i].filename = NULL;
-            the_sounds[i].buffer = -1;
-            the_sounds[i].source_index = -1;
-            the_sounds[i].stats = 0;
-        }
+        fprintf(stderr,"(Bridge Info) - already initialized\n");
         instances_number++;
         return AL_TRUE;
     }
@@ -57,12 +49,9 @@
     cache_pointer = 0;
     instances_number++;
     
-    // set the memory dimentsion and the increment width when reallocating
-    if (memorysize <= 0)
-        cache_size = 50;
-    else
-        cache_size = memorysize;
-
+    // initial memory size
+    cache_size = 50;
+    
     // open hardware device if present
     device = alcOpenDevice(NULL);
     sources_number = 16;
@@ -110,12 +99,8 @@
     }
 
     the_sounds = (al_sound_t *)Malloc (sizeof(al_sound_t) * cache_size);
-    for (i = 0; i < cache_size; i++) {
-        the_sounds[i].filename = NULL;
-        the_sounds[i].buffer = -1;
-        the_sounds[i].source_index = -1;
-        the_sounds[i].stats = 0;
-    }
+    for (i = 0; i < cache_size; i++)
+        the_sounds[i] = new_sound_el();
 
     alGetError();
     return AL_TRUE;
@@ -135,15 +120,16 @@
 
     instances_number--;
     if (instances_number > 0) {
+        // release memory only when last session ends
         return;
     }
     
-    //TODO: free other stuff also
-    for (i = 0; i < cache_size; i++)
-        alDeleteBuffers (1, &the_sounds[i].buffer);
+    for (i = 0; i < cache_size; i++) {
+        openal_unloadfile(i);
+    }
     free(the_sounds);
 
-    alSourceStopv	(sources_number, Sources);
+    alSourceStopv (sources_number, Sources);
     alDeleteSources (sources_number, Sources);
 
     free(Sources);
@@ -174,8 +160,8 @@
     ALenum format, error;
     ALsizei bitsize, freq;
     uint32_t fileformat;
-    al_sound_t soundData;
-    int len, i;
+    al_sound_t sound_data;
+    int len, i, index = -1;
     char *data;
     FILE *fp;
     
@@ -193,16 +179,24 @@
 #endif
             return i;
         }
+        // if we don't have memory available search for a free element
+        if (cache_pointer >= cache_size)
+            if (the_sounds[i].is_used == AL_FALSE)
+                index = i; 
     }
 
-    if (cache_pointer >= cache_size) {
-        fprintf(stderr,"(Bridge ERROR) - Cache size limit reached; consider allocating more space\n", filename);
-        return -2;
-    }
+    if (index == -1 && cache_pointer >= cache_size) {
+        fprintf(stderr,"(Bridge Info) - No free spots found; doubling cache size\n", filename);
+        cache_size *= 2;
+        the_sounds = (al_sound_t *)Realloc (the_sounds, sizeof(al_sound_t) * cache_size);
+        for (i = cache_size - 50; i < cache_size; i++) 
+            the_sounds[i] = new_sound_el();
+    } else 
+        index = ++cache_pointer;
+    
     
     // detect the file format, as written in the first 4 bytes of the header
     fp = Fopen (filename, "rb");
-
     if (fp == NULL) {
         fprintf(stderr,"(Bridge ERROR) - File %s not loaded\n", filename);
         return -3;
@@ -210,7 +204,6 @@
 
     error = fread (&fileformat, sizeof(uint32_t), 1, fp);
     fclose (fp);
-
     if (error < 0) {
         fprintf(stderr,"(Bridge ERROR) - File %s is too short\n", filename);
         return -4;
@@ -231,26 +224,26 @@
 
     if (error != 0) {
         fprintf(stderr,"(Bridge ERROR) - error loading file %s\n", filename);
-        free(data);
+        if(data)
+            free(data);
         return -6;
     }
 
-    alGenBuffers(1, &soundData.buffer);
-    soundData.filename = filename;
-    soundData.source_index = -1;
-    soundData.stats = 0;
+    // alGenBuffers happens here
+    sound_data = init_sound_el(filename);
     
     if (AL_NO_ERROR != alGetError()) {
-        fprintf(stderr,"(Bridge ERROR) - Failed to allocate memory for buffers\n");
+        fprintf(stderr,"(Bridge ERROR) - Failed to allocate memory for buffer %d\n", index);
+        free(data);
         return -5;
     }
     
     // copy pcm data in one buffer and free it
-    alBufferData(soundData.buffer, format, data, bitsize, freq);
+    alBufferData(sound_data.buffer, format, data, bitsize, freq);
     free(data);
 
     if (AL_NO_ERROR != alGetError()) {
-        fprintf(stderr,"(Bridge ERROR) - Failed to write data to buffers\n");
+        fprintf(stderr,"(Bridge ERROR) - Failed to write data to buffer %d\n", index);
         return -8;
     }
     
@@ -260,6 +253,21 @@
     fprintf(stderr,"(Bridge Info) - successfully loaded %s\n", filename);
 
     // returns the index of the source you just loaded, increments it and exits
-    the_sounds[cache_pointer] = soundData;
-    return cache_pointer++;
+    the_sounds[index] = sound_data;
+    return index;
 }
+
+
+void openal_unloadfile (uint32_t index) {
+    ALint state;
+
+    if (openal_ready() == AL_TRUE && index < cache_size && the_sounds[index].is_used == AL_TRUE) {
+        alGetSourcei (Sources[the_sounds[index].source_index], AL_SOURCE_STATE, &state);
+        if (state == AL_PLAYING || state == AL_PAUSED)
+            openal_stopsound(index);
+        
+        // free memory and 
+        alDeleteBuffers (1, &the_sounds[index].buffer);
+        the_sounds[index] = new_sound_el();
+    }
+}
\ No newline at end of file
diff -r a8c673657b79 -r 0e968ba12a84 misc/libopenalbridge/openalbridge.h
--- a/misc/libopenalbridge/openalbridge.h	Fri Jun 18 14:45:05 2010 +0200
+++ b/misc/libopenalbridge/openalbridge.h	Mon Jun 21 16:08:24 2010 +0200
@@ -27,7 +27,7 @@
 #endif
 
     // init audio context and allocate memory
-    int openal_init               (int memorysize);
+    int openal_init               (void);
 
     // close audio subsytem and free memory
     void openal_close             (void);
diff -r a8c673657b79 -r 0e968ba12a84 misc/libopenalbridge/openalbridge_t.h
--- a/misc/libopenalbridge/openalbridge_t.h	Fri Jun 18 14:45:05 2010 +0200
+++ b/misc/libopenalbridge/openalbridge_t.h	Mon Jun 21 16:08:24 2010 +0200
@@ -32,7 +32,7 @@
     const char *filename;       // name of the sound file
     ALuint buffer;              // actual sound content
     uint32_t source_index;      // index of the associated source
-    uint32_t stats;             // number of times the sound has been played
+    ALboolean is_used;          // tells if the element can be overwritten
 } al_sound_t;
 #pragma pack()
 
diff -r a8c673657b79 -r 0e968ba12a84 misc/libopenalbridge/tester.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libopenalbridge/tester.c	Mon Jun 21 16:08:24 2010 +0200
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#include "openalbridge.h"
+
+int main (int argc, int **argv) {
+    
+    openal_init();
+    
+    openal_close();
+    
+    return 0;
+}
\ No newline at end of file
diff -r a8c673657b79 -r 0e968ba12a84 misc/libopenalbridge/wrappers.c
--- a/misc/libopenalbridge/wrappers.c	Fri Jun 18 14:45:05 2010 +0200
+++ b/misc/libopenalbridge/wrappers.c	Mon Jun 21 16:08:24 2010 +0200
@@ -44,7 +44,7 @@
 }
 
 
-FILE *Fopen (const char *fname, char *mode)	{
+FILE *Fopen (const char *fname, char *mode) {
     FILE *fp;
 
     fp = fopen(fname,mode);
@@ -55,3 +55,24 @@
 }
 
 
+al_sound_t new_sound_el (void) {
+    al_sound_t sound;
+    
+    sound.filename = NULL;
+    sound.buffer = -1;
+    sound.source_index = -1;
+    sound.is_used = AL_FALSE;
+
+    return sound;
+}
+
+al_sound_t init_sound_el (const char *str) {
+    al_sound_t sound;
+    
+    sound.filename = str;
+    sound.source_index = -1;
+    sound.is_used = AL_TRUE;
+    alGenBuffers(1, &sound.buffer);
+
+    return sound;
+}
diff -r a8c673657b79 -r 0e968ba12a84 misc/libopenalbridge/wrappers.h
--- a/misc/libopenalbridge/wrappers.h	Fri Jun 18 14:45:05 2010 +0200
+++ b/misc/libopenalbridge/wrappers.h	Mon Jun 21 16:08:24 2010 +0200
@@ -26,5 +26,7 @@
 void *Realloc (void *aptr, size_t nbytes);
 FILE *Fopen (const char *fname, char *mode);
 void helper_fade (void *tmp);
+al_sound_t new_sound_el (void);
+al_sound_t init_sound_el (const char *str);
 
 #endif /*_OALB_WRAPPERS_H*/