hedgewars/uMisc.pas
branchexperimental3D
changeset 4812 f924be23ffb4
parent 4343 19cbea33e4d2
parent 4578 f3cf226fad16
child 4976 088d40d8aba2
equal deleted inserted replaced
4347:0ddb100fea61 4812:f924be23ffb4
    19 {$INCLUDE "options.inc"}
    19 {$INCLUDE "options.inc"}
    20 
    20 
    21 unit uMisc;
    21 unit uMisc;
    22 interface
    22 interface
    23 
    23 
    24 uses    SDLh, uConsts, uFloat, GLunit, Math;
    24 uses    SDLh, uConsts, GLunit, uTypes;
    25 
    25 
    26 var
    26 procedure movecursor(dx, dy: LongInt);
    27 /////// init flags ///////
    27 function  doSurfaceConversion(tmpsurf: PSDL_Surface): PSDL_Surface;
    28     cScreenWidth    : LongInt     = 1024;
    28 procedure MakeScreenshot(filename: shortstring);
    29     cScreenHeight   : LongInt     = 768;
    29 function  GetTeamStatString(p: PTeam): shortstring;
    30     cBits           : LongInt     = 32;
       
    31     //ipcPort is in uIO
       
    32     cFullScreen     : boolean     = false;
       
    33     isSoundEnabled  : boolean     = true;
       
    34     isMusicEnabled  : boolean     = false;
       
    35     cLocaleFName    : shortstring = 'en.txt';
       
    36     cInitVolume     : LongInt     = 100;
       
    37     cTimerInterval  : LongInt     = 8;
       
    38     PathPrefix      : shortstring = './';
       
    39     cShowFPS        : boolean     = false;
       
    40     cAltDamage      : boolean     = true;
       
    41     cReducedQuality : LongWord    = rqNone;
       
    42     //userNick is in uChat
       
    43     recordFileName  : shortstring = '';
       
    44     cReadyDelay     : Longword    = 0;
       
    45     cLogfileBase    : shortstring = 'debug';
       
    46 //////////////////////////
       
    47     
       
    48     isCursorVisible : boolean;
       
    49     isTerminated    : boolean;
       
    50     isInLag         : boolean;
       
    51     isPaused        : boolean;
       
    52 
       
    53     isSEBackup      : boolean;
       
    54     isInMultiShoot  : boolean;
       
    55     isSpeed         : boolean;
       
    56     isFirstFrame    : boolean;
       
    57 
       
    58     cStereoMode     : TStereoMode;
       
    59     fastUntilLag    : boolean;
       
    60 
       
    61     GameState       : TGameState;
       
    62     GameType        : TGameType;
       
    63     GameFlags       : Longword;
       
    64     TrainingFlags   : Longword;
       
    65     TurnTimeLeft    : Longword;
       
    66     ReadyTimeLeft   : Longword;
       
    67     cSuddenDTurns   : LongInt;
       
    68     cDamagePercent  : LongInt;
       
    69     cMineDudPercent : LongWord;
       
    70     cTemplateFilter : LongInt;
       
    71     cMapGen         : LongInt;
       
    72     cMazeSize       : LongInt;
       
    73 
       
    74     cHedgehogTurnTime: Longword;
       
    75     cMinesTime       : LongInt;
       
    76     cMaxAIThinkTime  : Longword;
       
    77 
       
    78     cHealthCaseProb  : LongInt;
       
    79     cHealthCaseAmount: LongInt;
       
    80     cWaterRise       : LongInt;
       
    81     cHealthDecrease  : LongInt;
       
    82 
       
    83     cCloudsNumber    : LongInt;
       
    84 
       
    85     cTagsMask        : byte;
       
    86     zoom             : GLfloat;
       
    87     ZoomValue        : GLfloat;
       
    88 
       
    89     cWaterLine       : LongInt;
       
    90     cGearScrEdgesDist: LongInt;
       
    91 
       
    92     GameTicks   : LongWord;
       
    93     TrainingTimeInc : Longword;
       
    94     TrainingTimeInD : Longword;
       
    95     TrainingTimeInM : Longword;
       
    96     TrainingTimeMax : Longword;
       
    97 
       
    98     TimeTrialStartTime: Longword;
       
    99     TimeTrialStopTime : Longword;
       
   100 
       
   101     // originally from uConsts
       
   102     Pathz: array[TPathType] of shortstring;
       
   103     CountTexz: array[1..Pred(AMMO_INFINITE)] of PTexture;
       
   104     LAND_WIDTH       : LongInt;
       
   105     LAND_HEIGHT      : LongInt;
       
   106     LAND_WIDTH_MASK  : LongWord;
       
   107     LAND_HEIGHT_MASK : LongWord;
       
   108     cMaxCaptions     : LongInt;
       
   109 
       
   110     cLeftScreenBorder     : LongInt;
       
   111     cRightScreenBorder    : LongInt;
       
   112     cScreenSpace          : LongInt;
       
   113 
       
   114     cCaseFactor     : Longword;
       
   115     cLandMines      : Longword;
       
   116     cExplosives     : Longword;
       
   117 
       
   118     cSeed           : shortstring;
       
   119     cVolumeDelta    : LongInt;
       
   120     cHasFocus       : boolean;
       
   121     cInactDelay     : Longword;
       
   122 
       
   123     bBetweenTurns   : boolean;
       
   124     bWaterRising    : boolean;
       
   125 
       
   126     ShowCrosshair   : boolean;
       
   127     CursorMovementX : LongInt;
       
   128     CursorMovementY : LongInt;
       
   129     cDrownSpeed     : hwFloat;
       
   130     cDrownSpeedf    : float;
       
   131     cMaxWindSpeed   : hwFloat;
       
   132     cWindSpeed      : hwFloat;
       
   133     cWindSpeedf     : float;
       
   134     cGravity        : hwFloat;
       
   135     cGravityf       : float;
       
   136     cDamageModifier : hwFloat;
       
   137     cLaserSighting  : boolean;
       
   138     cVampiric       : boolean;
       
   139     cArtillery      : boolean;
       
   140     WeaponTooltipTex : PTexture;
       
   141 
       
   142     flagMakeCapture : boolean;
       
   143 
       
   144     InitStepsFlags  : Longword;
       
   145     RealTicks       : Longword;
       
   146     AttackBar       : LongInt;
       
   147 
       
   148     WaterColorArray : array[0..3] of HwColor4f;
       
   149 
       
   150     CursorPoint     : TPoint;
       
   151     TargetPoint     : TPoint;
       
   152 
       
   153     TextureList     : PTexture;
       
   154 
       
   155     ScreenFade      : TScreenFade;
       
   156     ScreenFadeValue : LongInt;
       
   157     ScreenFadeSpeed : LongInt;
       
   158 
       
   159 {$IFDEF SDL13}
       
   160     SDLwindow       : PSDL_Window;
       
   161 {$ENDIF}
       
   162 
    30 
   163 procedure initModule;
    31 procedure initModule;
   164 procedure freeModule;
    32 procedure freeModule;
   165 procedure SplitBySpace(var a, b: shortstring);
       
   166 procedure SplitByChar(var a, b: ansistring; c: char);
       
   167 function  EnumToStr(const en : TGearType) : shortstring; overload;
       
   168 function  EnumToStr(const en : TSound) : shortstring; overload;
       
   169 function  EnumToStr(const en : TAmmoType) : shortstring; overload;
       
   170 function  EnumToStr(const en : THogEffect) : shortstring; overload;
       
   171 procedure movecursor(dx, dy: LongInt);
       
   172 function  hwSign(r: hwFloat): LongInt; inline;
       
   173 function  Min(a, b: LongInt): LongInt; inline;
       
   174 function  Max(a, b: LongInt): LongInt; inline;
       
   175 procedure OutError(Msg: shortstring; isFatalError: boolean);
       
   176 procedure TryDo(Assert: boolean; Msg: shortstring; isFatal: boolean); inline;
       
   177 procedure SDLTry(Assert: boolean; isFatal: boolean);
       
   178 function  IntToStr(n: LongInt): shortstring;
       
   179 function  FloatToStr(n: hwFloat): shortstring;
       
   180 function  DxDy2Angle(const _dY, _dX: hwFloat): GLfloat;
       
   181 function  DxDy2Angle32(const _dY, _dX: hwFloat): LongInt;
       
   182 function  DxDy2AttackAngle(const _dY, _dX: hwFloat): LongInt;
       
   183 (*
       
   184 procedure AdjustColor(var Color: Longword);
       
   185 procedure SetKB(n: Longword);
       
   186 *)
       
   187 procedure SendKB;
       
   188 procedure SetLittle(var r: hwFloat);
       
   189 procedure SendStat(sit: TStatInfoType; s: shortstring);
       
   190 function  Str2PChar(const s: shortstring): PChar;
       
   191 function  NewTexture(width, height: Longword; buf: Pointer): PTexture;
       
   192 function  Surface2Tex(surf: PSDL_Surface; enableClamp: boolean): PTexture;
       
   193 procedure FreeTexture(tex: PTexture);
       
   194 function  toPowerOf2(i: Longword): Longword; inline;
       
   195 function  DecodeBase64(s: shortstring): shortstring;
       
   196 function  doSurfaceConversion(tmpsurf: PSDL_Surface): PSDL_Surface;
       
   197 function  endian(independent: LongWord): LongWord; inline;
       
   198 {$IFDEF DEBUGFILE}
       
   199 procedure AddFileLog(s: shortstring);
       
   200 (* function  RectToStr(Rect: TSDL_Rect): shortstring; *)
       
   201 {$ENDIF}
       
   202 procedure MakeScreenshot(filename: shortstring);
       
   203 
    33 
   204 implementation
    34 implementation
   205 uses uConsole, uStore, uIO, uSound, typinfo, sysutils, uMobile;
    35 uses typinfo, sysutils, uVariables;
   206 
       
   207 var KBnum: Longword;
       
   208 {$IFDEF DEBUGFILE}
       
   209     f: textfile;
       
   210 {$ENDIF}
       
   211 
       
   212 // should this include "strtolower()" for the split string?
       
   213 procedure SplitBySpace(var a, b: shortstring);
       
   214 var i, t: LongInt;
       
   215 begin
       
   216 i:= Pos(' ', a);
       
   217 if i > 0 then
       
   218     begin
       
   219     for t:= 1 to Pred(i) do
       
   220         if (a[t] >= 'A')and(a[t] <= 'Z') then Inc(a[t], 32);
       
   221     b:= copy(a, i + 1, Length(a) - i);
       
   222     byte(a[0]):= Pred(i)
       
   223     end else b:= '';
       
   224 end;
       
   225 
       
   226 procedure SplitByChar(var a, b: ansistring; c: char);
       
   227 var i: LongInt;
       
   228 begin
       
   229 i:= Pos(c, a);
       
   230 if i > 0 then
       
   231     begin
       
   232     b:= copy(a, i + 1, Length(a) - i);
       
   233     setlength(a, Pred(i));
       
   234     end else b:= '';
       
   235 end;
       
   236 
       
   237 function EnumToStr(const en : TGearType) : shortstring; overload;
       
   238 begin
       
   239 EnumToStr:= GetEnumName(TypeInfo(TGearType), ord(en))
       
   240 end;
       
   241 
       
   242 function EnumToStr(const en : TSound) : shortstring; overload;
       
   243 begin
       
   244 EnumToStr:= GetEnumName(TypeInfo(TSound), ord(en))
       
   245 end;
       
   246 
       
   247 function EnumToStr(const en : TAmmoType) : shortstring; overload;
       
   248 begin
       
   249 EnumToStr:= GetEnumName(TypeInfo(TAmmoType), ord(en))
       
   250 end;
       
   251 
       
   252 function EnumToStr(const en: THogEffect) : shortstring; overload;
       
   253 begin
       
   254     EnumToStr := GetEnumName(TypeInfo(THogEffect), ord(en))
       
   255 end;
       
   256 
    36 
   257 procedure movecursor(dx, dy: LongInt);
    37 procedure movecursor(dx, dy: LongInt);
   258 var x, y: LongInt;
    38 var x, y: LongInt;
   259 begin
    39 begin
   260 if (dx = 0) and (dy = 0) then exit;
    40 if (dx = 0) and (dy = 0) then exit;
   263 Inc(x, dx);
    43 Inc(x, dx);
   264 Inc(y, dy);
    44 Inc(y, dy);
   265 SDL_WarpMouse(x, y);
    45 SDL_WarpMouse(x, y);
   266 end;
    46 end;
   267 
    47 
   268 function hwSign(r: hwFloat): LongInt;
       
   269 begin
       
   270 // yes, we have negative zero for a reason
       
   271 if r.isNegative then hwSign:= -1 else hwSign:= 1
       
   272 end;
       
   273 
       
   274 function Min(a, b: LongInt): LongInt;
       
   275 begin
       
   276 if a < b then Min:= a else Min:= b
       
   277 end;
       
   278 
       
   279 function Max(a, b: LongInt): LongInt;
       
   280 begin
       
   281 if a > b then Max:= a else Max:= b
       
   282 end;
       
   283 
       
   284 procedure OutError(Msg: shortstring; isFatalError: boolean);
       
   285 begin
       
   286 // obsolete? written in WriteLnToConsole() anyway
       
   287 // {$IFDEF DEBUGFILE}AddFileLog(Msg);{$ENDIF}
       
   288 WriteLnToConsole(Msg);
       
   289 if isFatalError then
       
   290     begin
       
   291     SendIPC('E' + GetLastConsoleLine);
       
   292     SDL_Quit;
       
   293     halt(1)
       
   294     end
       
   295 end;
       
   296 
       
   297 procedure TryDo(Assert: boolean; Msg: shortstring; isFatal: boolean);
       
   298 begin
       
   299 if not Assert then OutError(Msg, isFatal)
       
   300 end;
       
   301 
       
   302 procedure SDLTry(Assert: boolean; isFatal: boolean);
       
   303 begin
       
   304 if not Assert then OutError(SDL_GetError, isFatal)
       
   305 end;
       
   306 
       
   307 (*
       
   308 procedure AdjustColor(var Color: Longword);
       
   309 begin
       
   310 Color:= SDL_MapRGB(PixelFormat, (Color shr 16) and $FF, (Color shr 8) and $FF, Color and $FF)
       
   311 end;
       
   312 
       
   313 procedure SetKB(n: Longword);
       
   314 begin
       
   315 KBnum:= n
       
   316 end;
       
   317 *)
       
   318 
       
   319 
       
   320 function IntToStr(n: LongInt): shortstring;
       
   321 begin
       
   322 str(n, IntToStr)
       
   323 end;
       
   324 
       
   325 function FloatToStr(n: hwFloat): shortstring;
       
   326 begin
       
   327 FloatToStr:= cstr(n) + '_' + inttostr(Lo(n.QWordValue))
       
   328 end;
       
   329 
       
   330 procedure SetTextureParameters(enableClamp: Boolean);
       
   331 begin
       
   332     if enableClamp and ((cReducedQuality and rqClampLess) = 0) then
       
   333     begin
       
   334         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
       
   335         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
       
   336     end;
       
   337     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
       
   338     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
       
   339 end;
       
   340 
       
   341 function DxDy2Angle(const _dY, _dX: hwFloat): GLfloat;
       
   342 var dY, dX: Extended;
       
   343 begin
       
   344 dY:= _dY.QWordValue / $100000000;
       
   345 if _dY.isNegative then dY:= - dY;
       
   346 dX:= _dX.QWordValue / $100000000;
       
   347 if _dX.isNegative then dX:= - dX;
       
   348 DxDy2Angle:= arctan2(dY, dX) * 180 / pi
       
   349 end;
       
   350 
       
   351 function DxDy2Angle32(const _dY, _dX: hwFloat): LongInt;
       
   352 const _16divPI: Extended = 16/pi;
       
   353 var dY, dX: Extended;
       
   354 begin
       
   355 dY:= _dY.QWordValue / $100000000;
       
   356 if _dY.isNegative then dY:= - dY;
       
   357 dX:= _dX.QWordValue / $100000000;
       
   358 if _dX.isNegative then dX:= - dX;
       
   359 DxDy2Angle32:= trunc(arctan2(dY, dX) * _16divPI) and $1f
       
   360 end;
       
   361 
       
   362 function DxDy2AttackAngle(const _dY, _dX: hwFloat): LongInt;
       
   363 const MaxAngleDivPI: Extended = cMaxAngle/pi;
       
   364 var dY, dX: Extended;
       
   365 begin
       
   366 dY:= _dY.QWordValue / $100000000;
       
   367 if _dY.isNegative then dY:= - dY;
       
   368 dX:= _dX.QWordValue / $100000000;
       
   369 if _dX.isNegative then dX:= - dX;
       
   370 DxDy2AttackAngle:= trunc(arctan2(dY, dX) * MaxAngleDivPI)
       
   371 end;
       
   372 
       
   373 procedure SendKB;
       
   374 var s: shortstring;
       
   375 begin
       
   376 if KBnum <> 0 then
       
   377 begin
       
   378 s:= 'K' + inttostr(KBnum);
       
   379 SendIPCRaw(@s, Length(s) + 1)
       
   380 end
       
   381 end;
       
   382 
       
   383 procedure SetLittle(var r: hwFloat);
       
   384 begin
       
   385 r:= SignAs(cLittle, r)
       
   386 end;
       
   387 
       
   388 procedure SendStat(sit: TStatInfoType; s: shortstring);
       
   389 const stc: array [TStatInfoType] of char = 'rDkKHTPsSB';
       
   390 var buf: shortstring;
       
   391 begin
       
   392 buf:= 'i' + stc[sit] + s;
       
   393 SendIPCRaw(@buf[0], length(buf) + 1)
       
   394 end;
       
   395 
       
   396 function Str2PChar(const s: shortstring): PChar;
       
   397 const CharArray: array[byte] of Char = '';
       
   398 begin
       
   399 CharArray:= s;
       
   400 CharArray[Length(s)]:= #0;
       
   401 Str2PChar:= @CharArray
       
   402 end;
       
   403 
       
   404 function isPowerOf2(i: Longword): boolean;
       
   405 begin
       
   406 if i = 0 then exit(true);
       
   407 while (i and 1) = 0 do i:= i shr 1;
       
   408 isPowerOf2:= (i = 1)
       
   409 end;
       
   410 
       
   411 function toPowerOf2(i: Longword): Longword;
       
   412 begin
       
   413 toPowerOf2:= 1;
       
   414 while (toPowerOf2 < i) do toPowerOf2:= toPowerOf2 shl 1
       
   415 end;
       
   416 
       
   417 procedure ResetVertexArrays(texture: PTexture);
       
   418 begin
       
   419 with texture^ do
       
   420     begin
       
   421     vb[0].X:= 0;
       
   422     vb[0].Y:= 0;
       
   423     vb[1].X:= w;
       
   424     vb[1].Y:= 0;
       
   425     vb[2].X:= w;
       
   426     vb[2].Y:= h;
       
   427     vb[3].X:= 0;
       
   428     vb[3].Y:= h;
       
   429 
       
   430     tb[0].X:= 0;
       
   431     tb[0].Y:= 0;
       
   432     tb[1].X:= rx;
       
   433     tb[1].Y:= 0;
       
   434     tb[2].X:= rx;
       
   435     tb[2].Y:= ry;
       
   436     tb[3].X:= 0;
       
   437     tb[3].Y:= ry
       
   438     end;
       
   439 end;
       
   440 
       
   441 function NewTexture(width, height: Longword; buf: Pointer): PTexture;
       
   442 begin
       
   443 new(NewTexture);
       
   444 NewTexture^.PrevTexture:= nil;
       
   445 NewTexture^.NextTexture:= nil;
       
   446 NewTexture^.Scale:= 1;
       
   447 if TextureList <> nil then
       
   448     begin
       
   449     TextureList^.PrevTexture:= NewTexture;
       
   450     NewTexture^.NextTexture:= TextureList
       
   451     end;
       
   452 TextureList:= NewTexture;
       
   453 
       
   454 NewTexture^.w:= width;
       
   455 NewTexture^.h:= height;
       
   456 NewTexture^.rx:= 1.0;
       
   457 NewTexture^.ry:= 1.0;
       
   458 
       
   459 ResetVertexArrays(NewTexture);
       
   460 
       
   461 glGenTextures(1, @NewTexture^.id);
       
   462 
       
   463 glBindTexture(GL_TEXTURE_2D, NewTexture^.id);
       
   464 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf);
       
   465 
       
   466 SetTextureParameters(true);
       
   467 end;
       
   468 
       
   469 function Surface2Tex(surf: PSDL_Surface; enableClamp: boolean): PTexture;
       
   470 var tw, th, x, y: Longword;
       
   471     tmpp: pointer;
       
   472     fromP4, toP4: PLongWordArray;
       
   473 begin
       
   474 new(Surface2Tex);
       
   475 Surface2Tex^.PrevTexture:= nil;
       
   476 Surface2Tex^.NextTexture:= nil;
       
   477 if TextureList <> nil then
       
   478     begin
       
   479     TextureList^.PrevTexture:= Surface2Tex;
       
   480     Surface2Tex^.NextTexture:= TextureList
       
   481     end;
       
   482 TextureList:= Surface2Tex;
       
   483 
       
   484 Surface2Tex^.w:= surf^.w;
       
   485 Surface2Tex^.h:= surf^.h;
       
   486 
       
   487 if (surf^.format^.BytesPerPixel <> 4) then
       
   488     begin
       
   489     TryDo(false, 'Surface2Tex failed, expecting 32 bit surface', true);
       
   490     Surface2Tex^.id:= 0;
       
   491     exit
       
   492     end;
       
   493 
       
   494 
       
   495 glGenTextures(1, @Surface2Tex^.id);
       
   496 
       
   497 glBindTexture(GL_TEXTURE_2D, Surface2Tex^.id);
       
   498 
       
   499 if SDL_MustLock(surf) then
       
   500     SDLTry(SDL_LockSurface(surf) >= 0, true);
       
   501 
       
   502 if (not SupportNPOTT) and (not (isPowerOf2(Surf^.w) and isPowerOf2(Surf^.h))) then
       
   503     begin
       
   504     tw:= toPowerOf2(Surf^.w);
       
   505     th:= toPowerOf2(Surf^.h);
       
   506 
       
   507     Surface2Tex^.rx:= Surf^.w / tw;
       
   508     Surface2Tex^.ry:= Surf^.h / th;
       
   509 
       
   510     GetMem(tmpp, tw * th * surf^.format^.BytesPerPixel);
       
   511 
       
   512     fromP4:= Surf^.pixels;
       
   513     toP4:= tmpp;
       
   514 
       
   515     for y:= 0 to Pred(Surf^.h) do
       
   516         begin
       
   517         for x:= 0 to Pred(Surf^.w) do toP4^[x]:= fromP4^[x];
       
   518         for x:= Surf^.w to Pred(tw) do toP4^[x]:= 0;
       
   519         toP4:= @(toP4^[tw]);
       
   520         fromP4:= @(fromP4^[Surf^.pitch div 4])
       
   521         end;
       
   522 
       
   523     for y:= Surf^.h to Pred(th) do
       
   524         begin
       
   525         for x:= 0 to Pred(tw) do toP4^[x]:= 0;
       
   526         toP4:= @(toP4^[tw])
       
   527         end;
       
   528 
       
   529     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tw, th, 0, GL_RGBA, GL_UNSIGNED_BYTE, tmpp);
       
   530 
       
   531     FreeMem(tmpp, tw * th * surf^.format^.BytesPerPixel)
       
   532     end
       
   533 else
       
   534     begin
       
   535     Surface2Tex^.rx:= 1.0;
       
   536     Surface2Tex^.ry:= 1.0;
       
   537     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surf^.w, surf^.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, surf^.pixels);
       
   538     end;
       
   539 
       
   540 ResetVertexArrays(Surface2Tex);
       
   541 
       
   542 if SDL_MustLock(surf) then
       
   543     SDL_UnlockSurface(surf);
       
   544 
       
   545 SetTextureParameters(enableClamp);
       
   546 end;
       
   547 
       
   548 procedure FreeTexture(tex: PTexture);
       
   549 begin
       
   550     if tex <> nil then
       
   551     begin
       
   552         if tex^.NextTexture <> nil then
       
   553             tex^.NextTexture^.PrevTexture:= tex^.PrevTexture;
       
   554         if tex^.PrevTexture <> nil then
       
   555             tex^.PrevTexture^.NextTexture:= tex^.NextTexture
       
   556         else
       
   557             TextureList:= tex^.NextTexture;
       
   558         glDeleteTextures(1, @tex^.id);
       
   559         Dispose(tex);
       
   560     end
       
   561 end;
       
   562 
       
   563 function DecodeBase64(s: shortstring): shortstring;
       
   564 const table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
       
   565 var i, t, c: Longword;
       
   566 begin
       
   567 c:= 0;
       
   568 for i:= 1 to Length(s) do
       
   569     begin
       
   570     t:= Pos(s[i], table);
       
   571     if s[i] = '=' then inc(c);
       
   572     if t > 0 then byte(s[i]):= t - 1 else byte(s[i]):= 0
       
   573     end;
       
   574 
       
   575 i:= 1;
       
   576 t:= 1;
       
   577 while i <= length(s) do
       
   578     begin
       
   579     DecodeBase64[t    ]:= char((byte(s[i    ]) shl 2) or (byte(s[i + 1]) shr 4));
       
   580     DecodeBase64[t + 1]:= char((byte(s[i + 1]) shl 4) or (byte(s[i + 2]) shr 2));
       
   581     DecodeBase64[t + 2]:= char((byte(s[i + 2]) shl 6) or (byte(s[i + 3])      ));
       
   582     inc(t, 3);
       
   583     inc(i, 4)
       
   584     end;
       
   585 
       
   586 if c < 3 then t:= t - c;
       
   587 
       
   588 byte(DecodeBase64[0]):= t - 1
       
   589 end;
       
   590 
    48 
   591 procedure MakeScreenshot(filename: shortstring);
    49 procedure MakeScreenshot(filename: shortstring);
   592 var p: Pointer;
    50 var p: Pointer;
   593     size: Longword;
    51     size: Longword;
   594     f: file;
    52     f: file;
   609     96, 0, 0, 0, // vertical resolution
    67     96, 0, 0, 0, // vertical resolution
   610     0, 0, 0, 0, // number of colors (all)
    68     0, 0, 0, 0, // number of colors (all)
   611     0, 0, 0, 0 // number of important colors
    69     0, 0, 0, 0 // number of important colors
   612     );
    70     );
   613 begin
    71 begin
   614 playSound(sndShutter);
       
   615 
       
   616 // flash
    72 // flash
   617 ScreenFade:= sfFromWhite;
    73 ScreenFade:= sfFromWhite;
   618 ScreenFadeValue:= sfMax;
    74 ScreenFadeValue:= sfMax;
   619 ScreenFadeSpeed:= 5;
    75 ScreenFadeSpeed:= 5;
   620 
    76 
   658 {$I+}
   114 {$I+}
   659 
   115 
   660 FreeMem(p)
   116 FreeMem(p)
   661 end;
   117 end;
   662 
   118 
   663 {$IFDEF DEBUGFILE}
       
   664 procedure AddFileLog(s: shortstring);
       
   665 begin
       
   666 writeln(f, GameTicks: 6, ': ', s);
       
   667 flush(f)
       
   668 end;
       
   669 (*
       
   670 function RectToStr(Rect: TSDL_Rect): shortstring;
       
   671 begin
       
   672 RectToStr:= '(x: ' + inttostr(rect.x) + '; y: ' + inttostr(rect.y) + '; w: ' + inttostr(rect.w) + '; h: ' + inttostr(rect.h) + ')'
       
   673 end;
       
   674 *)
       
   675 {$ENDIF}
       
   676 
       
   677 function doSurfaceConversion(tmpsurf: PSDL_Surface): PSDL_Surface;
   119 function doSurfaceConversion(tmpsurf: PSDL_Surface): PSDL_Surface;
   678 {* for more information http://www.idevgames.com/forum/showpost.php?p=85864&postcount=7 *}
   120 {* for more information http://www.idevgames.com/forum/showpost.php?p=85864&postcount=7 *}
   679 var convertedSurf: PSDL_Surface = nil;
   121 var convertedSurf: PSDL_Surface = nil;
   680 begin
   122 begin
   681     if (tmpsurf^.format^.bitsperpixel = 24) or ((tmpsurf^.format^.bitsperpixel = 32) and (tmpsurf^.format^.rshift > tmpsurf^.format^.bshift)) then
   123     if (tmpsurf^.format^.bitsperpixel = 24) or ((tmpsurf^.format^.bitsperpixel = 32) and (tmpsurf^.format^.rshift > tmpsurf^.format^.bshift)) then
   682     begin
   124         begin
   683         convertedSurf:= SDL_ConvertSurface(tmpsurf, @conversionFormat, SDL_SWSURFACE);
   125         convertedSurf:= SDL_ConvertSurface(tmpsurf, @conversionFormat, SDL_SWSURFACE);
   684         SDL_FreeSurface(tmpsurf);
   126         SDL_FreeSurface(tmpsurf);
   685         exit(convertedSurf);
   127         exit(convertedSurf);
   686     end;
   128         end;
   687 
   129 
   688     exit(tmpsurf);
   130     exit(tmpsurf);
   689 end;
   131 end;
   690 
   132 
   691 function endian(independent: LongWord): LongWord; inline;
   133 
       
   134 function GetTeamStatString(p: PTeam): shortstring;
       
   135 var s: ansistring;
   692 begin
   136 begin
   693 {$IFDEF ENDIAN_LITTLE}
   137     s:= p^.TeamName + ':' + IntToStr(p^.TeamHealth) + ':';
   694 endian:= independent;
   138     GetTeamStatString:= s;
   695 {$ELSE}
       
   696 endian:= (((independent and $FF000000) shr 24) or
       
   697           ((independent and $00FF0000) shr 8) or
       
   698           ((independent and $0000FF00) shl 8) or
       
   699           ((independent and $000000FF) shl 24))
       
   700 {$ENDIF}
       
   701 end;
   139 end;
   702 
   140 
   703 
       
   704 procedure initModule;
   141 procedure initModule;
   705 {$IFDEF DEBUGFILE}{$IFNDEF IPHONEOS}var i: LongInt;{$ENDIF}{$ENDIF}
       
   706 begin
   142 begin
   707     Pathz:= cPathz;
       
   708         {*  REFERENCE
       
   709       4096 -> $FFFFF000
       
   710       2048 -> $FFFFF800
       
   711       1024 -> $FFFFFC00
       
   712        512 -> $FFFFFE00  *}
       
   713     if (cReducedQuality and rqLowRes) <> 0 then
       
   714     begin
       
   715         LAND_WIDTH:= 2048;
       
   716         LAND_HEIGHT:= 1024;
       
   717         LAND_WIDTH_MASK:= $FFFFF800;
       
   718         LAND_HEIGHT_MASK:= $FFFFFC00;
       
   719     end
       
   720     else
       
   721     begin
       
   722         LAND_WIDTH:= 4096;
       
   723         LAND_HEIGHT:= 2048;
       
   724         LAND_WIDTH_MASK:= $FFFFF000;
       
   725         LAND_HEIGHT_MASK:= $FFFFF800
       
   726     end;
       
   727 
       
   728     cDrownSpeed.QWordValue  := 257698038;       // 0.06
       
   729     cDrownSpeedf            := 0.06;
       
   730     cMaxWindSpeed.QWordValue:= 1073742;     // 0.00025
       
   731     cWindSpeed.QWordValue   := 429496;      // 0.0001
       
   732     cWindSpeedf             := 0.0001;
       
   733     cGravity                := cMaxWindSpeed * 2;
       
   734     cGravityf               := 0.00025 * 2;
       
   735     cDamageModifier         := _1;
       
   736     TargetPoint             := cTargetPointRef;
       
   737     TextureList             := nil;
       
   738 
       
   739     // int, longint longword and byte
       
   740     CursorMovementX     := 0;
       
   741     CursorMovementY     := 0;
       
   742     GameTicks           := 0;
       
   743     TrainingTimeInc     := 10000;
       
   744     TrainingTimeInD     := 500;
       
   745     TrainingTimeInM     := 5000;
       
   746     TrainingTimeMax     := 60000;
       
   747     TimeTrialStartTime  := 0;
       
   748     TimeTrialStopTime   := 0;
       
   749     cWaterLine          := LAND_HEIGHT;
       
   750     cGearScrEdgesDist   := 240;
       
   751 
       
   752     GameFlags           := 0;
       
   753     TrainingFlags       := 0;
       
   754     TurnTimeLeft        := 0;
       
   755     cSuddenDTurns       := 15;
       
   756     cDamagePercent      := 100;
       
   757     cMineDudPercent     := 0;
       
   758     cTemplateFilter     := 0;
       
   759     cMapGen             := 0;   // MAPGEN_REGULAR
       
   760     cMazeSize           := 0;
       
   761     cHedgehogTurnTime   := 45000;
       
   762     cMinesTime          := 3;
       
   763     cMaxAIThinkTime     := 9000;
       
   764     cCloudsNumber       := 9;
       
   765     cHealthCaseProb     := 35;
       
   766     cHealthCaseAmount   := 25;
       
   767     cWaterRise          := 47;
       
   768     cHealthDecrease     := 5;
       
   769 
       
   770     cTagsMask       := 0;
       
   771     KBnum           := 0;
       
   772     InitStepsFlags  := 0;
       
   773     RealTicks       := 0;
       
   774     AttackBar       := 0; // 0 - none, 1 - just bar at the right-down corner, 2 - from weapon
       
   775     cCaseFactor     := 5;  {0..9}
       
   776     cLandMines      := 4;
       
   777     cExplosives     := 2;
       
   778 
       
   779     GameState       := Low(TGameState);
       
   780     GameType        := gmtLocal;
       
   781     zoom            := cDefaultZoomLevel;
       
   782     ZoomValue       := cDefaultZoomLevel;
       
   783     WeaponTooltipTex:= nil;
       
   784     cLaserSighting  := false;
       
   785     cVampiric       := false;
       
   786     cArtillery      := false;
       
   787     flagMakeCapture := false;
       
   788     bBetweenTurns   := false;
       
   789     bWaterRising    := false;
       
   790     isCursorVisible := false;
       
   791     isTerminated    := false;
       
   792     isInLag         := false;
       
   793     isPaused        := false;
       
   794     isInMultiShoot  := false;
       
   795     isSpeed         := false;
       
   796     fastUntilLag    := false;
       
   797     isFirstFrame    := true;
       
   798     isSEBackup      := true;
       
   799     cSeed           := '';
       
   800     cVolumeDelta    := 0;
       
   801     cHasFocus       := true;
       
   802     cInactDelay     := 1250;
       
   803     ReadyTimeLeft   := 0;
       
   804 
       
   805     ScreenFade      := sfNone;
       
   806 
       
   807 {$IFDEF SDL13}
       
   808     SDLwindow       := nil;
       
   809 {$ENDIF}
       
   810 
       
   811     // those values still aren't perfect
       
   812     cLeftScreenBorder:= round(-cMinZoomLevel * cScreenWidth);
       
   813     cRightScreenBorder:= round(cMinZoomLevel * cScreenWidth + LAND_WIDTH);
       
   814     cScreenSpace:= cRightScreenBorder - cLeftScreenBorder;
       
   815 
       
   816     if isPhone() then
       
   817         cMaxCaptions:= 3
       
   818     else
       
   819         cMaxCaptions:= 4;
       
   820 
       
   821 {$IFDEF DEBUGFILE}
       
   822 {$I-}
       
   823 {$IFDEF IPHONEOS}
       
   824     Assign(f,'../Documents/hw-' + cLogfileBase + '.log');
       
   825     Rewrite(f);
       
   826 {$ELSE}
       
   827     if (ParamStr(1) <> '') and (ParamStr(2) <> '') then
       
   828         if (ParamCount <> 3) and (ParamCount <> cDefaultParamNum) then
       
   829         begin
       
   830             for i:= 0 to 7 do
       
   831             begin
       
   832                 assign(f, ExtractFileDir(ParamStr(2)) + '/' + cLogfileBase + inttostr(i) + '.log');
       
   833                 rewrite(f);
       
   834                 if IOResult = 0 then break;
       
   835             end;
       
   836             if IOResult <> 0 then f:= stderr; // if everything fails, write to stderr
       
   837         end
       
   838         else
       
   839         begin
       
   840             for i:= 0 to 7 do
       
   841             begin
       
   842                 assign(f, ParamStr(1) + '/Logs/' + cLogfileBase + inttostr(i) + '.log');
       
   843                 rewrite(f);
       
   844                 if IOResult = 0 then break;
       
   845             end;
       
   846             if IOResult <> 0 then f:= stderr; // if everything fails, write to stderr
       
   847         end
       
   848     else
       
   849         f:= stderr;
       
   850 {$ENDIF}
       
   851 {$I+}
       
   852 {$ENDIF}
       
   853 end;
   143 end;
   854 
   144 
   855 procedure freeModule;
   145 procedure freeModule;
   856 begin
   146 begin
   857     recordFileName:= '';
   147     recordFileName:= '';
   858     while TextureList <> nil do FreeTexture(TextureList);
       
   859 
       
   860 {$IFDEF DEBUGFILE}
       
   861     writeln(f, 'halt at ', GameTicks, ' ticks. TurnTimeLeft = ', TurnTimeLeft);
       
   862     flush(f);
       
   863     close(f);
       
   864 {$ENDIF}
       
   865 
       
   866     // re-init flags so they will always contain safe values
       
   867     cScreenWidth    := 1024;
       
   868     cScreenHeight   := 768;
       
   869     cBits           := 32;
       
   870     //ipcPort is in uIO
       
   871     cFullScreen     := false;
       
   872     isSoundEnabled  := true;
       
   873     isMusicEnabled  := false;
       
   874     cLocaleFName    := 'en.txt';
       
   875     cInitVolume     := 100;
       
   876     cTimerInterval  := 8;
       
   877     PathPrefix := './';
       
   878     cShowFPS        := false;
       
   879     cAltDamage      := true;
       
   880     cReducedQuality := rqNone;
       
   881     //userNick is in uChat
       
   882     recordFileName  := '';
       
   883     cReadyDelay     := 0;
       
   884 end;
   148 end;
   885 
   149 
   886 end.
   150 end.