diff -r 31570b766315 -r ed5a6478e710 hedgewars/uWorld.pas --- a/hedgewars/uWorld.pas Tue Nov 10 18:16:35 2015 +0100 +++ b/hedgewars/uWorld.pas Tue Nov 10 20:43:13 2015 +0100 @@ -1,6 +1,6 @@ (* * Hedgewars, a free turn based strategy game - * Copyright (c) 2004-2013 Andrey Korotaev + * Copyright (c) 2004-2015 Andrey Korotaev * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,11 +13,10 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *) {$INCLUDE "options.inc"} -{$IF GLunit = GL}{$DEFINE GLunit:=GL,GLext}{$ENDIF} unit uWorld; interface @@ -40,6 +39,7 @@ procedure animateWidget(widget: POnScreenWidget; fade, showWidget: boolean); procedure MoveCamera; procedure onFocusStateChanged; +procedure updateCursorVisibility; implementation uses @@ -52,7 +52,6 @@ , uVisualGears , uChat , uLandTexture - , GLunit , uVariables , uUtils , uTextures @@ -66,8 +65,7 @@ {$ENDIF} ; -var cWaveWidth, cWaveHeight: LongInt; - AMShiftTargetX, AMShiftTargetY, AMShiftX, AMShiftY, SlotsNum: LongInt; +var AMShiftTargetX, AMShiftTargetY, AMShiftX, AMShiftY, SlotsNum: LongInt; AMAnimStartTime, AMState : LongInt; AMAnimState: Single; tmpSurface: PSDL_Surface; @@ -79,7 +77,6 @@ amSel: TAmmoType = amNothing; missionTex: PTexture; missionTimer: LongInt; - stereoDepth: GLfloat; isFirstFrame: boolean; AMAnimType: LongInt; recTexture: PTexture; @@ -121,18 +118,22 @@ function AddGoal(s: ansistring; gf: longword; si: TGoalStrId; i: LongInt): ansistring; var t: ansistring; begin +{$IFNDEF PAS2C} if (GameFlags and gf) <> 0 then begin t:= inttostr(i); s:= s + FormatA(trgoal[si], t) + '|' end; +{$ENDIF} AddGoal:= s; end; function AddGoal(s: ansistring; gf: longword; si: TGoalStrId): ansistring; begin +{$IFNDEF PAS2C} if (GameFlags and gf) <> 0 then s:= s + trgoal[si] + '|'; +{$ENDIF} AddGoal:= s; end; @@ -212,10 +213,10 @@ end; // if the string has been set, show it for (default timeframe) seconds -if g <> '' then +if length(g) > 0 then ShowMission(trgoal[gidCaption], trgoal[gidSubCaption], g, 1, 0); -cWaveWidth:= SpritesData[sprWater].Width; +//cWaveWidth:= SpritesData[sprWater].Width; //cWaveHeight:= SpritesData[sprWater].Height; cWaveHeight:= 32; @@ -225,7 +226,7 @@ prevPoint.Y:= cScreenHeight div 2; //prevTargetPoint.X:= 0; //prevTargetPoint.Y:= 0; -WorldDx:= -(LAND_WIDTH div 2) + cScreenWidth div 2; +WorldDx:= -(LongInt(leftX + (playWidth div 2))); // -(LAND_WIDTH div 2);// + cScreenWidth div 2; WorldDy:= -(LAND_HEIGHT - (playHeight div 2)) + (cScreenHeight div 2); //aligns it to the bottom of the screen, minus the border @@ -401,14 +402,12 @@ // for uStore texture resetting procedure ResetWorldTex; begin - FreeTexture(fpsTexture); - fpsTexture:= nil; - FreeTexture(timeTexture); - timeTexture:= nil; - FreeTexture(missionTex); - missionTex:= nil; - FreeTexture(recTexture); - recTexture:= nil; + FreeAndNilTexture(fpsTexture); + FreeAndNilTexture(timeTexture); + FreeAndNilTexture(missionTex); + FreeAndNilTexture(recTexture); + FreeAndNilTexture(AmmoMenuTex); + AmmoMenuInvalidated:= true; end; function GetAmmoMenuTexture(Ammo: PHHAmmo): PTexture; @@ -419,6 +418,8 @@ AMRect: TSDL_Rect; {$IFDEF USE_AM_NUMCOLUMN}tmpsurf: PSDL_Surface;{$ENDIF} begin + if cOnlyStats then exit(nil); + SlotsNum:= 0; for i:= 0 to cMaxSlotIndex do if((i = 0) and (Ammo^[i,1].Count > 0)) or ((i <> 0) and (Ammo^[i,0].Count > 0)) then @@ -441,14 +442,14 @@ AmmoRect.w:= (BORDERSIZE*2) + (SlotsNumX * AMSlotSize) + (SlotsNumX-1); AmmoRect.h:= (BORDERSIZE*2) + (SlotsNumY * AMSlotSize) + (SlotsNumY-1); amSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, AmmoRect.w, AmmoRect.h, 32, RMask, GMask, BMask, AMask); - + AMRect.x:= BORDERSIZE; AMRect.y:= BORDERSIZE; AMRect.w:= AmmoRect.w - (BORDERSIZE*2); AMRect.h:= AmmoRect.h - (BORDERSIZE*2); SDL_FillRect(amSurface, @AMRect, SDL_MapRGB(amSurface^.format, 0,0,0)); - + x:= AMRect.x; y:= AMRect.y; for i:= 0 to cMaxSlotIndex do @@ -482,25 +483,25 @@ AMFrame:= LongInt(Ammo^[i,t].AmmoType) - 1; if STurns >= 0 then //weapon not usable yet, draw grayed out with turns remaining begin - DrawSpriteFrame2Surf(sprAMAmmosBW, amSurface, x + AMSlotPadding, + DrawSpriteFrame2Surf(sprAMAmmosBW, amSurface, x + AMSlotPadding, y + AMSlotPadding, AMFrame); if STurns < 100 then - DrawSpriteFrame2Surf(sprTurnsLeft, amSurface, - x + AMSlotSize-16, + DrawSpriteFrame2Surf(sprTurnsLeft, amSurface, + x + AMSlotSize-16, y + AMSlotSize + 1 - 16, STurns); end else //draw colored version begin - DrawSpriteFrame2Surf(sprAMAmmos, amSurface, x + AMSlotPadding, + DrawSpriteFrame2Surf(sprAMAmmos, amSurface, x + AMSlotPadding, y + AMSlotPadding, AMFrame); end; {$IFDEF USE_LANDSCAPE_AMMOMENU} - inc(y, AMSlotSize + 1); //the plus one is for the border + inc(y, AMSlotSize + 1); //the plus one is for the border {$ELSE} - inc(x, AMSlotSize + 1); + inc(x, AMSlotSize + 1); {$ENDIF} - end; - end; + end; + end; {$IFDEF USE_LANDSCAPE_AMMOMENU} inc(x, AMSlotSize + 1); {$ELSE} @@ -509,7 +510,7 @@ end; for i:= 1 to SlotsNumX -1 do -DrawLine2Surf(amSurface, i * (AMSlotSize+1)+1, BORDERSIZE, i * (AMSlotSize+1)+1, AMRect.h + BORDERSIZE - AMSlotSize - 2,160,160,160); +DrawLine2Surf(amSurface, i * (AMSlotSize+1)+1, BORDERSIZE, i * (AMSlotSize+1)+1, AMRect.h + BORDERSIZE - AMSlotSize - 2,160,160,160); for i:= 1 to SlotsNumY -1 do DrawLine2Surf(amSurface, BORDERSIZE, i * (AMSlotSize+1)+1, AMRect.w + BORDERSIZE, i * (AMSlotSize+1)+1,160,160,160); @@ -554,11 +555,11 @@ exit end; -//Init the menu -if(AmmoMenuInvalidated) then +//Init the menu +if(AmmoMenuInvalidated) then begin AmmoMenuInvalidated:= false; - FreeTexture(AmmoMenuTex); + FreeAndNilTexture(AmmoMenuTex); AmmoMenuTex:= GetAmmoMenuTexture(Ammo); {$IFDEF USE_LANDSCAPE_AMMOMENU} @@ -611,7 +612,7 @@ begin AMShiftX:= Round(AMShiftTargetX * (1 - AMAnimState)); AMShiftY:= Round(AMShiftTargetY * (1 - AMAnimState)); - if (AMAnimType and AMTypeMaskAlpha) <> 0 then + if (AMAnimType and AMTypeMaskAlpha) <> 0 then Tint($FF, $ff, $ff, Round($ff * AMAnimState)); end else @@ -636,10 +637,10 @@ begin AMShiftX:= Round(AMShiftTargetX * AMAnimState); AMShiftY:= Round(AMShiftTargetY * AMAnimState); - if (AMAnimType and AMTypeMaskAlpha) <> 0 then + if (AMAnimType and AMTypeMaskAlpha) <> 0 then Tint($FF, $ff, $ff, Round($ff * (1-AMAnimState))); end - else + else begin AMShiftX:= AMShiftTargetX; AMShiftY:= AMShiftTargetY; @@ -648,11 +649,11 @@ AMState:= AMHidden; end; end; - + DrawTexture(AmmoRect.x + AMShiftX, AmmoRect.y + AMShiftY, AmmoMenuTex); -if ((AMState = AMHiding) or (AMState = AMShowingUp)) and ((AMAnimType and AMTypeMaskAlpha) <> 0 )then - Tint($FF, $ff, $ff, $ff); +if ((AMState = AMHiding) or (AMState = AMShowingUp)) and ((AMAnimType and AMTypeMaskAlpha) <> 0 )then + untint; Pos:= -1; Slot:= -1; @@ -672,15 +673,15 @@ begin if (CursorPoint.Y <= (cScreenHeight - AmmoRect.y) - ( g * (AMSlotSize+1))) and (CursorPoint.Y > (cScreenHeight - AmmoRect.y) - ((g+1) * (AMSlotSize+1))) and - (CursorPoint.X > AmmoRect.x + ( c * (AMSlotSize+1))) and + (CursorPoint.X > AmmoRect.x + ( c * (AMSlotSize+1))) and (CursorPoint.X <= AmmoRect.x + ((c+1) * (AMSlotSize+1))) then begin Slot:= i; Pos:= t; STurns:= Ammoz[Ammo^[i, t].AmmoType].SkipTurns - CurrentTeam^.Clan^.TurnNumber; if (STurns < 0) and (AMShiftX = 0) and (AMShiftY = 0) then - DrawSprite(sprAMSlot, - AmmoRect.x + BORDERSIZE + (c * (AMSlotSize+1)) + AMSlotPadding, + DrawSprite(sprAMSlot, + AmmoRect.x + BORDERSIZE + (c * (AMSlotSize+1)) + AMSlotPadding, AmmoRect.y + BORDERSIZE + (g * (AMSlotSize+1)) + AMSlotPadding -1, 0); end; inc(g); @@ -702,15 +703,15 @@ begin if (CursorPoint.Y <= (cScreenHeight - AmmoRect.y) - ( c * (AMSlotSize+1))) and (CursorPoint.Y > (cScreenHeight - AmmoRect.y) - ((c+1) * (AMSlotSize+1))) and - (CursorPoint.X > AmmoRect.x + ( g * (AMSlotSize+1))) and + (CursorPoint.X > AmmoRect.x + ( g * (AMSlotSize+1))) and (CursorPoint.X <= AmmoRect.x + ((g+1) * (AMSlotSize+1))) then begin Slot:= i; Pos:= t; STurns:= Ammoz[Ammo^[i, t].AmmoType].SkipTurns - CurrentTeam^.Clan^.TurnNumber; if (STurns < 0) and (AMShiftX = 0) and (AMShiftY = 0) then - DrawSprite(sprAMSlot, - AmmoRect.x + BORDERSIZE + (g * (AMSlotSize+1)) + AMSlotPadding, + DrawSprite(sprAMSlot, + AmmoRect.x + BORDERSIZE + (g * (AMSlotSize+1)) + AMSlotPadding, AmmoRect.y + BORDERSIZE + (c * (AMSlotSize+1)) + AMSlotPadding -1, 0); end; inc(g); @@ -741,11 +742,11 @@ bShowAmmoMenu:= false; SetWeapon(Ammo^[Slot, Pos].AmmoType); bSelected:= false; - FreeWeaponTooltip; + FreeAndNilTexture(WeaponTooltipTex); {$IFDEF USE_TOUCH_INTERFACE}//show the aiming buttons + animation if (Ammo^[Slot, Pos].Propz and ammoprop_NeedUpDown) <> 0 then begin - if not(arrowUp.show) then + if (not arrowUp.show) then begin animateWidget(@arrowUp, true, true); animateWidget(@arrowDown, true, true); @@ -764,11 +765,11 @@ end end else - FreeWeaponTooltip; + FreeAndNilTexture(WeaponTooltipTex); if (WeaponTooltipTex <> nil) and (AMShiftX = 0) and (AMShiftY = 0) then {$IFDEF USE_LANDSCAPE_AMMOMENU} - if not isPhone() then + if (not isPhone()) then ShowWeaponTooltip(-WeaponTooltipTex^.w div 2, AmmoRect.y - WeaponTooltipTex^.h - AMSlotSize); {$ELSE} ShowWeaponTooltip(AmmoRect.x - WeaponTooltipTex^.w - 3, Min(AmmoRect.y + 1, cScreenHeight - WeaponTooltipTex^.h - 40)); @@ -781,127 +782,6 @@ {$ENDIF} end; -procedure DrawWater(Alpha: byte; OffsetY: LongInt); -var VertexBuffer: array [0..3] of TVertex2f; - r: TSDL_Rect; - lw, lh: GLfloat; -begin -if SuddenDeathDmg then - begin - SDWaterColorArray[0].a := Alpha; - SDWaterColorArray[1].a := Alpha; - SDWaterColorArray[2].a := Alpha; - SDWaterColorArray[3].a := Alpha - end -else - begin - WaterColorArray[0].a := Alpha; - WaterColorArray[1].a := Alpha; - WaterColorArray[2].a := Alpha; - WaterColorArray[3].a := Alpha - end; - -lw:= cScreenWidth / cScaleFactor; -lh:= trunc(cScreenHeight / cScaleFactor) + cScreenHeight div 2 + 16; - - // Water -r.y:= OffsetY + WorldDy + cWaterLine; -if WorldDy < trunc(cScreenHeight / cScaleFactor) + cScreenHeight div 2 - cWaterLine then - begin - if r.y < 0 then - r.y:= 0; - - glDisable(GL_TEXTURE_2D); - VertexBuffer[0].X:= -lw; - VertexBuffer[0].Y:= r.y; - VertexBuffer[1].X:= lw; - VertexBuffer[1].Y:= r.y; - VertexBuffer[2].X:= lw; - VertexBuffer[2].Y:= lh; - VertexBuffer[3].X:= -lw; - VertexBuffer[3].Y:= lh; - - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - if SuddenDeathDmg then - glColorPointer(4, GL_UNSIGNED_BYTE, 0, @SDWaterColorArray[0]) - else - glColorPointer(4, GL_UNSIGNED_BYTE, 0, @WaterColorArray[0]); - - glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); - - glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); - - glDisableClientState(GL_COLOR_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glColor4ub($FF, $FF, $FF, $FF); // must not be Tint() as color array seems to stay active and color reset is required - glEnable(GL_TEXTURE_2D); - end; -end; - -procedure DrawWaves(Dir, dX, dY: LongInt; tnt: Byte); -var VertexBuffer, TextureBuffer: array [0..3] of TVertex2f; - lw, waves, shift: GLfloat; - sprite: TSprite; -begin -if SuddenDeathDmg then - sprite:= sprSDWater -else - sprite:= sprWater; - -cWaveWidth:= SpritesData[sprite].Width; - -lw:= cScreenWidth / cScaleFactor; -waves:= lw * 2 / cWaveWidth; - -if SuddenDeathDmg then - Tint(LongInt(tnt) * SDWaterColorArray[2].r div 255 + 255 - tnt, - LongInt(tnt) * SDWaterColorArray[2].g div 255 + 255 - tnt, - LongInt(tnt) * SDWaterColorArray[2].b div 255 + 255 - tnt, - 255 - ) -else - Tint(LongInt(tnt) * WaterColorArray[2].r div 255 + 255 - tnt, - LongInt(tnt) * WaterColorArray[2].g div 255 + 255 - tnt, - LongInt(tnt) * WaterColorArray[2].b div 255 + 255 - tnt, - 255 - ); - -glBindTexture(GL_TEXTURE_2D, SpritesData[sprite].Texture^.id); - -VertexBuffer[0].X:= -lw; -VertexBuffer[0].Y:= cWaterLine + WorldDy + dY; -VertexBuffer[1].X:= lw; -VertexBuffer[1].Y:= VertexBuffer[0].Y; -VertexBuffer[2].X:= lw; -VertexBuffer[2].Y:= VertexBuffer[0].Y + SpritesData[sprite].Height; -VertexBuffer[3].X:= -lw; -VertexBuffer[3].Y:= VertexBuffer[2].Y; - -shift:= - lw / cWaveWidth; -TextureBuffer[0].X:= shift + (( - WorldDx + LongInt(RealTicks shr 6) * Dir + dX) mod cWaveWidth) / (cWaveWidth - 1); -TextureBuffer[0].Y:= 0; -TextureBuffer[1].X:= TextureBuffer[0].X + waves; -TextureBuffer[1].Y:= TextureBuffer[0].Y; -TextureBuffer[2].X:= TextureBuffer[1].X; -TextureBuffer[2].Y:= SpritesData[sprite].Texture^.ry; -TextureBuffer[3].X:= TextureBuffer[0].X; -TextureBuffer[3].Y:= TextureBuffer[2].Y; - - -glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); -glTexCoordPointer(2, GL_FLOAT, 0, @TextureBuffer[0]); -glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); - -untint; - -{for i:= -1 to cWaterSprCount do - DrawSprite(sprWater, - i * cWaveWidth + ((WorldDx + (RealTicks shr 6) * Dir + dX) mod cWaveWidth) - (cScreenWidth div 2), - cWaterLine + WorldDy + dY, - 0)} -end; - procedure DrawRepeated(spr, sprL, sprR: TSprite; Shift, OffsetY: LongInt); var i, w, h, lw, lh, rw, rh, sw: LongInt; begin @@ -975,180 +855,92 @@ else ZoomValue:= zoom; - // Sky - glClear(GL_COLOR_BUFFER_BIT); - //glPushMatrix; - //glScalef(1.0, 1.0, 1.0); - if (not isPaused) and (not isAFK) and (GameType <> gmtRecord) then MoveCamera; if cStereoMode = smNone then begin - glClear(GL_COLOR_BUFFER_BIT); + RenderClear(); DrawWorldStereo(Lag, rmDefault) - end {$IFDEF USE_S3D_RENDERING} - else if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) then - begin - // create left fb - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framel); - glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); - DrawWorldStereo(Lag, rmLeftEye); - - // create right fb - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framer); - glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); - DrawWorldStereo(0, rmRightEye); - - // detatch drawing from fbs - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, defaultFrame); - glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); - SetScale(cDefaultZoomLevel); - - // draw left frame - glBindTexture(GL_TEXTURE_2D, texl); - glBegin(GL_QUADS); - if cStereoMode = smHorizontal then - begin - glTexCoord2f(0.0, 0.0); - glVertex2d(cScreenWidth / -2, cScreenHeight); - glTexCoord2f(1.0, 0.0); - glVertex2d(0, cScreenHeight); - glTexCoord2f(1.0, 1.0); - glVertex2d(0, 0); - glTexCoord2f(0.0, 1.0); - glVertex2d(cScreenWidth / -2, 0); - end - else - begin - glTexCoord2f(0.0, 0.0); - glVertex2d(cScreenWidth / -2, cScreenHeight / 2); - glTexCoord2f(1.0, 0.0); - glVertex2d(cScreenWidth / 2, cScreenHeight / 2); - glTexCoord2f(1.0, 1.0); - glVertex2d(cScreenWidth / 2, 0); - glTexCoord2f(0.0, 1.0); - glVertex2d(cScreenWidth / -2, 0); - end; - glEnd(); - - // draw right frame - glBindTexture(GL_TEXTURE_2D, texr); - glBegin(GL_QUADS); - if cStereoMode = smHorizontal then - begin - glTexCoord2f(0.0, 0.0); - glVertex2d(0, cScreenHeight); - glTexCoord2f(1.0, 0.0); - glVertex2d(cScreenWidth / 2, cScreenHeight); - glTexCoord2f(1.0, 1.0); - glVertex2d(cScreenWidth / 2, 0); - glTexCoord2f(0.0, 1.0); - glVertex2d(0, 0); - end - else - begin - glTexCoord2f(0.0, 0.0); - glVertex2d(cScreenWidth / -2, cScreenHeight); - glTexCoord2f(1.0, 0.0); - glVertex2d(cScreenWidth / 2, cScreenHeight); - glTexCoord2f(1.0, 1.0); - glVertex2d(cScreenWidth / 2, cScreenHeight / 2); - glTexCoord2f(0.0, 1.0); - glVertex2d(cScreenWidth / -2, cScreenHeight / 2); - end; - glEnd(); - SetScale(zoom); end else begin - // clear scene - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); - // draw left eye in red channel only - if cStereoMode = smGreenRed then - glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE) - else if cStereoMode = smBlueRed then - glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE) - else if cStereoMode = smCyanRed then - glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE) - else - glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE); + // draw frame for left eye + RenderClear(rmLeftEye); DrawWorldStereo(Lag, rmLeftEye); - // draw right eye in selected channel(s) only - if cStereoMode = smRedGreen then - glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE) - else if cStereoMode = smRedBlue then - glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE) - else if cStereoMode = smRedCyan then - glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE) - else - glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE); - DrawWorldStereo(Lag, rmRightEye); - end + + // draw frame for right eye + RenderClear(rmRightEye); + DrawWorldStereo(0, rmRightEye); {$ENDIF} + end; + +FinishRender(); end; -procedure ChangeDepth(rm: TRenderMode; d: GLfloat); -begin -{$IFNDEF USE_S3D_RENDERING} - rm:= rm; d:= d; // avoid hint - exit; -{$ELSE} - d:= d / 5; - if rm = rmDefault then - exit - else if rm = rmLeftEye then - d:= -d; - stereoDepth:= stereoDepth + d; - glMatrixMode(GL_PROJECTION); - glTranslatef(d, 0, 0); - glMatrixMode(GL_MODELVIEW); -{$ENDIF} -end; - -procedure ResetDepth(rm: TRenderMode); +procedure RenderWorldEdge; +var + //VertexBuffer: array [0..3] of TVertex2f; + tmp, w: LongInt; + rect: TSDL_Rect; + //c1, c2: LongWord; // couple of colours for edges begin -{$IFNDEF USE_S3D_RENDERING} - rm:= rm; // avoid hint - exit; -{$ELSE} - if rm = rmDefault then - exit; - glMatrixMode(GL_PROJECTION); - glTranslatef(-stereoDepth, 0, 0); - glMatrixMode(GL_MODELVIEW); - stereoDepth:= 0; -{$ENDIF} -end; - - -procedure RenderWorldEdge(Lag: Longword); -var - VertexBuffer: array [0..3] of TVertex2f; - c1, c2: LongWord; // couple of colours for edges -begin -if WorldEdge <> weNone then +if (WorldEdge <> weNone) and (WorldEdge <> weSea) then begin (* 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. *) + rect.y:= ViewTopY; + rect.h:= ViewHeight; + tmp:= LongInt(leftX) + WorldDx; + w:= tmp - ViewLeftX; + + if w > 0 then + begin + rect.w:= w; + rect.x:= ViewLeftX; + DrawRect(rect, $10, $10, $10, $80, true); + if WorldEdge = weBounce then + DrawLineOnScreen(tmp - 1, ViewTopY, tmp - 1, ViewBottomY, 2, $54, $54, $FF, $FF); + end; + + tmp:= LongInt(rightX) + WorldDx; + w:= ViewRightX - tmp; + + if w > 0 then + begin + rect.w:= w; + rect.x:= tmp; + DrawRect(rect, $10, $10, $10, $80, true); + if WorldEdge = weBounce then + DrawLineOnScreen(tmp - 1, ViewTopY, tmp - 1, ViewBottomY, 2, $54, $54, $FF, $FF); + end; + + (* + WARNING: the following render code is outdated and does not work with + current Render.pas ! - don't just uncomment without fixing it first + glDisable(GL_TEXTURE_2D); glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); + if (WorldEdge = weWrap) or (worldEdge = weBounce) then + glColor4ub($00, $00, $00, $40) + else + begin + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(4, GL_UNSIGNED_BYTE, 0, @WorldFade[0]); + end; glPushMatrix; glTranslatef(WorldDx, WorldDy, 0); - glColorPointer(4, GL_UNSIGNED_BYTE, 0, @WorldFade[0]); VertexBuffer[0].X:= leftX-20; - VertexBuffer[0].Y:= -3000; + VertexBuffer[0].Y:= -3500; VertexBuffer[1].X:= leftX-20; VertexBuffer[1].Y:= cWaterLine+cVisibleWater; VertexBuffer[2].X:= leftX+30; VertexBuffer[2].Y:= cWaterLine+cVisibleWater; VertexBuffer[3].X:= leftX+30; - VertexBuffer[3].Y:= -3000; + VertexBuffer[3].Y:= -3500; glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); @@ -1186,7 +978,7 @@ glColor4ub($FF, $FF, $FF, $FF); // must not be Tint() as color array seems to stay active and color reset is required glEnable(GL_TEXTURE_2D); - // I'd still like to have things happen to the border when a wrap or bounce just occurred, based on a timer + // I'd still like to have things happen to the border when a wrap or bounce just occurred, based on a timer if WorldEdge = weBounce then begin // could maybe alternate order of these on a bounce, or maybe drop the outer ones. @@ -1227,6 +1019,7 @@ end; if LeftImpactTimer > Lag then dec(LeftImpactTimer,Lag) else LeftImpactTimer:= 0; if RightImpactTimer > Lag then dec(RightImpactTimer,Lag) else RightImpactTimer:= 0 + *) end; end; @@ -1288,7 +1081,7 @@ for i:= 0 to cMaxHHIndex do begin inc(h, Hedgehogs[i].HealthBarHealth); - if (h < TeamHealthBarHealth) and (Hedgehogs[i].HealthBarHealth > 0) then + if (h < TeamHealthBarHealth) and (Hedgehogs[i].HealthBarHealth > 0) then DrawTexture(15 + h * TeamHealthBarWidth div TeamHealthBarHealth, cScreenHeight + DrawHealthY + smallScreenOffset + 1, SpritesData[sprSlider].Texture); end; @@ -1312,34 +1105,86 @@ r.w:= NameTagTex^.w - 4; r.h:= NameTagTex^.h - 4; DrawTextureFromRect(-NameTagTex^.w - 14, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, NameTagTex); + + if OwnerTex <> nil then + begin + r.w:= OwnerTex^.w - 4; + r.h:= OwnerTex^.h - 4; + DrawTextureFromRect(-OwnerTex^.w - NameTagTex^.w - 16, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, OwnerTex) + end; + + if (GameFlags and gfAISurvival) <> 0 then + begin + r.w:= AIKillsTex^.w - 4; + r.h:= AIKillsTex^.h - 4; + DrawTextureFromRect(TeamHealthBarWidth + 24, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, AIKillsTex); + end; + // draw flag r.w:= 22; r.h:= 15; DrawTextureFromRect(-12, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, FlagTex); + end + // draw an arrow next to active team + else if (CurrentTeam = TeamsArray[t]) and (TurnTimeLeft > 0) then + begin + h:= -NameTagTex^.w - 24; + if OwnerTex <> nil then + h:= h - OwnerTex^.w - 4; + DrawSpriteRotatedF(sprFinger, h, cScreenHeight + DrawHealthY + smallScreenOffset + 2 + SpritesData[sprFinger].Width div 4, 0, 1, -90); end; end; if smallScreenOffset <> 0 then begin SetScale(cDefaultZoomLevel); if TeamsCount * 20 > Longword(cScreenHeight) div 5 then - Tint($FF,$FF,$FF,$FF); + untint; end; end; +var preShiftWorldDx: LongInt; + +procedure ShiftWorld(Dir: LongInt); inline; +begin + preShiftWorldDx:= WorldDx; + WorldDx:= WorldDx + LongInt(Dir * LongInt(playWidth)); + +end; + +procedure UnshiftWorld(); inline; +begin + WorldDx:= preShiftWorldDx; +end; + procedure DrawWorldStereo(Lag: LongInt; RM: TRenderMode); var i, t: LongInt; r: TSDL_Rect; tdx, tdy: Double; s: shortstring; offsetX, offsetY, screenBottom: LongInt; - VertexBuffer: array [0..3] of TVertex2f; + replicateToLeft, replicateToRight, tmp: boolean; + a: Byte; begin +if WorldEdge <> weWrap then + begin + replicateToLeft := false; + replicateToRight:= false; + end +else + begin + replicateToLeft := (LongInt(leftX) + WorldDx > ViewLeftX); + replicateToRight:= (LongInt(rightX) + WorldDx < ViewRightX); + end; + +ScreenBottom:= (WorldDy - trunc(cScreenHeight/cScaleFactor) - (cScreenHeight div 2) + cWaterLine); + +// note: offsetY is negative! +offsetY:= 10 * Min(0, -145 - ScreenBottom); // TODO limit this in the other direction too + if (cReducedQuality and rqNoBackground) = 0 then begin // Offsets relative to camera - spare them to wimpier cpus, no bg or flakes for them anyway - ScreenBottom:= (WorldDy - trunc(cScreenHeight/cScaleFactor) - (cScreenHeight div 2) + cWaterLine); - offsetY:= 10 * Min(0, -145 - ScreenBottom); SkyOffset:= offsetY div 35 + cWaveHeight; HorizontOffset:= SkyOffset; if ScreenBottom > SkyOffset then @@ -1363,67 +1208,159 @@ if (cReducedQuality and rq2DWater) = 0 then begin // Waves - DrawWater(255, SkyOffset); + DrawWater(255, SkyOffset, 0); ChangeDepth(RM, -cStereo_Water_distant); - DrawWaves( 1, 0 - WorldDx div 32, - cWaveHeight + offsetY div 35, 64); + DrawWaves( 1, 0 - WorldDx div 32, offsetY div 35, -49, 64); ChangeDepth(RM, -cStereo_Water_distant); - DrawWaves( -1, 25 + WorldDx div 25, - cWaveHeight + offsetY div 38, 48); + DrawWaves( -1, 25 + WorldDx div 25, offsetY div 38, -37, 48); ChangeDepth(RM, -cStereo_Water_distant); - DrawWaves( 1, 75 - WorldDx div 19, - cWaveHeight + offsetY div 45, 32); + DrawWaves( 1, 75 - WorldDx div 19, offsetY div 45, -23, 32); ChangeDepth(RM, -cStereo_Water_distant); - DrawWaves(-1, 100 + WorldDx div 14, - cWaveHeight + offsetY div 70, 24); + DrawWaves(-1, 100 + WorldDx div 14, offsetY div 70, -7, 24); end else - DrawWaves(-1, 100, - (cWaveHeight + (cWaveHeight shr 1)), 0); + DrawWaves(-1, 100, - cWaveHeight div 2, - cWaveHeight div 2, 0); + +ChangeDepth(RM, cStereo_Land); +DrawVisualGears(5); +DrawLand(WorldDx, WorldDy); + +if replicateToLeft then + begin + ShiftWorld(-1); + DrawLand(WorldDx, WorldDy); + UnshiftWorld(); + end; + +if replicateToRight then + begin + ShiftWorld(1); + DrawLand(WorldDx, WorldDy); + UnshiftWorld(); + end; + +DrawWater(255, 0, 0); - changeDepth(RM, cStereo_Land); - DrawVisualGears(5); - DrawLand(WorldDx, WorldDy); +(* +// Attack bar + if CurrentTeam <> nil then + case AttackBar of + //1: begin + //r:= StuffPoz[sPowerBar]; + //{$WARNINGS OFF} + //r.w:= (CurrentHedgehog^.Gear^.Power * 256) div cPowerDivisor; + //{$WARNINGS ON} + //DrawSpriteFromRect(r, cScreenWidth - 272, cScreenHeight - 48, 16, 0, Surface); + //end; + 2: with CurrentHedgehog^ do + begin + tdx:= hwSign(Gear^.dX) * Sin(Gear^.Angle * Pi / cMaxAngle); + tdy:= - Cos(Gear^.Angle * Pi / cMaxAngle); + for i:= (Gear^.Power * 24) div cPowerDivisor downto 0 do + DrawSprite(sprPower, + hwRound(Gear^.X) + GetLaunchX(CurAmmoType, hwSign(Gear^.dX), Gear^.Angle) + LongInt(round(WorldDx + tdx * (24 + i * 2))) - 16, + hwRound(Gear^.Y) + GetLaunchY(CurAmmoType, Gear^.Angle) + LongInt(round(WorldDy + tdy * (24 + i * 2))) - 16, + i) + end + end; +*) - DrawWater(255, 0); +tmp:= bShowFinger; +bShowFinger:= false; + +if replicateToLeft then + begin + ShiftWorld(-1); + DrawVisualGears(1); + DrawGears(); + DrawVisualGears(6); + UnshiftWorld(); + end; + +if replicateToRight then + begin + ShiftWorld(1); + DrawVisualGears(1); + DrawGears(); + DrawVisualGears(6); + UnshiftWorld(); + end; + +bShowFinger:= tmp; DrawVisualGears(1); DrawGears; DrawVisualGears(6); + if SuddenDeathDmg then - DrawWater(SDWaterOpacity, 0) + DrawWater(SDWaterOpacity, 0, 0) else - DrawWater(WaterOpacity, 0); + DrawWater(WaterOpacity, 0, 0); // Waves ChangeDepth(RM, cStereo_Water_near); -DrawWaves( 1, 25 - WorldDx div 9, - cWaveHeight, 12); +DrawWaves( 1, 25 - WorldDx div 9, 0, 0, 12); if (cReducedQuality and rq2DWater) = 0 then begin //DrawWater(WaterOpacity, - offsetY div 40); ChangeDepth(RM, cStereo_Water_near); - DrawWaves(-1, 50 + WorldDx div 6, - cWaveHeight - offsetY div 40, 8); + DrawWaves(-1, 50 + WorldDx div 6, - offsetY div 40, 23, 8); if SuddenDeathDmg then - DrawWater(SDWaterOpacity, - offsetY div 20) + DrawWater(SDWaterOpacity, - offsetY div 20, 23) else - DrawWater(WaterOpacity, - offsetY div 20); + DrawWater(WaterOpacity, - offsetY div 20, 23); ChangeDepth(RM, cStereo_Water_near); - DrawWaves( 1, 75 - WorldDx div 4, - cWaveHeight - offsetY div 20, 2); + DrawWaves( 1, 75 - WorldDx div 4, - offsetY div 20, 37, 2); if SuddenDeathDmg then - DrawWater(SDWaterOpacity, - offsetY div 10) + DrawWater(SDWaterOpacity, - offsetY div 10, 47) else - DrawWater(WaterOpacity, - offsetY div 10); + DrawWater(WaterOpacity, - offsetY div 10, 47); ChangeDepth(RM, cStereo_Water_near); - DrawWaves( -1, 25 + WorldDx div 3, - cWaveHeight - offsetY div 10, 0); + DrawWaves( -1, 25 + WorldDx div 3, - offsetY div 10, 59, 0); end else - DrawWaves(-1, 50, - (cWaveHeight shr 1), 0); + DrawWaves(-1, 50, cWaveHeight div 2, cWaveHeight div 2, 0); // everything after this ChangeDepth will be drawn outside the screen // note: negative parallax gears should last very little for a smooth stereo effect ChangeDepth(RM, cStereo_Outside); + + if replicateToLeft then + begin + ShiftWorld(-1); + DrawVisualGears(2); + UnshiftWorld(); + end; + + if replicateToRight then + begin + ShiftWorld(1); + DrawVisualGears(2); + UnshiftWorld(); + end; + DrawVisualGears(2); // everything after this ResetDepth will be drawn at screen level (depth = 0) // note: everything that needs to be readable should be on this level ResetDepth(RM); + + if replicateToLeft then + begin + ShiftWorld(-1); + DrawVisualGears(3); + UnshiftWorld(); + end; + + if replicateToRight then + begin + ShiftWorld(1); + DrawVisualGears(3); + UnshiftWorld(); + end; + DrawVisualGears(3); {$WARNINGS OFF} @@ -1440,7 +1377,7 @@ end; {$WARNINGS ON} -RenderWorldEdge(Lag); +RenderWorldEdge(); // this scale is used to keep the various widgets at the same dimension at all zoom levels SetScale(cDefaultZoomLevel); @@ -1460,7 +1397,7 @@ i:= Succ(Pred(ReadyTimeLeft) div 1000) else i:= Succ(Pred(TurnTimeLeft) div 1000); - + if i>99 then t:= 112 else if i>9 then @@ -1545,14 +1482,14 @@ AMAnimStartTime:= RealTicks - (AMAnimDuration - (RealTicks - AMAnimStartTime)); AMState:= AMShowingUp; end; -if not(bShowAmmoMenu) and ((AMstate = AMShowing) or (AMState = AMShowingUp)) then +if (not bShowAmmoMenu) and ((AMstate = AMShowing) or (AMState = AMShowingUp)) then begin if (AMState = AMShowing) then AMAnimStartTime:= RealTicks else AMAnimStartTime:= RealTicks - (AMAnimDuration - (RealTicks - AMAnimStartTime)); AMState:= AMHiding; - end; + end; if bShowAmmoMenu or (AMState = AMHiding) then ShowAmmoMenu; @@ -1564,6 +1501,7 @@ // Chat DrawChat; + // various captions if fastUntilLag then DrawTextureCentered(0, (cScreenHeight shr 1), SyncTexture); @@ -1607,11 +1545,11 @@ if t < 10 then s:= '0' + s; s:= inttostr(i div 60) + ':' + s; - - + + tmpSurface:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(s), cWhiteColorChannels); tmpSurface:= doSurfaceConversion(tmpSurface); - FreeTexture(timeTexture); + FreeAndNilTexture(timeTexture); timeTexture:= Surface2Tex(tmpSurface, false); SDL_FreeSurface(tmpSurface) end; @@ -1629,7 +1567,7 @@ s:= inttostr(FPS) + ' fps'; tmpSurface:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(s), cWhiteColorChannels); tmpSurface:= doSurfaceConversion(tmpSurface); - FreeTexture(fpsTexture); + FreeAndNilTexture(fpsTexture); fpsTexture:= Surface2Tex(tmpSurface, false); SDL_FreeSurface(tmpSurface) end; @@ -1644,7 +1582,7 @@ if ScreenFade <> sfNone then begin - if not isFirstFrame then + if (not isFirstFrame) then case ScreenFade of sfToBlack, sfToWhite: if ScreenFadeValue + Lag * ScreenFadeSpeed < sfMax then inc(ScreenFadeValue, Lag * ScreenFadeSpeed) @@ -1657,27 +1595,16 @@ end; if ScreenFade <> sfNone then begin + r.x:= ViewLeftX; + r.y:= ViewTopY; + r.w:= ViewWidth; + r.h:= ViewHeight; + case ScreenFade of - sfToBlack, sfFromBlack: Tint(0, 0, 0, ScreenFadeValue * 255 div 1000); - sfToWhite, sfFromWhite: Tint($FF, $FF, $FF, ScreenFadeValue * 255 div 1000); + sfToBlack, sfFromBlack: DrawRect(r, 0, 0, 0, ScreenFadeValue * 255 div 1000, true); + sfToWhite, sfFromWhite: DrawRect(r, $FF, $FF, $FF, ScreenFadeValue * 255 div 1000, true); end; - VertexBuffer[0].X:= -cScreenWidth; - VertexBuffer[0].Y:= cScreenHeight; - VertexBuffer[1].X:= -cScreenWidth; - VertexBuffer[1].Y:= 0; - VertexBuffer[2].X:= cScreenWidth; - VertexBuffer[2].Y:= 0; - VertexBuffer[3].X:= cScreenWidth; - VertexBuffer[3].Y:= cScreenHeight; - - glDisable(GL_TEXTURE_2D); - - glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); - glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); - - glEnable(GL_TEXTURE_2D); - untint; if not isFirstFrame and ((ScreenFadeValue = 0) or (ScreenFadeValue = sfMax)) then ScreenFade:= sfNone end @@ -1692,21 +1619,17 @@ s:= 'rec'; tmpSurface:= TTF_RenderUTF8_Blended(Fontz[fntBig].Handle, Str2PChar(s), cWhiteColorChannels); tmpSurface:= doSurfaceConversion(tmpSurface); - FreeTexture(recTexture); + FreeAndNilTexture(recTexture); recTexture:= Surface2Tex(tmpSurface, false); SDL_FreeSurface(tmpSurface) end; DrawTexture( -(cScreenWidth shr 1) + 50, 20, recTexture); + //a:= Byte(Round(127*(1 + sin(RealTicks*0.007)))); + a:= Byte(min(255, abs(-255 + ((RealTicks div 2) and 511)))); + // draw red circle - glDisable(GL_TEXTURE_2D); - Tint($FF, $00, $00, Byte(Round(127*(1 + sin(SDL_GetTicks()*0.007))))); - glBegin(GL_POLYGON); - for i:= 0 to 20 do - glVertex2f(-(cScreenWidth shr 1) + 30 + sin(i*2*Pi/20)*10, 35 + cos(i*2*Pi/20)*10); - glEnd(); - untint; - glEnable(GL_TEXTURE_2D); + DrawCircleFilled(-(cScreenWidth shr 1) + 30, 35, 10, $FF, $00, $00, a); end; {$ENDIF} @@ -1736,31 +1659,51 @@ // Cursor -if isCursorVisible then +if isCursorVisible and (not bShowAmmoMenu) then begin - if not bShowAmmoMenu then - begin - if not CurrentTeam^.ExtDriven then TargetCursorPoint:= CursorPoint; - with CurrentHedgehog^ do - if (Gear <> nil) and ((Gear^.State and gstHHChooseTarget) <> 0) then + if not CurrentTeam^.ExtDriven then TargetCursorPoint:= CursorPoint; + with CurrentHedgehog^ do + if (Gear <> nil) and ((Gear^.State and gstChooseTarget) <> 0) then + begin + if (CurAmmoType = amNapalm) or (CurAmmoType = amMineStrike) or (((GameFlags and gfMoreWind) <> 0) and ((CurAmmoType = amDrillStrike) or (CurAmmoType = amAirAttack))) then + 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); + i:= GetCurAmmoEntry(CurrentHedgehog^)^.Pos; + with Ammoz[CurAmmoType] do + if PosCount > 1 then begin - if (CurAmmoType = amNapalm) or (CurAmmoType = amMineStrike) then - 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); - i:= GetCurAmmoEntry(CurrentHedgehog^)^.Pos; - with Ammoz[CurAmmoType] do - if PosCount > 1 then - DrawSprite(PosSprite, TargetCursorPoint.X - (SpritesData[PosSprite].Width shr 1), cScreenHeight - TargetCursorPoint.Y - (SpritesData[PosSprite].Height shr 1),i); + if (CurAmmoType = amGirder) or (CurAmmoType = amTeleport) then + begin + // pulsating transparency + if ((GameTicks div 16) mod $80) >= $40 then + Tint($FF, $FF, $FF, $C0 - (GameTicks div 16) mod $40) + else + Tint($FF, $FF, $FF, $80 + (GameTicks div 16) mod $40); + end; + DrawSprite(PosSprite, TargetCursorPoint.X - (SpritesData[PosSprite].Width shr 1), cScreenHeight - TargetCursorPoint.Y - (SpritesData[PosSprite].Height shr 1),i); + Untint(); end; - DrawSprite(sprArrow, TargetCursorPoint.X, cScreenHeight - TargetCursorPoint.Y, (RealTicks shr 6) mod 8) - end + end; + //DrawSprite(sprArrow, TargetCursorPoint.X, cScreenHeight - TargetCursorPoint.Y, (RealTicks shr 6) mod 8) + 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); end; -isFirstFrame:= false; + +// debug stuff +if cViewLimitsDebug then + begin + r.x:= ViewLeftX; + r.y:= ViewTopY; + r.w:= ViewWidth; + r.h:= ViewHeight; + DrawRect(r, 255, 0, 0, 128, false); + end; + +isFirstFrame:= false end; var PrevSentPointTime: LongWord = 0; procedure MoveCamera; -var EdgesDist, wdy, shs,z, amNumOffsetX, amNumOffsetY: LongInt; +var EdgesDist, wdy, shs,z, amNumOffsetX, amNumOffsetY, dstX: LongInt; inbtwnTrgtAttks: Boolean; begin {$IFNDEF MOBILE} @@ -1768,8 +1711,8 @@ uCursor.updatePosition(); {$ENDIF} z:= round(200/zoom); -inbtwnTrgtAttks := (CurrentHedgehog <> nil) and ((Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_NeedTarget) <> 0) and ((GameFlags and gfInfAttack) <> 0); -if autoCameraOn and not PlacingHogs and (FollowGear <> nil) and (not isCursorVisible) and (not bShowAmmoMenu) and (not fastUntilLag) and not inbtwnTrgtAttks then +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); +if autoCameraOn and (not PlacingHogs) and (FollowGear <> nil) and (not isCursorVisible) and (not bShowAmmoMenu) and (not fastUntilLag) and (not inbtwnTrgtAttks) then if ((abs(CursorPoint.X - prevPoint.X) + abs(CursorPoint.Y - prevpoint.Y)) > 4) then begin FollowGear:= nil; @@ -1778,13 +1721,36 @@ end else begin - CursorPoint.X:= (prevPoint.X * 7 + hwRound(FollowGear^.X) + hwSign(FollowGear^.dX) * z + WorldDx) div 8; - if isPhone() or (cScreenHeight < 600) or ((hwSign(FollowGear^.dY) * z) < 10) then + dstX:= hwRound(FollowGear^.X) + hwSign(FollowGear^.dX) * z + WorldDx; + + if (WorldEdge = weWrap) then + begin + if dstX - prevPoint.X < (LongInt(leftX) - rightX) div 2 then + CursorPoint.X:= (prevPoint.X * 7 + dstX - (leftX - rightX)) div 8 + else if dstX - prevPoint.X > (LongInt(rightX) - leftX) div 2 then + CursorPoint.X:= (prevPoint.X * 7 + dstX - (rightX - leftX)) div 8 + else + CursorPoint.X:= (prevPoint.X * 7 + dstX) div 8; + end + else // usual camera movement routine + begin + CursorPoint.X:= (prevPoint.X * 7 + dstX) div 8; + end; + + if isPhone() or (cScreenHeight < 600) or (hwFloat(FollowGear^.dY * z).Round < 10) then CursorPoint.Y:= (prevPoint.Y * 7 + cScreenHeight - (hwRound(FollowGear^.Y) + WorldDy)) div 8 else CursorPoint.Y:= (prevPoint.Y * 7 + cScreenHeight - (hwRound(FollowGear^.Y) + hwSign(FollowGear^.dY) * z + WorldDy)) div 8; end; +if (WorldEdge = weWrap) then + begin + if -WorldDx < leftX then + WorldDx:= WorldDx - LongInt(rightX) + leftX + else if -WorldDx > rightX then + WorldDx:= WorldDx + LongInt(rightX) - leftX; + end; + wdy:= trunc(cScreenHeight / cScaleFactor) + cScreenHeight div 2 - cWaterLine - cVisibleWater; if WorldDy < wdy then WorldDy:= wdy; @@ -1810,7 +1776,7 @@ {$ENDIF} {$ENDIF} - if CursorPoint.X < AmmoRect.x + amNumOffsetX + 3 then//check left + if CursorPoint.X < AmmoRect.x + amNumOffsetX + 3 then//check left CursorPoint.X:= AmmoRect.x + amNumOffsetX + 3; if CursorPoint.X > AmmoRect.x + AmmoRect.w - 3 then//check right CursorPoint.X:= AmmoRect.x + AmmoRect.w - 3; @@ -1889,25 +1855,27 @@ procedure ShowMission(caption, subcaption, text: ansistring; icon, time : LongInt); var r: TSDL_Rect; begin +if cOnlyStats then exit; + r.w:= 32; r.h:= 32; if time = 0 then time:= 5000; missionTimer:= time; -FreeTexture(missionTex); +FreeAndNilTexture(missionTex); if icon > -1 then begin r.x:= 0; r.y:= icon * 32; - missionTex:= RenderHelpWindow(caption, subcaption, text, '', 0, MissionIcons, @r) + missionTex:= RenderHelpWindow(caption, subcaption, text, ansistring(''), 0, MissionIcons, @r) end else begin r.x:= ((-icon - 1) shr 4) * 32; r.y:= ((-icon - 1) mod 16) * 32; - missionTex:= RenderHelpWindow(caption, subcaption, text, '', 0, SpritesData[sprAMAmmos].Surface, @r) + missionTex:= RenderHelpWindow(caption, subcaption, text, ansistring(''), 0, SpritesData[sprAMAmmos].Surface, @r) end; end; @@ -1939,14 +1907,22 @@ {$IFDEF USE_VIDEO_RECORDING} // do not change volume during prerecording as it will affect sound in video file -if not flagPrerecording then +if (not flagPrerecording) then {$ENDIF} begin - if not cHasFocus then DampenAudio() + if (not cHasFocus) then DampenAudio() else UndampenAudio(); end; end; +procedure updateCursorVisibility; +begin + if isPaused or isAFK then + SDL_ShowCursor(1) + else + SDL_ShowCursor(ord(GameState = gsConfirm)) +end; + procedure SetUtilityWidgetState(ammoType: TAmmoType); begin {$IFDEF USE_TOUCH_INTERFACE} @@ -1954,11 +1930,11 @@ ammoType:= CurrentHedgehog^.CurAmmoType; if(CurrentHedgehog <> nil)then - if (Ammoz[ammoType].Ammo.Propz and ammoprop_Timerable) <> 0 then + if ((Ammoz[ammoType].Ammo.Propz and ammoprop_Timerable) <> 0) and (ammoType <> amDrillStrike) then begin utilityWidget.sprite:= sprTimerButton; animateWidget(@utilityWidget, true, true); - end + end else if (Ammoz[ammoType].Ammo.Propz and ammoprop_NeedTarget) <> 0 then begin utilityWidget.sprite:= sprTargetButton; @@ -1966,7 +1942,7 @@ end else if ammoType = amSwitch then begin - utilityWidget.sprite:= sprTargetButton; + utilityWidget.sprite:= sprSwitchButton; animateWidget(@utilityWidget, true, true); end else if utilityWidget.show then @@ -1982,7 +1958,7 @@ begin show:= showWidget; if fade then fadeAnimStart:= RealTicks; - + with moveAnim do begin animate:= true; @@ -2020,10 +1996,8 @@ missionTimer:= 0; missionTex:= nil; cOffsetY:= 0; - stereoDepth:= 0; AMState:= AMHidden; isFirstFrame:= true; - stereoDepth:= stereoDepth; // avoid hint FillChar(WorldFade, sizeof(WorldFade), 0); WorldFade[0].a:= 255; @@ -2034,6 +2008,8 @@ WorldEnd[2].a:= 255; WorldEnd[3].a:= 255; + AmmoMenuTex:= nil; + AmmoMenuInvalidated:= true end; procedure freeModule;