hedgewars/uWorld.pas
changeset 3693 09892cdb8f95
parent 3680 aaf832c6fbd7
parent 3691 34fe2149f75d
child 3695 c11abf387a7d
equal deleted inserted replaced
3680:aaf832c6fbd7 3693:09892cdb8f95
    20 
    20 
    21 unit uWorld;
    21 unit uWorld;
    22 interface
    22 interface
    23 uses SDLh, uGears, uConsts, uFloat, uRandom;
    23 uses SDLh, uGears, uConsts, uFloat, uRandom;
    24 
    24 
       
    25 type TRenderMode = (rmDefault, rmLeftEye, rmRightEye);
    25 
    26 
    26 var FollowGear: PGear;
    27 var FollowGear: PGear;
    27     WindBarWidth: LongInt;
    28     WindBarWidth: LongInt;
    28     bShowAmmoMenu: boolean;
    29     bShowAmmoMenu: boolean;
    29     bSelected: boolean;
    30     bSelected: boolean;
    42 procedure initModule;
    43 procedure initModule;
    43 procedure freeModule;
    44 procedure freeModule;
    44 
    45 
    45 procedure InitWorld;
    46 procedure InitWorld;
    46 procedure DrawWorld(Lag: LongInt);
    47 procedure DrawWorld(Lag: LongInt);
       
    48 procedure DrawWorldStereo(Lag: LongInt; RM: TRenderMode);
    47 procedure AddCaption(s: shortstring; Color: Longword; Group: TCapGroup);
    49 procedure AddCaption(s: shortstring; Color: Longword; Group: TCapGroup);
    48 procedure ShowMission(caption, subcaption, text: ansistring; icon, time : LongInt);
    50 procedure ShowMission(caption, subcaption, text: ansistring; icon, time : LongInt);
    49 procedure HideMission;
    51 procedure HideMission;
    50 procedure ShakeCamera(amount: LongWord);
    52 procedure ShakeCamera(amount: LongWord);
    51 procedure MoveCamera;
    53 procedure MoveCamera;
    69     SoundTimerTicks: Longword;
    71     SoundTimerTicks: Longword;
    70     prevPoint: TPoint;
    72     prevPoint: TPoint;
    71     amSel: TAmmoType = amNothing;
    73     amSel: TAmmoType = amNothing;
    72     missionTex: PTexture;
    74     missionTex: PTexture;
    73     missionTimer: LongInt;
    75     missionTimer: LongInt;
       
    76     stereoDepth: GLfloat = 0;
       
    77 
       
    78 const cStereo_Sky     = 0.0750;
       
    79       cStereo_Horizon = 0.0250;
       
    80       cStereo_Water   = 0.0125;
    74 
    81 
    75 procedure InitWorld;
    82 procedure InitWorld;
    76 var i, t: LongInt;
    83 var i, t: LongInt;
    77     cp: PClan;
    84     cp: PClan;
    78     g: ansistring;
    85     g: ansistring;
   526     end
   533     end
   527 end;
   534 end;
   528 
   535 
   529 
   536 
   530 procedure DrawWorld(Lag: LongInt);
   537 procedure DrawWorld(Lag: LongInt);
   531 var i, t: LongInt;
   538 var cc: array[0..3] of GLfloat;
   532     r: TSDL_Rect;
       
   533     tdx, tdy: Double;
       
   534     grp: TCapGroup;
       
   535     s: string[15];
       
   536     highlight: Boolean;
       
   537     offset, offsetX, offsetY, ScreenBottom: LongInt;
       
   538     VertexBuffer: array [0..3] of TVertex2f;
       
   539 begin
   539 begin
   540     if not isPaused then
   540     if not isPaused then
   541     begin
   541     begin
   542         if ZoomValue < zoom then
   542         if ZoomValue < zoom then
   543         begin
   543         begin
   562     //glScalef(1.0, 1.0, 1.0);
   562     //glScalef(1.0, 1.0, 1.0);
   563 
   563 
   564     if not isPaused then
   564     if not isPaused then
   565         MoveCamera;
   565         MoveCamera;
   566 
   566 
       
   567     if not isStereoEnabled then
       
   568     begin
       
   569         glClear(GL_COLOR_BUFFER_BIT);
       
   570         DrawWorldStereo(Lag, rmDefault)
       
   571     end
       
   572     else
       
   573     begin
       
   574         // create left fb
       
   575         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framel);
       
   576         glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
       
   577         DrawWorldStereo(Lag, rmLeftEye);
       
   578 
       
   579         // create right fb
       
   580         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framer);
       
   581         glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
       
   582         DrawWorldStereo(0, rmRightEye);
       
   583 
       
   584         // detatch drawing from fbs
       
   585         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
       
   586         glGetFloatv(GL_COLOR_CLEAR_VALUE, @cc);
       
   587         glClearColor(0, 0, 0, 0);
       
   588         glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
       
   589         glClearColor(cc[0], cc[1], cc[2], cc[3]);
       
   590         SetScale(cDefaultZoomLevel);
       
   591 
       
   592         // enable gl stuff
       
   593         glEnable(GL_TEXTURE_2D);
       
   594         glEnable(GL_BLEND);
       
   595         glBlendFunc(GL_ONE, GL_ONE);
       
   596 
       
   597         // draw left frame
       
   598         glBindTexture(GL_TEXTURE_2D, texl);
       
   599         glColor3f(0.0, 1.0, 1.0);
       
   600         glBegin(GL_QUADS);
       
   601             glTexCoord2f(0.0, 0.0);
       
   602             glVertex2d(cScreenWidth / -2, cScreenHeight);
       
   603             glTexCoord2f(1.0, 0.0);
       
   604             glVertex2d(cScreenWidth / 2, cScreenHeight);
       
   605             glTexCoord2f(1.0, 1.0);
       
   606             glVertex2d(cScreenWidth / 2, 0);
       
   607             glTexCoord2f(0.0, 1.0);
       
   608             glVertex2d(cScreenWidth / -2, 0);
       
   609         glEnd();
       
   610 
       
   611         // draw right frame
       
   612         glBindTexture(GL_TEXTURE_2D, texr);
       
   613         glColor3f(1.0, 0.0, 0.0);
       
   614         glBegin(GL_QUADS);
       
   615             glTexCoord2f(0.0, 0.0);
       
   616             glVertex2d(cScreenWidth / -2, cScreenHeight);
       
   617             glTexCoord2f(1.0, 0.0);
       
   618             glVertex2d(cScreenWidth / 2, cScreenHeight);
       
   619             glTexCoord2f(1.0, 1.0);
       
   620             glVertex2d(cScreenWidth / 2, 0);
       
   621             glTexCoord2f(0.0, 1.0);
       
   622             glVertex2d(cScreenWidth / -2, 0);
       
   623         glEnd();
       
   624 
       
   625         // reset
       
   626         glColor3f(1.0, 1.0, 1.0);
       
   627         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
       
   628         SetScale(zoom);
       
   629     end
       
   630 end;
       
   631 
       
   632 procedure ChangeDepth(rm: TRenderMode; d: GLfloat);
       
   633 begin
       
   634     if rm = rmDefault then exit
       
   635     else if rm = rmRightEye then d:= -d;
       
   636     stereoDepth:= stereoDepth + d;
       
   637     glMatrixMode(GL_PROJECTION);
       
   638     glTranslatef(d, 0, 0);
       
   639     glMatrixMode(GL_MODELVIEW)
       
   640 end;
       
   641  
       
   642 procedure ResetDepth(rm: TRenderMode);
       
   643 begin
       
   644     if rm = rmDefault then exit;
       
   645     glMatrixMode(GL_PROJECTION);
       
   646     glTranslatef(-stereoDepth, 0, 0);
       
   647     glMatrixMode(GL_MODELVIEW);
       
   648     stereoDepth:= 0;
       
   649 end;
       
   650  
       
   651 procedure DrawWorldStereo(Lag: LongInt; RM: TRenderMode);
       
   652 var i, t: LongInt;
       
   653     r: TSDL_Rect;
       
   654     tdx, tdy: Double;
       
   655     grp: TCapGroup;
       
   656     s: string[15];
       
   657     highlight: Boolean;
       
   658     offset, offsetX, offsetY, screenBottom: LongInt;
       
   659     scale: GLfloat;
       
   660     VertexBuffer: array [0..3] of TVertex2f;
       
   661 begin
   567     if (cReducedQuality and rqNoBackground) = 0 then
   662     if (cReducedQuality and rqNoBackground) = 0 then
   568     begin
   663     begin
   569         // Offsets relative to camera - spare them to wimpier cpus, no bg or flakes for them anyway
   664         // Offsets relative to camera - spare them to wimpier cpus, no bg or flakes for them anyway
   570         ScreenBottom:= (WorldDy - trunc(cScreenHeight/cScaleFactor) - (cScreenHeight div 2) + cWaterLine);
   665         ScreenBottom:= (WorldDy - trunc(cScreenHeight/cScaleFactor) - (cScreenHeight div 2) + cWaterLine);
   571         offsetY:= 10 * min(0, -145 - ScreenBottom);
   666         offsetY:= 10 * min(0, -145 - ScreenBottom);
   573         HorizontOffset:= SkyOffset;
   668         HorizontOffset:= SkyOffset;
   574         if ScreenBottom > SkyOffset then
   669         if ScreenBottom > SkyOffset then
   575             HorizontOffset:= HorizontOffset + ((ScreenBottom-SkyOffset) div 20);
   670             HorizontOffset:= HorizontOffset + ((ScreenBottom-SkyOffset) div 20);
   576 
   671 
   577         // background
   672         // background
       
   673         ChangeDepth(RM, cStereo_Sky);
   578         DrawRepeated(sprSky, sprSkyL, sprSkyR, (WorldDx + LAND_WIDTH div 2) * 3 div 8, SkyOffset);
   674         DrawRepeated(sprSky, sprSkyL, sprSkyR, (WorldDx + LAND_WIDTH div 2) * 3 div 8, SkyOffset);
       
   675         ChangeDepth(RM, -cStereo_Horizon);
   579         DrawRepeated(sprHorizont, sprHorizontL, sprHorizontR, (WorldDx + LAND_WIDTH div 2) * 3 div 5, HorizontOffset);
   676         DrawRepeated(sprHorizont, sprHorizontL, sprHorizontR, (WorldDx + LAND_WIDTH div 2) * 3 div 5, HorizontOffset);
   580     end;
   677     end
       
   678     else
       
   679         ChangeDepth(RM, cStereo_Sky - cStereo_Horizon);
   581 
   680 
   582     DrawVisualGears(0);
   681     DrawVisualGears(0);
   583     
   682     
   584     if (cReducedQuality and rq2DWater) = 0 then
   683     if (cReducedQuality and rq2DWater) = 0 then
   585     begin
   684     begin
   586         // Waves
   685         // Waves
   587         DrawWater(255, SkyOffset); 
   686         DrawWater(255, SkyOffset); 
       
   687         ChangeDepth(RM, -cStereo_Water);
   588         DrawWaves( 1,  0 - WorldDx div 32, - cWaveHeight + offsetY div 35, 64);
   688         DrawWaves( 1,  0 - WorldDx div 32, - cWaveHeight + offsetY div 35, 64);
       
   689         ChangeDepth(RM, -cStereo_Water);
   589         DrawWaves( -1,  25 + WorldDx div 25, - cWaveHeight + offsetY div 38, 48);
   690         DrawWaves( -1,  25 + WorldDx div 25, - cWaveHeight + offsetY div 38, 48);
       
   691         ChangeDepth(RM, -cStereo_Water);
   590         DrawWaves( 1,  75 - WorldDx div 19, - cWaveHeight + offsetY div 45, 32);
   692         DrawWaves( 1,  75 - WorldDx div 19, - cWaveHeight + offsetY div 45, 32);
       
   693         ChangeDepth(RM, -cStereo_Water);
   591         DrawWaves(-1, 100 + WorldDx div 14, - cWaveHeight + offsetY div 70, 24);
   694         DrawWaves(-1, 100 + WorldDx div 14, - cWaveHeight + offsetY div 70, 24);
   592     end
   695     end
   593     else
   696     else
       
   697     begin
       
   698         ChangeDepth(RM, -4 * cStereo_Water);
   594         DrawWaves(-1, 100, - (cWaveHeight + (cWaveHeight shr 1)), 0);
   699         DrawWaves(-1, 100, - (cWaveHeight + (cWaveHeight shr 1)), 0);
       
   700     end;
       
   701     ResetDepth(RM);
   595 
   702 
   596     DrawLand(WorldDx, WorldDy);
   703     DrawLand(WorldDx, WorldDy);
   597 
   704 
   598     DrawWater(255, 0);
   705     DrawWater(255, 0);
   599 
   706 
   626     DrawVisualGears(2);
   733     DrawVisualGears(2);
   627 
   734 
   628     DrawWater(cWaterOpacity, 0);
   735     DrawWater(cWaterOpacity, 0);
   629 
   736 
   630     // Waves
   737     // Waves
       
   738     ChangeDepth(RM, cStereo_Water);
   631     DrawWaves( 1, 25 - WorldDx div 9, - cWaveHeight, 12);
   739     DrawWaves( 1, 25 - WorldDx div 9, - cWaveHeight, 12);
   632 
   740 
   633     if (cReducedQuality and rq2DWater) = 0 then
   741     if (cReducedQuality and rq2DWater) = 0 then
   634     begin
   742     begin
   635         //DrawWater(cWaterOpacity, - offsetY div 40);
   743         //DrawWater(cWaterOpacity, - offsetY div 40);
       
   744         ChangeDepth(RM, cStereo_Water);
   636         DrawWaves(-1, 50 + WorldDx div 6, - cWaveHeight - offsetY div 40, 8);
   745         DrawWaves(-1, 50 + WorldDx div 6, - cWaveHeight - offsetY div 40, 8);
   637         DrawWater(cWaterOpacity, - offsetY div 20);
   746         DrawWater(cWaterOpacity, - offsetY div 20);
       
   747         ChangeDepth(RM, cStereo_Water);
   638         DrawWaves( 1, 75 - WorldDx div 4, - cWaveHeight - offsetY div 20, 2);
   748         DrawWaves( 1, 75 - WorldDx div 4, - cWaveHeight - offsetY div 20, 2);
   639         DrawWater(cWaterOpacity, - offsetY div 10);
   749         DrawWater(cWaterOpacity, - offsetY div 10);
       
   750         ChangeDepth(RM, cStereo_Water);
   640         DrawWaves( -1, 25 + WorldDx div 3, - cWaveHeight - offsetY div 10, 0);
   751         DrawWaves( -1, 25 + WorldDx div 3, - cWaveHeight - offsetY div 10, 0);
   641     end
   752     end
   642     else
   753     else
       
   754     begin
       
   755         ChangeDepth(RM, cStereo_Water);
   643         DrawWaves(-1, 50, - (cWaveHeight shr 1), 0);
   756         DrawWaves(-1, 50, - (cWaveHeight shr 1), 0);
   644 
   757     end;
       
   758     ResetDepth(RM);
   645 
   759 
   646 {$WARNINGS OFF}
   760 {$WARNINGS OFF}
   647 // Target
   761 // Target
   648 if (TargetPoint.X <> NoPointX) and (CurrentTeam <> nil) and (CurrentHedgehog <> nil) then
   762 if (TargetPoint.X <> NoPointX) and (CurrentTeam <> nil) and (CurrentHedgehog <> nil) then
   649     begin
   763     begin
   860 offsetX:= 8;
   974 offsetX:= 8;
   861 {$ELSE}
   975 {$ELSE}
   862 offsetX:= 10;
   976 offsetX:= 10;
   863 {$ENDIF}
   977 {$ENDIF}
   864 offsetY:= cOffsetY;
   978 offsetY:= cOffsetY;
   865 inc(Frames);
   979 
   866 
   980 // don't increment fps when drawing the right frame
   867 if cShowFPS or (GameType = gmtDemo) then inc(CountTicks, Lag);
   981 if (RM = rmDefault) or (RM = rmLeftEye) then
   868 if (GameType = gmtDemo) and (CountTicks >= 1000) then
   982 begin
   869    begin
   983     inc(Frames);
   870    i:=GameTicks div 1000;
   984 
   871    t:= i mod 60;
   985     if cShowFPS or (GameType = gmtDemo) then
   872    s:= inttostr(t);
   986         inc(CountTicks, Lag);
   873    if t < 10 then s:= '0' + s;
   987     if (GameType = gmtDemo) and (CountTicks >= 1000) then
   874    i:= i div 60;
   988     begin
   875    t:= i mod 60;
   989         i:=GameTicks div 1000;
   876    s:= inttostr(t) + ':' + s;
   990         t:= i mod 60;
   877    if t < 10 then s:= '0' + s;
   991         s:= inttostr(t);
   878    s:= inttostr(i div 60) + ':' + s;
   992         if t < 10 then s:= '0' + s;
       
   993         i:= i div 60;
       
   994         t:= i mod 60;
       
   995         s:= inttostr(t) + ':' + s;
       
   996         if t < 10 then s:= '0' + s;
       
   997         s:= inttostr(i div 60) + ':' + s;
   879    
   998    
   880    if timeTexture <> nil then
   999         if timeTexture <> nil then
   881         FreeTexture(timeTexture);
  1000             FreeTexture(timeTexture);
   882     timeTexture:= nil;
  1001         timeTexture:= nil;
   883     
  1002     
   884    tmpSurface:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(s), cWhiteColorChannels);
  1003         tmpSurface:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(s), cWhiteColorChannels);
   885    tmpSurface:= doSurfaceConversion(tmpSurface);
  1004         tmpSurface:= doSurfaceConversion(tmpSurface);
   886    timeTexture:= Surface2Tex(tmpSurface, false);
  1005         timeTexture:= Surface2Tex(tmpSurface, false);
   887    SDL_FreeSurface(tmpSurface)
  1006         SDL_FreeSurface(tmpSurface)
   888    end;
  1007     end;
   889 
  1008 
   890 if timeTexture <> nil then
  1009     if timeTexture <> nil then
   891    DrawTexture((cScreenWidth shr 1) - 20 - timeTexture^.w - offsetY, offsetX + timeTexture^.h+5, timeTexture);
  1010         DrawTexture((cScreenWidth shr 1) - 20 - timeTexture^.w - offsetY, offsetX + timeTexture^.h+5, timeTexture);
   892 
  1011 
   893 if cShowFPS then
  1012     if cShowFPS then
   894    begin
  1013     begin
   895    if CountTicks >= 1000 then
  1014         if CountTicks >= 1000 then
   896       begin
  1015         begin
   897       FPS:= Frames;
  1016             FPS:= Frames;
   898       Frames:= 0;
  1017             Frames:= 0;
   899       CountTicks:= 0;
  1018             CountTicks:= 0;
   900       s:= inttostr(FPS) + ' fps';
  1019             s:= inttostr(FPS) + ' fps';
   901       if fpsTexture <> nil then
  1020             if fpsTexture <> nil then
   902         FreeTexture(fpsTexture);
  1021                 FreeTexture(fpsTexture);
   903     fpsTexture:= nil;
  1022             fpsTexture:= nil;
   904       tmpSurface:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(s), cWhiteColorChannels);
  1023             tmpSurface:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(s), cWhiteColorChannels);
   905       tmpSurface:= doSurfaceConversion(tmpSurface);
  1024             tmpSurface:= doSurfaceConversion(tmpSurface);
   906       fpsTexture:= Surface2Tex(tmpSurface, false);
  1025             fpsTexture:= Surface2Tex(tmpSurface, false);
   907       SDL_FreeSurface(tmpSurface)
  1026             SDL_FreeSurface(tmpSurface)
   908       end;
  1027         end;
   909    if fpsTexture <> nil then
  1028         if fpsTexture <> nil then
   910       DrawTexture((cScreenWidth shr 1) - 60 - offsetY, offsetX, fpsTexture);
  1029             DrawTexture((cScreenWidth shr 1) - 60 - offsetY, offsetX, fpsTexture);
   911    end;
  1030     end;
   912 
  1031 
   913 if CountTicks >= 1000 then CountTicks:= 0;
  1032     if CountTicks >= 1000 then CountTicks:= 0;
   914 
  1033 
   915 // lag warning (?)
  1034     // lag warning (?)
   916 inc(SoundTimerTicks, Lag);
  1035     inc(SoundTimerTicks, Lag);
       
  1036 end;
       
  1037 
   917 if SoundTimerTicks >= 50 then
  1038 if SoundTimerTicks >= 50 then
   918    begin
  1039    begin
   919    SoundTimerTicks:= 0;
  1040    SoundTimerTicks:= 0;
   920    if cVolumeDelta <> 0 then
  1041    if cVolumeDelta <> 0 then
   921       begin
  1042       begin