hedgewars/uStore.pas
changeset 1 30f2d1037d5d
child 4 bcbd7adb4e4b
equal deleted inserted replaced
0:475c0f2f9d17 1:30f2d1037d5d
       
     1 (*
       
     2  * Hedgewars, a worms-like game
       
     3  * Copyright (c) 2004, 2005 Andrey Korotaev <unC0Rr@gmail.com>
       
     4  *
       
     5  * Distributed under the terms of the BSD-modified licence:
       
     6  *
       
     7  * Permission is hereby granted, free of charge, to any person obtaining a copy
       
     8  * of this software and associated documentation files (the "Software"), to deal
       
     9  * with the Software without restriction, including without limitation the
       
    10  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
       
    11  * sell copies of the Software, and to permit persons to whom the Software is
       
    12  * furnished to do so, subject to the following conditions:
       
    13  *
       
    14  * 1. Redistributions of source code must retain the above copyright notice,
       
    15  *    this list of conditions and the following disclaimer.
       
    16  * 2. Redistributions in binary form must reproduce the above copyright notice,
       
    17  *    this list of conditions and the following disclaimer in the documentation
       
    18  *    and/or other materials provided with the distribution.
       
    19  * 3. The name of the author may not be used to endorse or promote products
       
    20  *    derived from this software without specific prior written permission.
       
    21  *
       
    22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
       
    23  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
       
    24  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
       
    25  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       
    26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
       
    27  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
       
    28  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
       
    29  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
       
    30  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
       
    31  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    32  *)
       
    33 
       
    34 unit uStore;
       
    35 interface
       
    36 uses uConsts, uTeams, SDLh;
       
    37 {$INCLUDE options.inc}
       
    38 
       
    39 type PRangeArray = ^TRangeArray;
       
    40      TRangeArray = array[byte] of record
       
    41                                   Left, Right: integer;
       
    42                                   end;
       
    43 
       
    44 procedure StoreInit;
       
    45 procedure StoreLoad;
       
    46 procedure StoreRelease;
       
    47 procedure DrawGear(Stuff : TStuff; X, Y: integer; Surface: PSDL_Surface);
       
    48 procedure DrawSpriteFromRect(r: TSDL_Rect; X, Y, Height, Position: integer; Surface: PSDL_Surface);
       
    49 procedure DrawSprite (Sprite: TSprite; X, Y, Position: integer; Surface: PSDL_Surface);
       
    50 procedure DrawLand (X, Y: integer; Surface: PSDL_Surface);
       
    51 procedure DXOutText(X, Y: Integer; Font: THWFont; s: string; Surface: PSDL_Surface);
       
    52 procedure DrawCaption(X, Y: integer; Rect: TSDL_Rect; Surface: PSDL_Surface; const fromTempSurf: boolean = false);
       
    53 procedure DrawHedgehog(X, Y: integer; Dir: integer; Pos, Step: LongWord; Surface: PSDL_Surface);
       
    54 procedure DrawExplosion(X, Y, Radius: integer);
       
    55 procedure DrawLineExplosions(ar: PRangeArray; Radius: Longword; y, dY: integer; Count: Byte);
       
    56 procedure RenderHealth(var Hedgehog: THedgehog);
       
    57 function  RenderString(var s: shortstring; Color, Pos: integer): TSDL_Rect;
       
    58 procedure AddProgress;
       
    59 function  LoadImage(filename: string): PSDL_Surface;
       
    60 
       
    61 var PixelFormat: PSDL_PixelFormat;
       
    62  SDLPrimSurface: PSDL_Surface;
       
    63 
       
    64 implementation
       
    65 uses uMisc, uIO, uConsole, uLand;
       
    66 
       
    67 var StoreSurface,
       
    68      TempSurface,
       
    69        HHSurface: PSDL_Surface;
       
    70 
       
    71 procedure DrawExplosion(X, Y, Radius: integer);
       
    72 var ty, tx: integer;
       
    73     p: integer;
       
    74 begin
       
    75 for ty:= max(-Radius, -y) to min(radius, 1023 - y) do
       
    76     for tx:= max(0, round(x-radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(x+radius*sqrt(1-sqr(ty/radius)))) do
       
    77         Land[ty + y, tx]:= 0;
       
    78 
       
    79 if SDL_MustLock(LandSurface) then
       
    80    SDLTry(SDL_LockSurface(LandSurface) >= 0, true);
       
    81 
       
    82 p:= Longword(LandSurface.pixels);
       
    83 case LandSurface.format.BytesPerPixel of
       
    84      1: ;// not supported
       
    85      2: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do
       
    86             for tx:= max(0, round(x-radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(x+radius*sqrt(1-sqr(ty/radius)))) do
       
    87                 PWord(p + LandSurface.pitch*(y + ty) + tx * 2)^:= 0;
       
    88      3: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do
       
    89             for tx:= max(0, round(x-radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(x+radius*sqrt(1-sqr(ty/radius)))) do
       
    90                 begin
       
    91                 PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 0)^:= 0;
       
    92                 PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 1)^:= 0;
       
    93                 PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 2)^:= 0;
       
    94                 end;
       
    95      4: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do
       
    96             for tx:= max(0, round(x-radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(x+radius*sqrt(1-sqr(ty/radius)))) do
       
    97                 PLongword(p + LandSurface.pitch*(y + ty) + tx * 4)^:= 0;
       
    98      end;
       
    99 
       
   100 inc(Radius, 4);
       
   101 
       
   102 case LandSurface.format.BytesPerPixel of
       
   103      1: ;// not supported
       
   104      2: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do
       
   105             for tx:= max(0, round(x-radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(x+radius*sqrt(1-sqr(ty/radius)))) do
       
   106                if PWord(p + LandSurface.pitch*(y + ty) + tx * 2)^ <> 0 then
       
   107                   PWord(p + LandSurface.pitch*(y + ty) + tx * 2)^:= cExplosionBorderColor;
       
   108      3: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do
       
   109             for tx:= max(0, round(x-radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(x+radius*sqrt(1-sqr(ty/radius)))) do
       
   110                 if (PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 0)^ <> 0)
       
   111                 or (PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 1)^ <> 0)
       
   112                 or (PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 2)^ <> 0)
       
   113                 then begin
       
   114                 PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 0)^:= cExplosionBorderColor and $FF;
       
   115                 PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 1)^:= (cExplosionBorderColor shr 8) and $FF;
       
   116                 PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 2)^:= (cExplosionBorderColor shr 16);
       
   117                 end;
       
   118      4: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do
       
   119             for tx:= max(0, round(x-radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(x+radius*sqrt(1-sqr(ty/radius)))) do
       
   120                 if PLongword(p + LandSurface.pitch*(y + ty) + tx * 4)^ <> 0 then
       
   121                    PLongword(p + LandSurface.pitch*(y + ty) + tx * 4)^:= cExplosionBorderColor;
       
   122      end;
       
   123 
       
   124 if SDL_MustLock(LandSurface) then
       
   125    SDL_UnlockSurface(LandSurface);
       
   126 
       
   127 SDL_UpdateRect(LandSurface, X - Radius, Y - Radius, Radius * 2, Radius * 2)
       
   128 end;
       
   129 
       
   130 procedure DrawLineExplosions(ar: PRangeArray; Radius: Longword; y, dY: integer; Count: Byte);
       
   131 var tx, ty, i, p: integer;
       
   132 begin
       
   133 if SDL_MustLock(LandSurface) then
       
   134    SDL_LockSurface(LandSurface);
       
   135 
       
   136 p:= Longword(LandSurface.pixels);
       
   137 for i:= 0 to Pred(Count) do
       
   138     begin
       
   139     case LandSurface.format.BytesPerPixel of
       
   140      1: ;
       
   141      2: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do
       
   142             for tx:= max(0, round(ar[i].Left - radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(ar[i].Right + radius*sqrt(1-sqr(ty/radius)))) do
       
   143                 PWord(p + LandSurface.pitch*(y + ty) + tx * 2)^:= 0;
       
   144      3: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do
       
   145             for tx:= max(0, round(ar[i].Left - radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(ar[i].Right + radius*sqrt(1-sqr(ty/radius)))) do
       
   146                 begin
       
   147                 PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 0)^:= 0;
       
   148                 PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 1)^:= 0;
       
   149                 PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 2)^:= 0;
       
   150                 end;
       
   151      4: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do
       
   152             for tx:= max(0, round(ar[i].Left - radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(ar[i].Right + radius*sqrt(1-sqr(ty/radius)))) do
       
   153                 PLongword(p + LandSurface.pitch*(y + ty) + tx * 4)^:= 0;
       
   154      end;
       
   155     inc(y, dY)
       
   156     end;
       
   157 
       
   158 inc(Radius, 4);
       
   159 dec(y, Count*dY);
       
   160 
       
   161 for i:= 0 to Pred(Count) do
       
   162     begin
       
   163     case LandSurface.format.BytesPerPixel of
       
   164      1: ;
       
   165      2: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do
       
   166             for tx:= max(0, round(ar[i].Left - radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(ar[i].Right + radius*sqrt(1-sqr(ty/radius)))) do
       
   167                if PWord(p + LandSurface.pitch*(y + ty) + tx * 2)^ <> 0 then
       
   168                   PWord(p + LandSurface.pitch*(y + ty) + tx * 2)^:= cExplosionBorderColor;
       
   169      3: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do
       
   170             for tx:= max(0, round(ar[i].Left - radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(ar[i].Right + radius*sqrt(1-sqr(ty/radius)))) do
       
   171                 if (PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 0)^ <> 0)
       
   172                 or (PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 1)^ <> 0)
       
   173                 or (PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 2)^ <> 0)
       
   174                 then begin
       
   175                 PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 0)^:= cExplosionBorderColor and $FF;
       
   176                 PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 1)^:= (cExplosionBorderColor shr 8) and $FF;
       
   177                 PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 2)^:= (cExplosionBorderColor shr 16);
       
   178                 end;
       
   179      4: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do
       
   180             for tx:= max(0, round(ar[i].Left - radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(ar[i].Right + radius*sqrt(1-sqr(ty/radius)))) do
       
   181                 if PLongword(p + LandSurface.pitch*(y + ty) + tx * 4)^ <> 0 then
       
   182                    PLongword(p + LandSurface.pitch*(y + ty) + tx * 4)^:= cExplosionBorderColor;
       
   183      end;
       
   184     inc(y, dY)
       
   185     end;
       
   186 
       
   187 if SDL_MustLock(LandSurface) then
       
   188    SDL_UnlockSurface(LandSurface);
       
   189 end;
       
   190 
       
   191 procedure StoreInit;
       
   192 begin
       
   193 StoreSurface  := SDL_CreateRGBSurface(SDL_HWSURFACE, 576, 1024, cBits, PixelFormat.RMask, PixelFormat.GMask, PixelFormat.BMask, 0);
       
   194 TryDo( StoreSurface <> nil, errmsgCreateSurface + ': store' , true);
       
   195 
       
   196 TempSurface   := SDL_CreateRGBSurface(SDL_HWSURFACE, 724, 320, cBits, PixelFormat.RMask, PixelFormat.GMask, PixelFormat.BMask, 0);
       
   197 TryDo(  TempSurface <> nil, errmsgCreateSurface + ': temp'  , true);
       
   198 
       
   199 TryDo(SDL_SetColorKey( StoreSurface, SDL_SRCCOLORKEY or SDL_RLEACCEL, 0) = 0, errmsgTransparentSet, true);
       
   200 //TryDo(SDL_SetColorKey(SpriteSurface, SDL_SRCCOLORKEY or SDL_RLEACCEL, 0) = 0, errmsgTransparentSet, true);
       
   201 TryDo(SDL_SetColorKey(  TempSurface, SDL_SRCCOLORKEY or SDL_RLEACCEL, 0) = 0, errmsgTransparentSet, true);
       
   202 end;
       
   203 
       
   204 procedure LoadToSurface(Filename: String; Surface: PSDL_Surface; X, Y: integer);
       
   205 var tmpsurf: PSDL_Surface;
       
   206     rr: TSDL_Rect;
       
   207 begin
       
   208   tmpsurf:= LoadImage(Filename);
       
   209   rr.x:= X;
       
   210   rr.y:= Y;
       
   211   SDL_UpperBlit(tmpsurf, nil, Surface, @rr);
       
   212   SDL_FreeSurface(tmpsurf);
       
   213 end;
       
   214 
       
   215 function WriteInRoundRect(Surface: PSDL_Surface; X, Y: integer; Color: LongWord; Font: THWFont; s: string): TSDL_Rect;
       
   216 var w, h: integer;
       
   217     tmpsurf: PSDL_Surface;
       
   218     clr: TSDL_Color;
       
   219 begin
       
   220 TTF_SizeText(Fontz[Font].Handle, PChar(s), w, h);
       
   221 Result.x:= X;
       
   222 Result.y:= Y;
       
   223 Result.w:= w + 6;
       
   224 Result.h:= h + 6;
       
   225 SDL_FillRect(Surface, @Result, 0);
       
   226 Result.w:= 1;
       
   227 Result.y:= Y + 1;
       
   228 Result.h:= h + 4;
       
   229 SDL_FillRect(Surface, @Result, cWhiteColor);
       
   230 Result.x:= X + w + 5;
       
   231 SDL_FillRect(Surface, @Result, cWhiteColor);
       
   232 Result.x:= X + 1;
       
   233 Result.w:= w + 4;
       
   234 Result.y:= Y;
       
   235 Result.h:= 1;
       
   236 SDL_FillRect(Surface, @Result, cWhiteColor);
       
   237 Result.y:= Y + h + 5;
       
   238 SDL_FillRect(Surface, @Result, cWhiteColor);
       
   239 Result.x:= X + 1;
       
   240 Result.y:= Y + 1;
       
   241 Result.h:= h + 4;
       
   242 SDL_FillRect(Surface, @Result, cColorNearBlack);
       
   243 SDL_GetRGB(Color, Surface.format, @clr.r, @clr.g, @clr.b);
       
   244 tmpsurf:= TTF_RenderText_Blended(Fontz[Font].Handle, PChar(s), clr);
       
   245 Result.x:= X + 3;
       
   246 Result.y:= Y + 3;
       
   247 SDL_UpperBlit(tmpsurf, nil, Surface, @Result);
       
   248 SDL_FreeSurface(tmpsurf);
       
   249 Result.x:= X;
       
   250 Result.y:= Y;
       
   251 Result.w:= w + 6;
       
   252 Result.h:= h + 6
       
   253 end;
       
   254 
       
   255 procedure StoreLoad;
       
   256 var i: TStuff;
       
   257     ii: TSprite;
       
   258     fi: THWFont;
       
   259     s: string;
       
   260     tmpsurf: PSDL_Surface;
       
   261 
       
   262     procedure WriteNames(Font: THWFont);
       
   263     var Team: PTeam;
       
   264         i: integer;
       
   265         r: TSDL_Rect;
       
   266     begin
       
   267     r.x:= 0;
       
   268     r.y:= 272;
       
   269     Team:= TeamsList;
       
   270     while Team<>nil do
       
   271       begin
       
   272       r.w:= 1968;
       
   273       r:= WriteInRoundRect(StoreSurface, r.x, r.y, Team.Color, Font, Team.TeamName);
       
   274       Team.NameRect:= r;
       
   275       inc(r.y, r.h);
       
   276       for i:= 0 to 7 do
       
   277           if Team.Hedgehogs[i].Gear<>nil then
       
   278              begin
       
   279              r:= WriteInRoundRect(StoreSurface, r.x, r.y, Team.Color, Font, Team.Hedgehogs[i].Name);
       
   280              Team.Hedgehogs[i].NameRect:= r;
       
   281              inc(r.y, r.h)
       
   282              end;
       
   283       Team:= Team.Next
       
   284       end;
       
   285     end;
       
   286 
       
   287     procedure MakeCrossHairs;
       
   288     var Team: PTeam;
       
   289         r: TSDL_Rect;
       
   290         tmpsurf: PSDL_Surface;
       
   291         s: string;
       
   292         TransColor: Longword;
       
   293     begin
       
   294     r.x:= 0;
       
   295     r.y:= 256;
       
   296     r.w:= 16;
       
   297     r.h:= 16;
       
   298     s:= Pathz[ptGraphics] + cCHFileName;
       
   299     WriteToConsole(msgLoading + s + ' ');
       
   300     tmpsurf:= IMG_Load(PChar(s));
       
   301     TryDo(tmpsurf <> nil, msgFailed, true);
       
   302     WriteLnToConsole(msgOK);
       
   303     TransColor:= SDL_MapRGB(tmpsurf.format, $FF, $FF, $FF);
       
   304     TryDo(SDL_SetColorKey(tmpsurf, SDL_SRCCOLORKEY, TransColor) = 0, errmsgTransparentSet, true);
       
   305 
       
   306     Team:= TeamsList;
       
   307     while Team<>nil do
       
   308       begin
       
   309       SDL_FillRect(StoreSurface, @r, Team.Color);
       
   310       SDL_UpperBlit(tmpsurf, nil, StoreSurface, @r);
       
   311       Team.CrossHairRect:= r;
       
   312       inc(r.x, 16);
       
   313       Team:= Team.Next
       
   314       end;
       
   315       
       
   316     SDL_FreeSurface(tmpsurf)
       
   317     end;
       
   318 
       
   319     procedure InitHealth;
       
   320     var p: PTeam;
       
   321         i, t: integer;
       
   322     begin
       
   323     p:= TeamsList;
       
   324     t:= 0;
       
   325     while p <> nil do
       
   326           begin
       
   327           for i:= 0 to cMaxHHIndex do
       
   328               if p.Hedgehogs[i].Gear <> nil then
       
   329                  begin
       
   330                  p.Hedgehogs[i].HealthRect.y:= t;
       
   331                  RenderHealth(p.Hedgehogs[i]);
       
   332                  inc(t, p.Hedgehogs[i].HealthRect.h)
       
   333                  end;
       
   334           p:= p.Next
       
   335           end
       
   336     end;
       
   337 
       
   338     procedure LoadGraves;
       
   339     var p: PTeam;
       
   340         l: integer;
       
   341     begin
       
   342     p:= TeamsList;
       
   343     l:= 512;
       
   344     while p <> nil do
       
   345           begin
       
   346           dec(l, 32);
       
   347           if p.GraveName = '' then p.GraveName:= 'Simple';
       
   348           LoadToSurface(Pathz[ptGraves] + p.GraveName + '.png', StoreSurface, l, 512);
       
   349           p.GraveRect.x:= l;
       
   350           p.GraveRect.y:= 512;
       
   351           p.GraveRect.w:= 32;
       
   352           p.GraveRect.h:= 256;
       
   353           p:= p.Next
       
   354           end
       
   355     end;
       
   356 
       
   357     procedure GetSkyColor;
       
   358     var p: Longword;
       
   359     begin
       
   360     if SDL_MustLock(StoreSurface) then
       
   361        SDLTry(SDL_LockSurface(StoreSurface) >= 0, true);
       
   362     p:= Longword(StoreSurface.pixels) + Word(StuffPoz[sSky].x) * StoreSurface.format.BytesPerPixel;
       
   363     case StoreSurface.format.BytesPerPixel of
       
   364          1: cSkyColor:= PByte(p)^;
       
   365          2: cSkyColor:= PWord(p)^;
       
   366          3: cSkyColor:= (PByte(p)^) or (PByte(p + 1)^ shl 8) or (PByte(p + 2)^ shl 16);
       
   367          4: cSkyColor:= PLongword(p)^;
       
   368          end;
       
   369     if SDL_MustLock(StoreSurface) then
       
   370        SDL_UnlockSurface(StoreSurface)
       
   371     end;
       
   372 
       
   373     procedure GetExplosionBorderColor;
       
   374     var f: textfile;
       
   375         c: integer;
       
   376     begin
       
   377     s:= Pathz[ptThemeCurrent] + cThemeCFGFilename;
       
   378     WriteToConsole(msgLoading + s + ' ');
       
   379     AssignFile(f, s);
       
   380     {$I-}
       
   381     Reset(f);
       
   382     Readln(f, s);
       
   383     Closefile(f);
       
   384     {$I+}
       
   385     TryDo(IOResult = 0, msgFailed, true);
       
   386     WriteLnToConsole(msgOK);
       
   387     val(s, cExplosionBorderColor, c);
       
   388     if cFullScreen then
       
   389     cExplosionBorderColor:= SDL_MapRGB(PixelFormat, (cExplosionBorderColor shr 16) and $FF,
       
   390                                                     (cExplosionBorderColor shr 8) and $FF,
       
   391                                                      cExplosionBorderColor and $FF)
       
   392     else
       
   393     cExplosionBorderColor:= SDL_MapRGB(LandSurface.format, (cExplosionBorderColor shr 16) and $FF,
       
   394                                                            (cExplosionBorderColor shr 8) and $FF,
       
   395                                                             cExplosionBorderColor and $FF)
       
   396     end;
       
   397 
       
   398 begin
       
   399 for fi:= Low(THWFont) to High(THWFont) do
       
   400     with Fontz[fi] do
       
   401          begin
       
   402          s:= Pathz[ptFonts] + Name;
       
   403          WriteToConsole(msgLoading + s + ' ');
       
   404          Handle:= TTF_OpenFont(PChar(s), Height);
       
   405          TryDo(Handle <> nil, msgFailed, true);
       
   406          WriteLnToConsole(msgOK)
       
   407          end;
       
   408 AddProgress;
       
   409 s:= Pathz[ptMapCurrent] + cLandFileName;
       
   410 WriteToConsole(msgLoading + s + ' ');         // загружаем текущее поле
       
   411 //tmpsurf:= IMG_Load(PChar(s));
       
   412 tmpsurf:= LandSurface;
       
   413 TryDo(tmpsurf <> nil, msgFailed, true);
       
   414 if cFullScreen then
       
   415    begin
       
   416    LandSurface:= SDL_DisplayFormat(tmpsurf);
       
   417    SDL_FreeSurface(tmpsurf);
       
   418    end else LandSurface:= tmpsurf;
       
   419 TryDo(SDL_SetColorKey(LandSurface, SDL_SRCCOLORKEY or SDL_RLEACCEL, 0) = 0, errmsgTransparentSet, true);
       
   420 WriteLnToConsole(msgOK);
       
   421 
       
   422 GetExplosionBorderColor;
       
   423 
       
   424 AddProgress;
       
   425 for i:= Low(TStuff) to High(TStuff) do
       
   426     LoadToSurface(Pathz[StuffLoadData[i].Path] + StuffLoadData[i].FileName, StoreSurface, StuffPoz[i].x, StuffPoz[i].y);
       
   427 
       
   428 AddProgress;
       
   429 WriteNames(fnt16);
       
   430 MakeCrosshairs;
       
   431 LoadGraves;
       
   432 
       
   433 GetSkyColor;
       
   434 
       
   435 AddProgress;
       
   436 for ii:= Low(TSprite) to High(TSprite) do
       
   437     with SpritesData[ii] do
       
   438          begin
       
   439          Surface:= LoadImage(Pathz[Path] + FileName);
       
   440          TryDo(SDL_SetColorKey(Surface, SDL_SRCCOLORKEY or SDL_RLEACCEL, 0) = 0, errmsgTransparentSet, true)
       
   441          end;
       
   442 
       
   443 AddProgress;
       
   444 tmpsurf:= LoadImage(Pathz[ptGraphics] + cHHFileName);
       
   445 HHSurface:= SDL_DisplayFormat(tmpsurf);
       
   446 SDL_FreeSurface(tmpsurf);
       
   447 TryDo(SDL_SetColorKey(HHSurface, SDL_SRCCOLORKEY or SDL_RLEACCEL, 0) = 0, errmsgTransparentSet, true);
       
   448 
       
   449 InitHealth;
       
   450 
       
   451 {$IFDEF DUMP}
       
   452 SDL_SaveBMP_RW(LandSurface, SDL_RWFromFile('LandSurface.bmp', 'wb'), 1);
       
   453 SDL_SaveBMP_RW(StoreSurface, SDL_RWFromFile('StoreSurface.bmp', 'wb'), 1);
       
   454 SDL_SaveBMP_RW(TempSurface, SDL_RWFromFile('TempSurface.bmp', 'wb'), 1);
       
   455 {$ENDIF}
       
   456 end;
       
   457 
       
   458 procedure DrawFromRect(X, Y: integer; r: PSDL_Rect; SourceSurface, DestSurface: PSDL_Surface);
       
   459 var rr: TSDL_Rect;
       
   460 begin
       
   461 rr.x:= X;
       
   462 rr.y:= Y;
       
   463 rr.w:= r.w;
       
   464 rr.h:= r.h;
       
   465 if SDL_UpperBlit(SourceSurface, r, DestSurface, @rr) < 0 then
       
   466    begin
       
   467    Writeln('Blit: ', SDL_GetError);
       
   468    exit
       
   469    end;
       
   470 end;
       
   471 
       
   472 procedure DrawGear(Stuff: TStuff; X, Y: integer; Surface: PSDL_Surface);
       
   473 begin
       
   474 DrawFromRect(X, Y, @StuffPoz[Stuff], StoreSurface, Surface)
       
   475 end;
       
   476 
       
   477 procedure DrawSpriteFromRect(r: TSDL_Rect; X, Y, Height, Position: integer; Surface: PSDL_Surface);
       
   478 begin
       
   479 r.y:= r.y + Height * Position;
       
   480 r.h:= Height;
       
   481 DrawFromRect(X, Y, @r, StoreSurface, Surface)
       
   482 end;
       
   483 
       
   484 procedure DrawSprite(Sprite: TSprite; X, Y, Position: integer; Surface: PSDL_Surface);
       
   485 var r: TSDL_Rect;
       
   486 begin
       
   487 r.x:= 0;
       
   488 r.w:= SpritesData[Sprite].Width;
       
   489 r.y:= Position * SpritesData[Sprite].Height;
       
   490 r.h:= SpritesData[Sprite].Height;
       
   491 DrawFromRect(X, Y, @r, SpritesData[Sprite].Surface, Surface)
       
   492 end;
       
   493 
       
   494 procedure DXOutText(X, Y: Integer; Font: THWFont; s: string; Surface: PSDL_Surface);
       
   495 var clr: TSDL_Color;
       
   496     tmpsurf: PSDL_Surface;
       
   497     r: TSDL_Rect;
       
   498 begin
       
   499 r.x:= X;
       
   500 r.y:= Y;
       
   501 SDL_GetRGB(cWhiteColor, PixelFormat, @clr.r, @clr.g, @clr.b);
       
   502 tmpsurf:= TTF_RenderText_Solid(Fontz[Font].Handle, PChar(s), clr);
       
   503 SDL_UpperBlit(tmpsurf, nil, Surface, @r);
       
   504 SDL_FreeSurface(tmpsurf)
       
   505 end;
       
   506 
       
   507 procedure DrawLand(X, Y: integer; Surface: PSDL_Surface);
       
   508 const r: TSDL_Rect = (x: 0; y: 0; w: 2048; h: 1024);
       
   509 begin
       
   510 DrawFromRect(X, Y, @r, LandSurface, Surface)
       
   511 end;
       
   512 
       
   513 procedure DrawCaption(X, Y: integer; Rect: TSDL_Rect; Surface: PSDL_Surface; const fromTempSurf: boolean = false);
       
   514 begin
       
   515 if fromTempSurf then DrawFromRect(X - (Rect.w) div 2, Y, @Rect, TempSurface,  Surface)
       
   516                 else DrawFromRect(X - (Rect.w) div 2, Y, @Rect, StoreSurface, Surface)
       
   517 end;
       
   518 
       
   519 procedure DrawHedgehog(X, Y: integer; Dir: integer; Pos, Step: LongWord; Surface: PSDL_Surface);
       
   520 var r: TSDL_Rect;
       
   521 begin
       
   522 r.x:= Step * 32;
       
   523 r.y:= Pos * 32;
       
   524 if Dir = -1 then r.x:= cHHSurfaceWidth - 32 - r.x;
       
   525 r.w:= 32;
       
   526 r.h:= 32;
       
   527 DrawFromRect(X, Y, @r, HHSurface, Surface)
       
   528 end;
       
   529 
       
   530 procedure StoreRelease;
       
   531 var ii: TSprite;
       
   532 begin
       
   533 for ii:= Low(TSprite) to High(TSprite) do
       
   534     SDL_FreeSurface(SpritesData[ii].Surface);
       
   535 SDL_FreeSurface(  HHSurface  );
       
   536 SDL_FreeSurface(TempSurface  );
       
   537 SDL_FreeSurface(LandSurface  );
       
   538 SDL_FreeSurface(StoreSurface )
       
   539 end;
       
   540 
       
   541 procedure RenderHealth(var Hedgehog: THedgehog);
       
   542 var s: string;
       
   543 begin
       
   544 str(Hedgehog.Gear.Health, s);
       
   545 Hedgehog.HealthRect:= WriteInRoundRect(TempSurface, Hedgehog.HealthRect.x, Hedgehog.HealthRect.y, Hedgehog.Team.Color, fnt16, s);
       
   546 if Hedgehog.Gear.Damage > 0 then
       
   547    begin
       
   548    str(Hedgehog.Gear.Damage, s);
       
   549    Hedgehog.HealthTagRect:= WriteInRoundRect(TempSurface, Hedgehog.HealthRect.x + Hedgehog.HealthRect.w, Hedgehog.HealthRect.y, Hedgehog.Team.Color, fnt16, s)
       
   550    end;
       
   551 end;
       
   552 
       
   553 function RenderString(var s: shortstring; Color, Pos: integer): TSDL_Rect;
       
   554 begin
       
   555 Result:= WriteInRoundRect(TempSurface, 64, Pos * Fontz[fntBig].Height, Color, fntBig, s);
       
   556 end;
       
   557 
       
   558 procedure AddProgress;
       
   559 const Step: Longword = 0;
       
   560       ProgrSurf: PSDL_Surface = nil;
       
   561       MaxCalls = 10; // MaxCalls should be the count of calls to AddProgress to prevent memory leakage
       
   562 var r: TSDL_Rect;
       
   563 begin
       
   564 if Step = 0 then
       
   565    begin
       
   566    WriteToConsole(msgLoading + 'progress sprite... ');
       
   567    ProgrSurf:= IMG_Load(PChar(string('Data\Graphics\BigDigits.png')));
       
   568    SDLTry(ProgrSurf <> nil, true);
       
   569    WriteLnToConsole(msgOK)
       
   570    end;
       
   571 SDL_FillRect(SDLPrimSurface, nil, 0);
       
   572 r.x:= 0;
       
   573 r.w:= 32;
       
   574 r.h:= 32;
       
   575 r.y:= Step * 32;
       
   576 DrawFromRect(cScreenWidth div 2 - 16, cScreenHeight div 2 - 16, @r, ProgrSurf, SDLPrimSurface);
       
   577 SDL_Flip(SDLPrimSurface);
       
   578 inc(Step);
       
   579 if Step = MaxCalls then
       
   580    begin
       
   581    WriteLnToConsole('Freeing progress surface... ');
       
   582    SDL_FreeSurface(ProgrSurf)
       
   583    end;
       
   584 end;
       
   585 
       
   586 function  LoadImage(filename: string): PSDL_Surface;
       
   587 begin
       
   588 WriteToConsole(msgLoading + filename + '... ');
       
   589 Result:= IMG_Load(PChar(filename));
       
   590 TryDo(Result <> nil, msgFailed, true);
       
   591 WriteLnToConsole(msgOK)
       
   592 end;
       
   593 
       
   594 end.