hedgewars/uStore.pas
branchsdl2transition
changeset 11362 ed5a6478e710
parent 11360 7a7611adf715
parent 11317 62287d4044e7
child 11367 a91c4c4fd85c
equal deleted inserted replaced
11361:31570b766315 11362:ed5a6478e710
     1 (*
     1 (*
     2  * Hedgewars, a free turn based strategy game
     2  * Hedgewars, a free turn based strategy game
     3  * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr@gmail.com>
     3  * Copyright (c) 2004-2015 Andrey Korotaev <unC0Rr@gmail.com>
     4  *
     4  *
     5  * This program is free software; you can redistribute it and/or modify
     5  * This program is free software; you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation; version 2 of the License
     7  * the Free Software Foundation; version 2 of the License
     8  *
     8  *
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    12  * GNU General Public License for more details.
    13  *
    13  *
    14  * You should have received a copy of the GNU General Public License
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program; if not, write to the Free Software
    15  * along with this program; if not, write to the Free Software
    16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
    16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    17  *)
    17  *)
    18 
    18 
    19 {$INCLUDE "options.inc"}
    19 {$INCLUDE "options.inc"}
    20 {$IF GLunit = GL}{$DEFINE GLunit:=GL,GLext}{$ENDIF}
    20 {$IF GLunit = GL}{$DEFINE GLunit:=GL,GLext}{$ENDIF}
    21 
    21 
    22 unit uStore;
    22 unit uStore;
    23 interface
    23 interface
    24 uses StrUtils, SysUtils, uConsts, SDLh, GLunit, uTypes, uLandTexture, uCaptions, uChat;
    24 uses SysUtils, uConsts, SDLh, GLunit, uTypes, uLandTexture, uCaptions, uChat;
    25 
    25 
    26 procedure initModule;
    26 procedure initModule;
    27 procedure freeModule;
    27 procedure freeModule;
    28 
    28 
    29 procedure StoreLoad(reload: boolean);
    29 procedure StoreLoad(reload: boolean);
    40 function  LoadDataImageAltPath(const path, altPath: TPathType; const filename: shortstring; imageFlags: LongInt): PSDL_Surface;
    40 function  LoadDataImageAltPath(const path, altPath: TPathType; const filename: shortstring; imageFlags: LongInt): PSDL_Surface;
    41 // like LoadDataImage but uses altFile as fallback-filename if file cannot be loaded
    41 // like LoadDataImage but uses altFile as fallback-filename if file cannot be loaded
    42 function  LoadDataImageAltFile(const path: TPathType; const filename, altFile: shortstring; imageFlags: LongInt): PSDL_Surface;
    42 function  LoadDataImageAltFile(const path: TPathType; const filename, altFile: shortstring; imageFlags: LongInt): PSDL_Surface;
    43 
    43 
    44 procedure LoadHedgehogHat(var HH: THedgehog; newHat: shortstring);
    44 procedure LoadHedgehogHat(var HH: THedgehog; newHat: shortstring);
       
    45 procedure LoadHedgehogHat2(var HH: THedgehog; newHat: shortstring; allowSurfReuse: boolean);
       
    46 
       
    47 procedure InitZoom(zoom: real);
       
    48 
    45 procedure SetupOpenGL;
    49 procedure SetupOpenGL;
    46 procedure SetScale(f: GLfloat);
       
    47 function  RenderHelpWindow(caption, subcaption, description, extra: ansistring; extracolor: LongInt; iconsurf: PSDL_Surface; iconrect: PSDL_Rect): PTexture;
    50 function  RenderHelpWindow(caption, subcaption, description, extra: ansistring; extracolor: LongInt; iconsurf: PSDL_Surface; iconrect: PSDL_Rect): PTexture;
    48 procedure RenderWeaponTooltip(atype: TAmmoType);
    51 procedure RenderWeaponTooltip(atype: TAmmoType);
    49 procedure ShowWeaponTooltip(x, y: LongInt);
    52 procedure ShowWeaponTooltip(x, y: LongInt);
    50 procedure FreeWeaponTooltip;
       
    51 procedure MakeCrossHairs;
    53 procedure MakeCrossHairs;
    52 {$IFDEF USE_VIDEO_RECORDING}
    54 {$IFDEF USE_VIDEO_RECORDING}
    53 procedure InitOffscreenOpenGL;
    55 procedure InitOffscreenOpenGL;
    54 {$ENDIF}
    56 {$ENDIF}
    55 
    57 
    56 procedure WarpMouse(x, y: Word); inline;
    58 procedure WarpMouse(x, y: Word); inline;
    57 procedure SwapBuffers; {$IFDEF USE_VIDEO_RECORDING}cdecl{$ELSE}inline{$ENDIF};
    59 procedure SwapBuffers; {$IFDEF USE_VIDEO_RECORDING}cdecl{$ELSE}inline{$ENDIF};
    58 procedure SetSkyColor(r, g, b: real);
    60 procedure SetSkyColor(r, g, b: real);
    59 
    61 
    60 implementation
    62 implementation
    61 uses uMisc, uConsole, uVariables, uUtils, uTextures, uRender, uRenderUtils, uCommands
    63 uses uMisc, uConsole, uVariables, uUtils, uTextures, uRender, uRenderUtils,
    62     , uPhysFSLayer
    64      uCommands, uPhysFSLayer, uDebug
    63     , uDebug
       
    64     {$IFDEF USE_CONTEXT_RESTORE}, uWorld{$ENDIF};
    65     {$IFDEF USE_CONTEXT_RESTORE}, uWorld{$ENDIF};
    65 
    66 
    66 //type TGPUVendor = (gvUnknown, gvNVIDIA, gvATI, gvIntel, gvApple);
    67 //type TGPUVendor = (gvUnknown, gvNVIDIA, gvATI, gvIntel, gvApple);
    67 
    68 
    68 var MaxTextureSize: LongInt;
    69 var 
    69     SDLwindow: PSDL_Window;
    70     SDLwindow: PSDL_Window;
    70     SDLGLcontext: PSDL_GLContext;
    71     SDLGLcontext: PSDL_GLContext;
    71     squaresize : LongInt;
    72     squaresize : LongInt;
    72     numsquares : LongInt;
    73     numsquares : LongInt;
    73     ProgrTex: PTexture;
    74     ProgrTex: PTexture;
    74 
    75 
       
    76     prevHat: shortstring;
       
    77     tmpHatSurf: PSDL_Surface;
       
    78 
    75 const
    79 const
    76     cHHFileName = 'Hedgehog';
    80     cHHFileName = 'Hedgehog';
    77     cCHFileName = 'Crosshair';
    81     cCHFileName = 'Crosshair';
    78 
    82 
    79 function WriteInRect(Surface: PSDL_Surface; X, Y: LongInt; Color: LongWord; Font: THWFont; s: ansistring): TSDL_Rect;
    83 procedure freeTmpHatSurf();
       
    84 begin
       
    85     if tmpHatSurf = nil then exit;
       
    86     SDL_FreeSurface(tmpHatSurf);
       
    87     tmpHatSurf:= nil;
       
    88     prevHat:= 'NoHat';
       
    89 end;
       
    90 
       
    91 procedure InitZoom(zoom: real);
       
    92 begin
       
    93     SetScale(zoom);
       
    94     // make sure view limits are updated
       
    95     // because SetScale() doesn't do it, if zoom=cScaleFactor
       
    96     updateViewLimits();
       
    97 end;
       
    98 
       
    99 function WriteInRect(Surface: PSDL_Surface; X, Y: LongInt; Color: LongWord; Font: THWFont; s: PChar): TSDL_Rect;
    80 var w, h: LongInt;
   100 var w, h: LongInt;
    81     tmpsurf: PSDL_Surface;
   101     tmpsurf: PSDL_Surface;
    82     clr: TSDL_Color;
   102     clr: TSDL_Color;
    83     finalRect: TSDL_Rect;
   103     finalRect: TSDL_Rect;
    84 begin
   104 begin
    85 w:= 0; h:= 0; // avoid compiler hints
   105 w:= 0; h:= 0; // avoid compiler hints
    86 TTF_SizeUTF8(Fontz[Font].Handle, Str2PChar(s), @w, @h);
   106 TTF_SizeUTF8(Fontz[Font].Handle, s, @w, @h);
    87 finalRect.x:= X + cFontBorder + 2;
   107 finalRect.x:= X + cFontBorder + 2;
    88 finalRect.y:= Y + cFontBorder;
   108 finalRect.y:= Y + cFontBorder;
    89 finalRect.w:= w + cFontBorder * 2 + 4;
   109 finalRect.w:= w + cFontBorder * 2 + 4;
    90 finalRect.h:= h + cFontBorder * 2;
   110 finalRect.h:= h + cFontBorder * 2;
    91 clr.r:= Color shr 16;
   111 clr.r:= Color shr 16;
    92 clr.g:= (Color shr 8) and $FF;
   112 clr.g:= (Color shr 8) and $FF;
    93 clr.b:= Color and $FF;
   113 clr.b:= Color and $FF;
    94 tmpsurf:= TTF_RenderUTF8_Blended(Fontz[Font].Handle, Str2PChar(s), clr);
   114 tmpsurf:= TTF_RenderUTF8_Blended(Fontz[Font].Handle, s, clr);
       
   115 SDLTry(tmpsurf <> nil, 'TTF_RenderUTF8_Blended', true);
    95 tmpsurf:= doSurfaceConversion(tmpsurf);
   116 tmpsurf:= doSurfaceConversion(tmpsurf);
    96 SDLTry(tmpsurf <> nil, 'TTF_RenderUTF8_Blended, doSurfaceConversion', true);
   117 SDLTry(tmpsurf <> nil, 'TTF_RenderUTF8_Blended, doSurfaceConversion', true);
    97 SDL_UpperBlit(tmpsurf, nil, Surface, @finalRect);
   118 SDL_UpperBlit(tmpsurf, nil, Surface, @finalRect);
    98 SDL_FreeSurface(tmpsurf);
   119 SDL_FreeSurface(tmpsurf);
    99 finalRect.x:= X;
   120 finalRect.x:= X;
   146     drY: LongInt;
   167     drY: LongInt;
   147     texsurf, flagsurf, iconsurf: PSDL_Surface;
   168     texsurf, flagsurf, iconsurf: PSDL_Surface;
   148     foundBot: boolean;
   169     foundBot: boolean;
   149     year, month, md : word;
   170     year, month, md : word;
   150 begin
   171 begin
   151     if cOnlyStats then exit;
   172 if cOnlyStats then exit;
   152 r.x:= 0;
   173 r.x:= 0;
   153 r.y:= 0;
   174 r.y:= 0;
   154 drY:= - 4;
   175 drY:= - 4;
       
   176 {$IFNDEF PAS2C}
   155 DecodeDate(Date, year, month, md);
   177 DecodeDate(Date, year, month, md);
       
   178 {$ELSE}
       
   179 year:= 0;
       
   180 month:= 0;
       
   181 md:= 0;
       
   182 {$ENDIF}
   156 for t:= 0 to Pred(TeamsCount) do
   183 for t:= 0 to Pred(TeamsCount) do
   157     with TeamsArray[t]^ do
   184     with TeamsArray[t]^ do
   158         begin
   185         begin
   159         NameTagTex:= RenderStringTexLim(TeamName, Clan^.Color, Font, cTeamHealthWidth);
   186         NameTagTex:= RenderStringTexLim(ansistring(TeamName), Clan^.Color, Font, cTeamHealthWidth);
   160         if length(Owner) > 0 then
   187         if length(Owner) > 0 then
   161             OwnerTex:= RenderStringTexLim(Owner, Clan^.Color, Font, cTeamHealthWidth);
   188             OwnerTex:= RenderStringTexLim(ansistring(Owner), Clan^.Color, Font, cTeamHealthWidth);
   162 
   189 
   163         r.x:= 0;
   190         r.x:= 0;
   164         r.y:= 0;
   191         r.y:= 0;
   165         r.w:= 32;
   192         r.w:= 32;
   166         r.h:= 32;
   193         r.h:= 32;
   222 
   249 
   223         FlagTex:= Surface2Tex(texsurf, false);
   250         FlagTex:= Surface2Tex(texsurf, false);
   224         SDL_FreeSurface(texsurf);
   251         SDL_FreeSurface(texsurf);
   225         texsurf:= nil;
   252         texsurf:= nil;
   226 
   253 
   227         AIKillsTex := RenderStringTex(inttostr(stats.AIKills), Clan^.Color, fnt16);
   254         AIKillsTex := RenderStringTex(ansistring(inttostr(stats.AIKills)), Clan^.Color, fnt16);
   228 
   255 
   229         dec(drY, r.h + 2);
   256         dec(drY, r.h + 2);
   230         DrawHealthY:= drY;
   257         DrawHealthY:= drY;
   231         for i:= 0 to cMaxHHIndex do
   258         for i:= 0 to cMaxHHIndex do
   232             with Hedgehogs[i] do
   259             with Hedgehogs[i] do
   233                 if Gear <> nil then
   260                 if Gear <> nil then
   234                     begin
   261                     begin
   235                     NameTagTex:= RenderStringTexLim(Name, Clan^.Color, fnt16, cTeamHealthWidth);
   262                     NameTagTex:= RenderStringTexLim(ansistring(Name), Clan^.Color, fnt16, cTeamHealthWidth);
   236                     if Hat = 'NoHat' then
   263                     if Hat = 'NoHat' then
   237                         begin
   264                         begin
   238                         if ((month = 4) and (md = 20)) then
   265                         if (month = 4) and (md = 20) then
   239                             Hat := 'eastertop'; // Easter
   266                             Hat := 'eastertop'   // Easter
   240                         if ((month = 12) and (md = 25)) then
   267                         else if (month = 12) and ((md = 24) or (md = 25) or (md = 26)) then
   241                             Hat := 'Santa'; // Christmas
   268                             Hat := 'Santa'       // Christmas Eve/Christmas/Boxing Day
   242                         if ((month = 10) and (md = 31)) then
   269                         else if (month = 10) and (md = 31) then
   243                             Hat := 'fr_pumpkin'; // Halloween/Hedgewars' birthday
   270                             Hat := 'fr_pumpkin'; // Halloween/Hedgewars' birthday
   244                         end;
   271                         end;
   245                     
   272                     if (month = 4) and (md = 1) then
       
   273                         begin
       
   274                         AprilOne:= true;
       
   275                         Hat := 'fr_tomato'; // avoid promoting violence to hedgehogs. see http://hedgewars.org/node/5818
       
   276                         end;
       
   277 
   246                     if Hat <> 'NoHat' then
   278                     if Hat <> 'NoHat' then
   247                         begin
   279                         begin
   248                         if (Length(Hat) > 39) and (Copy(Hat,1,8) = 'Reserved') and (Copy(Hat,9,32) = PlayerHash) then
   280                         if (Length(Hat) > 39) and (Copy(Hat,1,8) = 'Reserved') and (Copy(Hat,9,32) = PlayerHash) then
   249                             LoadHedgehogHat(Hedgehogs[i], 'Reserved/' + Copy(Hat,9,Length(Hat)-8))
   281                             LoadHedgehogHat2(Hedgehogs[i], 'Reserved/' + Copy(Hat,9,Length(Hat)-8), true)
   250                         else
   282                         else
   251                             LoadHedgehogHat(Hedgehogs[i], Hat);
   283                             LoadHedgehogHat2(Hedgehogs[i], Hat, true);
   252                         end
   284                         end
   253                     end;
   285                     end;
   254         end;
   286         end;
       
   287 
       
   288     freeTmpHatSurf();
       
   289 
   255     MissionIcons:= LoadDataImage(ptGraphics, 'missions', ifCritical);
   290     MissionIcons:= LoadDataImage(ptGraphics, 'missions', ifCritical);
   256     iconsurf:= SDL_CreateRGBSurface(SDL_SWSURFACE, 28, 28, 32, RMask, GMask, BMask, AMask);
   291     iconsurf:= SDL_CreateRGBSurface(SDL_SWSURFACE, 28, 28, 32, RMask, GMask, BMask, AMask);
   257     if iconsurf <> nil then
   292     if iconsurf <> nil then
   258         begin
   293         begin
   259         r.x:= 0;
   294         r.x:= 0;
   312     tmpsurf: PSDL_Surface;
   347     tmpsurf: PSDL_Surface;
   313     i, imflags: LongInt;
   348     i, imflags: LongInt;
   314 begin
   349 begin
   315 AddFileLog('StoreLoad()');
   350 AddFileLog('StoreLoad()');
   316 
   351 
   317 if not reload then
   352 if (not reload) and (not cOnlyStats) then
   318     for fi:= Low(THWFont) to High(THWFont) do
   353     for fi:= Low(THWFont) to High(THWFont) do
   319         with Fontz[fi] do
   354         with Fontz[fi] do
   320             begin
   355             begin
   321             s:= cPathz[ptFonts] + '/' + Name;
   356             s:= cPathz[ptFonts] + '/' + Name;
   322             WriteToConsole(msgLoading + s + ' (' + inttostr(Height) + 'pt)... ');
   357             WriteToConsole(msgLoading + s + ' (' + inttostr(Height) + 'pt)... ');
   324             SDLTry(Handle <> nil, 'TTF_OpenFontRW', true);
   359             SDLTry(Handle <> nil, 'TTF_OpenFontRW', true);
   325             TTF_SetFontStyle(Handle, style);
   360             TTF_SetFontStyle(Handle, style);
   326             WriteLnToConsole(msgOK)
   361             WriteLnToConsole(msgOK)
   327             end;
   362             end;
   328 
   363 
   329 MakeCrossHairs;
   364 if not cOnlyStats then
   330 LoadGraves;
   365     begin
       
   366     MakeCrossHairs;
       
   367     LoadGraves;
       
   368 {$IFDEF IPHONEOS}
       
   369     tmpHatSurf:= LoadDataImage(ptHats, 'chef', ifNone);
       
   370 {$ELSE}
       
   371     tmpHatSurf:= LoadDataImage(ptHats, 'Reserved/chef', ifNone);
       
   372 {$ENDIF}
       
   373     ChefHatTexture:= Surface2Tex(tmpHatSurf, true);
       
   374     freeTmpHatSurf();
       
   375     end;
       
   376 
   331 if not reload then
   377 if not reload then
   332     AddProgress;
   378     AddProgress;
   333 
   379 
   334 for ii:= Low(TSprite) to High(TSprite) do
   380 for ii:= Low(TSprite) to High(TSprite) do
   335     with SpritesData[ii] do
   381     with SpritesData[ii] do
   336         // FIXME - add a sprite attribute to match on rq flags?
   382         // FIXME - add a sprite attribute to match on rq flags?
   337         if (((cReducedQuality and (rqNoBackground or rqLowRes)) = 0) or   // why rqLowRes?
   383         if (((cReducedQuality and (rqNoBackground or rqLowRes)) = 0) or   // why rqLowRes?
   338                 (not (ii in [sprSky, sprSkyL, sprSkyR, sprHorizont, sprHorizontL, sprHorizontR]))) and
   384                 (not (ii in [sprSky, sprSkyL, sprSkyR, sprHorizont, sprHorizontL, sprHorizontR])))
   339            (((cReducedQuality and rqPlainSplash) = 0) or ((not (ii in [sprSplash, sprDroplet, sprSDSplash, sprSDDroplet])))) and
   385            and (((cReducedQuality and rqPlainSplash) = 0) or ((not (ii in [sprSplash, sprDroplet, sprSDSplash, sprSDDroplet]))))
   340            (((cReducedQuality and rqKillFlakes) = 0) or cSnow or ((not (ii in [sprFlake, sprSDFlake])))) and
   386            and (((cReducedQuality and rqKillFlakes) = 0) or cSnow or ((not (ii in [sprFlake, sprSDFlake]))))
   341            ((cCloudsNumber > 0) or (ii <> sprCloud)) and
   387            and ((cCloudsNumber > 0) or (ii <> sprCloud))
   342            ((vobCount > 0) or (ii <> sprFlake)) then
   388            and ((vobCount > 0) or (ii <> sprFlake))
       
   389            and (savesurf or (not cOnlyStats)) // in stats-only only load those which are needed later
       
   390             then
   343             begin
   391             begin
   344             if reload then
   392             if reload then
   345                 tmpsurf:= Surface
   393                 tmpsurf:= Surface
   346             else
   394             else
   347                 begin
   395                 begin
   395                 end
   443                 end
   396             else
   444             else
   397                 Surface:= nil
   445                 Surface:= nil
   398         end;
   446         end;
   399 
   447 
   400 WriteNames(fnt16);
   448 if not cOnlyStats then
   401 
   449     begin
   402 if not reload then
   450     WriteNames(fnt16);
   403     AddProgress;
   451 
   404 
   452     if not reload then
   405 tmpsurf:= LoadDataImage(ptGraphics, cHHFileName, ifAlpha or ifCritical or ifTransparent);
   453         AddProgress;
   406 
   454 
   407 HHTexture:= Surface2Tex(tmpsurf, false);
   455     tmpsurf:= LoadDataImage(ptGraphics, cHHFileName, ifAlpha or ifCritical or ifTransparent);
   408 SDL_FreeSurface(tmpsurf);
   456 
   409 
   457     HHTexture:= Surface2Tex(tmpsurf, false);
   410 InitHealth;
   458     SDL_FreeSurface(tmpsurf);
   411 
   459 
   412 PauseTexture:= RenderStringTex(trmsg[sidPaused], cYellowColor, fntBig);
   460     InitHealth;
   413 AFKTexture:= RenderStringTex(trmsg[sidAFK], cYellowColor, fntBig);
   461 
   414 ConfirmTexture:= RenderStringTex(trmsg[sidConfirm], cYellowColor, fntBig);
   462     PauseTexture:= RenderStringTex(trmsg[sidPaused], cYellowColor, fntBig);
   415 SyncTexture:= RenderStringTex(trmsg[sidSync], cYellowColor, fntBig);
   463     AFKTexture:= RenderStringTex(trmsg[sidAFK], cYellowColor, fntBig);
   416 
   464     ConfirmTexture:= RenderStringTex(trmsg[sidConfirm], cYellowColor, fntBig);
   417 if not reload then
   465     SyncTexture:= RenderStringTex(trmsg[sidSync], cYellowColor, fntBig);
   418     AddProgress;
   466 
   419 
   467     if not reload then
   420 // name of weapons in ammo menu
   468         AddProgress;
   421 for ai:= Low(TAmmoType) to High(TAmmoType) do
   469 
   422     with Ammoz[ai] do
   470     // name of weapons in ammo menu
   423         begin
   471     for ai:= Low(TAmmoType) to High(TAmmoType) do
   424         TryDo(trAmmo[NameId] <> '','No default text/translation found for ammo type #' + intToStr(ord(ai)) + '!',true);
   472         with Ammoz[ai] do
   425         tmpsurf:= TTF_RenderUTF8_Blended(Fontz[CheckCJKFont(trAmmo[NameId],fnt16)].Handle, Str2PChar(trAmmo[NameId]), cWhiteColorChannels);
   473             begin
   426         TryDo(tmpsurf <> nil,'Name-texture creation for ammo type #' + intToStr(ord(ai)) + ' failed!',true);
   474             TryDo(length(trAmmo[NameId]) > 0,'No default text/translation found for ammo type #' + intToStr(ord(ai)) + '!',true);
       
   475             tmpsurf:= TTF_RenderUTF8_Blended(Fontz[CheckCJKFont(trAmmo[NameId],fnt16)].Handle, PChar(trAmmo[NameId]), cWhiteColorChannels);
       
   476             TryDo(tmpsurf <> nil,'Name-texture creation for ammo type #' + intToStr(ord(ai)) + ' failed!',true);
       
   477             tmpsurf:= doSurfaceConversion(tmpsurf);
       
   478             FreeAndNilTexture(NameTex);
       
   479             NameTex:= Surface2Tex(tmpsurf, false);
       
   480             SDL_FreeSurface(tmpsurf)
       
   481             end;
       
   482 
       
   483     // number of weapons in ammo menu
       
   484     for i:= Low(CountTexz) to High(CountTexz) do
       
   485         begin
       
   486         tmpsurf:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(IntToStr(i) + 'x'), cWhiteColorChannels);
   427         tmpsurf:= doSurfaceConversion(tmpsurf);
   487         tmpsurf:= doSurfaceConversion(tmpsurf);
   428         FreeTexture(NameTex);
   488         FreeAndNilTexture(CountTexz[i]);
   429         NameTex:= Surface2Tex(tmpsurf, false);
   489         CountTexz[i]:= Surface2Tex(tmpsurf, false);
   430         SDL_FreeSurface(tmpsurf)
   490         SDL_FreeSurface(tmpsurf)
   431         end;
   491         end;
   432 
   492 
   433 // number of weapons in ammo menu
   493     if not reload then
   434 for i:= Low(CountTexz) to High(CountTexz) do
   494         AddProgress;
   435     begin
       
   436     tmpsurf:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(IntToStr(i) + 'x'), cWhiteColorChannels);
       
   437     tmpsurf:= doSurfaceConversion(tmpsurf);
       
   438     FreeTexture(CountTexz[i]);
       
   439     CountTexz[i]:= Surface2Tex(tmpsurf, false);
       
   440     SDL_FreeSurface(tmpsurf)
       
   441     end;
   495     end;
   442 
   496 
   443 if not reload then
       
   444     AddProgress;
       
   445 IMG_Quit();
   497 IMG_Quit();
   446 end;
   498 end;
   447 
       
   448 {$IF DEFINED(USE_S3D_RENDERING) OR DEFINED(USE_VIDEO_RECORDING)}
       
   449 procedure CreateFramebuffer(var frame, depth, tex: GLuint);
       
   450 begin
       
   451     glGenFramebuffersEXT(1, @frame);
       
   452     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frame);
       
   453     glGenRenderbuffersEXT(1, @depth);
       
   454     glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth);
       
   455     glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, cScreenWidth, cScreenHeight);
       
   456     glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth);
       
   457     glGenTextures(1, @tex);
       
   458     glBindTexture(GL_TEXTURE_2D, tex);
       
   459     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,  cScreenWidth, cScreenHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nil);
       
   460     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
       
   461     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
       
   462     glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0);
       
   463 end;
       
   464 
       
   465 procedure DeleteFramebuffer(var frame, depth, tex: GLuint);
       
   466 begin
       
   467     glDeleteTextures(1, @tex);
       
   468     glDeleteRenderbuffersEXT(1, @depth);
       
   469     glDeleteFramebuffersEXT(1, @frame);
       
   470 end;
       
   471 {$ENDIF}
       
   472 
   499 
   473 procedure StoreRelease(reload: boolean);
   500 procedure StoreRelease(reload: boolean);
   474 var ii: TSprite;
   501 var ii: TSprite;
   475     ai: TAmmoType;
   502     ai: TAmmoType;
   476     i, t: LongInt;
   503     i, t: LongInt;
   486         end
   513         end
   487     end;
   514     end;
   488 SDL_FreeSurface(MissionIcons);
   515 SDL_FreeSurface(MissionIcons);
   489 
   516 
   490 // free the textures declared in uVariables
   517 // free the textures declared in uVariables
       
   518 FreeAndNilTexture(ChefHatTexture);
   491 FreeAndNilTexture(CrosshairTexture);
   519 FreeAndNilTexture(CrosshairTexture);
   492 FreeAndNilTexture(WeaponTooltipTex);
   520 FreeAndNilTexture(WeaponTooltipTex);
   493 FreeAndNilTexture(PauseTexture);
   521 FreeAndNilTexture(PauseTexture);
   494 FreeAndNilTexture(AFKTexture);
   522 FreeAndNilTexture(AFKTexture);
   495 FreeAndNilTexture(SyncTexture);
   523 FreeAndNilTexture(SyncTexture);
   530                 FreeAndNilTexture(TeamsArray[t]^.Hedgehogs[i].HealthTagTex);
   558                 FreeAndNilTexture(TeamsArray[t]^.Hedgehogs[i].HealthTagTex);
   531                 FreeAndNilTexture(TeamsArray[t]^.Hedgehogs[i].HatTex);
   559                 FreeAndNilTexture(TeamsArray[t]^.Hedgehogs[i].HatTex);
   532                 end;
   560                 end;
   533             end;
   561             end;
   534         end;
   562         end;
   535 {$IFDEF USE_VIDEO_RECORDING}
   563 
   536     if defaultFrame <> 0 then
   564 RendererCleanup();
   537         DeleteFramebuffer(defaultFrame, depthv, texv);
       
   538 {$ENDIF}
       
   539 {$IFDEF USE_S3D_RENDERING}
       
   540     if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) then
       
   541         begin
       
   542         DeleteFramebuffer(framel, depthl, texl);
       
   543         DeleteFramebuffer(framer, depthr, texr);
       
   544         end
       
   545 {$ENDIF}
       
   546 end;
   565 end;
   547 
   566 
   548 
   567 
   549 procedure RenderHealth(var Hedgehog: THedgehog);
   568 procedure RenderHealth(var Hedgehog: THedgehog);
   550 var s: shortstring;
   569 var s: shortstring;
   551 begin
   570 begin
   552 str(Hedgehog.Gear^.Health, s);
   571 str(Hedgehog.Gear^.Health, s);
   553 FreeTexture(Hedgehog.HealthTagTex);
   572 FreeAndNilTexture(Hedgehog.HealthTagTex);
   554 Hedgehog.HealthTagTex:= RenderStringTex(s, Hedgehog.Team^.Clan^.Color, fnt16)
   573 Hedgehog.HealthTagTex:= RenderStringTex(ansistring(s), Hedgehog.Team^.Clan^.Color, fnt16)
   555 end;
   574 end;
   556 
   575 
   557 function LoadImage(const filename: shortstring; imageFlags: LongInt): PSDL_Surface;
   576 function LoadImage(const filename: shortstring; imageFlags: LongInt): PSDL_Surface;
   558 var tmpsurf: PSDL_Surface;
   577 var tmpsurf: PSDL_Surface;
   559     s: shortstring;
   578     s: shortstring;
       
   579     rwops: PSDL_RWops;
   560 begin
   580 begin
   561     LoadImage:= nil;
   581     LoadImage:= nil;
   562     WriteToConsole(msgLoading + filename + '.png [flags: ' + inttostr(imageFlags) + '] ');
   582     WriteToConsole(msgLoading + filename + '.png [flags: ' + inttostr(imageFlags) + '] ');
   563 
   583 
   564     s:= filename + '.png';
   584     s:= filename + '.png';
   565     tmpsurf:= IMG_Load_RW(rwopsOpenRead(s), true);
   585 
   566 
   586     rwops:= nil;
       
   587     tmpsurf:= nil;
       
   588 
       
   589     if pfsExists(s) then
       
   590         begin
       
   591         // get data source
       
   592         rwops:= rwopsOpenRead(s);
       
   593 
       
   594         // load image with SDL (with freesrc param set to true)
       
   595         if rwops <> nil then
       
   596             tmpsurf:= IMG_Load_RW(rwops, true);
       
   597         end;
       
   598 
       
   599     // loading failed
   567     if tmpsurf = nil then
   600     if tmpsurf = nil then
   568         begin
   601         begin
   569         OutError(msgFailed, (imageFlags and ifCritical) <> 0);
   602         // output sdl error if loading failed when data source was available
       
   603         if rwops <> nil then
       
   604             begin
       
   605             // anounce that loading failed
       
   606             OutError(msgFailed, false);
       
   607 
       
   608             SDLTry(false, 'LoadImage', (imageFlags and ifCritical) <> 0);
       
   609             // rwops was already freed by IMG_Load_RW
       
   610             rwops:= nil;
       
   611             end else
       
   612             OutError(msgFailed, (imageFlags and ifCritical) <> 0);
   570         exit;
   613         exit;
   571         end;
   614         end;
   572 
   615 
   573     if ((imageFlags and ifIgnoreCaps) = 0) and ((tmpsurf^.w > MaxTextureSize) or (tmpsurf^.h > MaxTextureSize)) then
   616     if ((imageFlags and ifIgnoreCaps) = 0) and ((tmpsurf^.w > MaxTextureSize) or (tmpsurf^.h > MaxTextureSize)) then
   574         begin
   617         begin
   633 
   676 
   634     LoadDataImageAltFile:= tmpsurf;
   677     LoadDataImageAltFile:= tmpsurf;
   635 end;
   678 end;
   636 
   679 
   637 procedure LoadHedgehogHat(var HH: THedgehog; newHat: shortstring);
   680 procedure LoadHedgehogHat(var HH: THedgehog; newHat: shortstring);
   638 var texsurf: PSDL_Surface;
   681 begin
       
   682     LoadHedgehogHat2(HH, newHat, false);
       
   683 end;
       
   684 
       
   685 procedure LoadHedgehogHat2(var HH: THedgehog; newHat: shortstring; allowSurfReuse: boolean);
   639 begin
   686 begin
   640     // free the mem of any previously assigned texture.  This was previously only if the new one could be loaded, but, NoHat is usually a better choice
   687     // free the mem of any previously assigned texture.  This was previously only if the new one could be loaded, but, NoHat is usually a better choice
   641     if HH.HatTex <> nil then
   688     if HH.HatTex <> nil then
   642         begin
   689         FreeAndNilTexture(HH.HatTex);
   643         FreeTexture(HH.HatTex);
   690 
   644         HH.HatTex:= nil
   691     // load new hat surface if this hat is different than the one already loaded
   645         end;
   692     if newHat <> prevHat then
   646     texsurf:= LoadDataImage(ptHats, newHat, ifNone);
   693         begin
       
   694         freeTmpHatSurf();
       
   695         tmpHatSurf:= LoadDataImage(ptHats, newHat, ifNone);
       
   696         end;
       
   697 
   647 AddFileLog('Hat => '+newHat);
   698 AddFileLog('Hat => '+newHat);
   648     // only do something if the hat could be loaded
   699     // only do something if the hat could be loaded
   649     if texsurf <> nil then
   700     if tmpHatSurf <> nil then
   650         begin
   701         begin
   651 AddFileLog('Got Hat');
   702 AddFileLog('Got Hat');
   652 
   703 
   653         // assign new hat to hedgehog
   704         // assign new hat to hedgehog
   654         HH.HatTex:= Surface2Tex(texsurf, true);
   705         HH.HatTex:= Surface2Tex(tmpHatSurf, true);
   655 
   706 
       
   707         // remember that this hat was used last
       
   708         if allowSurfReuse then
       
   709             prevHat:= newHat
   656         // cleanup: free temporary surface mem
   710         // cleanup: free temporary surface mem
   657         SDL_FreeSurface(texsurf)
   711         else
   658         end;
   712             freeTmpHatSurf();
   659 end;
   713         end;
   660 
       
   661 function glLoadExtension(extension : shortstring) : boolean;
       
   662 begin
       
   663 {$IF GLunit = gles11}
       
   664     // FreePascal doesnt come with OpenGL ES 1.1 Extension headers
       
   665     extension:= extension; // avoid hint
       
   666     glLoadExtension:= false;
       
   667     AddFileLog('OpenGL - "' + extension + '" skipped')
       
   668 {$ELSE}
       
   669     glLoadExtension:= glext_LoadExtension(extension);
       
   670     if glLoadExtension then
       
   671         AddFileLog('OpenGL - "' + extension + '" loaded')
       
   672     else
       
   673         AddFileLog('OpenGL - "' + extension + '" failed to load');
       
   674 {$ENDIF}
       
   675 end;
   714 end;
   676 
   715 
   677 procedure SetupOpenGLAttributes;
   716 procedure SetupOpenGLAttributes;
   678 begin
   717 begin
   679 {$IFDEF IPHONEOS}
   718 {$IFDEF IPHONEOS}
   680     SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0);
   719     SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0);
   681     SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 1);
   720     SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 1);
       
   721  
       
   722     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
       
   723     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
   682 {$ELSE}
   724 {$ELSE}
   683     SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
   725     SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
   684 {$ENDIF}
   726 {$ENDIF}
   685     SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
   727     SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
   686     SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);
   728     SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);
   691     SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); // prefer hw rendering
   733     SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); // prefer hw rendering
   692 end;
   734 end;
   693 
   735 
   694 procedure SetupOpenGL;
   736 procedure SetupOpenGL;
   695 var buf: array[byte] of char;
   737 var buf: array[byte] of char;
   696     AuxBufNum: LongInt = 0;
       
   697     tmpstr: AnsiString;
       
   698     tmpint: LongInt;
       
   699     tmpn: LongInt;
       
   700 begin
   738 begin
   701     AddFileLog('Setting up OpenGL (using driver: ' + shortstring(SDL_GetCurrentVideoDriver()) + ')');
   739     AddFileLog('Setting up OpenGL (using driver: ' + shortstring(SDL_GetCurrentVideoDriver()) + ')');
   702 
       
   703     AuxBufNum:= AuxBufNum;
       
   704 
   740 
   705     // TODO: this function creates an opengles1.1 context
   741     // TODO: this function creates an opengles1.1 context
   706     // un-comment below and add proper logic to support opengles2.0
   742     // un-comment below and add proper logic to support opengles2.0
   707     //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
   743     //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
   708     //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
   744     //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
   709     if SDLGLcontext = nil then
   745     if SDLGLcontext = nil then
   710         SDLGLcontext:= SDL_GL_CreateContext(SDLwindow);
   746         SDLGLcontext:= SDL_GL_CreateContext(SDLwindow);
   711     SDLTry(SDLGLcontext <> nil, 'SDLGLcontext', true);
   747     SDLTry(SDLGLcontext <> nil, 'SDLGLcontext', true);
   712     SDLTry(SDL_GL_SetSwapInterval(1) = 0, 'SDL_GL_SetSwapInterval', true);
   748     SDLTry(SDL_GL_SetSwapInterval(1) = 0, 'SDL_GL_SetSwapInterval', true);
   713 
   749 
   714     // get the max (h and v) size for textures that the gpu can support
   750     RendererSetup();
   715     glGetIntegerv(GL_MAX_TEXTURE_SIZE, @MaxTextureSize);
   751 
   716     if MaxTextureSize <= 0 then
   752 // gl2 init/matrix code was here, but removed
   717         begin
       
   718         MaxTextureSize:= 1024;
       
   719         AddFileLog('OpenGL Warning - driver didn''t provide any valid max texture size; assuming 1024');
       
   720         end
       
   721     else if (MaxTextureSize < 1024) and (MaxTextureSize >= 512) then
       
   722         begin
       
   723         cReducedQuality := cReducedQuality or rqNoBackground;
       
   724         AddFileLog('Texture size too small for backgrounds, disabling.');
       
   725         end;
       
   726 
       
   727     // everyone loves debugging
       
   728     AddFileLog('OpenGL-- Renderer: ' + shortstring(pchar(glGetString(GL_RENDERER))));
       
   729     AddFileLog('  |----- Vendor: ' + shortstring(pchar(glGetString(GL_VENDOR))));
       
   730     AddFileLog('  |----- Version: ' + shortstring(pchar(glGetString(GL_VERSION))));
       
   731     AddFileLog('  |----- Texture Size: ' + inttostr(MaxTextureSize));
       
   732 {$IFDEF USE_VIDEO_RECORDING}
       
   733     glGetIntegerv(GL_AUX_BUFFERS, @AuxBufNum);
       
   734     AddFileLog('  |----- Number of auxiliary buffers: ' + inttostr(AuxBufNum));
       
   735 {$ENDIF}
       
   736     AddFileLog('  \----- Extensions: ');
       
   737 
       
   738     // fetch extentions and store them in string
       
   739     tmpstr := StrPas(PChar(glGetString(GL_EXTENSIONS)));
       
   740     tmpn := WordCount(tmpstr, [' ']);
       
   741     tmpint := 1;
       
   742 
       
   743     repeat
       
   744     begin
       
   745         // print up to 3 extentions per row
       
   746         // ExtractWord will return empty string if index out of range
       
   747         AddFileLog(TrimRight(
       
   748             ExtractWord(tmpint, tmpstr, [' ']) + ' ' +
       
   749             ExtractWord(tmpint+1, tmpstr, [' ']) + ' ' +
       
   750             ExtractWord(tmpint+2, tmpstr, [' '])
       
   751         ));
       
   752         tmpint := tmpint + 3;
       
   753     end;
       
   754     until (tmpint > tmpn);
       
   755     AddFileLog('');
       
   756 
       
   757     defaultFrame:= 0;
       
   758 {$IFDEF USE_VIDEO_RECORDING}
       
   759     if GameType = gmtRecord then
       
   760     begin
       
   761         if glLoadExtension('GL_EXT_framebuffer_object') then
       
   762         begin
       
   763             CreateFramebuffer(defaultFrame, depthv, texv);
       
   764             glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, defaultFrame);
       
   765             AddFileLog('Using framebuffer for video recording.');
       
   766         end
       
   767         else if AuxBufNum > 0 then
       
   768         begin
       
   769             glDrawBuffer(GL_AUX0);
       
   770             glReadBuffer(GL_AUX0);
       
   771             AddFileLog('Using auxiliary buffer for video recording.');
       
   772         end
       
   773         else
       
   774         begin
       
   775             glDrawBuffer(GL_BACK);
       
   776             glReadBuffer(GL_BACK);
       
   777             AddFileLog('Warning: off-screen rendering is not supported; using back buffer but it may not work.');
       
   778         end;
       
   779     end;
       
   780 {$ENDIF}
       
   781 
       
   782 {$IFDEF USE_S3D_RENDERING}
       
   783     if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) then
       
   784     begin
       
   785         // prepare left and right frame buffers and associated textures
       
   786         if glLoadExtension('GL_EXT_framebuffer_object') then
       
   787             begin
       
   788             CreateFramebuffer(framel, depthl, texl);
       
   789             CreateFramebuffer(framer, depthr, texr);
       
   790 
       
   791             // reset
       
   792             glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, defaultFrame)
       
   793             end
       
   794         else
       
   795             cStereoMode:= smNone;
       
   796     end;
       
   797 {$ENDIF}
       
   798 
       
   799     // set view port to whole window
       
   800     glViewport(0, 0, cScreenWidth, cScreenHeight);
       
   801 
       
   802     glMatrixMode(GL_MODELVIEW);
       
   803     // prepare default translation/scaling
       
   804     glLoadIdentity();
       
   805     glScalef(2.0 / cScreenWidth, -2.0 / cScreenHeight, 1.0);
       
   806     glTranslatef(0, -cScreenHeight / 2, 0);
       
   807 
       
   808     // enable alpha blending
       
   809     glEnable(GL_BLEND);
       
   810     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
       
   811     // disable/lower perspective correction (will not need it anyway)
       
   812     glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
       
   813     // disable dithering
       
   814     glDisable(GL_DITHER);
       
   815     // enable common states by default as they save a lot
       
   816     glEnable(GL_TEXTURE_2D);
       
   817     glEnableClientState(GL_VERTEX_ARRAY);
       
   818     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
       
   819 end;
       
   820 
       
   821 procedure SetScale(f: GLfloat);
       
   822 begin
       
   823 // leave immediately if scale factor did not change
       
   824     if f = cScaleFactor then
       
   825         exit;
       
   826 
       
   827     if f = cDefaultZoomLevel then
       
   828         glPopMatrix         // return to default scaling
       
   829     else                    // other scaling
       
   830         begin
       
   831         glPushMatrix;       // save default scaling
       
   832         glLoadIdentity;
       
   833         glScalef(f / cScreenWidth, -f / cScreenHeight, 1.0);
       
   834         glTranslatef(0, -cScreenHeight / 2, 0);
       
   835         end;
       
   836 
       
   837     cScaleFactor:= f;
       
   838 end;
   753 end;
   839 
   754 
   840 ////////////////////////////////////////////////////////////////////////////////
   755 ////////////////////////////////////////////////////////////////////////////////
   841 procedure AddProgress;
   756 procedure AddProgress;
   842 var r: TSDL_Rect;
   757 var r: TSDL_Rect;
   851         ProgrTex:= Surface2Tex(texsurf, false);
   766         ProgrTex:= Surface2Tex(texsurf, false);
   852 
   767 
   853         squaresize:= texsurf^.w shr 1;
   768         squaresize:= texsurf^.w shr 1;
   854         numsquares:= texsurf^.h div squaresize;
   769         numsquares:= texsurf^.h div squaresize;
   855         SDL_FreeSurface(texsurf);
   770         SDL_FreeSurface(texsurf);
       
   771         {$IFNDEF PAS2C}
   856         with mobileRecord do
   772         with mobileRecord do
   857             if GameLoading <> nil then
   773             if GameLoading <> nil then
   858                 GameLoading();
   774                 GameLoading();
   859 
   775         {$ENDIF}
   860         end;
   776         end;
   861 
   777 
   862     TryDo(ProgrTex <> nil, 'Error - Progress Texure is nil!', true);
   778     TryDo(ProgrTex <> nil, 'Error - Progress Texure is nil!', true);
   863 
   779 
   864     glClear(GL_COLOR_BUFFER_BIT);
   780     RenderClear();
   865     if Step < numsquares then
   781     if Step < numsquares then
   866         r.x:= 0
   782         r.x:= 0
   867     else
   783     else
   868         r.x:= squaresize;
   784         r.x:= squaresize;
   869 
   785 
   872     r.h:= squaresize;
   788     r.h:= squaresize;
   873 
   789 
   874     DrawTextureFromRect( -squaresize div 2, (cScreenHeight - squaresize) shr 1, @r, ProgrTex);
   790     DrawTextureFromRect( -squaresize div 2, (cScreenHeight - squaresize) shr 1, @r, ProgrTex);
   875 
   791 
   876     SwapBuffers;
   792     SwapBuffers;
       
   793 
   877     inc(Step);
   794     inc(Step);
   878 end;
   795 end;
   879 
   796 
   880 procedure FinishProgress;
   797 procedure FinishProgress;
   881 begin
   798 begin
       
   799     {$IFNDEF PAS2C}
   882     with mobileRecord do
   800     with mobileRecord do
   883         if GameLoaded <> nil then
   801         if GameLoaded <> nil then
   884             GameLoaded();
   802             GameLoaded();
       
   803     {$ENDIF}
   885     WriteLnToConsole('Freeing progress surface... ');
   804     WriteLnToConsole('Freeing progress surface... ');
   886     FreeTexture(ProgrTex);
   805     FreeAndNilTexture(ProgrTex);
   887     ProgrTex:= nil;
       
   888     Step:= 0
   806     Step:= 0
   889 end;
   807 end;
   890 
   808 
   891 function RenderHelpWindow(caption, subcaption, description, extra: ansistring; extracolor: LongInt; iconsurf: PSDL_Surface; iconrect: PSDL_Rect): PTexture;
   809 function RenderHelpWindow(caption, subcaption, description, extra: ansistring; extracolor: LongInt; iconsurf: PSDL_Surface; iconrect: PSDL_Rect): PTexture;
   892 var tmpsurf: PSDL_SURFACE;
   810 var tmpsurf: PSDL_SURFACE;
   895     r, r2: TSDL_Rect;
   813     r, r2: TSDL_Rect;
   896     wa, ha: LongInt;
   814     wa, ha: LongInt;
   897     tmpline, tmpline2, tmpdesc: ansistring;
   815     tmpline, tmpline2, tmpdesc: ansistring;
   898 begin
   816 begin
   899 // make sure there is a caption as well as a sub caption - description is optional
   817 // make sure there is a caption as well as a sub caption - description is optional
   900 if caption = '' then
   818 if length(caption) = 0 then
   901     caption:= '???';
   819     caption:= ansistring('???');
   902 if subcaption = '' then
   820 if length(subcaption) = 0 then
   903     subcaption:= _S' ';
   821     subcaption:= ansistring(_S' ');
   904 
   822 
   905 font:= CheckCJKFont(caption,fnt16);
   823 font:= CheckCJKFont(caption,fnt16);
   906 font:= CheckCJKFont(subcaption,font);
   824 font:= CheckCJKFont(subcaption,font);
   907 font:= CheckCJKFont(description,font);
   825 font:= CheckCJKFont(description,font);
   908 font:= CheckCJKFont(extra,font);
   826 font:= CheckCJKFont(extra,font);
   915 i:= 0; j:= 0; // avoid compiler hints
   833 i:= 0; j:= 0; // avoid compiler hints
   916 
   834 
   917 // TODO: Recheck height/position calculation
   835 // TODO: Recheck height/position calculation
   918 
   836 
   919 // get caption's dimensions
   837 // get caption's dimensions
   920 TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(caption), @i, @j);
   838 TTF_SizeUTF8(Fontz[font].Handle, PChar(caption), @i, @j);
   921 // width adds 36 px (image + space)
   839 // width adds 36 px (image + space)
   922 w:= i + 36 + wa;
   840 w:= i + 36 + wa;
   923 h:= j + ha;
   841 h:= j + ha;
   924 
   842 
   925 // get sub caption's dimensions
   843 // get sub caption's dimensions
   926 TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(subcaption), @i, @j);
   844 TTF_SizeUTF8(Fontz[font].Handle, PChar(subcaption), @i, @j);
   927 // width adds 36 px (image + space)
   845 // width adds 36 px (image + space)
   928 if w < (i + 36 + wa) then
   846 if w < (i + 36 + wa) then
   929     w:= i + 36 + wa;
   847     w:= i + 36 + wa;
   930 inc(h, j + ha);
   848 inc(h, j + ha);
   931 
   849 
   932 // get description's dimensions
   850 // get description's dimensions
   933 tmpdesc:= description;
   851 tmpdesc:= description;
   934 while tmpdesc <> '' do
   852 while length(tmpdesc) > 0 do
   935     begin
   853     begin
   936     tmpline:= tmpdesc;
   854     tmpline:= tmpdesc;
   937     SplitByChar(tmpline, tmpdesc, '|');
   855     SplitByCharA(tmpline, tmpdesc, '|');
   938     if tmpline <> '' then
   856     if length(tmpline) > 0 then
   939         begin
   857         begin
   940         TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(tmpline), @i, @j);
   858         TTF_SizeUTF8(Fontz[font].Handle, PChar(tmpline), @i, @j);
   941         if w < (i + wa) then
   859         if w < (i + wa) then
   942             w:= i + wa;
   860             w:= i + wa;
   943         inc(h, j + ha)
   861         inc(h, j + ha)
   944         end
   862         end
   945     end;
   863     end;
   946 
   864 
   947 if extra <> '' then
   865 if length(extra) > 0 then
   948     begin
   866     begin
   949     // get extra label's dimensions
   867     // get extra label's dimensions
   950     TTF_SizeUTF8(Fontz[font].Handle, Str2PChar(extra), @i, @j);
   868     TTF_SizeUTF8(Fontz[font].Handle, PChar(extra), @i, @j);
   951     if w < (i + wa) then
   869     if w < (i + wa) then
   952         w:= i + wa;
   870         w:= i + wa;
   953     inc(h, j + ha);
   871     inc(h, j + ha);
   954     end;
   872     end;
   955 
   873 
   966 r.w:= w;
   884 r.w:= w;
   967 r.h:= h;
   885 r.h:= h;
   968 DrawRoundRect(@r, cWhiteColor, cNearBlackColor, tmpsurf, true);
   886 DrawRoundRect(@r, cWhiteColor, cNearBlackColor, tmpsurf, true);
   969 
   887 
   970 // render caption
   888 // render caption
   971 r:= WriteInRect(tmpsurf, 36 + cFontBorder + 2, ha, $ffffffff, font, caption);
   889 r:= WriteInRect(tmpsurf, 36 + cFontBorder + 2, ha, $ffffffff, font, PChar(caption));
   972 // render sub caption
   890 // render sub caption
   973 r:= WriteInRect(tmpsurf, 36 + cFontBorder + 2, r.y + r.h, $ffc7c7c7, font, subcaption);
   891 r:= WriteInRect(tmpsurf, 36 + cFontBorder + 2, r.y + r.h, $ffc7c7c7, font, PChar(subcaption));
   974 
   892 
   975 // render all description lines
   893 // render all description lines
   976 tmpdesc:= description;
   894 tmpdesc:= description;
   977 while tmpdesc <> '' do
   895 while length(tmpdesc) > 0 do
   978     begin
   896     begin
   979     tmpline:= tmpdesc;
   897     tmpline:= tmpdesc;
   980     SplitByChar(tmpline, tmpdesc, '|');
   898     SplitByCharA(tmpline, tmpdesc, '|');
   981     r2:= r;
   899     r2:= r;
   982     if tmpline <> '' then
   900     if length(tmpline) > 0 then
   983         begin
   901         begin
   984         r:= WriteInRect(tmpsurf, cFontBorder + 2, r.y + r.h, $ff707070, font, tmpline);
   902         r:= WriteInRect(tmpsurf, cFontBorder + 2, r.y + r.h, $ff707070, font, PChar(tmpline));
   985 
   903 
   986         // render highlighted caption (if there is a ':')
   904         // render highlighted caption (if there is a ':')
   987         tmpline2:= _S'';
   905         tmpline2:= _S'';
   988         SplitByChar(tmpline, tmpline2, ':');
   906         SplitByCharA(tmpline, tmpline2, ':');
   989         if tmpline2 <> _S'' then
   907         if length(tmpline2) > 0 then
   990             WriteInRect(tmpsurf, cFontBorder + 2, r2.y + r2.h, $ffc7c7c7, font, tmpline + ':');
   908             begin
       
   909             tmpline:= tmpline + ':';
       
   910             WriteInRect(tmpsurf, cFontBorder + 2, r2.y + r2.h, $ffc7c7c7, font, PChar(tmpline));
       
   911             end;
   991         end
   912         end
   992     end;
   913     end;
   993 
   914 
   994 if extra <> '' then
   915 if length(extra) > 0 then
   995     r:= WriteInRect(tmpsurf, cFontBorder + 2, r.y + r.h, extracolor, font, extra);
   916     r:= WriteInRect(tmpsurf, cFontBorder + 2, r.y + r.h, extracolor, font, PChar(extra));
   996 
   917 
   997 r.x:= cFontBorder + 6;
   918 r.x:= cFontBorder + 6;
   998 r.y:= cFontBorder + 4;
   919 r.y:= cFontBorder + 4;
   999 r.w:= 32;
   920 r.w:= 32;
  1000 r.h:= 32;
   921 r.h:= 32;
  1017         WeaponTooltipTex:= nil;
   938         WeaponTooltipTex:= nil;
  1018         exit
   939         exit
  1019         end;
   940         end;
  1020 
   941 
  1021 // free old texture
   942 // free old texture
  1022 FreeWeaponTooltip;
   943 FreeAndNilTexture(WeaponTooltipTex);
  1023 
   944 
  1024 // image region
   945 // image region
  1025 i:= LongInt(atype) - 1;
   946 i:= LongInt(atype) - 1;
  1026 r.x:= (i shr 4) * 32;
   947 r.x:= (i shr 4) * 32;
  1027 r.y:= (i mod 16) * 32;
   948 r.y:= (i mod 16) * 32;
  1055 procedure ShowWeaponTooltip(x, y: LongInt);
   976 procedure ShowWeaponTooltip(x, y: LongInt);
  1056 begin
   977 begin
  1057 // draw the texture if it exists
   978 // draw the texture if it exists
  1058 if WeaponTooltipTex <> nil then
   979 if WeaponTooltipTex <> nil then
  1059     DrawTexture(x, y, WeaponTooltipTex)
   980     DrawTexture(x, y, WeaponTooltipTex)
  1060 end;
       
  1061 
       
  1062 procedure FreeWeaponTooltip;
       
  1063 begin
       
  1064 // free the existing texture (if there is any)
       
  1065 FreeTexture(WeaponTooltipTex);
       
  1066 WeaponTooltipTex:= nil
       
  1067 end;
   981 end;
  1068 
   982 
  1069 {$IFDEF USE_VIDEO_RECORDING}
   983 {$IFDEF USE_VIDEO_RECORDING}
  1070 procedure InitOffscreenOpenGL;
   984 procedure InitOffscreenOpenGL;
  1071 begin
   985 begin
  1169     if SDLwindow = nil then
  1083     if SDLwindow = nil then
  1170         SDLwindow:= SDL_CreateWindow('Hedgewars', x, y, cScreenWidth, cScreenHeight, flags);
  1084         SDLwindow:= SDL_CreateWindow('Hedgewars', x, y, cScreenWidth, cScreenHeight, flags);
  1171     SDLTry(SDLwindow <> nil, 'SDL_CreateWindow', true);
  1085     SDLTry(SDLwindow <> nil, 'SDL_CreateWindow', true);
  1172 
  1086 
  1173     SetupOpenGL();
  1087     SetupOpenGL();
       
  1088 
  1174     if reinit then
  1089     if reinit then
  1175         begin
  1090         begin
  1176         // clean the window from any previous content
  1091         // clean the window from any previous content
  1177         glClear(GL_COLOR_BUFFER_BIT);
  1092         RenderClear();
  1178         if SuddenDeathDmg then
  1093         if SuddenDeathDmg then
  1179             SetSkyColor(SDSkyColor.r * (SDTint/255) / 255, SDSkyColor.g * (SDTint/255) / 255, SDSkyColor.b * (SDTint/255) / 255)
  1094             SetSkyColor(SDSkyColor.r * (SDTint/255) / 255, SDSkyColor.g * (SDTint/255) / 255, SDSkyColor.b * (SDTint/255) / 255)
  1180         else if ((cReducedQuality and rqNoBackground) = 0) then
  1095         else if ((cReducedQuality and rqNoBackground) = 0) then
  1181             SetSkyColor(SkyColor.r / 255, SkyColor.g / 255, SkyColor.b / 255)
  1096             SetSkyColor(SkyColor.r / 255, SkyColor.g / 255, SkyColor.b / 255)
  1182         else
  1097         else
  1207     SDL_GL_SwapWindow(SDLwindow);
  1122     SDL_GL_SwapWindow(SDLwindow);
  1208 end;
  1123 end;
  1209 
  1124 
  1210 procedure SetSkyColor(r, g, b: real);
  1125 procedure SetSkyColor(r, g, b: real);
  1211 begin
  1126 begin
  1212     glClearColor(r, g, b, 0.99)
  1127     RenderSetClearColor(r, g, b, 0.99)
  1213 end;
  1128 end;
  1214 
  1129 
  1215 procedure initModule;
  1130 procedure initModule;
  1216 var ai: TAmmoType;
  1131 var ai: TAmmoType;
  1217     i: LongInt;
  1132     i: LongInt;
  1218 begin
  1133 begin
  1219     RegisterVariable('fullscr', @chFullScr, true);
  1134     RegisterVariable('fullscr', @chFullScr, true);
  1220 
  1135 
  1221     cScaleFactor:= 2.0;
  1136     cScaleFactor:= 2.0;
       
  1137     updateViewLimits();
  1222     Step:= 0;
  1138     Step:= 0;
  1223     ProgrTex:= nil;
  1139     ProgrTex:= nil;
  1224     SupportNPOTT:= false;
  1140     SupportNPOTT:= false;
  1225 
  1141 
  1226     // init all ammo name texture pointers
  1142     // init all ammo name texture pointers
  1231     // init all count texture pointers
  1147     // init all count texture pointers
  1232     for i:= Low(CountTexz) to High(CountTexz) do
  1148     for i:= Low(CountTexz) to High(CountTexz) do
  1233         CountTexz[i] := nil;
  1149         CountTexz[i] := nil;
  1234     SDLwindow:= nil;
  1150     SDLwindow:= nil;
  1235     SDLGLcontext:= nil;
  1151     SDLGLcontext:= nil;
       
  1152 
       
  1153     prevHat:= 'NoHat';
       
  1154     tmpHatSurf:= nil;
  1236 end;
  1155 end;
  1237 
  1156 
  1238 procedure freeModule;
  1157 procedure freeModule;
       
  1158 var fi: THWFont;
  1239 begin
  1159 begin
  1240     StoreRelease(false);
  1160     StoreRelease(false);
       
  1161     // make sure fonts are cleaned up
       
  1162     for fi:= Low(THWFont) to High(THWFont) do
       
  1163         with Fontz[fi] do
       
  1164             begin
       
  1165             if Handle <> nil then
       
  1166                 begin
       
  1167                 TTF_CloseFont(Handle);
       
  1168                 Handle:= nil;
       
  1169                 end;
       
  1170             end;
       
  1171 
  1241     TTF_Quit();
  1172     TTF_Quit();
  1242     SDL_GL_DeleteContext(SDLGLcontext);
  1173     SDL_GL_DeleteContext(SDLGLcontext);
  1243     SDL_DestroyWindow(SDLwindow);
  1174     SDL_DestroyWindow(SDLwindow);
  1244     SDL_Quit();
  1175     SDL_Quit();
  1245 end;
  1176 end;