hedgewars/uWorld.pas
branchsdl2transition
changeset 11362 ed5a6478e710
parent 9798 f2b18754742f
parent 11317 62287d4044e7
child 11519 aab4767d9a50
equal deleted inserted replaced
11361:31570b766315 11362:ed5a6478e710
     1 (*
     1 (*
     2  * Hedgewars, a free turn based strategy game
     2  * Hedgewars, a free turn based strategy game
     3  * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr@gmail.com>
     3  * Copyright (c) 2004-2015 Andrey Korotaev <unC0Rr@gmail.com>
     4  *
     4  *
     5  * This program is free software; you can redistribute it and/or modify
     5  * This program is free software; you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation; version 2 of the License
     7  * the Free Software Foundation; version 2 of the License
     8  *
     8  *
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    12  * GNU General Public License for more details.
    13  *
    13  *
    14  * You should have received a copy of the GNU General Public License
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program; if not, write to the Free Software
    15  * along with this program; if not, write to the Free Software
    16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
    16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    17  *)
    17  *)
    18 
    18 
    19 {$INCLUDE "options.inc"}
    19 {$INCLUDE "options.inc"}
    20 {$IF GLunit = GL}{$DEFINE GLunit:=GL,GLext}{$ENDIF}
       
    21 
    20 
    22 unit uWorld;
    21 unit uWorld;
    23 interface
    22 interface
    24 uses SDLh, uGears, uConsts, uFloat, uRandom, uTypes, uRenderUtils;
    23 uses SDLh, uGears, uConsts, uFloat, uRandom, uTypes, uRenderUtils;
    25 
    24 
    38 procedure InitTouchInterface;
    37 procedure InitTouchInterface;
    39 procedure SetUtilityWidgetState(ammoType: TAmmoType);
    38 procedure SetUtilityWidgetState(ammoType: TAmmoType);
    40 procedure animateWidget(widget: POnScreenWidget; fade, showWidget: boolean);
    39 procedure animateWidget(widget: POnScreenWidget; fade, showWidget: boolean);
    41 procedure MoveCamera;
    40 procedure MoveCamera;
    42 procedure onFocusStateChanged;
    41 procedure onFocusStateChanged;
       
    42 procedure updateCursorVisibility;
    43 
    43 
    44 implementation
    44 implementation
    45 uses
    45 uses
    46     uStore
    46     uStore
    47     , uMisc
    47     , uMisc
    50     , uSound
    50     , uSound
    51     , uAmmos
    51     , uAmmos
    52     , uVisualGears
    52     , uVisualGears
    53     , uChat
    53     , uChat
    54     , uLandTexture
    54     , uLandTexture
    55     , GLunit
       
    56     , uVariables
    55     , uVariables
    57     , uUtils
    56     , uUtils
    58     , uTextures
    57     , uTextures
    59     , uRender
    58     , uRender
    60     , uCaptions
    59     , uCaptions
    64 {$IFDEF USE_VIDEO_RECORDING}
    63 {$IFDEF USE_VIDEO_RECORDING}
    65     , uVideoRec
    64     , uVideoRec
    66 {$ENDIF}
    65 {$ENDIF}
    67     ;
    66     ;
    68 
    67 
    69 var cWaveWidth, cWaveHeight: LongInt;
    68 var AMShiftTargetX, AMShiftTargetY, AMShiftX, AMShiftY, SlotsNum: LongInt;
    70     AMShiftTargetX, AMShiftTargetY, AMShiftX, AMShiftY, SlotsNum: LongInt;
       
    71     AMAnimStartTime, AMState : LongInt;
    69     AMAnimStartTime, AMState : LongInt;
    72     AMAnimState: Single;
    70     AMAnimState: Single;
    73     tmpSurface: PSDL_Surface;
    71     tmpSurface: PSDL_Surface;
    74     fpsTexture: PTexture;
    72     fpsTexture: PTexture;
    75     timeTexture: PTexture;
    73     timeTexture: PTexture;
    77     CountTicks: Longword;
    75     CountTicks: Longword;
    78     prevPoint{, prevTargetPoint}: TPoint;
    76     prevPoint{, prevTargetPoint}: TPoint;
    79     amSel: TAmmoType = amNothing;
    77     amSel: TAmmoType = amNothing;
    80     missionTex: PTexture;
    78     missionTex: PTexture;
    81     missionTimer: LongInt;
    79     missionTimer: LongInt;
    82     stereoDepth: GLfloat;
       
    83     isFirstFrame: boolean;
    80     isFirstFrame: boolean;
    84     AMAnimType: LongInt;
    81     AMAnimType: LongInt;
    85     recTexture: PTexture;
    82     recTexture: PTexture;
    86     AmmoMenuTex     : PTexture;
    83     AmmoMenuTex     : PTexture;
    87     HorizontOffset: LongInt;
    84     HorizontOffset: LongInt;
   119 
   116 
   120 // helper functions to create the goal/game mode string
   117 // helper functions to create the goal/game mode string
   121 function AddGoal(s: ansistring; gf: longword; si: TGoalStrId; i: LongInt): ansistring;
   118 function AddGoal(s: ansistring; gf: longword; si: TGoalStrId; i: LongInt): ansistring;
   122 var t: ansistring;
   119 var t: ansistring;
   123 begin
   120 begin
       
   121 {$IFNDEF PAS2C}
   124     if (GameFlags and gf) <> 0 then
   122     if (GameFlags and gf) <> 0 then
   125         begin
   123         begin
   126         t:= inttostr(i);
   124         t:= inttostr(i);
   127         s:= s + FormatA(trgoal[si], t) + '|'
   125         s:= s + FormatA(trgoal[si], t) + '|'
   128         end;
   126         end;
       
   127 {$ENDIF}
   129     AddGoal:= s;
   128     AddGoal:= s;
   130 end;
   129 end;
   131 
   130 
   132 function AddGoal(s: ansistring; gf: longword; si: TGoalStrId): ansistring;
   131 function AddGoal(s: ansistring; gf: longword; si: TGoalStrId): ansistring;
   133 begin
   132 begin
       
   133 {$IFNDEF PAS2C}
   134     if (GameFlags and gf) <> 0 then
   134     if (GameFlags and gf) <> 0 then
   135         s:= s + trgoal[si] + '|';
   135         s:= s + trgoal[si] + '|';
       
   136 {$ENDIF}
   136     AddGoal:= s;
   137     AddGoal:= s;
   137 end;
   138 end;
   138 
   139 
   139 procedure InitWorld;
   140 procedure InitWorld;
   140 var i, t: LongInt;
   141 var i, t: LongInt;
   210     else
   211     else
   211         g:= AddGoal(g, gfAny, gidMineTimer, cMinesTime div 1000);
   212         g:= AddGoal(g, gfAny, gidMineTimer, cMinesTime div 1000);
   212     end;
   213     end;
   213 
   214 
   214 // if the string has been set, show it for (default timeframe) seconds
   215 // if the string has been set, show it for (default timeframe) seconds
   215 if g <> '' then
   216 if length(g) > 0 then
   216     ShowMission(trgoal[gidCaption], trgoal[gidSubCaption], g, 1, 0);
   217     ShowMission(trgoal[gidCaption], trgoal[gidSubCaption], g, 1, 0);
   217 
   218 
   218 cWaveWidth:= SpritesData[sprWater].Width;
   219 //cWaveWidth:= SpritesData[sprWater].Width;
   219 //cWaveHeight:= SpritesData[sprWater].Height;
   220 //cWaveHeight:= SpritesData[sprWater].Height;
   220 cWaveHeight:= 32;
   221 cWaveHeight:= 32;
   221 
   222 
   222 InitCameraBorders();
   223 InitCameraBorders();
   223 uCursor.init();
   224 uCursor.init();
   224 prevPoint.X:= 0;
   225 prevPoint.X:= 0;
   225 prevPoint.Y:= cScreenHeight div 2;
   226 prevPoint.Y:= cScreenHeight div 2;
   226 //prevTargetPoint.X:= 0;
   227 //prevTargetPoint.X:= 0;
   227 //prevTargetPoint.Y:= 0;
   228 //prevTargetPoint.Y:= 0;
   228 WorldDx:=  -(LAND_WIDTH div 2) + cScreenWidth div 2;
   229 WorldDx:=  -(LongInt(leftX + (playWidth div 2))); // -(LAND_WIDTH div 2);// + cScreenWidth div 2;
   229 WorldDy:=  -(LAND_HEIGHT - (playHeight div 2)) + (cScreenHeight div 2);
   230 WorldDy:=  -(LAND_HEIGHT - (playHeight div 2)) + (cScreenHeight div 2);
   230 
   231 
   231 //aligns it to the bottom of the screen, minus the border
   232 //aligns it to the bottom of the screen, minus the border
   232 SkyOffset:= 0;
   233 SkyOffset:= 0;
   233 HorizontOffset:= 0;
   234 HorizontOffset:= 0;
   399 end;
   400 end;
   400 
   401 
   401 // for uStore texture resetting
   402 // for uStore texture resetting
   402 procedure ResetWorldTex;
   403 procedure ResetWorldTex;
   403 begin
   404 begin
   404     FreeTexture(fpsTexture);
   405     FreeAndNilTexture(fpsTexture);
   405     fpsTexture:= nil;
   406     FreeAndNilTexture(timeTexture);
   406     FreeTexture(timeTexture);
   407     FreeAndNilTexture(missionTex);
   407     timeTexture:= nil;
   408     FreeAndNilTexture(recTexture);
   408     FreeTexture(missionTex);
   409     FreeAndNilTexture(AmmoMenuTex);
   409     missionTex:= nil;
   410     AmmoMenuInvalidated:= true;
   410     FreeTexture(recTexture);
       
   411     recTexture:= nil;
       
   412 end;
   411 end;
   413 
   412 
   414 function GetAmmoMenuTexture(Ammo: PHHAmmo): PTexture;
   413 function GetAmmoMenuTexture(Ammo: PHHAmmo): PTexture;
   415 const BORDERSIZE = 2;
   414 const BORDERSIZE = 2;
   416 var x, y, i, t, SlotsNumY, SlotsNumX, AMFrame: LongInt;
   415 var x, y, i, t, SlotsNumY, SlotsNumX, AMFrame: LongInt;
   417     STurns: LongInt;
   416     STurns: LongInt;
   418     amSurface: PSDL_Surface;
   417     amSurface: PSDL_Surface;
   419     AMRect: TSDL_Rect;
   418     AMRect: TSDL_Rect;
   420 {$IFDEF USE_AM_NUMCOLUMN}tmpsurf: PSDL_Surface;{$ENDIF}
   419 {$IFDEF USE_AM_NUMCOLUMN}tmpsurf: PSDL_Surface;{$ENDIF}
   421 begin
   420 begin
       
   421     if cOnlyStats then exit(nil);
       
   422 
   422     SlotsNum:= 0;
   423     SlotsNum:= 0;
   423     for i:= 0 to cMaxSlotIndex do
   424     for i:= 0 to cMaxSlotIndex do
   424         if((i = 0) and (Ammo^[i,1].Count > 0)) or ((i <> 0) and (Ammo^[i,0].Count > 0)) then
   425         if((i = 0) and (Ammo^[i,1].Count > 0)) or ((i <> 0) and (Ammo^[i,0].Count > 0)) then
   425             inc(SlotsNum);
   426             inc(SlotsNum);
   426 {$IFDEF USE_LANDSCAPE_AMMOMENU}
   427 {$IFDEF USE_LANDSCAPE_AMMOMENU}
   439 
   440 
   440 
   441 
   441     AmmoRect.w:= (BORDERSIZE*2) + (SlotsNumX * AMSlotSize) + (SlotsNumX-1);
   442     AmmoRect.w:= (BORDERSIZE*2) + (SlotsNumX * AMSlotSize) + (SlotsNumX-1);
   442     AmmoRect.h:= (BORDERSIZE*2) + (SlotsNumY * AMSlotSize) + (SlotsNumY-1);
   443     AmmoRect.h:= (BORDERSIZE*2) + (SlotsNumY * AMSlotSize) + (SlotsNumY-1);
   443     amSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, AmmoRect.w, AmmoRect.h, 32, RMask, GMask, BMask, AMask);
   444     amSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, AmmoRect.w, AmmoRect.h, 32, RMask, GMask, BMask, AMask);
   444     
   445 
   445     AMRect.x:= BORDERSIZE;
   446     AMRect.x:= BORDERSIZE;
   446     AMRect.y:= BORDERSIZE;
   447     AMRect.y:= BORDERSIZE;
   447     AMRect.w:= AmmoRect.w - (BORDERSIZE*2);
   448     AMRect.w:= AmmoRect.w - (BORDERSIZE*2);
   448     AMRect.h:= AmmoRect.h - (BORDERSIZE*2);
   449     AMRect.h:= AmmoRect.h - (BORDERSIZE*2);
   449 
   450 
   450     SDL_FillRect(amSurface, @AMRect, SDL_MapRGB(amSurface^.format, 0,0,0));
   451     SDL_FillRect(amSurface, @AMRect, SDL_MapRGB(amSurface^.format, 0,0,0));
   451     
   452 
   452     x:= AMRect.x;
   453     x:= AMRect.x;
   453     y:= AMRect.y;
   454     y:= AMRect.y;
   454     for i:= 0 to cMaxSlotIndex do
   455     for i:= 0 to cMaxSlotIndex do
   455         if ((i = 0) and (Ammo^[i, 1].Count > 0)) or ((i <> 0) and (Ammo^[i, 0].Count > 0)) then
   456         if ((i = 0) and (Ammo^[i, 1].Count > 0)) or ((i <> 0) and (Ammo^[i, 0].Count > 0)) then
   456             begin
   457             begin
   480                     begin
   481                     begin
   481                     STurns:= Ammoz[Ammo^[i, t].AmmoType].SkipTurns - CurrentTeam^.Clan^.TurnNumber;
   482                     STurns:= Ammoz[Ammo^[i, t].AmmoType].SkipTurns - CurrentTeam^.Clan^.TurnNumber;
   482                     AMFrame:= LongInt(Ammo^[i,t].AmmoType) - 1;
   483                     AMFrame:= LongInt(Ammo^[i,t].AmmoType) - 1;
   483                     if STurns >= 0 then //weapon not usable yet, draw grayed out with turns remaining
   484                     if STurns >= 0 then //weapon not usable yet, draw grayed out with turns remaining
   484                         begin
   485                         begin
   485                         DrawSpriteFrame2Surf(sprAMAmmosBW, amSurface, x + AMSlotPadding, 
   486                         DrawSpriteFrame2Surf(sprAMAmmosBW, amSurface, x + AMSlotPadding,
   486                                                                  y + AMSlotPadding, AMFrame);
   487                                                                  y + AMSlotPadding, AMFrame);
   487                         if STurns < 100 then
   488                         if STurns < 100 then
   488                             DrawSpriteFrame2Surf(sprTurnsLeft, amSurface, 
   489                             DrawSpriteFrame2Surf(sprTurnsLeft, amSurface,
   489                                 x + AMSlotSize-16, 
   490                                 x + AMSlotSize-16,
   490                                 y + AMSlotSize + 1 - 16, STurns);
   491                                 y + AMSlotSize + 1 - 16, STurns);
   491                         end
   492                         end
   492                     else //draw colored version
   493                     else //draw colored version
   493                         begin
   494                         begin
   494                         DrawSpriteFrame2Surf(sprAMAmmos, amSurface, x + AMSlotPadding, 
   495                         DrawSpriteFrame2Surf(sprAMAmmos, amSurface, x + AMSlotPadding,
   495                                                                y + AMSlotPadding, AMFrame);
   496                                                                y + AMSlotPadding, AMFrame);
   496                         end;
   497                         end;
   497 {$IFDEF USE_LANDSCAPE_AMMOMENU}
   498 {$IFDEF USE_LANDSCAPE_AMMOMENU}
   498 	    inc(y, AMSlotSize + 1); //the plus one is for the border
   499         inc(y, AMSlotSize + 1); //the plus one is for the border
   499 {$ELSE}
   500 {$ELSE}
   500 	    inc(x, AMSlotSize + 1);
   501         inc(x, AMSlotSize + 1);
   501 {$ENDIF}
   502 {$ENDIF}
   502 	    end;
   503         end;
   503 	end;
   504     end;
   504 {$IFDEF USE_LANDSCAPE_AMMOMENU}
   505 {$IFDEF USE_LANDSCAPE_AMMOMENU}
   505     inc(x, AMSlotSize + 1);
   506     inc(x, AMSlotSize + 1);
   506 {$ELSE}
   507 {$ELSE}
   507     inc(y, AMSlotSize + 1);
   508     inc(y, AMSlotSize + 1);
   508 {$ENDIF}
   509 {$ENDIF}
   509     end;
   510     end;
   510 
   511 
   511 for i:= 1 to SlotsNumX -1 do
   512 for i:= 1 to SlotsNumX -1 do
   512 DrawLine2Surf(amSurface, i * (AMSlotSize+1)+1, BORDERSIZE, i * (AMSlotSize+1)+1, AMRect.h + BORDERSIZE - AMSlotSize - 2,160,160,160);            
   513 DrawLine2Surf(amSurface, i * (AMSlotSize+1)+1, BORDERSIZE, i * (AMSlotSize+1)+1, AMRect.h + BORDERSIZE - AMSlotSize - 2,160,160,160);
   513 for i:= 1 to SlotsNumY -1 do
   514 for i:= 1 to SlotsNumY -1 do
   514 DrawLine2Surf(amSurface, BORDERSIZE, i * (AMSlotSize+1)+1, AMRect.w + BORDERSIZE, i * (AMSlotSize+1)+1,160,160,160);
   515 DrawLine2Surf(amSurface, BORDERSIZE, i * (AMSlotSize+1)+1, AMRect.w + BORDERSIZE, i * (AMSlotSize+1)+1,160,160,160);
   515 
   516 
   516 //draw outer border
   517 //draw outer border
   517 DrawSpriteFrame2Surf(sprAMCorners, amSurface, 0                    , 0                    , 0);
   518 DrawSpriteFrame2Surf(sprAMCorners, amSurface, 0                    , 0                    , 0);
   552     bShowAmmoMenu:= false;
   553     bShowAmmoMenu:= false;
   553     AMState:= AMHidden;
   554     AMState:= AMHidden;
   554     exit
   555     exit
   555     end;
   556     end;
   556 
   557 
   557 //Init the menu 
   558 //Init the menu
   558 if(AmmoMenuInvalidated) then 
   559 if(AmmoMenuInvalidated) then
   559     begin
   560     begin
   560     AmmoMenuInvalidated:= false;
   561     AmmoMenuInvalidated:= false;
   561     FreeTexture(AmmoMenuTex);
   562     FreeAndNilTexture(AmmoMenuTex);
   562     AmmoMenuTex:= GetAmmoMenuTexture(Ammo);
   563     AmmoMenuTex:= GetAmmoMenuTexture(Ammo);
   563 
   564 
   564 {$IFDEF USE_LANDSCAPE_AMMOMENU}
   565 {$IFDEF USE_LANDSCAPE_AMMOMENU}
   565     if isPhone() then
   566     if isPhone() then
   566         begin
   567         begin
   609     else
   610     else
   610         if AMAnimState < 1 then
   611         if AMAnimState < 1 then
   611             begin
   612             begin
   612             AMShiftX:= Round(AMShiftTargetX * (1 - AMAnimState));
   613             AMShiftX:= Round(AMShiftTargetX * (1 - AMAnimState));
   613             AMShiftY:= Round(AMShiftTargetY * (1 - AMAnimState));
   614             AMShiftY:= Round(AMShiftTargetY * (1 - AMAnimState));
   614             if (AMAnimType and AMTypeMaskAlpha) <> 0 then 
   615             if (AMAnimType and AMTypeMaskAlpha) <> 0 then
   615                 Tint($FF, $ff, $ff, Round($ff * AMAnimState));
   616                 Tint($FF, $ff, $ff, Round($ff * AMAnimState));
   616             end
   617             end
   617         else
   618         else
   618             begin
   619             begin
   619             AMShiftX:= 0;
   620             AMShiftX:= 0;
   634     else
   635     else
   635         if AMAnimState < 1 then
   636         if AMAnimState < 1 then
   636             begin
   637             begin
   637             AMShiftX:= Round(AMShiftTargetX * AMAnimState);
   638             AMShiftX:= Round(AMShiftTargetX * AMAnimState);
   638             AMShiftY:= Round(AMShiftTargetY * AMAnimState);
   639             AMShiftY:= Round(AMShiftTargetY * AMAnimState);
   639             if (AMAnimType and AMTypeMaskAlpha) <> 0 then 
   640             if (AMAnimType and AMTypeMaskAlpha) <> 0 then
   640                 Tint($FF, $ff, $ff, Round($ff * (1-AMAnimState)));
   641                 Tint($FF, $ff, $ff, Round($ff * (1-AMAnimState)));
   641             end
   642             end
   642          else 
   643          else
   643             begin
   644             begin
   644             AMShiftX:= AMShiftTargetX;
   645             AMShiftX:= AMShiftTargetX;
   645             AMShiftY:= AMShiftTargetY;
   646             AMShiftY:= AMShiftTargetY;
   646             prevPoint:= CursorPoint;
   647             prevPoint:= CursorPoint;
   647             //prevTargetPoint:= TargetCursorPoint;
   648             //prevTargetPoint:= TargetCursorPoint;
   648             AMState:= AMHidden;
   649             AMState:= AMHidden;
   649             end;
   650             end;
   650     end;
   651     end;
   651     
   652 
   652 DrawTexture(AmmoRect.x + AMShiftX, AmmoRect.y + AMShiftY, AmmoMenuTex);
   653 DrawTexture(AmmoRect.x + AMShiftX, AmmoRect.y + AMShiftY, AmmoMenuTex);
   653 
   654 
   654 if ((AMState = AMHiding) or (AMState = AMShowingUp)) and ((AMAnimType and AMTypeMaskAlpha) <> 0 )then 
   655 if ((AMState = AMHiding) or (AMState = AMShowingUp)) and ((AMAnimType and AMTypeMaskAlpha) <> 0 )then
   655     Tint($FF, $ff, $ff, $ff);
   656     untint;
   656 
   657 
   657 Pos:= -1;
   658 Pos:= -1;
   658 Slot:= -1;
   659 Slot:= -1;
   659 {$IFDEF USE_LANDSCAPE_AMMOMENU}
   660 {$IFDEF USE_LANDSCAPE_AMMOMENU}
   660 c:= -1;
   661 c:= -1;
   670             for t:=0 to cMaxSlotAmmoIndex do
   671             for t:=0 to cMaxSlotAmmoIndex do
   671                 if (Ammo^[i, t].Count > 0) and (Ammo^[i, t].AmmoType <> amNothing) then
   672                 if (Ammo^[i, t].Count > 0) and (Ammo^[i, t].AmmoType <> amNothing) then
   672                     begin
   673                     begin
   673                     if (CursorPoint.Y <= (cScreenHeight - AmmoRect.y) - ( g    * (AMSlotSize+1))) and
   674                     if (CursorPoint.Y <= (cScreenHeight - AmmoRect.y) - ( g    * (AMSlotSize+1))) and
   674                        (CursorPoint.Y >  (cScreenHeight - AmmoRect.y) - ((g+1) * (AMSlotSize+1))) and
   675                        (CursorPoint.Y >  (cScreenHeight - AmmoRect.y) - ((g+1) * (AMSlotSize+1))) and
   675                        (CursorPoint.X >  AmmoRect.x                   + ( c    * (AMSlotSize+1))) and 
   676                        (CursorPoint.X >  AmmoRect.x                   + ( c    * (AMSlotSize+1))) and
   676                        (CursorPoint.X <= AmmoRect.x                   + ((c+1) * (AMSlotSize+1))) then
   677                        (CursorPoint.X <= AmmoRect.x                   + ((c+1) * (AMSlotSize+1))) then
   677                         begin
   678                         begin
   678                         Slot:= i;
   679                         Slot:= i;
   679                         Pos:= t;
   680                         Pos:= t;
   680                         STurns:= Ammoz[Ammo^[i, t].AmmoType].SkipTurns - CurrentTeam^.Clan^.TurnNumber;
   681                         STurns:= Ammoz[Ammo^[i, t].AmmoType].SkipTurns - CurrentTeam^.Clan^.TurnNumber;
   681                         if (STurns < 0) and (AMShiftX = 0) and (AMShiftY = 0) then
   682                         if (STurns < 0) and (AMShiftX = 0) and (AMShiftY = 0) then
   682                             DrawSprite(sprAMSlot, 
   683                             DrawSprite(sprAMSlot,
   683                                        AmmoRect.x + BORDERSIZE + (c * (AMSlotSize+1)) + AMSlotPadding, 
   684                                        AmmoRect.x + BORDERSIZE + (c * (AMSlotSize+1)) + AMSlotPadding,
   684                                        AmmoRect.y + BORDERSIZE + (g  * (AMSlotSize+1)) + AMSlotPadding -1, 0);
   685                                        AmmoRect.y + BORDERSIZE + (g  * (AMSlotSize+1)) + AMSlotPadding -1, 0);
   685                         end;
   686                         end;
   686                         inc(g);
   687                         inc(g);
   687                    end;
   688                    end;
   688             end;
   689             end;
   700             for t:=0 to cMaxSlotAmmoIndex do
   701             for t:=0 to cMaxSlotAmmoIndex do
   701                 if (Ammo^[i, t].Count > 0) and (Ammo^[i, t].AmmoType <> amNothing) then
   702                 if (Ammo^[i, t].Count > 0) and (Ammo^[i, t].AmmoType <> amNothing) then
   702                     begin
   703                     begin
   703                     if (CursorPoint.Y <= (cScreenHeight - AmmoRect.y) - ( c    * (AMSlotSize+1))) and
   704                     if (CursorPoint.Y <= (cScreenHeight - AmmoRect.y) - ( c    * (AMSlotSize+1))) and
   704                        (CursorPoint.Y >  (cScreenHeight - AmmoRect.y) - ((c+1) * (AMSlotSize+1))) and
   705                        (CursorPoint.Y >  (cScreenHeight - AmmoRect.y) - ((c+1) * (AMSlotSize+1))) and
   705                        (CursorPoint.X >  AmmoRect.x                   + ( g    * (AMSlotSize+1))) and 
   706                        (CursorPoint.X >  AmmoRect.x                   + ( g    * (AMSlotSize+1))) and
   706                        (CursorPoint.X <= AmmoRect.x                   + ((g+1) * (AMSlotSize+1))) then
   707                        (CursorPoint.X <= AmmoRect.x                   + ((g+1) * (AMSlotSize+1))) then
   707                         begin
   708                         begin
   708                         Slot:= i;
   709                         Slot:= i;
   709                         Pos:= t;
   710                         Pos:= t;
   710                         STurns:= Ammoz[Ammo^[i, t].AmmoType].SkipTurns - CurrentTeam^.Clan^.TurnNumber;
   711                         STurns:= Ammoz[Ammo^[i, t].AmmoType].SkipTurns - CurrentTeam^.Clan^.TurnNumber;
   711                         if (STurns < 0) and (AMShiftX = 0) and (AMShiftY = 0) then
   712                         if (STurns < 0) and (AMShiftX = 0) and (AMShiftY = 0) then
   712                             DrawSprite(sprAMSlot, 
   713                             DrawSprite(sprAMSlot,
   713                                        AmmoRect.x + BORDERSIZE + (g * (AMSlotSize+1)) + AMSlotPadding, 
   714                                        AmmoRect.x + BORDERSIZE + (g * (AMSlotSize+1)) + AMSlotPadding,
   714                                        AmmoRect.y + BORDERSIZE + (c  * (AMSlotSize+1)) + AMSlotPadding -1, 0);
   715                                        AmmoRect.y + BORDERSIZE + (c  * (AMSlotSize+1)) + AMSlotPadding -1, 0);
   715                         end;
   716                         end;
   716                         inc(g);
   717                         inc(g);
   717                    end;
   718                    end;
   718             end;
   719             end;
   739             if bSelected and (Ammoz[Ammo^[Slot, Pos].AmmoType].SkipTurns - CurrentTeam^.Clan^.TurnNumber < 0) then
   740             if bSelected and (Ammoz[Ammo^[Slot, Pos].AmmoType].SkipTurns - CurrentTeam^.Clan^.TurnNumber < 0) then
   740                 begin
   741                 begin
   741                 bShowAmmoMenu:= false;
   742                 bShowAmmoMenu:= false;
   742                 SetWeapon(Ammo^[Slot, Pos].AmmoType);
   743                 SetWeapon(Ammo^[Slot, Pos].AmmoType);
   743                 bSelected:= false;
   744                 bSelected:= false;
   744                 FreeWeaponTooltip;
   745                 FreeAndNilTexture(WeaponTooltipTex);
   745 {$IFDEF USE_TOUCH_INTERFACE}//show the aiming buttons + animation
   746 {$IFDEF USE_TOUCH_INTERFACE}//show the aiming buttons + animation
   746                 if (Ammo^[Slot, Pos].Propz and ammoprop_NeedUpDown) <> 0 then
   747                 if (Ammo^[Slot, Pos].Propz and ammoprop_NeedUpDown) <> 0 then
   747                     begin
   748                     begin
   748                     if not(arrowUp.show) then
   749                     if (not arrowUp.show) then
   749                         begin
   750                         begin
   750                         animateWidget(@arrowUp, true, true);
   751                         animateWidget(@arrowUp, true, true);
   751                         animateWidget(@arrowDown, true, true);
   752                         animateWidget(@arrowDown, true, true);
   752                         end;
   753                         end;
   753                     end
   754                     end
   762                 exit
   763                 exit
   763                 end;
   764                 end;
   764             end
   765             end
   765         end
   766         end
   766     else
   767     else
   767         FreeWeaponTooltip;
   768         FreeAndNilTexture(WeaponTooltipTex);
   768 
   769 
   769     if (WeaponTooltipTex <> nil) and (AMShiftX = 0) and (AMShiftY = 0) then
   770     if (WeaponTooltipTex <> nil) and (AMShiftX = 0) and (AMShiftY = 0) then
   770 {$IFDEF USE_LANDSCAPE_AMMOMENU}
   771 {$IFDEF USE_LANDSCAPE_AMMOMENU}
   771         if not isPhone() then
   772         if (not isPhone()) then
   772             ShowWeaponTooltip(-WeaponTooltipTex^.w div 2, AmmoRect.y - WeaponTooltipTex^.h - AMSlotSize);
   773             ShowWeaponTooltip(-WeaponTooltipTex^.w div 2, AmmoRect.y - WeaponTooltipTex^.h - AMSlotSize);
   773 {$ELSE}
   774 {$ELSE}
   774         ShowWeaponTooltip(AmmoRect.x - WeaponTooltipTex^.w - 3, Min(AmmoRect.y + 1, cScreenHeight - WeaponTooltipTex^.h - 40));
   775         ShowWeaponTooltip(AmmoRect.x - WeaponTooltipTex^.w - 3, Min(AmmoRect.y + 1, cScreenHeight - WeaponTooltipTex^.h - 40));
   775 {$ENDIF}
   776 {$ENDIF}
   776 
   777 
   777     bSelected:= false;
   778     bSelected:= false;
   778 {$IFNDEF USE_TOUCH_INTERFACE}
   779 {$IFNDEF USE_TOUCH_INTERFACE}
   779    if (AMShiftX = 0) and (AMShiftY = 0) then
   780    if (AMShiftX = 0) and (AMShiftY = 0) then
   780         DrawSprite(sprArrow, CursorPoint.X, cScreenHeight - CursorPoint.Y, (RealTicks shr 6) mod 8);
   781         DrawSprite(sprArrow, CursorPoint.X, cScreenHeight - CursorPoint.Y, (RealTicks shr 6) mod 8);
   781 {$ENDIF}
   782 {$ENDIF}
   782 end;
       
   783 
       
   784 procedure DrawWater(Alpha: byte; OffsetY: LongInt);
       
   785 var VertexBuffer: array [0..3] of TVertex2f;
       
   786     r: TSDL_Rect;
       
   787     lw, lh: GLfloat;
       
   788 begin
       
   789 if SuddenDeathDmg then
       
   790     begin
       
   791     SDWaterColorArray[0].a := Alpha;
       
   792     SDWaterColorArray[1].a := Alpha;
       
   793     SDWaterColorArray[2].a := Alpha;
       
   794     SDWaterColorArray[3].a := Alpha
       
   795     end
       
   796 else
       
   797     begin
       
   798     WaterColorArray[0].a := Alpha;
       
   799     WaterColorArray[1].a := Alpha;
       
   800     WaterColorArray[2].a := Alpha;
       
   801     WaterColorArray[3].a := Alpha
       
   802     end;
       
   803 
       
   804 lw:= cScreenWidth / cScaleFactor;
       
   805 lh:= trunc(cScreenHeight / cScaleFactor) + cScreenHeight div 2 + 16;
       
   806 
       
   807     // Water
       
   808 r.y:= OffsetY + WorldDy + cWaterLine;
       
   809 if WorldDy < trunc(cScreenHeight / cScaleFactor) + cScreenHeight div 2 - cWaterLine then
       
   810     begin
       
   811         if r.y < 0 then
       
   812             r.y:= 0;
       
   813 
       
   814         glDisable(GL_TEXTURE_2D);
       
   815         VertexBuffer[0].X:= -lw;
       
   816         VertexBuffer[0].Y:= r.y;
       
   817         VertexBuffer[1].X:= lw;
       
   818         VertexBuffer[1].Y:= r.y;
       
   819         VertexBuffer[2].X:= lw;
       
   820         VertexBuffer[2].Y:= lh;
       
   821         VertexBuffer[3].X:= -lw;
       
   822         VertexBuffer[3].Y:= lh;
       
   823 
       
   824         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
       
   825         glEnableClientState(GL_COLOR_ARRAY);
       
   826         if SuddenDeathDmg then
       
   827             glColorPointer(4, GL_UNSIGNED_BYTE, 0, @SDWaterColorArray[0])
       
   828         else
       
   829             glColorPointer(4, GL_UNSIGNED_BYTE, 0, @WaterColorArray[0]);
       
   830 
       
   831         glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
       
   832 
       
   833         glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
       
   834 
       
   835         glDisableClientState(GL_COLOR_ARRAY);
       
   836         glEnableClientState(GL_TEXTURE_COORD_ARRAY);
       
   837         glColor4ub($FF, $FF, $FF, $FF); // must not be Tint() as color array seems to stay active and color reset is required
       
   838         glEnable(GL_TEXTURE_2D);
       
   839     end;
       
   840 end;
       
   841 
       
   842 procedure DrawWaves(Dir, dX, dY: LongInt; tnt: Byte);
       
   843 var VertexBuffer, TextureBuffer: array [0..3] of TVertex2f;
       
   844     lw, waves, shift: GLfloat;
       
   845     sprite: TSprite;
       
   846 begin
       
   847 if SuddenDeathDmg then
       
   848     sprite:= sprSDWater
       
   849 else
       
   850     sprite:= sprWater;
       
   851 
       
   852 cWaveWidth:= SpritesData[sprite].Width;
       
   853 
       
   854 lw:= cScreenWidth / cScaleFactor;
       
   855 waves:= lw * 2 / cWaveWidth;
       
   856 
       
   857 if SuddenDeathDmg then
       
   858     Tint(LongInt(tnt) * SDWaterColorArray[2].r div 255 + 255 - tnt,
       
   859          LongInt(tnt) * SDWaterColorArray[2].g div 255 + 255 - tnt,
       
   860          LongInt(tnt) * SDWaterColorArray[2].b div 255 + 255 - tnt,
       
   861          255
       
   862     )
       
   863 else
       
   864     Tint(LongInt(tnt) * WaterColorArray[2].r div 255 + 255 - tnt,
       
   865          LongInt(tnt) * WaterColorArray[2].g div 255 + 255 - tnt,
       
   866          LongInt(tnt) * WaterColorArray[2].b div 255 + 255 - tnt,
       
   867          255
       
   868     );
       
   869 
       
   870 glBindTexture(GL_TEXTURE_2D, SpritesData[sprite].Texture^.id);
       
   871 
       
   872 VertexBuffer[0].X:= -lw;
       
   873 VertexBuffer[0].Y:= cWaterLine + WorldDy + dY;
       
   874 VertexBuffer[1].X:= lw;
       
   875 VertexBuffer[1].Y:= VertexBuffer[0].Y;
       
   876 VertexBuffer[2].X:= lw;
       
   877 VertexBuffer[2].Y:= VertexBuffer[0].Y + SpritesData[sprite].Height;
       
   878 VertexBuffer[3].X:= -lw;
       
   879 VertexBuffer[3].Y:= VertexBuffer[2].Y;
       
   880 
       
   881 shift:= - lw / cWaveWidth;
       
   882 TextureBuffer[0].X:= shift + (( - WorldDx + LongInt(RealTicks shr 6) * Dir + dX) mod cWaveWidth) / (cWaveWidth - 1);
       
   883 TextureBuffer[0].Y:= 0;
       
   884 TextureBuffer[1].X:= TextureBuffer[0].X + waves;
       
   885 TextureBuffer[1].Y:= TextureBuffer[0].Y;
       
   886 TextureBuffer[2].X:= TextureBuffer[1].X;
       
   887 TextureBuffer[2].Y:= SpritesData[sprite].Texture^.ry;
       
   888 TextureBuffer[3].X:= TextureBuffer[0].X;
       
   889 TextureBuffer[3].Y:= TextureBuffer[2].Y;
       
   890 
       
   891 
       
   892 glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
       
   893 glTexCoordPointer(2, GL_FLOAT, 0, @TextureBuffer[0]);
       
   894 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
       
   895 
       
   896 untint;
       
   897 
       
   898 {for i:= -1 to cWaterSprCount do
       
   899     DrawSprite(sprWater,
       
   900         i * cWaveWidth + ((WorldDx + (RealTicks shr 6) * Dir + dX) mod cWaveWidth) - (cScreenWidth div 2),
       
   901         cWaterLine + WorldDy + dY,
       
   902         0)}
       
   903 end;
   783 end;
   904 
   784 
   905 procedure DrawRepeated(spr, sprL, sprR: TSprite; Shift, OffsetY: LongInt);
   785 procedure DrawRepeated(spr, sprL, sprR: TSprite; Shift, OffsetY: LongInt);
   906 var i, w, h, lw, lh, rw, rh, sw: LongInt;
   786 var i, w, h, lw, lh, rw, rh, sw: LongInt;
   907 begin
   787 begin
   973             zoom:= ZoomValue
   853             zoom:= ZoomValue
   974         end
   854         end
   975     else
   855     else
   976         ZoomValue:= zoom;
   856         ZoomValue:= zoom;
   977 
   857 
   978     // Sky
       
   979     glClear(GL_COLOR_BUFFER_BIT);
       
   980     //glPushMatrix;
       
   981     //glScalef(1.0, 1.0, 1.0);
       
   982 
       
   983     if (not isPaused) and (not isAFK) and (GameType <> gmtRecord) then
   858     if (not isPaused) and (not isAFK) and (GameType <> gmtRecord) then
   984         MoveCamera;
   859         MoveCamera;
   985 
   860 
   986     if cStereoMode = smNone then
   861     if cStereoMode = smNone then
   987         begin
   862         begin
   988         glClear(GL_COLOR_BUFFER_BIT);
   863         RenderClear();
   989         DrawWorldStereo(Lag, rmDefault)
   864         DrawWorldStereo(Lag, rmDefault)
   990         end
       
   991 {$IFDEF USE_S3D_RENDERING}
   865 {$IFDEF USE_S3D_RENDERING}
   992     else if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) then
       
   993         begin
       
   994         // create left fb
       
   995         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framel);
       
   996         glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
       
   997         DrawWorldStereo(Lag, rmLeftEye);
       
   998 
       
   999         // create right fb
       
  1000         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framer);
       
  1001         glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
       
  1002         DrawWorldStereo(0, rmRightEye);
       
  1003 
       
  1004         // detatch drawing from fbs
       
  1005         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, defaultFrame);
       
  1006         glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
       
  1007         SetScale(cDefaultZoomLevel);
       
  1008 
       
  1009         // draw left frame
       
  1010         glBindTexture(GL_TEXTURE_2D, texl);
       
  1011         glBegin(GL_QUADS);
       
  1012             if cStereoMode = smHorizontal then
       
  1013                 begin
       
  1014                 glTexCoord2f(0.0, 0.0);
       
  1015                 glVertex2d(cScreenWidth / -2, cScreenHeight);
       
  1016                 glTexCoord2f(1.0, 0.0);
       
  1017                 glVertex2d(0, cScreenHeight);
       
  1018                 glTexCoord2f(1.0, 1.0);
       
  1019                 glVertex2d(0, 0);
       
  1020                 glTexCoord2f(0.0, 1.0);
       
  1021                 glVertex2d(cScreenWidth / -2, 0);
       
  1022                 end
       
  1023             else
       
  1024                 begin
       
  1025                 glTexCoord2f(0.0, 0.0);
       
  1026                 glVertex2d(cScreenWidth / -2, cScreenHeight / 2);
       
  1027                 glTexCoord2f(1.0, 0.0);
       
  1028                 glVertex2d(cScreenWidth / 2, cScreenHeight / 2);
       
  1029                 glTexCoord2f(1.0, 1.0);
       
  1030                 glVertex2d(cScreenWidth / 2, 0);
       
  1031                 glTexCoord2f(0.0, 1.0);
       
  1032                 glVertex2d(cScreenWidth / -2, 0);
       
  1033                 end;
       
  1034         glEnd();
       
  1035 
       
  1036         // draw right frame
       
  1037         glBindTexture(GL_TEXTURE_2D, texr);
       
  1038         glBegin(GL_QUADS);
       
  1039             if cStereoMode = smHorizontal then
       
  1040                 begin
       
  1041                 glTexCoord2f(0.0, 0.0);
       
  1042                 glVertex2d(0, cScreenHeight);
       
  1043                 glTexCoord2f(1.0, 0.0);
       
  1044                 glVertex2d(cScreenWidth / 2, cScreenHeight);
       
  1045                 glTexCoord2f(1.0, 1.0);
       
  1046                 glVertex2d(cScreenWidth / 2, 0);
       
  1047                 glTexCoord2f(0.0, 1.0);
       
  1048                 glVertex2d(0, 0);
       
  1049                 end
       
  1050             else
       
  1051                 begin
       
  1052                 glTexCoord2f(0.0, 0.0);
       
  1053                 glVertex2d(cScreenWidth / -2, cScreenHeight);
       
  1054                 glTexCoord2f(1.0, 0.0);
       
  1055                 glVertex2d(cScreenWidth / 2, cScreenHeight);
       
  1056                 glTexCoord2f(1.0, 1.0);
       
  1057                 glVertex2d(cScreenWidth / 2, cScreenHeight / 2);
       
  1058                 glTexCoord2f(0.0, 1.0);
       
  1059                 glVertex2d(cScreenWidth / -2, cScreenHeight / 2);
       
  1060                 end;
       
  1061         glEnd();
       
  1062         SetScale(zoom);
       
  1063         end
   866         end
  1064     else
   867     else
  1065         begin
   868         begin
  1066         // clear scene
   869         // draw frame for left eye
  1067         glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
   870         RenderClear(rmLeftEye);
  1068         glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
       
  1069         // draw left eye in red channel only
       
  1070         if cStereoMode = smGreenRed then
       
  1071             glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE)
       
  1072         else if cStereoMode = smBlueRed then
       
  1073             glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE)
       
  1074         else if cStereoMode = smCyanRed then
       
  1075             glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE)
       
  1076         else
       
  1077             glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE);
       
  1078         DrawWorldStereo(Lag, rmLeftEye);
   871         DrawWorldStereo(Lag, rmLeftEye);
  1079         // draw right eye in selected channel(s) only
   872 
  1080         if cStereoMode = smRedGreen then
   873         // draw frame for right eye
  1081             glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE)
   874         RenderClear(rmRightEye);
  1082         else if cStereoMode = smRedBlue then
   875         DrawWorldStereo(0, rmRightEye);
  1083             glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE)
   876 {$ENDIF}
  1084         else if cStereoMode = smRedCyan then
   877         end;
  1085             glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE)
   878 
  1086         else
   879 FinishRender();
  1087             glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE);
   880 end;
  1088         DrawWorldStereo(Lag, rmRightEye);
   881 
  1089         end
   882 procedure RenderWorldEdge;
  1090 {$ENDIF}
       
  1091 end;
       
  1092 
       
  1093 procedure ChangeDepth(rm: TRenderMode; d: GLfloat);
       
  1094 begin
       
  1095 {$IFNDEF USE_S3D_RENDERING}
       
  1096     rm:= rm; d:= d; // avoid hint
       
  1097     exit;
       
  1098 {$ELSE}
       
  1099     d:= d / 5;
       
  1100     if rm = rmDefault then
       
  1101         exit
       
  1102     else if rm = rmLeftEye then
       
  1103         d:= -d;
       
  1104     stereoDepth:= stereoDepth + d;
       
  1105     glMatrixMode(GL_PROJECTION);
       
  1106     glTranslatef(d, 0, 0);
       
  1107     glMatrixMode(GL_MODELVIEW);
       
  1108 {$ENDIF}
       
  1109 end;
       
  1110  
       
  1111 procedure ResetDepth(rm: TRenderMode);
       
  1112 begin
       
  1113 {$IFNDEF USE_S3D_RENDERING}
       
  1114     rm:= rm; // avoid hint
       
  1115     exit;
       
  1116 {$ELSE}
       
  1117     if rm = rmDefault then
       
  1118         exit;
       
  1119     glMatrixMode(GL_PROJECTION);
       
  1120     glTranslatef(-stereoDepth, 0, 0);
       
  1121     glMatrixMode(GL_MODELVIEW);
       
  1122     stereoDepth:= 0;
       
  1123 {$ENDIF}
       
  1124 end;
       
  1125 
       
  1126 
       
  1127 procedure RenderWorldEdge(Lag: Longword);
       
  1128 var
   883 var
  1129     VertexBuffer: array [0..3] of TVertex2f;
   884     //VertexBuffer: array [0..3] of TVertex2f;
  1130     c1, c2: LongWord; // couple of colours for edges
   885     tmp, w: LongInt;
  1131 begin
   886     rect: TSDL_Rect;
  1132 if WorldEdge <> weNone then
   887     //c1, c2: LongWord; // couple of colours for edges
       
   888 begin
       
   889 if (WorldEdge <> weNone) and (WorldEdge <> weSea) then
  1133     begin
   890     begin
  1134 (* I think for a bounded world, will fill the left and right areas with black or something. Also will probably want various border effects/animations based on border type.  Prob also, say, trigger a border animation timer on an impact. *)
   891 (* I think for a bounded world, will fill the left and right areas with black or something. Also will probably want various border effects/animations based on border type.  Prob also, say, trigger a border animation timer on an impact. *)
       
   892 
       
   893     rect.y:= ViewTopY;
       
   894     rect.h:= ViewHeight;
       
   895     tmp:= LongInt(leftX) + WorldDx;
       
   896     w:= tmp - ViewLeftX;
       
   897 
       
   898     if w > 0 then
       
   899         begin
       
   900         rect.w:= w;
       
   901         rect.x:= ViewLeftX;
       
   902         DrawRect(rect, $10, $10, $10, $80, true);
       
   903         if WorldEdge = weBounce then
       
   904             DrawLineOnScreen(tmp - 1, ViewTopY, tmp - 1, ViewBottomY, 2, $54, $54, $FF, $FF);
       
   905         end;
       
   906 
       
   907     tmp:= LongInt(rightX) + WorldDx;
       
   908     w:= ViewRightX - tmp;
       
   909 
       
   910     if w > 0 then
       
   911         begin
       
   912         rect.w:= w;
       
   913         rect.x:= tmp;
       
   914         DrawRect(rect, $10, $10, $10, $80, true);
       
   915         if WorldEdge = weBounce then
       
   916             DrawLineOnScreen(tmp - 1, ViewTopY, tmp - 1, ViewBottomY, 2, $54, $54, $FF, $FF);
       
   917         end;
       
   918 
       
   919     (*
       
   920     WARNING: the following render code is outdated and does not work with
       
   921              current Render.pas ! - don't just uncomment without fixing it first
  1135 
   922 
  1136     glDisable(GL_TEXTURE_2D);
   923     glDisable(GL_TEXTURE_2D);
  1137     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
   924     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  1138     glEnableClientState(GL_COLOR_ARRAY);
   925     if (WorldEdge = weWrap) or (worldEdge = weBounce) then
       
   926         glColor4ub($00, $00, $00, $40)
       
   927     else
       
   928         begin
       
   929         glEnableClientState(GL_COLOR_ARRAY);
       
   930         glColorPointer(4, GL_UNSIGNED_BYTE, 0, @WorldFade[0]);
       
   931         end;
  1139 
   932 
  1140     glPushMatrix;
   933     glPushMatrix;
  1141     glTranslatef(WorldDx, WorldDy, 0);
   934     glTranslatef(WorldDx, WorldDy, 0);
  1142     glColorPointer(4, GL_UNSIGNED_BYTE, 0, @WorldFade[0]);
       
  1143 
   935 
  1144     VertexBuffer[0].X:= leftX-20;
   936     VertexBuffer[0].X:= leftX-20;
  1145     VertexBuffer[0].Y:= -3000;
   937     VertexBuffer[0].Y:= -3500;
  1146     VertexBuffer[1].X:= leftX-20;
   938     VertexBuffer[1].X:= leftX-20;
  1147     VertexBuffer[1].Y:= cWaterLine+cVisibleWater;
   939     VertexBuffer[1].Y:= cWaterLine+cVisibleWater;
  1148     VertexBuffer[2].X:= leftX+30;
   940     VertexBuffer[2].X:= leftX+30;
  1149     VertexBuffer[2].Y:= cWaterLine+cVisibleWater;
   941     VertexBuffer[2].Y:= cWaterLine+cVisibleWater;
  1150     VertexBuffer[3].X:= leftX+30;
   942     VertexBuffer[3].X:= leftX+30;
  1151     VertexBuffer[3].Y:= -3000;
   943     VertexBuffer[3].Y:= -3500;
  1152 
   944 
  1153     glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
   945     glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
  1154     glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
   946     glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
  1155 
   947 
  1156     VertexBuffer[0].X:= rightX+20;
   948     VertexBuffer[0].X:= rightX+20;
  1184     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
   976     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  1185 
   977 
  1186     glColor4ub($FF, $FF, $FF, $FF); // must not be Tint() as color array seems to stay active and color reset is required
   978     glColor4ub($FF, $FF, $FF, $FF); // must not be Tint() as color array seems to stay active and color reset is required
  1187     glEnable(GL_TEXTURE_2D);
   979     glEnable(GL_TEXTURE_2D);
  1188 
   980 
  1189     // I'd still like to have things happen to the border when a wrap or bounce just occurred, based on a timer 
   981     // I'd still like to have things happen to the border when a wrap or bounce just occurred, based on a timer
  1190     if WorldEdge = weBounce then
   982     if WorldEdge = weBounce then
  1191         begin
   983         begin
  1192         // could maybe alternate order of these on a bounce, or maybe drop the outer ones.
   984         // could maybe alternate order of these on a bounce, or maybe drop the outer ones.
  1193         if LeftImpactTimer mod 2 = 0 then
   985         if LeftImpactTimer mod 2 = 0 then
  1194             begin
   986             begin
  1225         DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 5.0, $2E8B5780);
  1017         DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 5.0, $2E8B5780);
  1226         DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 5.0, $2E8B5780)
  1018         DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 5.0, $2E8B5780)
  1227         end;
  1019         end;
  1228     if LeftImpactTimer > Lag then dec(LeftImpactTimer,Lag) else LeftImpactTimer:= 0;
  1020     if LeftImpactTimer > Lag then dec(LeftImpactTimer,Lag) else LeftImpactTimer:= 0;
  1229     if RightImpactTimer > Lag then dec(RightImpactTimer,Lag) else RightImpactTimer:= 0
  1021     if RightImpactTimer > Lag then dec(RightImpactTimer,Lag) else RightImpactTimer:= 0
       
  1022     *)
  1230     end;
  1023     end;
  1231 end;
  1024 end;
  1232 
  1025 
  1233 
  1026 
  1234 procedure RenderTeamsHealth;
  1027 procedure RenderTeamsHealth;
  1286         h:= 0;
  1079         h:= 0;
  1287         if not hasGone then
  1080         if not hasGone then
  1288             for i:= 0 to cMaxHHIndex do
  1081             for i:= 0 to cMaxHHIndex do
  1289                 begin
  1082                 begin
  1290                 inc(h, Hedgehogs[i].HealthBarHealth);
  1083                 inc(h, Hedgehogs[i].HealthBarHealth);
  1291                 if (h < TeamHealthBarHealth) and (Hedgehogs[i].HealthBarHealth > 0) then 
  1084                 if (h < TeamHealthBarHealth) and (Hedgehogs[i].HealthBarHealth > 0) then
  1292                     DrawTexture(15 + h * TeamHealthBarWidth div TeamHealthBarHealth, cScreenHeight + DrawHealthY + smallScreenOffset + 1, SpritesData[sprSlider].Texture);
  1085                     DrawTexture(15 + h * TeamHealthBarWidth div TeamHealthBarHealth, cScreenHeight + DrawHealthY + smallScreenOffset + 1, SpritesData[sprSlider].Texture);
  1293                 end;
  1086                 end;
  1294 
  1087 
  1295         // draw ai kill counter for gfAISurvival
  1088         // draw ai kill counter for gfAISurvival
  1296         if (GameFlags and gfAISurvival) <> 0 then
  1089         if (GameFlags and gfAISurvival) <> 0 then
  1310             r.x:= 2;
  1103             r.x:= 2;
  1311             r.y:= 2;
  1104             r.y:= 2;
  1312             r.w:= NameTagTex^.w - 4;
  1105             r.w:= NameTagTex^.w - 4;
  1313             r.h:= NameTagTex^.h - 4;
  1106             r.h:= NameTagTex^.h - 4;
  1314             DrawTextureFromRect(-NameTagTex^.w - 14, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, NameTagTex);
  1107             DrawTextureFromRect(-NameTagTex^.w - 14, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, NameTagTex);
       
  1108 
       
  1109             if OwnerTex <> nil then
       
  1110                 begin
       
  1111                 r.w:= OwnerTex^.w - 4;
       
  1112                 r.h:= OwnerTex^.h - 4;
       
  1113                 DrawTextureFromRect(-OwnerTex^.w - NameTagTex^.w - 16, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, OwnerTex)
       
  1114                 end;
       
  1115 
       
  1116             if (GameFlags and gfAISurvival) <> 0 then
       
  1117                 begin
       
  1118                 r.w:= AIKillsTex^.w - 4;
       
  1119                 r.h:= AIKillsTex^.h - 4;
       
  1120                 DrawTextureFromRect(TeamHealthBarWidth + 24, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, AIKillsTex);
       
  1121                 end;
       
  1122 
  1315             // draw flag
  1123             // draw flag
  1316             r.w:= 22;
  1124             r.w:= 22;
  1317             r.h:= 15;
  1125             r.h:= 15;
  1318             DrawTextureFromRect(-12, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, FlagTex);
  1126             DrawTextureFromRect(-12, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, FlagTex);
       
  1127             end
       
  1128         // draw an arrow next to active team
       
  1129         else if (CurrentTeam = TeamsArray[t]) and (TurnTimeLeft > 0) then
       
  1130             begin
       
  1131             h:= -NameTagTex^.w - 24;
       
  1132             if OwnerTex <> nil then
       
  1133                 h:= h - OwnerTex^.w - 4;
       
  1134             DrawSpriteRotatedF(sprFinger, h, cScreenHeight + DrawHealthY + smallScreenOffset + 2 + SpritesData[sprFinger].Width div 4, 0, 1, -90);
  1319             end;
  1135             end;
  1320         end;
  1136         end;
  1321 if smallScreenOffset <> 0 then
  1137 if smallScreenOffset <> 0 then
  1322     begin
  1138     begin
  1323     SetScale(cDefaultZoomLevel);
  1139     SetScale(cDefaultZoomLevel);
  1324     if TeamsCount * 20 > Longword(cScreenHeight) div 5 then
  1140     if TeamsCount * 20 > Longword(cScreenHeight) div 5 then
  1325         Tint($FF,$FF,$FF,$FF);
  1141         untint;
  1326     end;
  1142     end;
  1327 end;
  1143 end;
  1328 
  1144 
       
  1145 
       
  1146 var preShiftWorldDx: LongInt;
       
  1147 
       
  1148 procedure ShiftWorld(Dir: LongInt); inline;
       
  1149 begin
       
  1150     preShiftWorldDx:= WorldDx;
       
  1151     WorldDx:= WorldDx + LongInt(Dir * LongInt(playWidth));
       
  1152 
       
  1153 end;
       
  1154 
       
  1155 procedure UnshiftWorld(); inline;
       
  1156 begin
       
  1157     WorldDx:= preShiftWorldDx;
       
  1158 end;
  1329 
  1159 
  1330 procedure DrawWorldStereo(Lag: LongInt; RM: TRenderMode);
  1160 procedure DrawWorldStereo(Lag: LongInt; RM: TRenderMode);
  1331 var i, t: LongInt;
  1161 var i, t: LongInt;
  1332     r: TSDL_Rect;
  1162     r: TSDL_Rect;
  1333     tdx, tdy: Double;
  1163     tdx, tdy: Double;
  1334     s: shortstring;
  1164     s: shortstring;
  1335     offsetX, offsetY, screenBottom: LongInt;
  1165     offsetX, offsetY, screenBottom: LongInt;
  1336     VertexBuffer: array [0..3] of TVertex2f;
  1166     replicateToLeft, replicateToRight, tmp: boolean;
  1337 begin
  1167     a: Byte;
       
  1168 begin
       
  1169 if WorldEdge <> weWrap then
       
  1170     begin
       
  1171     replicateToLeft := false;
       
  1172     replicateToRight:= false;
       
  1173     end
       
  1174 else
       
  1175     begin
       
  1176     replicateToLeft := (LongInt(leftX)  + WorldDx > ViewLeftX);
       
  1177     replicateToRight:= (LongInt(rightX) + WorldDx < ViewRightX);
       
  1178     end;
       
  1179 
       
  1180 ScreenBottom:= (WorldDy - trunc(cScreenHeight/cScaleFactor) - (cScreenHeight div 2) + cWaterLine);
       
  1181 
       
  1182 // note: offsetY is negative!
       
  1183 offsetY:= 10 *  Min(0, -145 - ScreenBottom); // TODO limit this in the other direction too
       
  1184 
  1338 if (cReducedQuality and rqNoBackground) = 0 then
  1185 if (cReducedQuality and rqNoBackground) = 0 then
  1339     begin
  1186     begin
  1340         // Offsets relative to camera - spare them to wimpier cpus, no bg or flakes for them anyway
  1187         // Offsets relative to camera - spare them to wimpier cpus, no bg or flakes for them anyway
  1341         ScreenBottom:= (WorldDy - trunc(cScreenHeight/cScaleFactor) - (cScreenHeight div 2) + cWaterLine);
       
  1342         offsetY:= 10 * Min(0, -145 - ScreenBottom);
       
  1343         SkyOffset:= offsetY div 35 + cWaveHeight;
  1188         SkyOffset:= offsetY div 35 + cWaveHeight;
  1344         HorizontOffset:= SkyOffset;
  1189         HorizontOffset:= SkyOffset;
  1345         if ScreenBottom > SkyOffset then
  1190         if ScreenBottom > SkyOffset then
  1346             HorizontOffset:= HorizontOffset + ((ScreenBottom-SkyOffset) div 20);
  1191             HorizontOffset:= HorizontOffset + ((ScreenBottom-SkyOffset) div 20);
  1347 
  1192 
  1361 DrawVisualGears(4);
  1206 DrawVisualGears(4);
  1362 
  1207 
  1363 if (cReducedQuality and rq2DWater) = 0 then
  1208 if (cReducedQuality and rq2DWater) = 0 then
  1364     begin
  1209     begin
  1365         // Waves
  1210         // Waves
  1366         DrawWater(255, SkyOffset); 
  1211         DrawWater(255, SkyOffset, 0);
  1367         ChangeDepth(RM, -cStereo_Water_distant);
  1212         ChangeDepth(RM, -cStereo_Water_distant);
  1368         DrawWaves( 1,  0 - WorldDx div 32, - cWaveHeight + offsetY div 35, 64);
  1213         DrawWaves( 1,  0 - WorldDx div 32, offsetY div 35, -49, 64);
  1369         ChangeDepth(RM, -cStereo_Water_distant);
  1214         ChangeDepth(RM, -cStereo_Water_distant);
  1370         DrawWaves( -1,  25 + WorldDx div 25, - cWaveHeight + offsetY div 38, 48);
  1215         DrawWaves( -1,  25 + WorldDx div 25, offsetY div 38, -37, 48);
  1371         ChangeDepth(RM, -cStereo_Water_distant);
  1216         ChangeDepth(RM, -cStereo_Water_distant);
  1372         DrawWaves( 1,  75 - WorldDx div 19, - cWaveHeight + offsetY div 45, 32);
  1217         DrawWaves( 1,  75 - WorldDx div 19, offsetY div 45, -23, 32);
  1373         ChangeDepth(RM, -cStereo_Water_distant);
  1218         ChangeDepth(RM, -cStereo_Water_distant);
  1374         DrawWaves(-1, 100 + WorldDx div 14, - cWaveHeight + offsetY div 70, 24);
  1219         DrawWaves(-1, 100 + WorldDx div 14, offsetY div 70, -7, 24);
  1375     end
  1220     end
  1376 else
  1221 else
  1377         DrawWaves(-1, 100, - (cWaveHeight + (cWaveHeight shr 1)), 0);
  1222     DrawWaves(-1, 100, - cWaveHeight div 2, - cWaveHeight div 2, 0);
  1378 
  1223 
  1379     changeDepth(RM, cStereo_Land);
  1224 ChangeDepth(RM, cStereo_Land);
  1380     DrawVisualGears(5);
  1225 DrawVisualGears(5);
       
  1226 DrawLand(WorldDx, WorldDy);
       
  1227 
       
  1228 if replicateToLeft then
       
  1229     begin
       
  1230     ShiftWorld(-1);
  1381     DrawLand(WorldDx, WorldDy);
  1231     DrawLand(WorldDx, WorldDy);
  1382 
  1232     UnshiftWorld();
  1383     DrawWater(255, 0);
  1233     end;
       
  1234 
       
  1235 if replicateToRight then
       
  1236     begin
       
  1237     ShiftWorld(1);
       
  1238     DrawLand(WorldDx, WorldDy);
       
  1239     UnshiftWorld();
       
  1240     end;
       
  1241 
       
  1242 DrawWater(255, 0, 0);
       
  1243 
       
  1244 (*
       
  1245 // Attack bar
       
  1246     if CurrentTeam <> nil then
       
  1247         case AttackBar of
       
  1248         //1: begin
       
  1249         //r:= StuffPoz[sPowerBar];
       
  1250         //{$WARNINGS OFF}
       
  1251         //r.w:= (CurrentHedgehog^.Gear^.Power * 256) div cPowerDivisor;
       
  1252         //{$WARNINGS ON}
       
  1253         //DrawSpriteFromRect(r, cScreenWidth - 272, cScreenHeight - 48, 16, 0, Surface);
       
  1254         //end;
       
  1255         2: with CurrentHedgehog^ do
       
  1256                 begin
       
  1257                 tdx:= hwSign(Gear^.dX) * Sin(Gear^.Angle * Pi / cMaxAngle);
       
  1258                 tdy:= - Cos(Gear^.Angle * Pi / cMaxAngle);
       
  1259                 for i:= (Gear^.Power * 24) div cPowerDivisor downto 0 do
       
  1260                     DrawSprite(sprPower,
       
  1261                             hwRound(Gear^.X) + GetLaunchX(CurAmmoType, hwSign(Gear^.dX), Gear^.Angle) + LongInt(round(WorldDx + tdx * (24 + i * 2))) - 16,
       
  1262                             hwRound(Gear^.Y) + GetLaunchY(CurAmmoType, Gear^.Angle) + LongInt(round(WorldDy + tdy * (24 + i * 2))) - 16,
       
  1263                             i)
       
  1264                 end
       
  1265         end;
       
  1266 *)
       
  1267 
       
  1268 tmp:= bShowFinger;
       
  1269 bShowFinger:= false;
       
  1270 
       
  1271 if replicateToLeft then
       
  1272     begin
       
  1273     ShiftWorld(-1);
       
  1274     DrawVisualGears(1);
       
  1275     DrawGears();
       
  1276     DrawVisualGears(6);
       
  1277     UnshiftWorld();
       
  1278     end;
       
  1279 
       
  1280 if replicateToRight then
       
  1281     begin
       
  1282     ShiftWorld(1);
       
  1283     DrawVisualGears(1);
       
  1284     DrawGears();
       
  1285     DrawVisualGears(6);
       
  1286     UnshiftWorld();
       
  1287     end;
       
  1288 
       
  1289 bShowFinger:= tmp;
  1384 
  1290 
  1385 DrawVisualGears(1);
  1291 DrawVisualGears(1);
  1386 DrawGears;
  1292 DrawGears;
  1387 DrawVisualGears(6);
  1293 DrawVisualGears(6);
  1388 
  1294 
       
  1295 
  1389 if SuddenDeathDmg then
  1296 if SuddenDeathDmg then
  1390     DrawWater(SDWaterOpacity, 0)
  1297     DrawWater(SDWaterOpacity, 0, 0)
  1391 else
  1298 else
  1392     DrawWater(WaterOpacity, 0);
  1299     DrawWater(WaterOpacity, 0, 0);
  1393 
  1300 
  1394     // Waves
  1301     // Waves
  1395 ChangeDepth(RM, cStereo_Water_near);
  1302 ChangeDepth(RM, cStereo_Water_near);
  1396 DrawWaves( 1, 25 - WorldDx div 9, - cWaveHeight, 12);
  1303 DrawWaves( 1, 25 - WorldDx div 9, 0, 0, 12);
  1397 
  1304 
  1398 if (cReducedQuality and rq2DWater) = 0 then
  1305 if (cReducedQuality and rq2DWater) = 0 then
  1399     begin
  1306     begin
  1400     //DrawWater(WaterOpacity, - offsetY div 40);
  1307     //DrawWater(WaterOpacity, - offsetY div 40);
  1401     ChangeDepth(RM, cStereo_Water_near);
  1308     ChangeDepth(RM, cStereo_Water_near);
  1402     DrawWaves(-1, 50 + WorldDx div 6, - cWaveHeight - offsetY div 40, 8);
  1309     DrawWaves(-1, 50 + WorldDx div 6, - offsetY div 40, 23, 8);
  1403     if SuddenDeathDmg then
  1310     if SuddenDeathDmg then
  1404         DrawWater(SDWaterOpacity, - offsetY div 20)
  1311         DrawWater(SDWaterOpacity, - offsetY div 20, 23)
  1405     else
  1312     else
  1406         DrawWater(WaterOpacity, - offsetY div 20);
  1313         DrawWater(WaterOpacity, - offsetY div 20, 23);
  1407     ChangeDepth(RM, cStereo_Water_near);
  1314     ChangeDepth(RM, cStereo_Water_near);
  1408     DrawWaves( 1, 75 - WorldDx div 4, - cWaveHeight - offsetY div 20, 2);
  1315     DrawWaves( 1, 75 - WorldDx div 4, - offsetY div 20, 37, 2);
  1409         if SuddenDeathDmg then
  1316         if SuddenDeathDmg then
  1410             DrawWater(SDWaterOpacity, - offsetY div 10)
  1317             DrawWater(SDWaterOpacity, - offsetY div 10, 47)
  1411         else
  1318         else
  1412             DrawWater(WaterOpacity, - offsetY div 10);
  1319             DrawWater(WaterOpacity, - offsetY div 10, 47);
  1413         ChangeDepth(RM, cStereo_Water_near);
  1320         ChangeDepth(RM, cStereo_Water_near);
  1414         DrawWaves( -1, 25 + WorldDx div 3, - cWaveHeight - offsetY div 10, 0);
  1321         DrawWaves( -1, 25 + WorldDx div 3, - offsetY div 10, 59, 0);
  1415         end
  1322         end
  1416     else
  1323     else
  1417         DrawWaves(-1, 50, - (cWaveHeight shr 1), 0);
  1324         DrawWaves(-1, 50, cWaveHeight div 2, cWaveHeight div 2, 0);
  1418 
  1325 
  1419 // everything after this ChangeDepth will be drawn outside the screen
  1326 // everything after this ChangeDepth will be drawn outside the screen
  1420 // note: negative parallax gears should last very little for a smooth stereo effect
  1327 // note: negative parallax gears should last very little for a smooth stereo effect
  1421     ChangeDepth(RM, cStereo_Outside);
  1328     ChangeDepth(RM, cStereo_Outside);
       
  1329 
       
  1330     if replicateToLeft then
       
  1331         begin
       
  1332         ShiftWorld(-1);
       
  1333         DrawVisualGears(2);
       
  1334         UnshiftWorld();
       
  1335         end;
       
  1336 
       
  1337     if replicateToRight then
       
  1338         begin
       
  1339         ShiftWorld(1);
       
  1340         DrawVisualGears(2);
       
  1341         UnshiftWorld();
       
  1342         end;
       
  1343 
  1422     DrawVisualGears(2);
  1344     DrawVisualGears(2);
  1423 
  1345 
  1424 // everything after this ResetDepth will be drawn at screen level (depth = 0)
  1346 // everything after this ResetDepth will be drawn at screen level (depth = 0)
  1425 // note: everything that needs to be readable should be on this level
  1347 // note: everything that needs to be readable should be on this level
  1426     ResetDepth(RM);
  1348     ResetDepth(RM);
       
  1349 
       
  1350     if replicateToLeft then
       
  1351         begin
       
  1352         ShiftWorld(-1);
       
  1353         DrawVisualGears(3);
       
  1354         UnshiftWorld();
       
  1355         end;
       
  1356 
       
  1357     if replicateToRight then
       
  1358         begin
       
  1359         ShiftWorld(1);
       
  1360         DrawVisualGears(3);
       
  1361         UnshiftWorld();
       
  1362         end;
       
  1363 
  1427     DrawVisualGears(3);
  1364     DrawVisualGears(3);
  1428 
  1365 
  1429 {$WARNINGS OFF}
  1366 {$WARNINGS OFF}
  1430 // Target
  1367 // Target
  1431 if (TargetPoint.X <> NoPointX) and (CurrentTeam <> nil) and (CurrentHedgehog <> nil) then
  1368 if (TargetPoint.X <> NoPointX) and (CurrentTeam <> nil) and (CurrentHedgehog <> nil) then
  1438             DrawSpriteRotatedF(sprTargetP, TargetPoint.X + WorldDx, TargetPoint.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360)
  1375             DrawSpriteRotatedF(sprTargetP, TargetPoint.X + WorldDx, TargetPoint.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360)
  1439         end
  1376         end
  1440     end;
  1377     end;
  1441 {$WARNINGS ON}
  1378 {$WARNINGS ON}
  1442 
  1379 
  1443 RenderWorldEdge(Lag);
  1380 RenderWorldEdge();
  1444 
  1381 
  1445 // this scale is used to keep the various widgets at the same dimension at all zoom levels
  1382 // this scale is used to keep the various widgets at the same dimension at all zoom levels
  1446 SetScale(cDefaultZoomLevel);
  1383 SetScale(cDefaultZoomLevel);
  1447 
  1384 
  1448 // Turn time
  1385 // Turn time
  1458         begin
  1395         begin
  1459         if ReadyTimeLeft <> 0 then
  1396         if ReadyTimeLeft <> 0 then
  1460             i:= Succ(Pred(ReadyTimeLeft) div 1000)
  1397             i:= Succ(Pred(ReadyTimeLeft) div 1000)
  1461         else
  1398         else
  1462             i:= Succ(Pred(TurnTimeLeft) div 1000);
  1399             i:= Succ(Pred(TurnTimeLeft) div 1000);
  1463        
  1400 
  1464         if i>99 then
  1401         if i>99 then
  1465             t:= 112
  1402             t:= 112
  1466         else if i>9 then
  1403         else if i>9 then
  1467             t:= 96
  1404             t:= 96
  1468         else
  1405         else
  1543         AMAnimStartTime:= RealTicks
  1480         AMAnimStartTime:= RealTicks
  1544     else
  1481     else
  1545         AMAnimStartTime:= RealTicks - (AMAnimDuration - (RealTicks - AMAnimStartTime));
  1482         AMAnimStartTime:= RealTicks - (AMAnimDuration - (RealTicks - AMAnimStartTime));
  1546     AMState:= AMShowingUp;
  1483     AMState:= AMShowingUp;
  1547     end;
  1484     end;
  1548 if not(bShowAmmoMenu) and ((AMstate = AMShowing) or (AMState = AMShowingUp)) then
  1485 if (not bShowAmmoMenu) and ((AMstate = AMShowing) or (AMState = AMShowingUp)) then
  1549     begin
  1486     begin
  1550     if (AMState = AMShowing) then
  1487     if (AMState = AMShowing) then
  1551         AMAnimStartTime:= RealTicks
  1488         AMAnimStartTime:= RealTicks
  1552     else
  1489     else
  1553         AMAnimStartTime:= RealTicks - (AMAnimDuration - (RealTicks - AMAnimStartTime));
  1490         AMAnimStartTime:= RealTicks - (AMAnimDuration - (RealTicks - AMAnimStartTime));
  1554     AMState:= AMHiding;
  1491     AMState:= AMHiding;
  1555     end; 
  1492     end;
  1556 
  1493 
  1557 if bShowAmmoMenu or (AMState = AMHiding) then
  1494 if bShowAmmoMenu or (AMState = AMHiding) then
  1558     ShowAmmoMenu;
  1495     ShowAmmoMenu;
  1559 
  1496 
  1560 // Cursor
  1497 // Cursor
  1561 if isCursorVisible and bShowAmmoMenu then
  1498 if isCursorVisible and bShowAmmoMenu then
  1562     DrawSprite(sprArrow, CursorPoint.X, cScreenHeight - CursorPoint.Y, (RealTicks shr 6) mod 8);
  1499     DrawSprite(sprArrow, CursorPoint.X, cScreenHeight - CursorPoint.Y, (RealTicks shr 6) mod 8);
  1563 
  1500 
  1564 // Chat
  1501 // Chat
  1565 DrawChat;
  1502 DrawChat;
       
  1503 
  1566 
  1504 
  1567 // various captions
  1505 // various captions
  1568 if fastUntilLag then
  1506 if fastUntilLag then
  1569     DrawTextureCentered(0, (cScreenHeight shr 1), SyncTexture);
  1507     DrawTextureCentered(0, (cScreenHeight shr 1), SyncTexture);
  1570 if isPaused then
  1508 if isPaused then
  1605         t:= i mod 60;
  1543         t:= i mod 60;
  1606         s:= inttostr(t) + ':' + s;
  1544         s:= inttostr(t) + ':' + s;
  1607         if t < 10 then
  1545         if t < 10 then
  1608             s:= '0' + s;
  1546             s:= '0' + s;
  1609         s:= inttostr(i div 60) + ':' + s;
  1547         s:= inttostr(i div 60) + ':' + s;
  1610    
  1548 
  1611     
  1549 
  1612         tmpSurface:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(s), cWhiteColorChannels);
  1550         tmpSurface:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(s), cWhiteColorChannels);
  1613         tmpSurface:= doSurfaceConversion(tmpSurface);
  1551         tmpSurface:= doSurfaceConversion(tmpSurface);
  1614         FreeTexture(timeTexture);
  1552         FreeAndNilTexture(timeTexture);
  1615         timeTexture:= Surface2Tex(tmpSurface, false);
  1553         timeTexture:= Surface2Tex(tmpSurface, false);
  1616         SDL_FreeSurface(tmpSurface)
  1554         SDL_FreeSurface(tmpSurface)
  1617         end;
  1555         end;
  1618 
  1556 
  1619     if timeTexture <> nil then
  1557     if timeTexture <> nil then
  1627             Frames:= 0;
  1565             Frames:= 0;
  1628             CountTicks:= 0;
  1566             CountTicks:= 0;
  1629             s:= inttostr(FPS) + ' fps';
  1567             s:= inttostr(FPS) + ' fps';
  1630             tmpSurface:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(s), cWhiteColorChannels);
  1568             tmpSurface:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(s), cWhiteColorChannels);
  1631             tmpSurface:= doSurfaceConversion(tmpSurface);
  1569             tmpSurface:= doSurfaceConversion(tmpSurface);
  1632             FreeTexture(fpsTexture);
  1570             FreeAndNilTexture(fpsTexture);
  1633             fpsTexture:= Surface2Tex(tmpSurface, false);
  1571             fpsTexture:= Surface2Tex(tmpSurface, false);
  1634             SDL_FreeSurface(tmpSurface)
  1572             SDL_FreeSurface(tmpSurface)
  1635             end;
  1573             end;
  1636         if fpsTexture <> nil then
  1574         if fpsTexture <> nil then
  1637             DrawTexture((cScreenWidth shr 1) - 60 - offsetY, offsetX, fpsTexture);
  1575             DrawTexture((cScreenWidth shr 1) - 60 - offsetY, offsetX, fpsTexture);
  1642 if GameState = gsConfirm then
  1580 if GameState = gsConfirm then
  1643     DrawTextureCentered(0, (cScreenHeight shr 1)-40, ConfirmTexture);
  1581     DrawTextureCentered(0, (cScreenHeight shr 1)-40, ConfirmTexture);
  1644 
  1582 
  1645 if ScreenFade <> sfNone then
  1583 if ScreenFade <> sfNone then
  1646     begin
  1584     begin
  1647     if not isFirstFrame then
  1585     if (not isFirstFrame) then
  1648         case ScreenFade of
  1586         case ScreenFade of
  1649             sfToBlack, sfToWhite:     if ScreenFadeValue + Lag * ScreenFadeSpeed < sfMax then
  1587             sfToBlack, sfToWhite:     if ScreenFadeValue + Lag * ScreenFadeSpeed < sfMax then
  1650                                           inc(ScreenFadeValue, Lag * ScreenFadeSpeed)
  1588                                           inc(ScreenFadeValue, Lag * ScreenFadeSpeed)
  1651                                       else
  1589                                       else
  1652                                           ScreenFadeValue:= sfMax;
  1590                                           ScreenFadeValue:= sfMax;
  1655                                       else
  1593                                       else
  1656                                           ScreenFadeValue:= 0;
  1594                                           ScreenFadeValue:= 0;
  1657             end;
  1595             end;
  1658     if ScreenFade <> sfNone then
  1596     if ScreenFade <> sfNone then
  1659         begin
  1597         begin
       
  1598         r.x:= ViewLeftX;
       
  1599         r.y:= ViewTopY;
       
  1600         r.w:= ViewWidth;
       
  1601         r.h:= ViewHeight;
       
  1602 
  1660         case ScreenFade of
  1603         case ScreenFade of
  1661             sfToBlack, sfFromBlack: Tint(0, 0, 0, ScreenFadeValue * 255 div 1000);
  1604             sfToBlack, sfFromBlack: DrawRect(r, 0, 0, 0, ScreenFadeValue * 255 div 1000, true);
  1662             sfToWhite, sfFromWhite: Tint($FF, $FF, $FF, ScreenFadeValue * 255 div 1000);
  1605             sfToWhite, sfFromWhite: DrawRect(r, $FF, $FF, $FF, ScreenFadeValue * 255 div 1000, true);
  1663             end;
  1606             end;
  1664 
  1607 
  1665         VertexBuffer[0].X:= -cScreenWidth;
       
  1666         VertexBuffer[0].Y:= cScreenHeight;
       
  1667         VertexBuffer[1].X:= -cScreenWidth;
       
  1668         VertexBuffer[1].Y:= 0;
       
  1669         VertexBuffer[2].X:= cScreenWidth;
       
  1670         VertexBuffer[2].Y:= 0;
       
  1671         VertexBuffer[3].X:= cScreenWidth;
       
  1672         VertexBuffer[3].Y:= cScreenHeight;
       
  1673 
       
  1674         glDisable(GL_TEXTURE_2D);
       
  1675 
       
  1676         glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
       
  1677         glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
       
  1678 
       
  1679         glEnable(GL_TEXTURE_2D);
       
  1680         untint;
       
  1681         if not isFirstFrame and ((ScreenFadeValue = 0) or (ScreenFadeValue = sfMax)) then
  1608         if not isFirstFrame and ((ScreenFadeValue = 0) or (ScreenFadeValue = sfMax)) then
  1682             ScreenFade:= sfNone
  1609             ScreenFade:= sfNone
  1683         end
  1610         end
  1684     end;
  1611     end;
  1685 
  1612 
  1690     if recTexture = nil then
  1617     if recTexture = nil then
  1691         begin
  1618         begin
  1692         s:= 'rec';
  1619         s:= 'rec';
  1693         tmpSurface:= TTF_RenderUTF8_Blended(Fontz[fntBig].Handle, Str2PChar(s), cWhiteColorChannels);
  1620         tmpSurface:= TTF_RenderUTF8_Blended(Fontz[fntBig].Handle, Str2PChar(s), cWhiteColorChannels);
  1694         tmpSurface:= doSurfaceConversion(tmpSurface);
  1621         tmpSurface:= doSurfaceConversion(tmpSurface);
  1695         FreeTexture(recTexture);
  1622         FreeAndNilTexture(recTexture);
  1696         recTexture:= Surface2Tex(tmpSurface, false);
  1623         recTexture:= Surface2Tex(tmpSurface, false);
  1697         SDL_FreeSurface(tmpSurface)
  1624         SDL_FreeSurface(tmpSurface)
  1698         end;
  1625         end;
  1699     DrawTexture( -(cScreenWidth shr 1) + 50, 20, recTexture);
  1626     DrawTexture( -(cScreenWidth shr 1) + 50, 20, recTexture);
  1700 
  1627 
       
  1628     //a:= Byte(Round(127*(1 + sin(RealTicks*0.007))));
       
  1629     a:= Byte(min(255, abs(-255 + ((RealTicks div 2) and 511))));
       
  1630 
  1701     // draw red circle
  1631     // draw red circle
  1702     glDisable(GL_TEXTURE_2D); 
  1632     DrawCircleFilled(-(cScreenWidth shr 1) + 30, 35, 10, $FF, $00, $00, a);
  1703     Tint($FF, $00, $00, Byte(Round(127*(1 + sin(SDL_GetTicks()*0.007)))));
       
  1704     glBegin(GL_POLYGON);
       
  1705     for i:= 0 to 20 do
       
  1706         glVertex2f(-(cScreenWidth shr 1) + 30 + sin(i*2*Pi/20)*10, 35 + cos(i*2*Pi/20)*10);
       
  1707     glEnd();
       
  1708     untint;
       
  1709     glEnable(GL_TEXTURE_2D);
       
  1710     end;
  1633     end;
  1711 {$ENDIF}
  1634 {$ENDIF}
  1712 
  1635 
  1713 SetScale(zoom);
  1636 SetScale(zoom);
  1714 
  1637 
  1734                 end
  1657                 end
  1735         end;
  1658         end;
  1736 
  1659 
  1737 
  1660 
  1738 // Cursor
  1661 // Cursor
  1739 if isCursorVisible then
  1662 if isCursorVisible and (not bShowAmmoMenu) then
  1740     begin
  1663     begin
  1741     if not bShowAmmoMenu then
  1664     if not CurrentTeam^.ExtDriven then TargetCursorPoint:= CursorPoint;
  1742         begin
  1665     with CurrentHedgehog^ do
  1743         if not CurrentTeam^.ExtDriven then TargetCursorPoint:= CursorPoint;
  1666         if (Gear <> nil) and ((Gear^.State and gstChooseTarget) <> 0) then
  1744         with CurrentHedgehog^ do
  1667             begin
  1745             if (Gear <> nil) and ((Gear^.State and gstHHChooseTarget) <> 0) then
  1668         if (CurAmmoType = amNapalm) or (CurAmmoType = amMineStrike) or (((GameFlags and gfMoreWind) <> 0) and ((CurAmmoType = amDrillStrike) or (CurAmmoType = amAirAttack))) then
       
  1669             DrawLine(-3000, topY-300, 7000, topY-300, 3.0, (Team^.Clan^.Color shr 16), (Team^.Clan^.Color shr 8) and $FF, Team^.Clan^.Color and $FF, $FF);
       
  1670         i:= GetCurAmmoEntry(CurrentHedgehog^)^.Pos;
       
  1671         with Ammoz[CurAmmoType] do
       
  1672             if PosCount > 1 then
  1746                 begin
  1673                 begin
  1747             if (CurAmmoType = amNapalm) or (CurAmmoType = amMineStrike) then
  1674                 if (CurAmmoType = amGirder) or (CurAmmoType = amTeleport) then
  1748                 DrawLine(-3000, topY-300, 7000, topY-300, 3.0, (Team^.Clan^.Color shr 16), (Team^.Clan^.Color shr 8) and $FF, Team^.Clan^.Color and $FF, $FF);
  1675                     begin
  1749             i:= GetCurAmmoEntry(CurrentHedgehog^)^.Pos;
  1676                 // pulsating transparency
  1750             with Ammoz[CurAmmoType] do
  1677                     if ((GameTicks div 16) mod $80) >= $40 then
  1751                 if PosCount > 1 then
  1678                         Tint($FF, $FF, $FF, $C0 - (GameTicks div 16) mod $40)
  1752                     DrawSprite(PosSprite, TargetCursorPoint.X - (SpritesData[PosSprite].Width shr 1), cScreenHeight - TargetCursorPoint.Y - (SpritesData[PosSprite].Height shr 1),i);
  1679                     else
       
  1680                         Tint($FF, $FF, $FF, $80 + (GameTicks div 16) mod $40);
       
  1681                     end;
       
  1682                 DrawSprite(PosSprite, TargetCursorPoint.X - (SpritesData[PosSprite].Width shr 1), cScreenHeight - TargetCursorPoint.Y - (SpritesData[PosSprite].Height shr 1),i);
       
  1683                 Untint();
  1753                 end;
  1684                 end;
  1754         DrawSprite(sprArrow, TargetCursorPoint.X, cScreenHeight - TargetCursorPoint.Y, (RealTicks shr 6) mod 8)
  1685             end;
  1755         end
  1686     //DrawSprite(sprArrow, TargetCursorPoint.X, cScreenHeight - TargetCursorPoint.Y, (RealTicks shr 6) mod 8)
  1756     end;
  1687     DrawTextureF(SpritesData[sprArrow].Texture, cDefaultZoomLevel / cScaleFactor, TargetCursorPoint.X + round(SpritesData[sprArrow].Width / cScaleFactor), cScreenHeight + round(SpritesData[sprArrow].Height / cScaleFactor) - TargetCursorPoint.Y, (RealTicks shr 6) mod 8, 1, SpritesData[sprArrow].Width, SpritesData[sprArrow].Height);
  1757 isFirstFrame:= false;
  1688     end;
       
  1689 
       
  1690 // debug stuff
       
  1691 if cViewLimitsDebug then
       
  1692     begin
       
  1693     r.x:= ViewLeftX;
       
  1694     r.y:= ViewTopY;
       
  1695     r.w:= ViewWidth;
       
  1696     r.h:= ViewHeight;
       
  1697     DrawRect(r, 255, 0, 0, 128, false);
       
  1698     end;
       
  1699 
       
  1700 isFirstFrame:= false
  1758 end;
  1701 end;
  1759 
  1702 
  1760 var PrevSentPointTime: LongWord = 0;
  1703 var PrevSentPointTime: LongWord = 0;
  1761 
  1704 
  1762 procedure MoveCamera;
  1705 procedure MoveCamera;
  1763 var EdgesDist, wdy, shs,z, amNumOffsetX, amNumOffsetY: LongInt;
  1706 var EdgesDist, wdy, shs,z, amNumOffsetX, amNumOffsetY, dstX: LongInt;
  1764     inbtwnTrgtAttks: Boolean;
  1707     inbtwnTrgtAttks: Boolean;
  1765 begin
  1708 begin
  1766 {$IFNDEF MOBILE}
  1709 {$IFNDEF MOBILE}
  1767 if (not (CurrentTeam^.ExtDriven and isCursorVisible and (not bShowAmmoMenu) and autoCameraOn)) and cHasFocus and (GameState <> gsConfirm) then
  1710 if (not (CurrentTeam^.ExtDriven and isCursorVisible and (not bShowAmmoMenu) and autoCameraOn)) and cHasFocus and (GameState <> gsConfirm) then
  1768     uCursor.updatePosition();
  1711     uCursor.updatePosition();
  1769 {$ENDIF}
  1712 {$ENDIF}
  1770 z:= round(200/zoom);
  1713 z:= round(200/zoom);
  1771 inbtwnTrgtAttks := (CurrentHedgehog <> nil) and ((Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_NeedTarget) <> 0) and ((GameFlags and gfInfAttack) <> 0);
  1714 inbtwnTrgtAttks := ((GameFlags and gfInfAttack) <> 0) and (CurrentHedgehog <> nil) and ((CurrentHedgehog^.Gear = nil) or (CurrentHedgehog^.Gear <> FollowGear)) and ((Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_NeedTarget) <> 0);
  1772 if autoCameraOn and not PlacingHogs and (FollowGear <> nil) and (not isCursorVisible) and (not bShowAmmoMenu) and (not fastUntilLag) and not inbtwnTrgtAttks then
  1715 if autoCameraOn and (not PlacingHogs) and (FollowGear <> nil) and (not isCursorVisible) and (not bShowAmmoMenu) and (not fastUntilLag) and (not inbtwnTrgtAttks) then
  1773     if ((abs(CursorPoint.X - prevPoint.X) + abs(CursorPoint.Y - prevpoint.Y)) > 4) then
  1716     if ((abs(CursorPoint.X - prevPoint.X) + abs(CursorPoint.Y - prevpoint.Y)) > 4) then
  1774         begin
  1717         begin
  1775         FollowGear:= nil;
  1718         FollowGear:= nil;
  1776         prevPoint:= CursorPoint;
  1719         prevPoint:= CursorPoint;
  1777         exit
  1720         exit
  1778         end
  1721         end
  1779     else
  1722     else
  1780         begin
  1723         begin
  1781         CursorPoint.X:= (prevPoint.X * 7 + hwRound(FollowGear^.X) + hwSign(FollowGear^.dX) * z + WorldDx) div 8;
  1724             dstX:= hwRound(FollowGear^.X) + hwSign(FollowGear^.dX) * z + WorldDx;
  1782         if isPhone() or (cScreenHeight < 600) or ((hwSign(FollowGear^.dY) * z) < 10)  then
  1725 
       
  1726             if (WorldEdge = weWrap) then
       
  1727                 begin
       
  1728                     if dstX - prevPoint.X < (LongInt(leftX) - rightX) div 2 then
       
  1729                         CursorPoint.X:= (prevPoint.X * 7 + dstX - (leftX - rightX)) div 8
       
  1730                     else if dstX - prevPoint.X > (LongInt(rightX) - leftX) div 2 then
       
  1731                         CursorPoint.X:= (prevPoint.X * 7 + dstX - (rightX - leftX)) div 8
       
  1732                     else
       
  1733                         CursorPoint.X:= (prevPoint.X * 7 + dstX) div 8;
       
  1734                 end
       
  1735             else // usual camera movement routine
       
  1736                 begin
       
  1737                     CursorPoint.X:= (prevPoint.X * 7 + dstX) div 8;
       
  1738                 end;
       
  1739 
       
  1740         if isPhone() or (cScreenHeight < 600) or (hwFloat(FollowGear^.dY * z).Round < 10) then
  1783             CursorPoint.Y:= (prevPoint.Y * 7 + cScreenHeight - (hwRound(FollowGear^.Y) + WorldDy)) div 8
  1741             CursorPoint.Y:= (prevPoint.Y * 7 + cScreenHeight - (hwRound(FollowGear^.Y) + WorldDy)) div 8
  1784         else
  1742         else
  1785             CursorPoint.Y:= (prevPoint.Y * 7 + cScreenHeight - (hwRound(FollowGear^.Y) + hwSign(FollowGear^.dY) * z + WorldDy)) div 8;
  1743             CursorPoint.Y:= (prevPoint.Y * 7 + cScreenHeight - (hwRound(FollowGear^.Y) + hwSign(FollowGear^.dY) * z + WorldDy)) div 8;
  1786         end;
  1744         end;
       
  1745 
       
  1746 if (WorldEdge = weWrap) then
       
  1747     begin
       
  1748         if -WorldDx < leftX then
       
  1749             WorldDx:= WorldDx - LongInt(rightX) + leftX
       
  1750         else if -WorldDx > rightX then
       
  1751             WorldDx:= WorldDx + LongInt(rightX) - leftX;
       
  1752     end;
  1787 
  1753 
  1788 wdy:= trunc(cScreenHeight / cScaleFactor) + cScreenHeight div 2 - cWaterLine - cVisibleWater;
  1754 wdy:= trunc(cScreenHeight / cScaleFactor) + cScreenHeight div 2 - cWaterLine - cVisibleWater;
  1789 if WorldDy < wdy then
  1755 if WorldDy < wdy then
  1790     WorldDy:= wdy;
  1756     WorldDy:= wdy;
  1791 
  1757 
  1808     {$ELSE}
  1774     {$ELSE}
  1809     amNumOffsetX:= 0;
  1775     amNumOffsetX:= 0;
  1810     {$ENDIF}
  1776     {$ENDIF}
  1811 
  1777 
  1812 {$ENDIF}
  1778 {$ENDIF}
  1813     if CursorPoint.X < AmmoRect.x + amNumOffsetX + 3 then//check left 
  1779     if CursorPoint.X < AmmoRect.x + amNumOffsetX + 3 then//check left
  1814         CursorPoint.X:= AmmoRect.x + amNumOffsetX + 3;
  1780         CursorPoint.X:= AmmoRect.x + amNumOffsetX + 3;
  1815     if CursorPoint.X > AmmoRect.x + AmmoRect.w - 3 then//check right
  1781     if CursorPoint.X > AmmoRect.x + AmmoRect.w - 3 then//check right
  1816         CursorPoint.X:= AmmoRect.x + AmmoRect.w - 3;
  1782         CursorPoint.X:= AmmoRect.x + AmmoRect.w - 3;
  1817     if CursorPoint.Y > cScreenHeight - AmmoRect.y -amNumOffsetY - 1 then//check top
  1783     if CursorPoint.Y > cScreenHeight - AmmoRect.y -amNumOffsetY - 1 then//check top
  1818         CursorPoint.Y:= cScreenHeight - AmmoRect.y - amNumOffsetY - 1;
  1784         CursorPoint.Y:= cScreenHeight - AmmoRect.y - amNumOffsetY - 1;
  1887 end;
  1853 end;
  1888 
  1854 
  1889 procedure ShowMission(caption, subcaption, text: ansistring; icon, time : LongInt);
  1855 procedure ShowMission(caption, subcaption, text: ansistring; icon, time : LongInt);
  1890 var r: TSDL_Rect;
  1856 var r: TSDL_Rect;
  1891 begin
  1857 begin
       
  1858 if cOnlyStats then exit;
       
  1859 
  1892 r.w:= 32;
  1860 r.w:= 32;
  1893 r.h:= 32;
  1861 r.h:= 32;
  1894 
  1862 
  1895 if time = 0 then
  1863 if time = 0 then
  1896     time:= 5000;
  1864     time:= 5000;
  1897 missionTimer:= time;
  1865 missionTimer:= time;
  1898 FreeTexture(missionTex);
  1866 FreeAndNilTexture(missionTex);
  1899 
  1867 
  1900 if icon > -1 then
  1868 if icon > -1 then
  1901     begin
  1869     begin
  1902     r.x:= 0;
  1870     r.x:= 0;
  1903     r.y:= icon * 32;
  1871     r.y:= icon * 32;
  1904     missionTex:= RenderHelpWindow(caption, subcaption, text, '', 0, MissionIcons, @r)
  1872     missionTex:= RenderHelpWindow(caption, subcaption, text, ansistring(''), 0, MissionIcons, @r)
  1905     end
  1873     end
  1906 else
  1874 else
  1907     begin
  1875     begin
  1908     r.x:= ((-icon - 1) shr 4) * 32;
  1876     r.x:= ((-icon - 1) shr 4) * 32;
  1909     r.y:= ((-icon - 1) mod 16) * 32;
  1877     r.y:= ((-icon - 1) mod 16) * 32;
  1910     missionTex:= RenderHelpWindow(caption, subcaption, text, '', 0, SpritesData[sprAMAmmos].Surface, @r)
  1878     missionTex:= RenderHelpWindow(caption, subcaption, text, ansistring(''), 0, SpritesData[sprAMAmmos].Surface, @r)
  1911     end;
  1879     end;
  1912 end;
  1880 end;
  1913 
  1881 
  1914 procedure HideMission;
  1882 procedure HideMission;
  1915 begin
  1883 begin
  1937 exit;
  1905 exit;
  1938 {$ENDIF}
  1906 {$ENDIF}
  1939 
  1907 
  1940 {$IFDEF USE_VIDEO_RECORDING}
  1908 {$IFDEF USE_VIDEO_RECORDING}
  1941 // do not change volume during prerecording as it will affect sound in video file
  1909 // do not change volume during prerecording as it will affect sound in video file
  1942 if not flagPrerecording then
  1910 if (not flagPrerecording) then
  1943 {$ENDIF}
  1911 {$ENDIF}
  1944     begin
  1912     begin
  1945     if not cHasFocus then DampenAudio()
  1913     if (not cHasFocus) then DampenAudio()
  1946     else UndampenAudio();
  1914     else UndampenAudio();
  1947     end;
  1915     end;
       
  1916 end;
       
  1917 
       
  1918 procedure updateCursorVisibility;
       
  1919 begin
       
  1920     if isPaused or isAFK then
       
  1921         SDL_ShowCursor(1)
       
  1922     else
       
  1923         SDL_ShowCursor(ord(GameState = gsConfirm))
  1948 end;
  1924 end;
  1949 
  1925 
  1950 procedure SetUtilityWidgetState(ammoType: TAmmoType);
  1926 procedure SetUtilityWidgetState(ammoType: TAmmoType);
  1951 begin
  1927 begin
  1952 {$IFDEF USE_TOUCH_INTERFACE}
  1928 {$IFDEF USE_TOUCH_INTERFACE}
  1953 if(ammoType = amNothing)then
  1929 if(ammoType = amNothing)then
  1954     ammoType:= CurrentHedgehog^.CurAmmoType;
  1930     ammoType:= CurrentHedgehog^.CurAmmoType;
  1955 
  1931 
  1956 if(CurrentHedgehog <> nil)then
  1932 if(CurrentHedgehog <> nil)then
  1957     if (Ammoz[ammoType].Ammo.Propz and ammoprop_Timerable) <> 0 then
  1933     if ((Ammoz[ammoType].Ammo.Propz and ammoprop_Timerable) <> 0) and (ammoType <> amDrillStrike) then
  1958         begin
  1934         begin
  1959         utilityWidget.sprite:= sprTimerButton;
  1935         utilityWidget.sprite:= sprTimerButton;
  1960         animateWidget(@utilityWidget, true, true);
  1936         animateWidget(@utilityWidget, true, true);
  1961         end 
  1937         end
  1962     else if (Ammoz[ammoType].Ammo.Propz and ammoprop_NeedTarget) <> 0 then
  1938     else if (Ammoz[ammoType].Ammo.Propz and ammoprop_NeedTarget) <> 0 then
  1963         begin
  1939         begin
  1964         utilityWidget.sprite:= sprTargetButton;
  1940         utilityWidget.sprite:= sprTargetButton;
  1965         animateWidget(@utilityWidget, true, true);
  1941         animateWidget(@utilityWidget, true, true);
  1966         end
  1942         end
  1967     else if ammoType = amSwitch then
  1943     else if ammoType = amSwitch then
  1968         begin
  1944         begin
  1969         utilityWidget.sprite:= sprTargetButton;
  1945         utilityWidget.sprite:= sprSwitchButton;
  1970         animateWidget(@utilityWidget, true, true);
  1946         animateWidget(@utilityWidget, true, true);
  1971         end
  1947         end
  1972     else if utilityWidget.show then
  1948     else if utilityWidget.show then
  1973         animateWidget(@utilityWidget, true, false);
  1949         animateWidget(@utilityWidget, true, false);
  1974 {$ELSE}
  1950 {$ELSE}
  1980 begin
  1956 begin
  1981 with widget^ do
  1957 with widget^ do
  1982     begin
  1958     begin
  1983     show:= showWidget;
  1959     show:= showWidget;
  1984     if fade then fadeAnimStart:= RealTicks;
  1960     if fade then fadeAnimStart:= RealTicks;
  1985     
  1961 
  1986     with moveAnim do
  1962     with moveAnim do
  1987         begin
  1963         begin
  1988         animate:= true;
  1964         animate:= true;
  1989         startTime:= RealTicks;
  1965         startTime:= RealTicks;
  1990         source.x:= source.x xor target.x; //swap source <-> target
  1966         source.x:= source.x xor target.x; //swap source <-> target
  2018     prevPoint.X:= 0;
  1994     prevPoint.X:= 0;
  2019     prevPoint.Y:= 0;
  1995     prevPoint.Y:= 0;
  2020     missionTimer:= 0;
  1996     missionTimer:= 0;
  2021     missionTex:= nil;
  1997     missionTex:= nil;
  2022     cOffsetY:= 0;
  1998     cOffsetY:= 0;
  2023     stereoDepth:= 0;
       
  2024     AMState:= AMHidden;
  1999     AMState:= AMHidden;
  2025     isFirstFrame:= true;
  2000     isFirstFrame:= true;
  2026     stereoDepth:= stereoDepth; // avoid hint
       
  2027 
  2001 
  2028     FillChar(WorldFade, sizeof(WorldFade), 0);
  2002     FillChar(WorldFade, sizeof(WorldFade), 0);
  2029     WorldFade[0].a:= 255;
  2003     WorldFade[0].a:= 255;
  2030     WorldFade[1].a:= 255;
  2004     WorldFade[1].a:= 255;
  2031     FillChar(WorldEnd, sizeof(WorldEnd), 0);
  2005     FillChar(WorldEnd, sizeof(WorldEnd), 0);
  2032     WorldEnd[0].a:= 255;
  2006     WorldEnd[0].a:= 255;
  2033     WorldEnd[1].a:= 255;
  2007     WorldEnd[1].a:= 255;
  2034     WorldEnd[2].a:= 255;
  2008     WorldEnd[2].a:= 255;
  2035     WorldEnd[3].a:= 255;
  2009     WorldEnd[3].a:= 255;
  2036 
  2010 
       
  2011     AmmoMenuTex:= nil;
       
  2012     AmmoMenuInvalidated:= true
  2037 end;
  2013 end;
  2038 
  2014 
  2039 procedure freeModule;
  2015 procedure freeModule;
  2040 begin
  2016 begin
  2041     ResetWorldTex();
  2017     ResetWorldTex();