--- a/hedgewars/uLocale.pas Sun Oct 28 15:18:26 2012 +0100
+++ b/hedgewars/uLocale.pas Fri Dec 06 22:20:53 2019 +0100
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr@gmail.com>
+ * Copyright (c) 2004-2015 Andrey Korotaev <unC0Rr@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -13,7 +13,7 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*)
{$INCLUDE "options.inc"}
@@ -22,58 +22,84 @@
interface
uses uTypes;
-const MAX_EVENT_STRINGS = 100;
+const MAX_EVENT_STRINGS = 255;
procedure LoadLocale(FileName: shortstring);
-function Format(fmt: shortstring; var arg: shortstring): shortstring;
-function FormatA(fmt: ansistring; var arg: ansistring): ansistring;
function GetEventString(e: TEventId): ansistring;
+function Format(fmt: shortstring; arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9: shortstring; argCount: Byte): shortstring;
+function Format(fmt: shortstring; arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9: shortstring): shortstring;
+function Format(fmt: shortstring; arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8: shortstring): shortstring;
+function Format(fmt: shortstring; arg1, arg2, arg3, arg4, arg5, arg6, arg7: shortstring): shortstring;
+function Format(fmt: shortstring; arg1, arg2, arg3, arg4, arg5, arg6: shortstring): shortstring;
+function Format(fmt: shortstring; arg1, arg2, arg3, arg4, arg5: shortstring): shortstring;
+function Format(fmt: shortstring; arg1, arg2, arg3, arg4: shortstring): shortstring;
+function Format(fmt: shortstring; arg1, arg2, arg3: shortstring): shortstring;
+function Format(fmt: shortstring; arg1, arg2: shortstring): shortstring;
+function Format(fmt: shortstring; arg1: shortstring): shortstring;
+function FormatA(fmt: ansistring; arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9: ansistring; argCount: Byte): ansistring;
+function FormatA(fmt: ansistring; arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9: ansistring): ansistring;
+function FormatA(fmt: ansistring; arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8: ansistring): ansistring;
+function FormatA(fmt: ansistring; arg1, arg2, arg3, arg4, arg5, arg6, arg7: ansistring): ansistring;
+function FormatA(fmt: ansistring; arg1, arg2, arg3, arg4, arg5, arg6: ansistring): ansistring;
+function FormatA(fmt: ansistring; arg1, arg2, arg3, arg4, arg5: ansistring): ansistring;
+function FormatA(fmt: ansistring; arg1, arg2, arg3, arg4: ansistring): ansistring;
+function FormatA(fmt: ansistring; arg1, arg2, arg3: ansistring): ansistring;
+function FormatA(fmt: ansistring; arg1, arg2: ansistring): ansistring;
+function FormatA(fmt: ansistring; arg1: ansistring): ansistring;
+
{$IFDEF HWLIBRARY}
-procedure LoadLocaleWrapper(str: pchar); cdecl; export;
+procedure LoadLocaleWrapper(path: pchar; userpath: pchar; filename: pchar); cdecl; export;
{$ENDIF}
implementation
-uses uRandom, uUtils, uVariables, uDebug;
+uses SysUtils, uRandom, uUtils, uVariables, uDebug, uPhysFSLayer;
var trevt: array[TEventId] of array [0..Pred(MAX_EVENT_STRINGS)] of ansistring;
trevt_n: array[TEventId] of integer;
procedure LoadLocale(FileName: shortstring);
var s: ansistring;
- f: textfile;
+ f: pfsFile;
a, b, c: LongInt;
first: array[TEventId] of boolean;
e: TEventId;
- loaded: boolean;
begin
-loaded:= false;
+{- TODO: Add support for localized decimal separator in Pas2C -}
+{$IFNDEF PAS2C}
+lDecimalSeparator:= FormatSettings.DecimalSeparator;
+{$ENDIF}
+
for e:= Low(TEventId) to High(TEventId) do
first[e]:= true;
-{$I-} // iochecks off
-Assign(f, FileName);
-filemode:= 0; // readonly
-Reset(f);
-if IOResult = 0 then
- loaded:= true;
-TryDo(loaded, 'Cannot load locale "' + FileName + '"', false);
-if loaded then
+f:= pfsOpenRead(FileName);
+checkFails(f <> nil, 'Cannot load locale "' + FileName + '"', false);
+
+s:= '';
+
+if f <> nil then
begin
- while not eof(f) do
+ while not pfsEof(f) do
begin
- readln(f, s);
+ pfsReadLnA(f, s);
if Length(s) = 0 then
continue;
if (s[1] < '0') or (s[1] > '9') then
continue;
- TryDo(Length(s) > 6, 'Load locale: empty string', true);
+ checkFails(Length(s) > 6, 'Load locale: empty string', true);
+ {$IFNDEF PAS2C}
val(s[1]+s[2], a, c);
- TryDo(c = 0, 'Load locale: numbers should be two-digit: ' + s, true);
- TryDo(s[3] = ':', 'Load locale: ":" expected', true);
+ checkFails(c = 0, ansistring('Load locale: numbers should be two-digit: ') + s, true);
val(s[4]+s[5], b, c);
- TryDo(c = 0, 'Load locale: numbers should be two-digit' + s, true);
- TryDo(s[6] = '=', 'Load locale: "=" expected', true);
+ checkFails(c = 0, ansistring('Load locale: numbers should be two-digit: ') + s, true);
+ {$ELSE}
+ val(s[1]+s[2], a);
+ val(s[4]+s[5], b);
+ {$ENDIF}
+ checkFails(s[3] = ':', 'Load locale: ":" expected', true);
+ checkFails(s[6] = '=', 'Load locale: "=" expected', true);
+ if not allOK then exit;
Delete(s, 1, 6);
case a of
0: if (b >=0) and (b <= ord(High(TAmmoStrId))) then
@@ -82,7 +108,7 @@
trmsg[TMsgStrId(b)]:= s;
2: if (b >=0) and (b <= ord(High(TEventId))) then
begin
- TryDo(trevt_n[TEventId(b)] < MAX_EVENT_STRINGS, 'Too many event strings in ' + IntToStr(a) + ':' + IntToStr(b), false);
+ checkFails(trevt_n[TEventId(b)] < MAX_EVENT_STRINGS, 'Too many event strings in ' + IntToStr(a) + ':' + IntToStr(b), false);
if first[TEventId(b)] then
begin
trevt_n[TEventId(b)]:= 0;
@@ -97,11 +123,12 @@
trammod[TAmmoStrId(b)]:= s;
5: if (b >=0) and (b <= ord(High(TGoalStrId))) then
trgoal[TGoalStrId(b)]:= s;
+ 6: if (b >=0) and (b <= ord(High(TCmdHelpStrId))) then
+ trcmd[TCmdHelpStrId(b)]:= s;
end;
end;
- Close(f);
+ pfsClose(f);
end;
-{$I+}
end;
function GetEventString(e: TEventId): ansistring;
@@ -112,30 +139,171 @@
GetEventString:= trevt[e][GetRandom(trevt_n[e])]; // Pick a random message and return it
end;
-function Format(fmt: shortstring; var arg: shortstring): shortstring;
-var i: LongInt;
+// Format the string fmt.
+// Take a shortstring with placeholders %1, %2, %3, ... %9. and replace
+// them with the corresponding elements of an array with up to
+// argCount. ArgCount must not be larger than 9.
+// Each placeholder must be used exactly once and numbers MUST NOT be
+// skipped (e.g. using %1 and %3 but not %2.
+function Format(fmt: shortstring; arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9: shortstring; argCount: Byte): shortstring;
+var i, p: LongInt;
+tempstr, curArg: shortstring;
begin
-i:= Pos('%1', fmt);
-if i = 0 then
- Format:= fmt
-else
- Format:= copy(fmt, 1, i - 1) + arg + Format(copy(fmt, i + 2, Length(fmt) - i - 1), arg)
+tempstr:= fmt;
+for i:=0 to argCount - 1 do
+ begin
+ case i of
+ 0: curArg:= arg1;
+ 1: curArg:= arg2;
+ 2: curArg:= arg3;
+ 3: curArg:= arg4;
+ 4: curArg:= arg5;
+ 5: curArg:= arg6;
+ 6: curArg:= arg7;
+ 7: curArg:= arg8;
+ 8: curArg:= arg9;
+ end;
+
+ repeat
+ p:= Pos('%'+IntToStr(i+1), tempstr);
+ if (p <> 0) then
+ begin
+ delete(tempstr, p, 2);
+ insert(curArg, tempstr, p);
+ end;
+ until (p = 0);
+ end;
+Format:= tempstr;
+end;
+
+// Same as Format, but for ansistring
+function FormatA(fmt: ansistring; arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9: ansistring; argCount: Byte): ansistring;
+var i, p: LongInt;
+tempstr, curArg: ansistring;
+begin
+tempstr:= fmt;
+for i:=0 to argCount - 1 do
+ begin
+ case i of
+ 0: curArg:= arg1;
+ 1: curArg:= arg2;
+ 2: curArg:= arg3;
+ 3: curArg:= arg4;
+ 4: curArg:= arg5;
+ 5: curArg:= arg6;
+ 6: curArg:= arg7;
+ 7: curArg:= arg8;
+ 8: curArg:= arg9;
+ end;
+
+ repeat
+ p:= Pos('%'+IntToStr(i+1), tempstr);
+ if (p <> 0) then
+ begin
+ delete(tempstr, p, 2);
+ insert(curArg, tempstr, p);
+ end;
+ until (p = 0);
+ end;
+FormatA:= tempstr;
end;
-function FormatA(fmt: ansistring; var arg: ansistring): ansistring;
-var i: LongInt;
+// The following functions are just shortcuts of Format/FormatA, with fewer argument counts
+function Format(fmt: shortstring; arg1: shortstring): shortstring;
+begin
+ Format:= Format(fmt, arg1, '', '', '', '', '', '', '', '', 1);
+end;
+function Format(fmt: shortstring; arg1, arg2: shortstring): shortstring;
+begin
+ Format:= Format(fmt, arg1, arg2, '', '', '', '', '', '', '', 2);
+end;
+function Format(fmt: shortstring; arg1, arg2, arg3: shortstring): shortstring;
+begin
+ Format:= Format(fmt, arg1, arg2, arg3, '', '', '', '', '', '', 3);
+end;
+function Format(fmt: shortstring; arg1, arg2, arg3, arg4: shortstring): shortstring;
+begin
+ Format:= Format(fmt, arg1, arg2, arg3, arg4, '', '', '', '', '', 4);
+end;
+function Format(fmt: shortstring; arg1, arg2, arg3, arg4, arg5: shortstring): shortstring;
+begin
+ Format:= Format(fmt, arg1, arg2, arg3, arg4, arg5, '', '', '', '', 5);
+end;
+function Format(fmt: shortstring; arg1, arg2, arg3, arg4, arg5, arg6: shortstring): shortstring;
+begin
+ Format:= Format(fmt, arg1, arg2, arg3, arg4, arg5, arg6, '', '', '', 6);
+end;
+function Format(fmt: shortstring; arg1, arg2, arg3, arg4, arg5, arg6, arg7: shortstring): shortstring;
+begin
+ Format:= Format(fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, '', '', 7);
+end;
+function Format(fmt: shortstring; arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8: shortstring): shortstring;
+begin
+ Format:= Format(fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, '', 8);
+end;
+function Format(fmt: shortstring; arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9: shortstring): shortstring;
begin
-i:= Pos('%1', fmt);
-if i = 0 then
- FormatA:= fmt
-else
- FormatA:= copy(fmt, 1, i - 1) + arg + FormatA(copy(fmt, i + 2, Length(fmt) - i - 1), arg)
+ Format:= Format(fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, 9);
+end;
+
+function FormatA(fmt: ansistring; arg1: ansistring): ansistring;
+begin
+ FormatA:= FormatA(fmt, arg1, ansistring(''), ansistring(''), ansistring(''), ansistring(''), ansistring(''), ansistring(''), ansistring(''), ansistring(''), 1);
+end;
+function FormatA(fmt: ansistring; arg1, arg2: ansistring): ansistring;
+begin
+ FormatA:= FormatA(fmt, arg1, arg2, ansistring(''), ansistring(''), ansistring(''), ansistring(''), ansistring(''), ansistring(''), ansistring(''), 2);
+end;
+function FormatA(fmt: ansistring; arg1, arg2, arg3: ansistring): ansistring;
+begin
+ FormatA:= FormatA(fmt, arg1, arg2, arg3, ansistring(''), ansistring(''), ansistring(''), ansistring(''), ansistring(''), ansistring(''), 3);
+end;
+function FormatA(fmt: ansistring; arg1, arg2, arg3, arg4: ansistring): ansistring;
+begin
+ FormatA:= FormatA(fmt, arg1, arg2, arg3, arg4, ansistring(''), ansistring(''), ansistring(''), ansistring(''), ansistring(''), 4);
+end;
+function FormatA(fmt: ansistring; arg1, arg2, arg3, arg4, arg5: ansistring): ansistring;
+begin
+ FormatA:= FormatA(fmt, arg1, arg2, arg3, arg4, arg5, ansistring(''), ansistring(''), ansistring(''), ansistring(''), 5);
+end;
+function FormatA(fmt: ansistring; arg1, arg2, arg3, arg4, arg5, arg6: ansistring): ansistring;
+begin
+ FormatA:= FormatA(fmt, arg1, arg2, arg3, arg4, arg5, arg6, ansistring(''), ansistring(''), ansistring(''), 6);
+end;
+function FormatA(fmt: ansistring; arg1, arg2, arg3, arg4, arg5, arg6, arg7: ansistring): ansistring;
+begin
+ FormatA:= FormatA(fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ansistring(''), ansistring(''), 7);
+end;
+function FormatA(fmt: ansistring; arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8: ansistring): ansistring;
+begin
+ FormatA:= FormatA(fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ansistring(''), 8);
+end;
+function FormatA(fmt: ansistring; arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9: ansistring): ansistring;
+begin
+ FormatA:= FormatA(fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, 9);
end;
{$IFDEF HWLIBRARY}
-procedure LoadLocaleWrapper(str: pchar); cdecl; export;
+procedure LoadLocaleWrapper(path: pchar; userpath: pchar; filename: pchar); cdecl; export;
begin
- LoadLocale(Strpas(str));
+ PathPrefix := Strpas(path);
+ UserPathPrefix := Strpas(userpath);
+
+ //normally this var set in preInit of engine
+ allOK := true;
+
+ uVariables.initModule;
+
+ PathPrefix:= PathPrefix + #0;
+ UserPathPrefix:= UserPathPrefix + #0;
+ uPhysFSLayer.initModule(@PathPrefix[1], @UserPathPrefix[1]);
+ PathPrefix:= copy(PathPrefix, 1, length(PathPrefix) - 1);
+ UserPathPrefix:= copy(UserPathPrefix, 1, length(UserPathPrefix) - 1);
+
+ LoadLocale(Strpas(filename));
+
+ uPhysFSLayer.freeModule;
+ uVariables.freeModule;
end;
{$ENDIF}