hedgewars/uWorld.pas
branchwebgl
changeset 9950 2759212a27de
parent 9521 8054d9d775fd
parent 9812 a293a9ecdc82
child 9952 32f5982604f4
equal deleted inserted replaced
9521:8054d9d775fd 9950:2759212a27de
    58     , uTextures
    58     , uTextures
    59     , uRender
    59     , uRender
    60     , uCaptions
    60     , uCaptions
    61     , uCursor
    61     , uCursor
    62     , uCommands
    62     , uCommands
       
    63     , uTeams
    63 {$IFDEF USE_VIDEO_RECORDING}
    64 {$IFDEF USE_VIDEO_RECORDING}
    64     , uVideoRec
    65     , uVideoRec
    65 {$ENDIF}
    66 {$ENDIF}
    66 {$IFDEF GL2}
    67 {$IFDEF GL2}
    67     , uMatrix
    68     , uMatrix
    86     AMAnimType: LongInt;
    87     AMAnimType: LongInt;
    87     recTexture: PTexture;
    88     recTexture: PTexture;
    88     AmmoMenuTex     : PTexture;
    89     AmmoMenuTex     : PTexture;
    89     HorizontOffset: LongInt;
    90     HorizontOffset: LongInt;
    90     cOffsetY: LongInt;
    91     cOffsetY: LongInt;
       
    92     WorldEnd, WorldFade : array[0..3] of HwColor4f;
    91 
    93 
    92 const cStereo_Sky           = 0.0500;
    94 const cStereo_Sky           = 0.0500;
    93       cStereo_Horizon       = 0.0250;
    95       cStereo_Horizon       = 0.0250;
    94       cStereo_MidDistance   = 0.0175;
    96       cStereo_MidDistance   = 0.0175;
    95       cStereo_Water_distant = 0.0125;
    97       cStereo_Water_distant = 0.0125;
   919 UpdateModelviewProjection;
   921 UpdateModelviewProjection;
   920 {$ENDIF}
   922 {$ENDIF}
   921 
   923 
   922 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
   924 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
   923 
   925 
   924 Tint($FF, $FF, $FF, $FF);
   926 untint;
   925 
   927 
   926 {for i:= -1 to cWaterSprCount do
   928 {for i:= -1 to cWaterSprCount do
   927     DrawSprite(sprWater,
   929     DrawSprite(sprWater,
   928         i * cWaveWidth + ((WorldDx + (RealTicks shr 6) * Dir + dX) mod cWaveWidth) - (cScreenWidth div 2),
   930         i * cWaveWidth + ((WorldDx + (RealTicks shr 6) * Dir + dX) mod cWaveWidth) - (cScreenWidth div 2),
   929         cWaterLine + WorldDy + dY,
   931         cWaterLine + WorldDy + dY,
  1006     // Sky
  1008     // Sky
  1007     glClear(GL_COLOR_BUFFER_BIT);
  1009     glClear(GL_COLOR_BUFFER_BIT);
  1008     //glPushMatrix;
  1010     //glPushMatrix;
  1009     //glScalef(1.0, 1.0, 1.0);
  1011     //glScalef(1.0, 1.0, 1.0);
  1010 
  1012 
  1011     if (not isPaused) and (GameType <> gmtRecord) then
  1013     if (not isPaused) and (not isAFK) and (GameType <> gmtRecord) then
  1012         MoveCamera;
  1014         MoveCamera;
  1013 
  1015 
  1014     if cStereoMode = smNone then
  1016     if cStereoMode = smNone then
  1015         begin
  1017         begin
  1016         glClear(GL_COLOR_BUFFER_BIT);
  1018         glClear(GL_COLOR_BUFFER_BIT);
  1162     {$ENDIF}
  1164     {$ENDIF}
  1163     cStereoDepth:= 0;
  1165     cStereoDepth:= 0;
  1164 {$ENDIF}
  1166 {$ENDIF}
  1165 end;
  1167 end;
  1166 
  1168 
       
  1169 procedure RenderWorldEdge(Lag: Longword);
       
  1170 var
       
  1171     VertexBuffer: array [0..3] of TVertex2f;
       
  1172     c1, c2: LongWord; // couple of colours for edges
       
  1173 begin
       
  1174 if WorldEdge <> weNone then
       
  1175     begin
       
  1176 (* 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. *)
       
  1177 
       
  1178     glDisable(GL_TEXTURE_2D);
       
  1179     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
       
  1180     glEnableClientState(GL_COLOR_ARRAY);
       
  1181 
       
  1182     glPushMatrix;
       
  1183     glTranslatef(WorldDx, WorldDy, 0);
       
  1184     glColorPointer(4, GL_UNSIGNED_BYTE, 0, @WorldFade[0]);
       
  1185 
       
  1186     VertexBuffer[0].X:= leftX-20;
       
  1187     VertexBuffer[0].Y:= -3000;
       
  1188     VertexBuffer[1].X:= leftX-20;
       
  1189     VertexBuffer[1].Y:= cWaterLine+cVisibleWater;
       
  1190     VertexBuffer[2].X:= leftX+30;
       
  1191     VertexBuffer[2].Y:= cWaterLine+cVisibleWater;
       
  1192     VertexBuffer[3].X:= leftX+30;
       
  1193     VertexBuffer[3].Y:= -3000;
       
  1194 
       
  1195     glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
       
  1196     glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
       
  1197 
       
  1198     VertexBuffer[0].X:= rightX+20;
       
  1199     VertexBuffer[1].X:= rightX+20;
       
  1200     VertexBuffer[2].X:= rightX-30;
       
  1201     VertexBuffer[3].X:= rightX-30;
       
  1202 
       
  1203     glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
       
  1204     glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
       
  1205 
       
  1206     glColorPointer(4, GL_UNSIGNED_BYTE, 0, @WorldEnd[0]);
       
  1207 
       
  1208     VertexBuffer[0].X:= -5000;
       
  1209     VertexBuffer[1].X:= -5000;
       
  1210     VertexBuffer[2].X:= leftX-20;
       
  1211     VertexBuffer[3].X:= leftX-20;
       
  1212 
       
  1213     glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
       
  1214     glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
       
  1215 
       
  1216     VertexBuffer[0].X:= rightX+5000;
       
  1217     VertexBuffer[1].X:= rightX+5000;
       
  1218     VertexBuffer[2].X:= rightX+20;
       
  1219     VertexBuffer[3].X:= rightX+20;
       
  1220 
       
  1221     glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
       
  1222     glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
       
  1223 
       
  1224     glPopMatrix;
       
  1225     glDisableClientState(GL_COLOR_ARRAY);
       
  1226     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
       
  1227 
       
  1228     glColor4ub($FF, $FF, $FF, $FF); // must not be Tint() as color array seems to stay active and color reset is required
       
  1229     glEnable(GL_TEXTURE_2D);
       
  1230 
       
  1231     // I'd still like to have things happen to the border when a wrap or bounce just occurred, based on a timer 
       
  1232     if WorldEdge = weBounce then
       
  1233         begin
       
  1234         // could maybe alternate order of these on a bounce, or maybe drop the outer ones.
       
  1235         if LeftImpactTimer mod 2 = 0 then
       
  1236             begin
       
  1237             c1:= $5454FFFF; c2:= $FFFFFFFF;
       
  1238             end
       
  1239         else begin
       
  1240             c1:= $FFFFFFFF; c2:= $5454FFFF;
       
  1241             end;
       
  1242         DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 7.0,   c1);
       
  1243         DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 5.0,   c2);
       
  1244         DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 3.0,   c1);
       
  1245         DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 1.0,   c2);
       
  1246         if RightImpactTimer mod 2 = 0 then
       
  1247             begin
       
  1248             c1:= $5454FFFF; c2:= $FFFFFFFF;
       
  1249             end
       
  1250         else begin
       
  1251             c1:= $FFFFFFFF; c2:= $5454FFFF;
       
  1252             end;
       
  1253         DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 7.0, c1);
       
  1254         DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 5.0, c2);
       
  1255         DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 3.0, c1);
       
  1256         DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 1.0, c2)
       
  1257         end
       
  1258     else if WorldEdge = weWrap then
       
  1259         begin
       
  1260         DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 5.0, $A0, $30, $60, max(50,255-LeftImpactTimer));
       
  1261         DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 2.0, $FF0000FF);
       
  1262         DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 5.0, $A0, $30, $60, max(50,255-RightImpactTimer));
       
  1263         DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 2.0, $FF0000FF);
       
  1264         end
       
  1265     else
       
  1266         begin
       
  1267         DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 5.0, $2E8B5780);
       
  1268         DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 5.0, $2E8B5780)
       
  1269         end;
       
  1270     if LeftImpactTimer > Lag then dec(LeftImpactTimer,Lag) else LeftImpactTimer:= 0;
       
  1271     if RightImpactTimer > Lag then dec(RightImpactTimer,Lag) else RightImpactTimer:= 0
       
  1272     end;
       
  1273 end;
       
  1274 
       
  1275 
       
  1276 procedure RenderTeamsHealth;
       
  1277 var t, i, h, smallScreenOffset, TeamHealthBarWidth : LongInt;
       
  1278     r: TSDL_Rect;
       
  1279     highlight: boolean;
       
  1280     htex: PTexture;
       
  1281 begin
       
  1282 if TeamsCount * 20 > Longword(cScreenHeight) div 7 then  // take up less screen on small displays
       
  1283     begin
       
  1284     SetScale(1.5);
       
  1285     smallScreenOffset:= cScreenHeight div 6;
       
  1286     if TeamsCount * 100 > Longword(cScreenHeight) then
       
  1287         Tint($FF,$FF,$FF,$80);
       
  1288     end
       
  1289 else smallScreenOffset:= 0;
       
  1290 for t:= 0 to Pred(TeamsCount) do
       
  1291     with TeamsArray[t]^ do
       
  1292       if TeamHealth > 0 then
       
  1293         begin
       
  1294         highlight:= bShowFinger and (CurrentTeam = TeamsArray[t]) and ((RealTicks mod 1000) < 500);
       
  1295 
       
  1296         if highlight then
       
  1297             begin
       
  1298             Tint(Clan^.Color shl 8 or $FF);
       
  1299             htex:= GenericHealthTexture
       
  1300             end
       
  1301         else
       
  1302             htex:= Clan^.HealthTex;
       
  1303 
       
  1304         // draw owner
       
  1305         if OwnerTex <> nil then
       
  1306             DrawTexture(-OwnerTex^.w - NameTagTex^.w - 18, cScreenHeight + DrawHealthY + smallScreenOffset, OwnerTex);
       
  1307 
       
  1308         // draw name
       
  1309         DrawTexture(-NameTagTex^.w - 16, cScreenHeight + DrawHealthY + smallScreenOffset, NameTagTex);
       
  1310 
       
  1311         // draw flag
       
  1312         DrawTexture(-14, cScreenHeight + DrawHealthY + smallScreenOffset, FlagTex);
       
  1313 
       
  1314         TeamHealthBarWidth:= cTeamHealthWidth * TeamHealthBarHealth div MaxTeamHealth;
       
  1315 
       
  1316         // draw health bar
       
  1317         r.x:= 0;
       
  1318         r.y:= 0;
       
  1319         r.w:= 2 + TeamHealthBarWidth;
       
  1320         r.h:= htex^.h;
       
  1321         DrawTextureFromRect(14, cScreenHeight + DrawHealthY + smallScreenOffset, @r, htex);
       
  1322 
       
  1323         // draw health bars right border
       
  1324         inc(r.x, cTeamHealthWidth + 2);
       
  1325         r.w:= 3;
       
  1326         DrawTextureFromRect(TeamHealthBarWidth + 15, cScreenHeight + DrawHealthY + smallScreenOffset, @r, htex);
       
  1327 
       
  1328         h:= 0;
       
  1329         if not hasGone then
       
  1330             for i:= 0 to cMaxHHIndex do
       
  1331                 begin
       
  1332                 inc(h, Hedgehogs[i].HealthBarHealth);
       
  1333                 if (h < TeamHealthBarHealth) and (Hedgehogs[i].HealthBarHealth > 0) then 
       
  1334                     DrawTexture(15 + h * TeamHealthBarWidth div TeamHealthBarHealth, cScreenHeight + DrawHealthY + smallScreenOffset + 1, SpritesData[sprSlider].Texture);
       
  1335                 end;
       
  1336 
       
  1337         // draw ai kill counter for gfAISurvival
       
  1338         if (GameFlags and gfAISurvival) <> 0 then
       
  1339             begin
       
  1340             DrawTexture(TeamHealthBarWidth + 22, cScreenHeight + DrawHealthY + smallScreenOffset, AIKillsTex);
       
  1341             end;
       
  1342 
       
  1343         // if highlighted, draw flag and other contents again to keep their colors
       
  1344         // this approach should be faster than drawing all borders one by one tinted or not
       
  1345         if highlight then
       
  1346             begin
       
  1347             if TeamsCount * 100 > Longword(cScreenHeight) then
       
  1348                 Tint($FF,$FF,$FF,$80)
       
  1349             else untint;
       
  1350 
       
  1351             if OwnerTex <> nil then
       
  1352                 begin
       
  1353                 r.x:= 2;
       
  1354                 r.y:= 2;
       
  1355                 r.w:= OwnerTex^.w - 4;
       
  1356                 r.h:= OwnerTex^.h - 4;
       
  1357                 DrawTextureFromRect(-OwnerTex^.w - NameTagTex^.w - 16, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, OwnerTex)
       
  1358                 end;
       
  1359             // draw name
       
  1360             r.x:= 2;
       
  1361             r.y:= 2;
       
  1362             r.w:= NameTagTex^.w - 4;
       
  1363             r.h:= NameTagTex^.h - 4;
       
  1364             DrawTextureFromRect(-NameTagTex^.w - 14, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, NameTagTex);
       
  1365             // draw flag
       
  1366             r.w:= 22;
       
  1367             r.h:= 15;
       
  1368             DrawTextureFromRect(-12, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, FlagTex);
       
  1369             end;
       
  1370         end;
       
  1371 if smallScreenOffset <> 0 then
       
  1372     begin
       
  1373     SetScale(cDefaultZoomLevel);
       
  1374     if TeamsCount * 20 > Longword(cScreenHeight) div 5 then
       
  1375         Tint($FF,$FF,$FF,$FF);
       
  1376     end;
       
  1377 end;
       
  1378 
       
  1379 
       
  1380 >>>>>>> other
  1167 procedure DrawWorldStereo(Lag: LongInt; RM: TRenderMode);
  1381 procedure DrawWorldStereo(Lag: LongInt; RM: TRenderMode);
  1168 var i, t, h: LongInt;
  1382 var i, t: LongInt;
  1169     r: TSDL_Rect;
  1383     r: TSDL_Rect;
  1170     tdx, tdy: Double;
  1384     tdx, tdy: Double;
  1171     s: shortstring;
  1385     s: shortstring;
  1172     highlight: Boolean;
  1386     offsetX, offsetY, screenBottom: LongInt;
  1173     smallScreenOffset, offsetX, offsetY, screenBottom: LongInt;
       
  1174     VertexBuffer: array [0..3] of TVertex2f;
  1387     VertexBuffer: array [0..3] of TVertex2f;
  1175     lw, lh: GLfloat;
       
  1176     WorldEnd, WorldFade : array[0..3] of HwColor4f;
       
  1177 begin
  1388 begin
  1178 if (cReducedQuality and rqNoBackground) = 0 then
  1389 if (cReducedQuality and rqNoBackground) = 0 then
  1179     begin
  1390     begin
  1180         // Offsets relative to camera - spare them to wimpier cpus, no bg or flakes for them anyway
  1391         // Offsets relative to camera - spare them to wimpier cpus, no bg or flakes for them anyway
  1181         ScreenBottom:= (WorldDy - trunc(cScreenHeight/cScaleFactor) - (cScreenHeight div 2) + cWaterLine);
  1392         ScreenBottom:= (WorldDy - trunc(cScreenHeight/cScaleFactor) - (cScreenHeight div 2) + cWaterLine);
  1191             Tint(SDTint, SDTint, SDTint, $FF);
  1402             Tint(SDTint, SDTint, SDTint, $FF);
  1192         DrawRepeated(sprSky, sprSkyL, sprSkyR, (WorldDx + LAND_WIDTH div 2) * 3 div 8, SkyOffset);
  1403         DrawRepeated(sprSky, sprSkyL, sprSkyR, (WorldDx + LAND_WIDTH div 2) * 3 div 8, SkyOffset);
  1193         ChangeDepth(RM, -cStereo_Horizon);
  1404         ChangeDepth(RM, -cStereo_Horizon);
  1194         DrawRepeated(sprHorizont, sprHorizontL, sprHorizontR, (WorldDx + LAND_WIDTH div 2) * 3 div 5, HorizontOffset);
  1405         DrawRepeated(sprHorizont, sprHorizontL, sprHorizontR, (WorldDx + LAND_WIDTH div 2) * 3 div 5, HorizontOffset);
  1195         if SuddenDeathDmg then
  1406         if SuddenDeathDmg then
  1196             Tint($FF, $FF, $FF, $FF);
  1407             untint;
  1197     end;
  1408     end;
  1198 
  1409 
  1199 DrawVisualGears(0);
  1410 DrawVisualGears(0);
  1200 ChangeDepth(RM, -cStereo_MidDistance);
  1411 ChangeDepth(RM, -cStereo_MidDistance);
  1201 DrawVisualGears(4);
  1412 DrawVisualGears(4);
  1302             DrawSpriteRotatedF(sprTargetP, TargetPoint.X + WorldDx, TargetPoint.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360)
  1513             DrawSpriteRotatedF(sprTargetP, TargetPoint.X + WorldDx, TargetPoint.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360)
  1303         end
  1514         end
  1304     end;
  1515     end;
  1305 {$WARNINGS ON}
  1516 {$WARNINGS ON}
  1306 
  1517 
  1307 if WorldEdge <> weNone then
  1518 RenderWorldEdge(Lag);
  1308     begin
       
  1309 (* 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. *)
       
  1310 
       
  1311     FillChar(WorldFade, sizeof(WorldFade), 0);
       
  1312     WorldFade[0].a:= 255;
       
  1313     WorldFade[1].a:= 255;
       
  1314     FillChar(WorldEnd, sizeof(WorldEnd), 0);
       
  1315     WorldEnd[0].a:= 255;
       
  1316     WorldEnd[1].a:= 255;
       
  1317     WorldEnd[2].a:= 255;
       
  1318     WorldEnd[3].a:= 255;
       
  1319 
       
  1320     glDisable(GL_TEXTURE_2D);
       
  1321     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
       
  1322     glEnableClientState(GL_COLOR_ARRAY);
       
  1323 
       
  1324     glPushMatrix;
       
  1325     glTranslatef(WorldDx, WorldDy, 0);
       
  1326     glColorPointer(4, GL_UNSIGNED_BYTE, 0, @WorldFade[0]);
       
  1327 
       
  1328     VertexBuffer[0].X:= leftX-20;
       
  1329     VertexBuffer[0].Y:= -3000;
       
  1330     VertexBuffer[1].X:= leftX-20;
       
  1331     VertexBuffer[1].Y:= cWaterLine+cVisibleWater;
       
  1332     VertexBuffer[2].X:= leftX+30;
       
  1333     VertexBuffer[2].Y:= cWaterLine+cVisibleWater;
       
  1334     VertexBuffer[3].X:= leftX+30;
       
  1335     VertexBuffer[3].Y:= -3000;
       
  1336 
       
  1337     glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
       
  1338     glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
       
  1339 
       
  1340     VertexBuffer[0].X:= rightX+20;
       
  1341     VertexBuffer[1].X:= rightX+20;
       
  1342     VertexBuffer[2].X:= rightX-30;
       
  1343     VertexBuffer[3].X:= rightX-30;
       
  1344 
       
  1345     glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
       
  1346     glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
       
  1347 
       
  1348     glColorPointer(4, GL_UNSIGNED_BYTE, 0, @WorldEnd[0]);
       
  1349 
       
  1350     VertexBuffer[0].X:= -5000;
       
  1351     VertexBuffer[1].X:= -5000;
       
  1352     VertexBuffer[2].X:= leftX-20;
       
  1353     VertexBuffer[3].X:= leftX-20;
       
  1354 
       
  1355     glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
       
  1356     glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
       
  1357 
       
  1358     VertexBuffer[0].X:= rightX+5000;
       
  1359     VertexBuffer[1].X:= rightX+5000;
       
  1360     VertexBuffer[2].X:= rightX+20;
       
  1361     VertexBuffer[3].X:= rightX+20;
       
  1362 
       
  1363     glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
       
  1364     glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
       
  1365 
       
  1366     glPopMatrix;
       
  1367     glDisableClientState(GL_COLOR_ARRAY);
       
  1368     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
       
  1369 
       
  1370     glColor4ub($FF, $FF, $FF, $FF); // must not be Tint() as color array seems to stay active and color reset is required
       
  1371     glEnable(GL_TEXTURE_2D);
       
  1372 
       
  1373     DrawLine(leftX, -3000, leftX, cWaterLine+cVisibleWater, 3.0, $FF, $00, $FF, $FF);
       
  1374     DrawLine(rightX, -3000, rightX, cWaterLine+cVisibleWater, 3.0, $FF, $00, $FF, $FF);
       
  1375     end;
       
  1376 
  1519 
  1377 // this scale is used to keep the various widgets at the same dimension at all zoom levels
  1520 // this scale is used to keep the various widgets at the same dimension at all zoom levels
  1378 SetScale(cDefaultZoomLevel);
  1521 SetScale(cDefaultZoomLevel);
  1379 
  1522 
  1380 // Turn time
  1523 // Turn time
       
  1524 if UIDisplay <> uiNone then
       
  1525     begin
  1381 {$IFDEF USE_TOUCH_INTERFACE}
  1526 {$IFDEF USE_TOUCH_INTERFACE}
  1382 offsetX:= cScreenHeight - 13;
  1527     offsetX:= cScreenHeight - 13;
  1383 {$ELSE}
  1528 {$ELSE}
  1384 offsetX:= 48;
  1529     offsetX:= 48;
  1385 {$ENDIF}
  1530 {$ENDIF}
  1386 offsetY:= cOffsetY;
  1531     offsetY:= cOffsetY;
  1387 if ((TurnTimeLeft <> 0) and (TurnTimeLeft < 1000000)) or (ReadyTimeLeft <> 0) then
  1532     if ((TurnTimeLeft <> 0) and (TurnTimeLeft < 1000000)) or (ReadyTimeLeft <> 0) then
  1388     begin
  1533         begin
  1389     if ReadyTimeLeft <> 0 then
  1534         if ReadyTimeLeft <> 0 then
  1390         i:= Succ(Pred(ReadyTimeLeft) div 1000)
  1535             i:= Succ(Pred(ReadyTimeLeft) div 1000)
  1391     else
  1536         else
  1392         i:= Succ(Pred(TurnTimeLeft) div 1000);
  1537             i:= Succ(Pred(TurnTimeLeft) div 1000);
  1393 
  1538        
  1394     if i>99 then
  1539         if i>99 then
  1395         t:= 112
  1540             t:= 112
  1396     else if i>9 then
  1541         else if i>9 then
  1397         t:= 96
  1542             t:= 96
  1398     else
  1543         else
  1399         t:= 80;
  1544             t:= 80;
  1400     DrawSprite(sprFrame, -(cScreenWidth shr 1) + t + offsetY, cScreenHeight - offsetX, 1);
  1545         DrawSprite(sprFrame, -(cScreenWidth shr 1) + t + offsetY, cScreenHeight - offsetX, 1);
  1401     while i > 0 do
  1546         while i > 0 do
  1402         begin
  1547             begin
  1403         dec(t, 32);
  1548             dec(t, 32);
  1404         DrawSprite(sprBigDigit, -(cScreenWidth shr 1) + t + offsetY, cScreenHeight - offsetX, i mod 10);
  1549             DrawSprite(sprBigDigit, -(cScreenWidth shr 1) + t + offsetY, cScreenHeight - offsetX, i mod 10);
  1405         i:= i div 10
  1550             i:= i div 10
       
  1551             end;
       
  1552         DrawSprite(sprFrame, -(cScreenWidth shr 1) + t - 4 + offsetY, cScreenHeight - offsetX, 0);
  1406         end;
  1553         end;
  1407     DrawSprite(sprFrame, -(cScreenWidth shr 1) + t - 4 + offsetY, cScreenHeight - offsetX, 0);
       
  1408     end;
       
  1409 
  1554 
  1410 // Captions
  1555 // Captions
  1411 DrawCaptions;
  1556     DrawCaptions
       
  1557     end;
  1412 
  1558 
  1413 {$IFDEF USE_TOUCH_INTERFACE}
  1559 {$IFDEF USE_TOUCH_INTERFACE}
  1414 // Draw buttons Related to the Touch interface
  1560 // Draw buttons Related to the Touch interface
  1415 DrawScreenWidget(@arrowLeft);
  1561 DrawScreenWidget(@arrowLeft);
  1416 DrawScreenWidget(@arrowRight);
  1562 DrawScreenWidget(@arrowRight);
  1422 DrawScreenWidget(@AMWidget);
  1568 DrawScreenWidget(@AMWidget);
  1423 DrawScreenWidget(@pauseButton);
  1569 DrawScreenWidget(@pauseButton);
  1424 DrawScreenWidget(@utilityWidget);
  1570 DrawScreenWidget(@utilityWidget);
  1425 {$ENDIF}
  1571 {$ENDIF}
  1426 
  1572 
  1427 // Teams Healths
  1573 if UIDisplay = uiAll then
  1428 if TeamsCount * 20 > Longword(cScreenHeight) div 7 then  // take up less screen on small displays
  1574     RenderTeamsHealth;
  1429     begin
       
  1430     SetScale(1.5);
       
  1431     smallScreenOffset:= cScreenHeight div 6;
       
  1432     if TeamsCount * 20 > Longword(cScreenHeight) div 5 then
       
  1433         Tint($FF,$FF,$FF,$80);
       
  1434     end
       
  1435 else smallScreenOffset:= 0;
       
  1436 for t:= 0 to Pred(TeamsCount) do
       
  1437     with TeamsArray[t]^ do
       
  1438       if TeamHealth > 0 then
       
  1439         begin
       
  1440         h:= 0;
       
  1441         highlight:= bShowFinger and (CurrentTeam = TeamsArray[t]) and ((RealTicks mod 1000) < 500);
       
  1442 
       
  1443         if highlight then
       
  1444             Tint(Clan^.Color shl 8 or $FF);
       
  1445 
       
  1446          // draw name
       
  1447         DrawTexture(-NameTagTex^.w - 16, cScreenHeight + DrawHealthY + smallScreenOffset, NameTagTex);
       
  1448 
       
  1449         // draw flag
       
  1450         DrawTexture(-14, cScreenHeight + DrawHealthY + smallScreenOffset, FlagTex);
       
  1451 
       
  1452         // draw health bar
       
  1453         r.x:= 0;
       
  1454         r.y:= 0;
       
  1455         r.w:= 2 + TeamHealthBarWidth;
       
  1456         r.h:= HealthTex^.h;
       
  1457         DrawTextureFromRect(14, cScreenHeight + DrawHealthY + smallScreenOffset, @r, HealthTex);
       
  1458 
       
  1459         // draw health bars right border
       
  1460         inc(r.x, cTeamHealthWidth + 2);
       
  1461         r.w:= 3;
       
  1462         DrawTextureFromRect(TeamHealthBarWidth + 15, cScreenHeight + DrawHealthY + smallScreenOffset, @r, HealthTex);
       
  1463 
       
  1464         if (not highlight) and (not hasGone) then
       
  1465             for i:= 0 to cMaxHHIndex do
       
  1466                 if Hedgehogs[i].Gear <> nil then
       
  1467                     begin
       
  1468                     inc(h,Hedgehogs[i].Gear^.Health);
       
  1469                     if h < TeamHealth then DrawTexture(15 + h*TeamHealthBarWidth div TeamHealth, cScreenHeight + DrawHealthY + smallScreenOffset + 1, SpritesData[sprSlider].Texture);
       
  1470                     end;
       
  1471 
       
  1472         // draw ai kill counter for gfAISurvival
       
  1473         if (GameFlags and gfAISurvival) <> 0 then
       
  1474             begin
       
  1475             DrawTexture(TeamHealthBarWidth + 22, cScreenHeight + DrawHealthY + smallScreenOffset, AIKillsTex);
       
  1476             end;
       
  1477 
       
  1478         // if highlighted, draw flag and other contents again to keep their colors
       
  1479         // this approach should be faster than drawing all borders one by one tinted or not
       
  1480         if highlight then
       
  1481             begin
       
  1482             if TeamsCount * 20 > Longword(cScreenHeight) div 5 then
       
  1483                 Tint($FF,$FF,$FF,$80)
       
  1484             else Tint($FF, $FF, $FF, $FF);
       
  1485 
       
  1486             // draw name
       
  1487             r.x:= 2;
       
  1488             r.y:= 2;
       
  1489             r.w:= NameTagTex^.w - 4;
       
  1490             r.h:= NameTagTex^.h - 4;
       
  1491             DrawTextureFromRect(-NameTagTex^.w - 14, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, NameTagTex);
       
  1492             // draw flag
       
  1493             r.w:= 22;
       
  1494             r.h:= 15;
       
  1495             DrawTextureFromRect(-12, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, FlagTex);
       
  1496             // draw health bar
       
  1497             r.w:= TeamHealthBarWidth + 1;
       
  1498             r.h:= HealthTex^.h - 4;
       
  1499             DrawTextureFromRect(15, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, HealthTex);
       
  1500             if not hasGone and (TeamHealth > 1) then
       
  1501                 begin
       
  1502                 Tint(Clan^.Color shl 8 or $FF);
       
  1503                 for i:= 0 to cMaxHHIndex do
       
  1504                     if Hedgehogs[i].Gear <> nil then
       
  1505                         begin
       
  1506                         inc(h,Hedgehogs[i].Gear^.Health);
       
  1507                         if h < TeamHealth then DrawTexture(15 + h*TeamHealthBarWidth div TeamHealth, cScreenHeight + DrawHealthY + smallScreenOffset + 1, SpritesData[sprSlider].Texture);
       
  1508                         end;
       
  1509                 if TeamsCount * 20 > Longword(cScreenHeight) div 5 then
       
  1510                     Tint($FF,$FF,$FF,$80)
       
  1511                 else Tint($FF, $FF, $FF, $FF);
       
  1512                 end;
       
  1513             end;
       
  1514         end;
       
  1515 if smallScreenOffset <> 0 then
       
  1516     begin
       
  1517     SetScale(cDefaultZoomLevel);
       
  1518     if TeamsCount * 20 > Longword(cScreenHeight) div 5 then
       
  1519         Tint($FF,$FF,$FF,$FF);
       
  1520     end;
       
  1521 
  1575 
  1522 // Lag alert
  1576 // Lag alert
  1523 if isInLag then
  1577 if isInLag then
  1524     DrawSprite(sprLag, 32 - (cScreenWidth shr 1), 32, (RealTicks shr 7) mod 12);
  1578     DrawSprite(sprLag, 32 - (cScreenWidth shr 1), 32, (RealTicks shr 7) mod 12);
  1525 
  1579 
  1526 // Wind bar
  1580 // Wind bar
       
  1581 if UIDisplay <> uiNone then
       
  1582     begin
  1527 {$IFDEF USE_TOUCH_INTERFACE}
  1583 {$IFDEF USE_TOUCH_INTERFACE}
  1528     offsetX:= cScreenHeight - 13;
  1584     offsetX:= cScreenHeight - 13;
  1529     offsetY:= (cScreenWidth shr 1) + 74;
  1585     offsetY:= (cScreenWidth shr 1) + 74;
  1530 {$ELSE}
  1586 {$ELSE}
  1531     offsetX:= 30;
  1587     offsetX:= 30;
  1543         DrawSpriteFromRect(sprWindR, r, (cScreenWidth shr 1) - offsetY + 77, cScreenHeight - offsetX + 2, 13, 0);
  1599         DrawSpriteFromRect(sprWindR, r, (cScreenWidth shr 1) - offsetY + 77, cScreenHeight - offsetX + 2, 13, 0);
  1544         end
  1600         end
  1545     else
  1601     else
  1546         if WindBarWidth < 0 then
  1602         if WindBarWidth < 0 then
  1547         begin
  1603         begin
  1548             {$WARNINGS OFF}
  1604         {$WARNINGS OFF}
  1549             r.x:= (Longword(WindBarWidth) + RealTicks shr 6) mod 8;
  1605         r.x:= (Longword(WindBarWidth) + RealTicks shr 6) mod 8;
  1550             {$WARNINGS ON}
  1606         {$WARNINGS ON}
  1551             r.y:= 0;
  1607         r.y:= 0;
  1552             r.w:= - WindBarWidth;
  1608         r.w:= - WindBarWidth;
  1553             r.h:= 13;
  1609         r.h:= 13;
  1554             DrawSpriteFromRect(sprWindL, r, (cScreenWidth shr 1) - offsetY + 74 + WindBarWidth, cScreenHeight - offsetX + 2, 13, 0);
  1610         DrawSpriteFromRect(sprWindL, r, (cScreenWidth shr 1) - offsetY + 74 + WindBarWidth, cScreenHeight - offsetX + 2, 13, 0);
  1555         end;
  1611         end
       
  1612     end;
  1556 
  1613 
  1557 // AmmoMenu
  1614 // AmmoMenu
  1558 if bShowAmmoMenu and ((AMState = AMHidden) or (AMState = AMHiding)) then
  1615 if bShowAmmoMenu and ((AMState = AMHidden) or (AMState = AMHiding)) then
  1559     begin
  1616     begin
  1560     if (AMState = AMHidden) then
  1617     if (AMState = AMHidden) then
  1586 // various captions
  1643 // various captions
  1587 if fastUntilLag then
  1644 if fastUntilLag then
  1588     DrawTextureCentered(0, (cScreenHeight shr 1), SyncTexture);
  1645     DrawTextureCentered(0, (cScreenHeight shr 1), SyncTexture);
  1589 if isPaused then
  1646 if isPaused then
  1590     DrawTextureCentered(0, (cScreenHeight shr 1), PauseTexture);
  1647     DrawTextureCentered(0, (cScreenHeight shr 1), PauseTexture);
  1591 if (not isFirstFrame) and (missionTimer <> 0) or isPaused or fastUntilLag or (GameState = gsConfirm) then
  1648 if isAFK then
       
  1649     DrawTextureCentered(0, (cScreenHeight shr 1), AFKTexture);
       
  1650 if not isFirstFrame and (missionTimer <> 0) or isPaused or fastUntilLag or (GameState = gsConfirm) then
  1592     begin
  1651     begin
  1593     if (ReadyTimeLeft = 0) and (missionTimer > 0) then
  1652     if (ReadyTimeLeft = 0) and (missionTimer > 0) then
  1594         dec(missionTimer, Lag);
  1653         dec(missionTimer, Lag);
  1595     if missionTimer < 0 then
  1654     if missionTimer < 0 then
  1596         missionTimer:= 0; // avoid subtracting below 0
  1655         missionTimer:= 0; // avoid subtracting below 0
  1692 
  1751 
  1693         glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
  1752         glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
  1694         glDrawArrays(GL_TRIANGLE_FAN, 0, High(VertexBuffer) - Low(VertexBuffer) + 1);
  1753         glDrawArrays(GL_TRIANGLE_FAN, 0, High(VertexBuffer) - Low(VertexBuffer) + 1);
  1695 
  1754 
  1696         glEnable(GL_TEXTURE_2D);
  1755         glEnable(GL_TEXTURE_2D);
  1697         Tint($FF, $FF, $FF, $FF);
  1756         untint;
  1698         if (not isFirstFrame) and ((ScreenFadeValue = 0) or (ScreenFadeValue = sfMax)) then
  1757         if not isFirstFrame and ((ScreenFadeValue = 0) or (ScreenFadeValue = sfMax)) then
  1699             ScreenFade:= sfNone
  1758             ScreenFade:= sfNone
  1700         end
  1759         end
  1701     end;
  1760     end;
  1702 
  1761 
  1703 {$IFDEF USE_VIDEO_RECORDING}
  1762 {$IFDEF USE_VIDEO_RECORDING}
  1720     Tint($FF, $00, $00, Byte(Round(127*(1 + sin(SDL_GetTicks()*0.007)))));
  1779     Tint($FF, $00, $00, Byte(Round(127*(1 + sin(SDL_GetTicks()*0.007)))));
  1721     glBegin(GL_POLYGON);
  1780     glBegin(GL_POLYGON);
  1722     for i:= 0 to 20 do
  1781     for i:= 0 to 20 do
  1723         glVertex2f(-(cScreenWidth shr 1) + 30 + sin(i*2*Pi/20)*10, 35 + cos(i*2*Pi/20)*10);
  1782         glVertex2f(-(cScreenWidth shr 1) + 30 + sin(i*2*Pi/20)*10, 35 + cos(i*2*Pi/20)*10);
  1724     glEnd();
  1783     glEnd();
  1725     Tint($FF, $FF, $FF, $FF);
  1784     untint;
  1726     glEnable(GL_TEXTURE_2D);
  1785     glEnable(GL_TEXTURE_2D);
  1727     end;
  1786     end;
  1728 {$ENDIF}
  1787 {$ENDIF}
  1729 
  1788 
  1730 SetScale(zoom);
  1789 SetScale(zoom);
  1777 
  1836 
  1778 var PrevSentPointTime: LongWord = 0;
  1837 var PrevSentPointTime: LongWord = 0;
  1779 
  1838 
  1780 procedure MoveCamera;
  1839 procedure MoveCamera;
  1781 var EdgesDist, wdy, shs,z, amNumOffsetX, amNumOffsetY: LongInt;
  1840 var EdgesDist, wdy, shs,z, amNumOffsetX, amNumOffsetY: LongInt;
       
  1841     inbtwnTrgtAttks: Boolean;
  1782 begin
  1842 begin
  1783 {$IFNDEF MOBILE}
  1843 {$IFNDEF MOBILE}
  1784 if (not (CurrentTeam^.ExtDriven and isCursorVisible and (not bShowAmmoMenu) and autoCameraOn)) and cHasFocus and (GameState <> gsConfirm) then
  1844 if (not (CurrentTeam^.ExtDriven and isCursorVisible and (not bShowAmmoMenu) and autoCameraOn)) and cHasFocus and (GameState <> gsConfirm) then
  1785     uCursor.updatePosition();
  1845     uCursor.updatePosition();
  1786 {$ENDIF}
  1846 {$ENDIF}
  1787 z:= round(200/zoom);
  1847 z:= round(200/zoom);
  1788 if (not PlacingHogs) and (FollowGear <> nil) and (not isCursorVisible) and (not bShowAmmoMenu) and (not fastUntilLag) and autoCameraOn then
  1848 inbtwnTrgtAttks := (CurrentHedgehog <> nil) and ((Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_NeedTarget) <> 0) and ((GameFlags and gfInfAttack) <> 0);
       
  1849 if autoCameraOn and not PlacingHogs and (FollowGear <> nil) and (not isCursorVisible) and (not bShowAmmoMenu) and (not fastUntilLag) and not inbtwnTrgtAttks then
  1789     if ((abs(CursorPoint.X - prevPoint.X) + abs(CursorPoint.Y - prevpoint.Y)) > 4) then
  1850     if ((abs(CursorPoint.X - prevPoint.X) + abs(CursorPoint.Y - prevpoint.Y)) > 4) then
  1790         begin
  1851         begin
  1791         FollowGear:= nil;
  1852         FollowGear:= nil;
  1792         prevPoint:= CursorPoint;
  1853         prevPoint:= CursorPoint;
  1793         exit
  1854         exit
  2038     cOffsetY:= 0;
  2099     cOffsetY:= 0;
  2039     stereoDepth:= 0;
  2100     stereoDepth:= 0;
  2040     AMState:= AMHidden;
  2101     AMState:= AMHidden;
  2041     isFirstFrame:= true;
  2102     isFirstFrame:= true;
  2042     stereoDepth:= stereoDepth; // avoid hint
  2103     stereoDepth:= stereoDepth; // avoid hint
       
  2104 
       
  2105     FillChar(WorldFade, sizeof(WorldFade), 0);
       
  2106     WorldFade[0].a:= 255;
       
  2107     WorldFade[1].a:= 255;
       
  2108     FillChar(WorldEnd, sizeof(WorldEnd), 0);
       
  2109     WorldEnd[0].a:= 255;
       
  2110     WorldEnd[1].a:= 255;
       
  2111     WorldEnd[2].a:= 255;
       
  2112     WorldEnd[3].a:= 255;
       
  2113 
  2043 end;
  2114 end;
  2044 
  2115 
  2045 procedure freeModule;
  2116 procedure freeModule;
  2046 begin
  2117 begin
  2047     ResetWorldTex();
  2118     ResetWorldTex();