--- a/hedgewars/uStore.pas Wed May 16 18:22:28 2018 +0200
+++ b/hedgewars/uStore.pas Wed Jul 31 23:14:27 2019 +0200
@@ -46,6 +46,8 @@
procedure LoadHedgehogHat(var HH: THedgehog; newHat: shortstring);
procedure LoadHedgehogHat2(var HH: THedgehog; newHat: shortstring; allowSurfReuse: boolean);
+procedure LoadDefaultClanColors(s: shortstring);
+
procedure InitZoom(zoom: real);
procedure SetupOpenGL;
@@ -112,6 +114,7 @@
clr.r:= Color shr 16;
clr.g:= (Color shr 8) and $FF;
clr.b:= Color and $FF;
+clr.a:= $FF;
tmpsurf:= TTF_RenderUTF8_Blended(Fontz[Font].Handle, s, clr);
if tmpsurf = nil then exit;
tmpsurf:= doSurfaceConversion(tmpsurf);
@@ -277,19 +280,23 @@
if ExtDriven then
NameTagTex:= RenderStringTexLim(ansistring(Name), Clan^.Color, fnt16, cTeamHealthWidth)
else NameTagTex:= RenderStringTex(ansistring(Name), Clan^.Color, fnt16);
- if Hat = 'NoHat' then
+ if cHolidaySilliness then
begin
- if (month = 4) and (md = 20) then
- Hat := 'eastertop' // Easter
- else if (month = 12) and ((md = 24) or (md = 25) or (md = 26)) then
- Hat := 'Santa' // Christmas Eve/Christmas/Boxing Day
- else if (month = 10) and (md = 31) then
- Hat := 'fr_pumpkin'; // Halloween/Hedgewars' birthday
- end;
- if (month = 4) and (md = 1) then
- begin
- AprilOne:= true;
- Hat := 'fr_tomato'; // avoid promoting violence to hedgehogs. see http://hedgewars.org/node/5818
+ // Special hats on special days
+ if Hat = 'NoHat' then
+ begin
+ if (month = 4) and (md = 20) then
+ Hat := 'eastertop' // Easter
+ else if (month = 12) and ((md = 24) or (md = 25) or (md = 26)) then
+ Hat := 'Santa' // Christmas Eve/Christmas/Boxing Day
+ else if (month = 10) and (md = 31) then
+ Hat := 'fr_pumpkin'; // Halloween/Hedgewars' birthday
+ end;
+ if (month = 4) and (md = 1) then
+ begin
+ AprilOne:= true;
+ Hat := 'fr_tomato'; // avoid promoting violence to hedgehogs. see https://hedgewars.org/node/5818
+ end;
end;
if Hat <> 'NoHat' then
@@ -321,9 +328,9 @@
for t:= 0 to Pred(ClansCount) do
with ClansArray[t]^ do
- HealthTex:= makeHealthBarTexture(cTeamHealthWidth + 5, Teams[0]^.NameTagTex^.h, Color);
+ HealthTex:= makeHealthBarTexture(cTeamHealthWidth + 5, 19 * HDPIScaleFactor, Color);
-GenericHealthTexture:= makeHealthBarTexture(cTeamHealthWidth + 5, TeamsArray[0]^.NameTagTex^.h, cWhiteColor)
+GenericHealthTexture:= makeHealthBarTexture(cTeamHealthWidth + 5, 19 * HDPIScaleFactor, cWhiteColor)
end;
@@ -518,12 +525,12 @@
InitHealth;
- PauseTexture:= RenderStringTex(trmsg[sidPaused], cYellowColor, fntBig);
- AFKTexture:= RenderStringTex(trmsg[sidAFK], cYellowColor, fntBig);
+ PauseTexture:= RenderStringTex(trmsg[sidPaused], cCentralMessageColor, fntBig);
+ AFKTexture:= RenderStringTex(trmsg[sidAFK], cCentralMessageColor, fntBig);
keyConfirm:= KeyBindToName('confirm');
keyQuit:= KeyBindToName('quit');
- ConfirmTexture:= RenderStringTex(Format(trmsg[sidConfirm], [keyConfirm, keyQuit]), cYellowColor, fntBig);
- SyncTexture:= RenderStringTex(trmsg[sidSync], cYellowColor, fntBig);
+ ConfirmTexture:= RenderStringTex(FormatA(trmsg[sidConfirm], ansistring(keyConfirm), ansistring(keyQuit)), cCentralMessageColor, fntBig);
+ SyncTexture:= RenderStringTex(trmsg[sidSync], cCentralMessageColor, fntBig);
if not reload then
AddProgress;
@@ -544,7 +551,8 @@
// number of weapons in ammo menu
for i:= Low(CountTexz) to High(CountTexz) do
begin
- tmpsurf:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(IntToStr(i) + 'x'), cWhiteColorChannels);
+ tmpsurf:= TTF_RenderUTF8_Blended(Fontz[CheckCJKFont(trmsg[sidAmmoCount],fnt16)].Handle, Str2PChar(Format(shortstring(trmsg[sidAmmoCount]), IntToStr(i))), cWhiteColorChannels);
+ if checkFails(tmpsurf <> nil,'Number texture creation for ammo type #' + intToStr(ord(ai)) + ' failed!',true) then exit;
tmpsurf:= doSurfaceConversion(tmpsurf);
FreeAndNilTexture(CountTexz[i]);
CountTexz[i]:= Surface2Tex(tmpsurf, false);
@@ -629,18 +637,24 @@
procedure RenderHealth(var Hedgehog: THedgehog);
var s: shortstring;
begin
-s:= IntToStr(Hedgehog.Gear^.Health);
FreeAndNilTexture(Hedgehog.HealthTagTex);
+if Hedgehog.Gear <> nil then
+ s:= IntToStr(Hedgehog.Gear^.Health)
+else if Hedgehog.GearHidden <> nil then
+ s:= IntToStr(Hedgehog.GearHidden^.Health)
+else
+ exit;
Hedgehog.HealthTagTex:= RenderStringTex(ansistring(s), Hedgehog.Team^.Clan^.Color, fnt16)
end;
function LoadImage(const filename: shortstring; imageFlags: LongInt): PSDL_Surface;
var tmpsurf: PSDL_Surface;
s: shortstring;
+ logMsg: shortstring;
rwops: PSDL_RWops;
begin
LoadImage:= nil;
- WriteToConsole(msgLoading + filename + '.png [flags: ' + inttostr(imageFlags) + '] ');
+ logMsg:= msgLoading + filename + '.png [flags: ' + inttostr(imageFlags) + ']';
s:= filename + '.png';
@@ -664,20 +678,22 @@
if rwops <> nil then
begin
// anounce that loading failed
- OutError(msgFailed, false);
+ OutError(logMsg + ' ' + msgFailed, false);
- if SDLCheck(false, 'LoadImage', (imageFlags and ifCritical) <> 0) then exit;
+ if SDLCheck(false, 'LoadImage: ' + logMsg + ' ' + msgFailed, (imageFlags and ifCritical) <> 0) then
+ exit;
// rwops was already freed by IMG_Load_RW
rwops:= nil;
- end else
- OutError(msgFailed, (imageFlags and ifCritical) <> 0);
+ end
+ else
+ OutError(logMsg + ' ' + msgFailed, (imageFlags and ifCritical) <> 0);
exit;
end;
if ((imageFlags and ifIgnoreCaps) = 0) and ((tmpsurf^.w > MaxTextureSize) or (tmpsurf^.h > MaxTextureSize)) then
begin
SDL_FreeSurface(tmpsurf);
- OutError(msgFailedSize, ((not cOnlyStats) and ((imageFlags and ifCritical) <> 0)));
+ OutError(logMsg + ' ' + msgFailedSize, ((not cOnlyStats) and ((imageFlags and ifCritical) <> 0)));
// dummy surface to replace non-critical textures that failed to load due to their size
LoadImage:= SDL_CreateRGBSurface(SDL_SWSURFACE, 2, 2, 32, RMask, GMask, BMask, AMask);
exit;
@@ -688,7 +704,8 @@
if (imageFlags and ifColorKey) <> 0 then
if checkFails(SDL_SetColorKey(tmpsurf, SDL_TRUE, 0) = 0, errmsgTransparentSet, true) then exit;
- WriteLnToConsole(msgOK + ' (' + inttostr(tmpsurf^.w) + 'x' + inttostr(tmpsurf^.h) + ')');
+ // log success
+ WriteLnToConsole(logMsg + ' ' + msgOK + ' (' + inttostr(tmpsurf^.w) + 'x' + inttostr(tmpsurf^.h) + ')');
LoadImage:= tmpsurf //Result
end;
@@ -774,6 +791,72 @@
end;
end;
+// Load default clan colors from config fiile
+procedure LoadDefaultClanColors(s: shortstring);
+var i: LongInt;
+ f: PFSFile;
+ key, value, l, temp: shortstring;
+ color, tempColor: Longword;
+ clanID, tempClanID: byte;
+begin
+ if cOnlyStats then exit;
+
+ WriteLnToConsole('Loading default clan colors from: ' + s);
+
+ l:= '';
+ if pfsExists(s) then
+ begin
+ f:= pfsOpenRead(s);
+ while (not pfsEOF(f)) and (l <> '[colors]') do
+ pfsReadLn(f, l);
+
+ while (not pfsEOF(f)) and (l <> '') do
+ begin
+ pfsReadLn(f, l);
+
+ key:= '';
+ i:= 1;
+ while (i <= length(l)) and (l[i] <> '=') do
+ begin
+ key:= key + l[i];
+ inc(i)
+ end;
+ temp:= copy(key, 1, 5);
+ if temp = 'color' then
+ begin
+ temp:= copy(key, 6, length(key) - 5);
+ tempClanID:= StrToInt(temp);
+ clanID:= tempClanID
+ end
+ else
+ continue;
+
+ if i < length(l) then
+ begin
+ value:= copy(l, i + 1, length(l) - i);
+ if (length(value) = 2) and (value[1] = '\') then
+ value:= value[1] + ''
+ else if (value[1] = '"') and (value[length(value)] = '"') then
+ value:= copy(value, 2, length(value) - 2);
+ if value[1] <> '#' then
+ continue;
+ temp:= copy(value, 2, length(value) - 1);
+ tempColor:= StrToInt('$'+temp);
+ color:= tempColor
+ end;
+
+ if clanID <= cClanColors then
+ ClanColorArray[clanID]:= color;
+
+ end;
+
+ pfsClose(f)
+ end
+ else
+ WriteLnToConsole('Settings file not found');
+end;
+
+
procedure SetupOpenGLAttributes;
begin
{$IFDEF IPHONEOS}
@@ -838,7 +921,7 @@
{$ENDIF}
end;
- if checkFails((ProgrTex <> nil) and (LoadingText <> nil), 'Error - Progress or Loading Texture is nil!', true) then exit;
+ if checkFails((ProgrTex <> nil) and (LoadingText <> nil), 'Error - Progress or Loading texture is nil!', true) then exit;
RenderClear();
if Step < numsquares then
@@ -877,7 +960,7 @@
font: THWFont;
r, r2: TSDL_Rect;
wa, ha: LongInt;
- tmpline, tmpline2, tmpdesc: ansistring;
+ tmpline, tmpline2, tmpline3, tmpdesc: ansistring;
begin
// make sure there is a caption as well as a sub caption - description is optional
if length(caption) = 0 then
@@ -917,7 +1000,9 @@
while length(tmpdesc) > 0 do
begin
tmpline:= tmpdesc;
+ EscapeCharA(tmpline, '|');
SplitByCharA(tmpline, tmpdesc, '|');
+ UnEscapeCharA(tmpline, '|');
if length(tmpline) > 0 then
begin
TTF_SizeUTF8(Fontz[font].Handle, PChar(tmpline), @i, @j);
@@ -960,21 +1045,38 @@
while length(tmpdesc) > 0 do
begin
tmpline:= tmpdesc;
+ EscapeCharA(tmpline, '|');
SplitByCharA(tmpline, tmpdesc, '|');
+ UnEscapeCharA(tmpline, '|');
r2:= r;
if length(tmpline) > 0 then
begin
- r:= WriteInRect(tmpsurf, cFontBorder + 2, r.y + r.h, $ff707070, font, PChar(tmpline));
- // render highlighted caption (if there is a ':')
+ // Render highlighted caption if there is a ':',
+ // from the beginning of the line to (and including) the ':'.
+ // With '::', the colons will be suppressed in the final text.
+ EscapeCharA(tmpline, ':');
tmpline2:= _S'';
SplitByCharA(tmpline, tmpline2, ':');
if length(tmpline2) > 0 then
begin
- tmpline:= tmpline + ':';
+ if (tmpline2[1] <> ':') then
+ begin
+ tmpline:= tmpline + ':';
+ tmpline3:= tmpline + tmpline2;
+ end
+ else
+ tmpline3:= tmpline + Copy(tmpline2, 2, Length(tmpline2)-1);
+ UnEscapeCharA(tmpline3, ':');
+ r:= WriteInRect(tmpsurf, cFontBorder + 2, r.y + r.h, $ff707070, font, PChar(tmpline3));
WriteInRect(tmpsurf, cFontBorder + 2, r2.y + r2.h, $ffc7c7c7, font, PChar(tmpline));
- end;
- end
+ end
+ else
+ begin
+ UnEscapeCharA(tmpline, ':');
+ r:= WriteInRect(tmpsurf, cFontBorder + 2, r.y + r.h, $ff707070, font, PChar(tmpline));
+ end
+ end;
end;
if length(extra) > 0 then
@@ -984,7 +1086,7 @@
r.y:= cFontBorder + 4;
r.w:= 32;
r.h:= 32;
-SDL_FillRect(tmpsurf, @r, $ff000000);
+SDL_FillRect(tmpsurf, @r, SDL_MapRGB(tmpsurf^.format, 0, 0, 0));
SDL_UpperBlit(iconsurf, iconrect, tmpsurf, @r);
RenderHelpWindow:= Surface2Tex(tmpsurf, true);
@@ -1021,25 +1123,21 @@
extra:= _S'';
extracolor:= 0;
-if (CurrentTeam <> nil) and (Ammoz[atype].SkipTurns >= CurrentTeam^.Clan^.TurnNumber) then // weapon or utility is not yet available
- begin
- if (atype = amTardis) and (SuddenDeathActive) then
- extra:= trmsg[sidNotAvailableInSD]
- else
- extra:= trmsg[sidNotYetAvailable];
- extracolor:= LongInt($ffc77070);
- end
-else if (((GameFlags and gfInfAttack) <> 0) and ((Ammoz[atype].Ammo.Propz and ammoprop_ForceTurnEnd) = 0)) or ((Ammoz[atype].Ammo.Propz and ammoprop_NoRoundEnd) <> 0) then
- // weapon or utility will not end your turn
- begin
- extra:= trmsg[sidNoEndTurn];
- extracolor:= LongInt($ff70c770);
- end
-else
- begin
- extra:= _S'';
- extracolor:= 0;
- end;
+if (trluaammoe[Ammoz[atype].NameId] = true) then
+ if (CurrentTeam <> nil) and (Ammoz[atype].SkipTurns >= CurrentTeam^.Clan^.TurnNumber) then // weapon or utility is not yet available
+ begin
+ if (atype = amTardis) and (SuddenDeathActive) then
+ extra:= trmsg[sidNotAvailableInSD]
+ else
+ extra:= trmsg[sidNotYetAvailable];
+ extracolor:= LongInt($ffc77070);
+ end
+ else if ((((GameFlags and gfInfAttack) <> 0) and ((Ammoz[atype].Ammo.Propz and ammoprop_ForceTurnEnd) = 0)) or ((Ammoz[atype].Ammo.Propz and ammoprop_NoRoundEnd) <> 0)) and (not (PlacingHogs and (atype = amTeleport))) then
+ // weapon or utility will not end your turn
+ begin
+ extra:= trmsg[sidNoEndTurn];
+ extracolor:= LongInt($ff70c770);
+ end;
if length(trluaammo[Ammoz[atype].NameId]) > 0 then
ammoname := trluaammo[Ammoz[atype].NameId]
@@ -1144,7 +1242,7 @@
end;
// these attributes must be set up before creating the sdl window
-{$IFNDEF WIN32}
+{$IFNDEF WINDOWS}
(* On a large number of testers machines, SDL default to software rendering
when opengl attributes were set. These attributes were "set" after
CreateWindow in .15, which probably did nothing.