289
310
y:= cScreenHeight - AMyOffset;
290
311
DrawSprite(sprAMCorners, x - BORDERSIZE, y, 2);
291
312
for i:= 0 to cMaxSlotAmmoIndex + 1 do
292
DrawSprite(sprAMBorderHorizontal, x + i * AMSlotSize, y, 1);
313
DrawSprite(sprAMBorderHorizontal, x + i * AMSlotSize, y, 1);
293
314
DrawSprite(sprAMCorners, x + AMWidth - AMxOffset, y, 3);
294
315
dec(y, AMSlotSize);
295
316
DrawSprite(sprAMBorderVertical, x - BORDERSIZE, y, 0);
296
317
for i:= 0 to cMaxSlotAmmoIndex do
297
DrawSprite(sprAMSlot, x + i * AMSlotSize, y, 2);
318
DrawSprite(sprAMSlot, x + i * AMSlotSize, y, 2);
298
319
DrawSprite(sprAMSlot, x + (cMaxSlotAmmoIndex + 1) * AMSlotSize, y, 1);
299
320
DrawSprite(sprAMBorderVertical, x + AMWidth - AMxOffset, y, 1);
437
471
procedure DrawWaves(Dir, dX, dY: LongInt; tnt: Byte);
438
472
var VertexBuffer, TextureBuffer: array [0..3] of TVertex2f;
439
473
lw, waves, shift: GLfloat;
476
if SuddenDeathDmg then
481
cWaveWidth:= SpritesData[sprite].Width;
441
483
lw:= cScreenWidth / cScaleFactor;
442
484
waves:= lw * 2 / cWaveWidth;
444
Tint(LongInt(tnt) * WaterColorArray[2].r div 255 + 255 - tnt,
445
LongInt(tnt) * WaterColorArray[2].g div 255 + 255 - tnt,
446
LongInt(tnt) * WaterColorArray[2].b div 255 + 255 - tnt,
486
if SuddenDeathDmg then
487
Tint(LongInt(tnt) * SDWaterColorArray[2].r div 255 + 255 - tnt,
488
LongInt(tnt) * SDWaterColorArray[2].g div 255 + 255 - tnt,
489
LongInt(tnt) * SDWaterColorArray[2].b div 255 + 255 - tnt,
493
Tint(LongInt(tnt) * WaterColorArray[2].r div 255 + 255 - tnt,
494
LongInt(tnt) * WaterColorArray[2].g div 255 + 255 - tnt,
495
LongInt(tnt) * WaterColorArray[2].b div 255 + 255 - tnt,
450
glBindTexture(GL_TEXTURE_2D, SpritesData[sprWater].Texture^.id);
499
glBindTexture(GL_TEXTURE_2D, SpritesData[sprite].Texture^.id);
452
501
VertexBuffer[0].X:= -lw;
453
502
VertexBuffer[0].Y:= cWaterLine + WorldDy + dY;
454
503
VertexBuffer[1].X:= lw;
455
504
VertexBuffer[1].Y:= VertexBuffer[0].Y;
456
505
VertexBuffer[2].X:= lw;
457
VertexBuffer[2].Y:= VertexBuffer[0].Y + SpritesData[sprWater].Height;
506
VertexBuffer[2].Y:= VertexBuffer[0].Y + SpritesData[sprite].Height;
458
507
VertexBuffer[3].X:= -lw;
459
508
VertexBuffer[3].Y:= VertexBuffer[2].Y;
562
604
if not isPaused then
607
if cStereoMode = smNone then
609
glClear(GL_COLOR_BUFFER_BIT);
610
DrawWorldStereo(Lag, rmDefault)
612
{$IFNDEF S3D_DISABLED}
613
else if (cStereoMode = smAFR) then
615
AFRToggle:= not AFRToggle;
616
glClear(GL_COLOR_BUFFER_BIT);
618
DrawWorldStereo(Lag, rmLeftEye)
620
DrawWorldStereo(Lag, rmRightEye)
622
else if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) then
625
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framel);
626
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
627
DrawWorldStereo(Lag, rmLeftEye);
630
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framer);
631
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
632
DrawWorldStereo(0, rmRightEye);
634
// detatch drawing from fbs
635
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
636
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
637
SetScale(cDefaultZoomLevel);
640
glBindTexture(GL_TEXTURE_2D, texl);
642
if cStereoMode = smHorizontal then
644
glTexCoord2f(0.0, 0.0);
645
glVertex2d(cScreenWidth / -2, cScreenHeight);
646
glTexCoord2f(1.0, 0.0);
647
glVertex2d(0, cScreenHeight);
648
glTexCoord2f(1.0, 1.0);
650
glTexCoord2f(0.0, 1.0);
651
glVertex2d(cScreenWidth / -2, 0);
655
glTexCoord2f(0.0, 0.0);
656
glVertex2d(cScreenWidth / -2, cScreenHeight / 2);
657
glTexCoord2f(1.0, 0.0);
658
glVertex2d(cScreenWidth / 2, cScreenHeight / 2);
659
glTexCoord2f(1.0, 1.0);
660
glVertex2d(cScreenWidth / 2, 0);
661
glTexCoord2f(0.0, 1.0);
662
glVertex2d(cScreenWidth / -2, 0);
667
glBindTexture(GL_TEXTURE_2D, texr);
669
if cStereoMode = smHorizontal then
671
glTexCoord2f(0.0, 0.0);
672
glVertex2d(0, cScreenHeight);
673
glTexCoord2f(1.0, 0.0);
674
glVertex2d(cScreenWidth / 2, cScreenHeight);
675
glTexCoord2f(1.0, 1.0);
676
glVertex2d(cScreenWidth / 2, 0);
677
glTexCoord2f(0.0, 1.0);
682
glTexCoord2f(0.0, 0.0);
683
glVertex2d(cScreenWidth / -2, cScreenHeight);
684
glTexCoord2f(1.0, 0.0);
685
glVertex2d(cScreenWidth / 2, cScreenHeight);
686
glTexCoord2f(1.0, 1.0);
687
glVertex2d(cScreenWidth / 2, cScreenHeight / 2);
688
glTexCoord2f(0.0, 1.0);
689
glVertex2d(cScreenWidth / -2, cScreenHeight / 2);
697
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
698
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
699
// draw left eye in red channel only
700
if cStereoMode = smGreenRed then
701
glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE)
702
else if cStereoMode = smBlueRed then
703
glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE)
704
else if cStereoMode = smCyanRed then
705
glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE)
707
glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE);
708
DrawWorldStereo(Lag, rmLeftEye);
709
// draw right eye in selected channel(s) only
710
if cStereoMode = smRedGreen then
711
glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE)
712
else if cStereoMode = smRedBlue then
713
glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE)
714
else if cStereoMode = smRedCyan then
715
glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE)
717
glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE);
718
DrawWorldStereo(Lag, rmRightEye);
723
procedure ChangeDepth(rm: TRenderMode; d: GLfloat);
725
{$IFDEF S3D_DISABLED}
726
rm:= rm; d:= d; // avoid hint
730
if rm = rmDefault then exit
731
else if rm = rmLeftEye then d:= -d;
732
stereoDepth:= stereoDepth + d;
733
glMatrixMode(GL_PROJECTION);
734
glTranslatef(d, 0, 0);
735
glMatrixMode(GL_MODELVIEW);
739
procedure ResetDepth(rm: TRenderMode);
741
{$IFDEF S3D_DISABLED}
742
rm:= rm; // avoid hint
745
if rm = rmDefault then exit;
746
glMatrixMode(GL_PROJECTION);
747
glTranslatef(-stereoDepth, 0, 0);
748
glMatrixMode(GL_MODELVIEW);
753
procedure DrawWorldStereo(Lag: LongInt; RM: TRenderMode);
759
smallScreenOffset, offsetX, offsetY, screenBottom: LongInt;
760
VertexBuffer: array [0..3] of TVertex2f;
565
762
if (cReducedQuality and rqNoBackground) = 0 then
567
764
// Offsets relative to camera - spare them to wimpier cpus, no bg or flakes for them anyway
582
783
if (cReducedQuality and rq2DWater) = 0 then
585
DrawWater(255, SkyOffset);
786
DrawWater(255, SkyOffset);
787
ChangeDepth(RM, -cStereo_Water_distant);
586
788
DrawWaves( 1, 0 - WorldDx div 32, - cWaveHeight + offsetY div 35, 64);
789
ChangeDepth(RM, -cStereo_Water_distant);
587
790
DrawWaves( -1, 25 + WorldDx div 25, - cWaveHeight + offsetY div 38, 48);
791
ChangeDepth(RM, -cStereo_Water_distant);
588
792
DrawWaves( 1, 75 - WorldDx div 19, - cWaveHeight + offsetY div 45, 32);
793
ChangeDepth(RM, -cStereo_Water_distant);
589
794
DrawWaves(-1, 100 + WorldDx div 14, - cWaveHeight + offsetY div 70, 24);
592
797
DrawWaves(-1, 100, - (cWaveHeight + (cWaveHeight shr 1)), 0);
799
changeDepth(RM, cStereo_Land);
594
800
DrawLand(WorldDx, WorldDy);
596
802
DrawWater(255, 0);
620
826
DrawVisualGears(1);
626
DrawWater(cWaterOpacity, 0);
829
if SuddenDeathDmg then
830
DrawWater(cSDWaterOpacity, 0)
832
DrawWater(cWaterOpacity, 0);
835
ChangeDepth(RM, cStereo_Water_near);
629
836
DrawWaves( 1, 25 - WorldDx div 9, - cWaveHeight, 12);
631
838
if (cReducedQuality and rq2DWater) = 0 then
633
840
//DrawWater(cWaterOpacity, - offsetY div 40);
841
ChangeDepth(RM, cStereo_Water_near);
634
842
DrawWaves(-1, 50 + WorldDx div 6, - cWaveHeight - offsetY div 40, 8);
635
DrawWater(cWaterOpacity, - offsetY div 20);
843
if SuddenDeathDmg then
844
DrawWater(cSDWaterOpacity, - offsetY div 20)
846
DrawWater(cWaterOpacity, - offsetY div 20);
847
ChangeDepth(RM, cStereo_Water_near);
636
848
DrawWaves( 1, 75 - WorldDx div 4, - cWaveHeight - offsetY div 20, 2);
637
DrawWater(cWaterOpacity, - offsetY div 10);
849
if SuddenDeathDmg then
850
DrawWater(cSDWaterOpacity, - offsetY div 10)
852
DrawWater(cWaterOpacity, - offsetY div 10);
853
ChangeDepth(RM, cStereo_Water_near);
638
854
DrawWaves( -1, 25 + WorldDx div 3, - cWaveHeight - offsetY div 10, 0);
641
857
DrawWaves(-1, 50, - (cWaveHeight shr 1), 0);
859
// everything after this ChangeDepth will be drawn outside the screen
860
// note: negative parallax gears should last very little for a smooth stereo effect
861
ChangeDepth(RM, cStereo_Outside);
864
// everything after this ResetDepth will be drawn at screen level (depth = 0)
865
// note: everything that needs to be readable should be on this level
686
910
DrawSprite(sprFrame, -(cScreenWidth shr 1) + t - 4 + offsetY, cScreenHeight - offsetX, 0);
691
if ((TrainingFlags and tfTimeTrial) <> 0) and (TimeTrialStartTime > 0) then
693
if TimeTrialStopTime = 0 then i:= RealTicks - TimeTrialStartTime else i:= TimeTrialStopTime - TimeTrialStartTime;
696
DrawSprite(sprFrame, -cScreenWidth div 2 + t, 8, 1);
699
DrawSprite(sprBigDigit, -cScreenWidth div 2 + t, 8, i mod 10);
703
DrawSprite(sprBigDigit, -cScreenWidth div 2 + t, 8, i mod 10);
707
DrawSprite(sprBigDigit, -cScreenWidth div 2 + t, 8, i mod 10);
710
DrawSprite(sprBigDigit, -cScreenWidth div 2 + t, 8, 11);
714
DrawSprite(sprBigDigit, -cScreenWidth div 2 + t, 8, i mod 10);
718
DrawSprite(sprBigDigit, -cScreenWidth div 2 + t, 8, i mod 6);
721
DrawSprite(sprBigDigit, -cScreenWidth div 2 + t, 8, 10);
725
DrawSprite(sprBigDigit, -cScreenWidth div 2 + t, 8, i mod 10);
729
DrawSprite(sprBigDigit, -cScreenWidth div 2 + t, 8, i mod 10);
731
DrawSprite(sprFrame, -cScreenWidth div 2 + t - 4, 8, 0);
917
if TeamsCount * 20 > cScreenHeight div 7 then // take up less screen on small displays
920
smallScreenOffset:= cScreenHeight div 6;
921
if TeamsCount * 20 > cScreenHeight div 5 then Tint($FF,$FF,$FF,$80);
923
else smallScreenOffset:= 0;
739
924
for t:= 0 to Pred(TeamsCount) do
740
925
with TeamsArray[t]^ do
742
927
highlight:= bShowFinger and (CurrentTeam = TeamsArray[t]) and ((RealTicks mod 1000) < 500);
744
929
if highlight then
930
Tint(Clan^.Color shl 8 or $FF);
748
DrawTexture(-NameTagTex^.w - 16, cScreenHeight + DrawHealthY, NameTagTex);
933
DrawTexture(-NameTagTex^.w - 16, cScreenHeight + DrawHealthY + smallScreenOffset, NameTagTex);
751
DrawTexture(-14, cScreenHeight + DrawHealthY, FlagTex);
936
DrawTexture(-14, cScreenHeight + DrawHealthY + smallScreenOffset, FlagTex);
753
938
// draw health bar
756
941
r.w:= 2 + TeamHealthBarWidth;
757
942
r.h:= HealthTex^.h;
758
DrawFromRect(14, cScreenHeight + DrawHealthY, @r, HealthTex);
943
DrawFromRect(14, cScreenHeight + DrawHealthY + smallScreenOffset, @r, HealthTex);
760
// draw health bar's right border
945
// draw health bars right border
761
946
inc(r.x, cTeamHealthWidth + 2);
763
DrawFromRect(TeamHealthBarWidth + 16, cScreenHeight + DrawHealthY, @r, HealthTex);
948
DrawFromRect(TeamHealthBarWidth + 16, cScreenHeight + DrawHealthY + smallScreenOffset, @r, HealthTex);
765
950
// draw ai kill counter for gfAISurvival
766
951
if (GameFlags and gfAISurvival) <> 0 then begin
767
DrawTexture(TeamHealthBarWidth + 22, cScreenHeight + DrawHealthY,
952
DrawTexture(TeamHealthBarWidth + 22, cScreenHeight + DrawHealthY + smallScreenOffset,
772
957
// this approach should be faster than drawing all borders one by one tinted or not
773
958
if highlight then
775
Tint($FF, $FF, $FF, $FF);
960
if TeamsCount * 20 > cScreenHeight div 5 then Tint($FF,$FF,$FF,$80)
961
else Tint($FF, $FF, $FF, $FF);
780
966
r.w:= NameTagTex^.w - 4;
781
967
r.h:= NameTagTex^.h - 4;
782
DrawFromRect(-NameTagTex^.w - 14, cScreenHeight + DrawHealthY + 2, @r, NameTagTex);
968
DrawFromRect(-NameTagTex^.w - 14, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, NameTagTex);
786
DrawFromRect(-12, cScreenHeight + DrawHealthY + 2, @r, FlagTex);
972
DrawFromRect(-12, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, FlagTex);
787
973
// draw health bar
788
974
r.w:= TeamHealthBarWidth + 1;
789
975
r.h:= HealthTex^.h - 4;
790
DrawFromRect(16, cScreenHeight + DrawHealthY + 2, @r, HealthTex);
976
DrawFromRect(16, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, HealthTex);
979
if smallScreenOffset <> 0 then
981
SetScale(cDefaultZoomLevel);
982
if TeamsCount * 20 > cScreenHeight div 5 then Tint($FF,$FF,$FF,$FF);
795
986
if isInLag then DrawSprite(sprLag, 32 - (cScreenWidth shr 1), 32, (RealTicks shr 7) mod 12);
853
1046
offsetY:= cOffsetY;
856
if cShowFPS or (GameType = gmtDemo) then inc(CountTicks, Lag);
857
if (GameType = gmtDemo) and (CountTicks >= 1000) then
859
i:=GameTicks div 1000;
862
if t < 10 then s:= '0' + s;
865
s:= inttostr(t) + ':' + s;
866
if t < 10 then s:= '0' + s;
867
s:= inttostr(i div 60) + ':' + s;
869
if timeTexture <> nil then
870
FreeTexture(timeTexture);
873
tmpSurface:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(s), cWhiteColorChannels);
874
tmpSurface:= doSurfaceConversion(tmpSurface);
875
timeTexture:= Surface2Tex(tmpSurface, false);
876
SDL_FreeSurface(tmpSurface)
879
if timeTexture <> nil then
880
DrawTexture((cScreenWidth shr 1) - 20 - timeTexture^.w - offsetY, offsetX + timeTexture^.h+5, timeTexture);
884
if CountTicks >= 1000 then
889
s:= inttostr(FPS) + ' fps';
890
if fpsTexture <> nil then
891
FreeTexture(fpsTexture);
893
tmpSurface:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(s), cWhiteColorChannels);
894
tmpSurface:= doSurfaceConversion(tmpSurface);
895
fpsTexture:= Surface2Tex(tmpSurface, false);
896
SDL_FreeSurface(tmpSurface)
898
if fpsTexture <> nil then
899
DrawTexture((cScreenWidth shr 1) - 60 - offsetY, offsetX, fpsTexture);
902
if CountTicks >= 1000 then CountTicks:= 0;
905
inc(SoundTimerTicks, Lag);
1047
if (RM = rmDefault) or (RM = rmRightEye) then
1051
if cShowFPS or (GameType = gmtDemo) then
1052
inc(CountTicks, Lag);
1053
if (GameType = gmtDemo) and (CountTicks >= 1000) then
1055
i:=GameTicks div 1000;
1058
if t < 10 then s:= '0' + s;
1061
s:= inttostr(t) + ':' + s;
1062
if t < 10 then s:= '0' + s;
1063
s:= inttostr(i div 60) + ':' + s;
1065
if timeTexture <> nil then
1066
FreeTexture(timeTexture);
1069
tmpSurface:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(s), cWhiteColorChannels);
1070
tmpSurface:= doSurfaceConversion(tmpSurface);
1071
timeTexture:= Surface2Tex(tmpSurface, false);
1072
SDL_FreeSurface(tmpSurface)
1075
if timeTexture <> nil then
1076
DrawTexture((cScreenWidth shr 1) - 20 - timeTexture^.w - offsetY, offsetX + timeTexture^.h+5, timeTexture);
1080
if CountTicks >= 1000 then
1085
s:= inttostr(FPS) + ' fps';
1086
if fpsTexture <> nil then
1087
FreeTexture(fpsTexture);
1089
tmpSurface:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(s), cWhiteColorChannels);
1090
tmpSurface:= doSurfaceConversion(tmpSurface);
1091
fpsTexture:= Surface2Tex(tmpSurface, false);
1092
SDL_FreeSurface(tmpSurface)
1094
if fpsTexture <> nil then
1095
DrawTexture((cScreenWidth shr 1) - 60 - offsetY, offsetX, fpsTexture);
1098
if CountTicks >= 1000 then CountTicks:= 0;
1101
inc(SoundTimerTicks, Lag);
906
1104
if SoundTimerTicks >= 50 then
908
1106
SoundTimerTicks:= 0;