1 (* Copyright (C) DooM 2D:Forever Developers
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 {$INCLUDE ../shared/a_modes.inc}
25 GAME_VERSION
= '0.667';
31 UID_MAX_PLAYER
= $7FFF;
32 UID_MAX_MONSTER
= $FFFF;
35 TDirection
= (D_LEFT
, D_RIGHT
);
36 WArray
= array of Word;
37 DWArray
= array of DWORD
;
38 String20
= String[20];
40 function g_CreateUID(UIDType
: Byte): Word;
41 function g_GetUIDType(UID
: Word): Byte;
42 function g_Collide(X1
, Y1
: Integer; Width1
, Height1
: Word;
43 X2
, Y2
: Integer; Width2
, Height2
: Word): Boolean;
44 function g_CollideLine(x1
, y1
, x2
, y2
, rX
, rY
: Integer; rWidth
, rHeight
: Word): Boolean;
45 function g_CollidePoint(X
, Y
, X2
, Y2
: Integer; Width
, Height
: Word): Boolean;
46 function g_CollideLevel(X
, Y
: Integer; Width
, Height
: Word): Boolean;
47 function g_CollideAround(X1
, Y1
: Integer; Width1
, Height1
: Word;
48 X2
, Y2
: Integer; Width2
, Height2
: Word): Boolean;
49 function g_CollidePlayer(X
, Y
: Integer; Width
, Height
: Word): Boolean;
50 function g_CollideMonster(X
, Y
: Integer; Width
, Height
: Word): Boolean;
51 function g_PatchLength(X1
, Y1
, X2
, Y2
: Integer): Word;
52 function g_TraceVector(X1
, Y1
, X2
, Y2
: Integer): Boolean;
53 function g_GetAcidHit(X
, Y
: Integer; Width
, Height
: Word): Byte;
54 function g_Look(a
, b
: PObj
; d
: TDirection
): Boolean;
55 procedure IncMax(var A
: Integer; B
, Max
: Integer); overload
;
56 procedure IncMax(var A
: Single; B
, Max
: Single); overload
;
57 procedure IncMax(var A
: Integer; Max
: Integer); overload
;
58 procedure IncMax(var A
: Single; Max
: Single); overload
;
59 procedure IncMax(var A
: Word; B
, Max
: Word); overload
;
60 procedure IncMax(var A
: Word; Max
: Word); overload
;
61 procedure IncMax(var A
: SmallInt; B
, Max
: SmallInt); overload
;
62 procedure IncMax(var A
: SmallInt; Max
: SmallInt); overload
;
63 procedure DecMin(var A
: Integer; B
, Min
: Integer); overload
;
64 procedure DecMin(var A
: Single; B
, Min
: Single); overload
;
65 procedure DecMin(var A
: Integer; Min
: Integer); overload
;
66 procedure DecMin(var A
: Single; Min
: Single); overload
;
67 procedure DecMin(var A
: Word; B
, Min
: Word); overload
;
68 procedure DecMin(var A
: Word; Min
: Word); overload
;
69 procedure DecMin(var A
: Byte; B
, Min
: Byte); overload
;
70 procedure DecMin(var A
: Byte; Min
: Byte); overload
;
71 function Sign(A
: Integer): ShortInt; overload
;
72 function Sign(A
: Single): ShortInt; overload
;
73 function PointToRect(X
, Y
, X1
, Y1
: Integer; Width
, Height
: Word): Integer;
74 function GetAngle(baseX
, baseY
, pointX
, PointY
: Integer): SmallInt;
75 function GetAngle2(vx
, vy
: Integer): SmallInt;
76 function GetLines(Text: string; FontID
: DWORD
; MaxWidth
: Word): SArray
;
77 procedure Sort(var a
: SArray
);
78 function Sscanf(const s
: string; const fmt
: string;
79 const Pointers
: array of Pointer): Integer;
80 function InDWArray(a
: DWORD
; arr
: DWArray
): Boolean;
81 function InWArray(a
: Word; arr
: WArray
): Boolean;
82 function InSArray(a
: string; arr
: SArray
): Boolean;
83 function GetPos(UID
: Word; o
: PObj
): Boolean;
84 function parse(s
: string): SArray
;
85 function parse2(s
: string; delim
: Char): SArray
;
86 function g_GetFileTime(fileName
: String): Integer;
87 function g_SetFileTime(fileName
: String; time
: Integer): Boolean;
88 procedure SortSArray(var S
: SArray
);
89 function b_Text_Format(S
: string): string;
90 function b_Text_Unformat(S
: string): string;
95 Math
, g_map
, g_gfx
, g_player
, SysUtils
, MAPDEF
,
96 StrUtils
, e_graphics
, g_monsters
, g_items
;
98 function g_PatchLength(X1
, Y1
, X2
, Y2
: Integer): Word;
100 Result
:= Min(Round(Hypot(Abs(X2
-X1
), Abs(Y2
-Y1
))), 65535);
103 function g_CollideLevel(X
, Y
: Integer; Width
, Height
: Word): Boolean;
105 result
:= g_Map_CollidePanel(X
, Y
, Width
, Height
, (PANEL_WALL
or PANEL_CLOSEDOOR
or PANEL_OPENDOOR
), false);
116 for a := 0 to High(gWalls) do
117 if gWalls[a].Enabled and
118 not ( ((Y + Height <= gWalls[a].Y) or
119 (Y >= gWalls[a].Y + gWalls[a].Height)) or
120 ((X + Width <= gWalls[a].X) or
121 (X >= gWalls[a].X + gWalls[a].Width)) ) then
129 function g_CollidePlayer(X
, Y
: Integer; Width
, Height
: Word): Boolean;
135 if gPlayers
= nil then Exit
;
137 for a
:= 0 to High(gPlayers
) do
138 if (gPlayers
[a
] <> nil) and gPlayers
[a
].Live
then
139 if gPlayers
[a
].Collide(X
, Y
, Width
, Height
) then
146 function g_CollideMonster(X
, Y
: Integer; Width
, Height
: Word): Boolean;
152 if gMonsters
= nil then Exit
;
154 for a
:= 0 to High(gMonsters
) do
155 if (gMonsters
[a
] <> nil) and gMonsters
[a
].Live
then
156 if g_Obj_Collide(X
, Y
, Width
, Height
, @gMonsters
[a
].Obj
) then
163 function g_TraceVector(X1
, Y1
, X2
, Y2
: Integer): Boolean;
167 Xerr
, Yerr
, d
: LongWord;
173 Assert(gCollideMap
<> nil, 'g_TraceVector: gCollideMap = nil');
180 if dx
> 0 then incX
:= 1 else if dx
< 0 then incX
:= -1 else incX
:= 0;
181 if dy
> 0 then incY
:= 1 else if dy
< 0 then incY
:= -1 else incY
:= 0;
186 if dx
> dy
then d
:= dx
else d
:= dy
;
206 if (y
> gMapInfo
.Height
-1) or
207 (y
< 0) or (x
> gMapInfo
.Width
-1) or (x
< 0) then
209 if ByteBool(gCollideMap
[y
, x
] and MARK_BLOCKED
) then
216 function g_CreateUID(UIDType
: Byte): Word;
227 Result
:= UID_MAX_GAME
+$1+Random(UID_MAX_PLAYER
-UID_MAX_GAME
+$1);
230 if gPlayers
<> nil then
231 for i
:= 0 to High(gPlayers
) do
232 if gPlayers
[i
] <> nil then
233 if Result
= gPlayers
[i
].UID
then
244 Result
:= UID_MAX_PLAYER
+$1+Random(UID_MAX_MONSTER
-UID_MAX_GAME
-UID_MAX_PLAYER
+$1);
247 if gMonsters
<> nil then
248 for i
:= 0 to High(gMonsters
) do
249 if gMonsters
[i
] <> nil then
250 if Result
= gMonsters
[i
].UID
then
260 function g_GetUIDType(UID
: Word): Byte;
262 if UID
<= UID_MAX_GAME
then
265 if UID
<= UID_MAX_PLAYER
then
268 Result
:= UID_MONSTER
;
271 function g_Collide(X1
, Y1
: Integer; Width1
, Height1
: Word;
272 X2
, Y2
: Integer; Width2
, Height2
: Word): Boolean;
274 Result
:= not ( ((Y1
+ Height1
<= Y2
) or
275 (Y2
+ Height2
<= Y1
)) or
276 ((X1
+ Width1
<= X2
) or
277 (X2
+ Width2
<= X1
)) );
280 function g_CollideAround(X1
, Y1
: Integer; Width1
, Height1
: Word;
281 X2
, Y2
: Integer; Width2
, Height2
: Word): Boolean;
283 Result
:= g_Collide(X1
, Y1
, Width1
, Height1
, X2
, Y2
, Width2
, Height2
) or
284 g_Collide(X1
+1, Y1
, Width1
, Height1
, X2
, Y2
, Width2
, Height2
) or
285 g_Collide(X1
-1, Y1
, Width1
, Height1
, X2
, Y2
, Width2
, Height2
) or
286 g_Collide(X1
, Y1
+1, Width1
, Height1
, X2
, Y2
, Width2
, Height2
) or
287 g_Collide(X1
, Y1
-1, Width1
, Height1
, X2
, Y2
, Width2
, Height2
);
290 function c(X1
, Y1
, Width1
, Height1
, X2
, Y2
, Width2
, Height2
: Integer): Boolean;
292 Result
:= not (((Y1
+ Height1
<= Y2
) or
293 (Y1
>= Y2
+ Height2
)) or
294 ((X1
+ Width1
<= X2
) or
295 (X1
>= X2
+ Width2
)));
298 function g_Collide2(X1
, Y1
, X2
, Y2
, X3
, Y3
, X4
, Y4
: Integer): Boolean;
300 //Result := not (((Y2 <= Y3) or (Y1 >= Y4)) or ((X2 <= X3) or (X1 >= X4)));
301 Result
:= c(X1
, Y1
, X2
-X1
, Y2
-Y1
, X3
, Y3
, X4
-X3
, Y4
-Y3
);
304 function g_CollidePoint(X
, Y
, X2
, Y2
: Integer; Width
, Height
: Word): Boolean;
308 Result
:= (x
>= 0) and (x
<= Width
) and
309 (y
>= 0) and (y
<= Height
);
312 procedure IncMax(var A
: Integer; B
, Max
: Integer);
314 if A
+B
> Max
then A
:= Max
else A
:= A
+B
;
317 procedure IncMax(var A
: Single; B
, Max
: Single);
319 if A
+B
> Max
then A
:= Max
else A
:= A
+B
;
322 procedure DecMin(var A
: Integer; B
, Min
: Integer);
324 if A
-B
< Min
then A
:= Min
else A
:= A
-B
;
327 procedure DecMin(var A
: Word; B
, Min
: Word);
329 if A
-B
< Min
then A
:= Min
else A
:= A
-B
;
332 procedure DecMin(var A
: Single; B
, Min
: Single);
334 if A
-B
< Min
then A
:= Min
else A
:= A
-B
;
337 procedure IncMax(var A
: Integer; Max
: Integer);
339 if A
+1 > Max
then A
:= Max
else A
:= A
+1;
342 procedure IncMax(var A
: Single; Max
: Single);
344 if A
+1 > Max
then A
:= Max
else A
:= A
+1;
347 procedure IncMax(var A
: Word; B
, Max
: Word);
349 if A
+B
> Max
then A
:= Max
else A
:= A
+B
;
352 procedure IncMax(var A
: Word; Max
: Word);
354 if A
+1 > Max
then A
:= Max
else A
:= A
+1;
357 procedure IncMax(var A
: SmallInt; B
, Max
: SmallInt);
359 if A
+B
> Max
then A
:= Max
else A
:= A
+B
;
362 procedure IncMax(var A
: SmallInt; Max
: SmallInt);
364 if A
+1 > Max
then A
:= Max
else A
:= A
+1;
367 procedure DecMin(var A
: Integer; Min
: Integer);
369 if A
-1 < Min
then A
:= Min
else A
:= A
-1;
372 procedure DecMin(var A
: Single; Min
: Single);
374 if A
-1 < Min
then A
:= Min
else A
:= A
-1;
377 procedure DecMin(var A
: Word; Min
: Word);
379 if A
-1 < Min
then A
:= Min
else A
:= A
-1;
382 procedure DecMin(var A
: Byte; B
, Min
: Byte);
384 if A
-B
< Min
then A
:= Min
else A
:= A
-B
;
387 procedure DecMin(var A
: Byte; Min
: Byte); overload
;
389 if A
-1 < Min
then A
:= Min
else A
:= A
-1;
392 function Sign(A
: Integer): ShortInt;
394 if A
< 0 then Result
:= -1
395 else if A
> 0 then Result
:= 1
399 function Sign(A
: Single): ShortInt;
403 if Abs(A
) < Eps
then Result
:= 0
404 else if A
< 0 then Result
:= -1
408 function PointToRect(X
, Y
, X1
, Y1
: Integer; Width
, Height
: Word): Integer;
410 X
:= X
-X1
; // A(0;0) --- B(W;0)
415 if Y
< 0 then // Ñëåâà ñâåðõó: ðàññòîÿíèå äî A
416 Result
:= Round(Hypot(X
, Y
))
418 if Y
> Height
then // Ñëåâà ñíèçó: ðàññòîÿíèå äî D
419 Result
:= Round(Hypot(X
, Y
-Height
))
420 else // Ñëåâà ïîñåðåäèíå: ðàññòîÿíèå äî AD
427 if y
< 0 then // Ñïðàâà ñâåðõó: ðàññòîÿíèå äî B
428 Result
:= Round(Hypot(X
, Y
))
430 if Y
> Height
then // Ñïðàâà ñíèçó: ðàññòîÿíèå äî C
431 Result
:= Round(Hypot(X
, Y
-Height
))
432 else // Ñïðàâà ïîñåðåäèíå: ðàññòîÿíèå äî BC
437 if Y
< 0 then // Ïîñåðåäèíå ñâåðõó: ðàññòîÿíèå äî AB
440 if Y
> Height
then // Ïîñåðåäèíå ñíèçó: ðàññòîÿíèå äî DC
442 else // Âíóòðè ïðÿìîóãîëüíèêà: ðàññòîÿíèå 0
447 function g_GetAcidHit(X
, Y
: Integer; Width
, Height
: Word): Byte;
449 tab
: array[0..3] of Byte = (0, 5, 10, 20);
455 if g_Map_CollidePanel(X
, Y
, Width
, Height
, PANEL_ACID1
, False) then a
:= a
or 1;
456 if g_Map_CollidePanel(X
, Y
, Width
, Height
, PANEL_ACID2
, False) then a
:= a
or 2;
461 function g_Look(a
, b
: PObj
; d
: TDirection
): Boolean;
463 if ((b
^.X
> a
^.X
) and (d
= D_LEFT
)) or
464 ((b
^.X
< a
^.X
) and (d
= D_RIGHT
)) then
470 Result
:= g_TraceVector(a
^.X
+a
^.Rect
.X
+(a
^.Rect
.Width
div 2),
471 a
^.Y
+a
^.Rect
.Y
+(a
^.Rect
.Height
div 2),
472 b
^.X
+b
^.Rect
.X
+(b
^.Rect
.Width
div 2),
473 b
^.Y
+b
^.Rect
.Y
+(b
^.Rect
.Height
div 2));
476 function GetAngle(baseX
, baseY
, pointX
, PointY
: Integer): SmallInt;
481 a
:= abs(pointX
-baseX
);
482 b
:= abs(pointY
-baseY
);
484 if a
= 0 then c
:= 90
485 else c
:= RadToDeg(ArcTan(b
/a
));
487 if pointY
< baseY
then c
:= -c
;
488 if pointX
> baseX
then c
:= 180-c
;
493 function GetAngle2(vx
, vy
: Integer): SmallInt;
504 c
:= RadToDeg(ArcTan(b
/a
));
516 {function g_CollideLine(x1, y1, x2, y2, rX, rY: Integer; rWidth, rHeight: Word): Boolean;
518 table: array[0..8, 0..8] of Byte =
519 ((0, 0, 3, 3, 1, 2, 2, 0, 1),
520 (0, 0, 0, 0, 4, 7, 2, 0, 1),
521 (3, 0, 0, 0, 4, 4, 1, 3, 1),
522 (3, 0, 0, 0, 0, 0, 5, 6, 1),
523 (1, 4, 4, 0, 0, 0, 5, 5, 1),
524 (2, 7, 4, 0, 0, 0, 0, 0, 1),
525 (2, 2, 1, 5, 5, 0, 0, 0, 1),
526 (0, 0, 3, 6, 5, 0, 0, 0, 1),
527 (1, 1, 1, 1, 1, 1, 1, 1, 1));
529 function GetClass(x, y: Integer): Byte;
533 if x < rX then Result := 7
534 else if x < rX+rWidth then Result := 0
537 else if y < rY+rHeight then
539 if x < rX then Result := 6
540 else if x < rX+rWidth then Result := 8
545 if x < rX then Result := 5
546 else if x < rX+rWidth then Result := 4
552 case table[GetClass(x1, y1), GetClass(x2, y2)] of
555 2: Result := Abs((rY-y1))/Abs((rX-x1)) <= Abs((y2-y1))/Abs((x2-x1));
556 3: Result := Abs((rY-y1))/Abs((rX+rWidth-x1)) <= Abs((y2-y1))/Abs((x2-x1));
557 4: Result := Abs((rY+rHeight-y1))/Abs((rX+rWidth-x1)) >= Abs((y2-y1))/Abs((x2-x1));
558 5: Result := Abs((rY+rHeight-y1))/Abs((rX-x1)) >= Abs((y2-y1))/Abs((x2-x1));
559 6: Result := (Abs((rY-y1))/Abs((rX+rWidth-x1)) <= Abs((y2-y1))/Abs((x2-x1))) and
560 (Abs((rY+rHeight-y1))/Abs((rX-x1)) >= Abs((y2-y1))/Abs((x2-x1)));
561 7: Result := (Abs((rY+rHeight-y1))/Abs((rX+rWidth-x1)) >= Abs((y2-y1))/Abs((x2-x1))) and
562 (Abs((rY-y1))/Abs((rX-x1)) <= Abs((y2-y1))/Abs((x2-x1)));
563 else Result := False;
567 function g_CollideLine(x1
, y1
, x2
, y2
, rX
, rY
: Integer; rWidth
, rHeight
: Word): Boolean;
582 if dx
> 0 then incX
:= 1 else if dx
< 0 then incX
:= -1 else incX
:= 0;
583 if dy
> 0 then incY
:= 1 else if dy
< 0 then incY
:= -1 else incY
:= 0;
588 if dx
> dy
then d
:= dx
else d
:= dy
;
608 if (x
>= rX
) and (x
<= (rX
+ rWidth
- 1)) and
609 (y
>= rY
) and (y
<= (rY
+ rHeight
- 1)) then Exit
;
615 function GetStr(var Str
: string): string;
620 for a
:= 1 to Length(Str
) do
621 if (a
= Length(Str
)) or (Str
[a
+1] = ' ') then
623 Result
:= Copy(Str
, 1, a
);
630 {function GetLines(Text: string; MaxChars: Word): SArray;
638 while Pos(' ', Text) <> 0 do Text := AnsiReplaceStr(Text, ' ', ' ');
642 SetLength(b, Length(b)+1);
643 b[High(b)] := GetStr(Text);
649 if a > High(b) then Break;
654 if Length(str) >= MaxChars then
658 SetLength(Result, Length(Result)+1);
659 Result[High(Result)] := Copy(str, 1, MaxChars);
660 Delete(str, 1, MaxChars);
666 while (a <= High(b)) and (Length(str+' '+b[a]) <= MaxChars) do
672 SetLength(Result, Length(Result)+1);
673 Result[High(Result)] := str;
677 function GetLines(Text: string; FontID
: DWORD
; MaxWidth
: Word): SArray
;
679 function TextLen(Text: string): Word;
683 e_CharFont_GetSize(FontID
, Text, Result
, h
);
691 SetLength(Result
, 0);
696 // Óäàëÿåì ìíîæåñòâåííûå ïðîáåëû:
697 while Pos(' ', Text) <> 0 do
698 Text := AnsiReplaceStr(Text, ' ', ' ');
702 SetLength(b
, Length(b
)+1);
703 b
[High(b
)] := GetStr(Text);
715 if TextLen(str
) > MaxWidth
then
716 begin // Òåêóùàÿ ñòðîêà ñëèøêîì äëèííàÿ => ðàçáèâàåì
719 SetLength(Result
, Length(Result
)+1);
722 while (c
< Length(str
)) and
723 (TextLen(Copy(str
, 1, c
+1)) < MaxWidth
) do
726 Result
[High(Result
)] := Copy(str
, 1, c
);
730 else // Ñòðîêà íîðìàëüíîé äëèíû => ñîåäèíÿåì ñî ñëåäóþùèìè
732 while (a
<= High(b
)) and
733 (TextLen(str
+' '+b
[a
]) < MaxWidth
) do
739 SetLength(Result
, Length(Result
)+1);
740 Result
[High(Result
)] := str
;
745 procedure Sort(var a
: SArray
);
750 if a
= nil then Exit
;
752 for i
:= High(a
) downto Low(a
) do
753 for j
:= Low(a
) to High(a
)-1 do
754 if LowerCase(a
[j
]) > LowerCase(a
[j
+1]) then
762 function Sscanf(const s
: String; const fmt
: String;
763 const Pointers
: array of Pointer): Integer;
770 function GetInt(): Integer;
773 while (n
<= Length(s
)) and (s
[n
] = ' ') do
776 while (n
<= Length(s
)) and (s
[n
] in ['0'..'9', '+', '-']) do
782 Result
:= Length(s1
);
785 function GetFloat(): Integer;
788 while (n
<= Length(s
)) and (s
[n
] = ' ') do
791 while (n
<= Length(s
)) and //jd >= rather than >
792 (s
[n
] in ['0'..'9', '+', '-', '.', 'e', 'E']) do
798 Result
:= Length(s1
);
801 function GetString(): Integer;
804 while (n
<= Length(s
)) and (s
[n
] = ' ') do
807 while (n
<= Length(s
)) and (s
[n
] <> ' ') do
813 Result
:= Length(s1
);
816 function ScanStr(c
: Char): Boolean;
818 while (n
<= Length(s
)) and (s
[n
] <> c
) do
822 Result
:= (n
<= Length(s
));
825 function GetFmt(): Integer;
831 while (fmt
[m
] = ' ') and (m
< Length(fmt
)) do
833 if (m
>= Length(fmt
)) then
836 if (fmt
[m
] = '%') then
840 'd': Result
:= vtInteger
;
841 'f': Result
:= vtExtended
;
842 's': Result
:= vtString
;
848 if (not ScanStr(fmt
[m
])) then
860 for i
:= 0 to High(Pointers
) do
869 L
:= StrToIntDef(s1
, 0);
870 Move(L
, Pointers
[i
]^, SizeOf(LongInt));
879 if GetFloat() > 0 then
881 X
:= StrToFloatDef(s1
, 0.0);
882 Move(X
, Pointers
[i
]^, SizeOf(Extended
));
891 if GetString() > 0 then
893 Move(s1
, Pointers
[i
]^, Length(s1
)+1);
906 function InDWArray(a
: DWORD
; arr
: DWArray
): Boolean;
912 if arr
= nil then Exit
;
914 for b
:= 0 to High(arr
) do
922 function InWArray(a
: Word; arr
: WArray
): Boolean;
928 if arr
= nil then Exit
;
930 for b
:= 0 to High(arr
) do
938 function InSArray(a
: string; arr
: SArray
): Boolean;
944 if arr
= nil then Exit
;
946 a
:= AnsiLowerCase(a
);
948 for b
:= 0 to High(arr
) do
949 if AnsiLowerCase(arr
[b
]) = a
then
956 function GetPos(UID
: Word; o
: PObj
): Boolean;
963 case g_GetUIDType(UID
) of
966 p
:= g_Player_Get(UID
);
967 if p
= nil then Exit
;
968 if not p
.Live
then Exit
;
975 m
:= g_Monsters_Get(UID
);
976 if m
= nil then Exit
;
977 if not m
.Live
then Exit
;
987 function parse(s
: String): SArray
;
997 for a
:= 1 to Length(s
) do
998 if (s
[a
] = ',') or (a
= Length(s
)) then
1000 SetLength(Result
, Length(Result
)+1);
1003 Result
[High(Result
)] := Copy(s
, 1, a
-1)
1004 else // Êîíåö ñòðîêè
1005 Result
[High(Result
)] := s
;
1013 function parse2(s
: string; delim
: Char): SArray
;
1018 if s
= '' then Exit
;
1022 for a
:= 1 to Length(s
) do
1023 if (s
[a
] = delim
) or (a
= Length(s
)) then
1025 SetLength(Result
, Length(Result
)+1);
1027 if s
[a
] = delim
then Result
[High(Result
)] := Copy(s
, 1, a
-1)
1028 else Result
[High(Result
)] := s
;
1036 function g_GetFileTime(fileName
: String): Integer;
1040 if not FileExists(fileName
) then
1046 AssignFile(F
, fileName
);
1048 Result
:= FileGetDate(TFileRec(F
).Handle
);
1052 function g_SetFileTime(fileName
: String; time
: Integer): Boolean;
1056 if (not FileExists(fileName
)) or (time
< 0) then
1062 AssignFile(F
, fileName
);
1064 Result
:= (FileSetDate(TFileRec(F
).Handle
, time
) = 0);
1068 procedure SortSArray(var S
: SArray
);
1076 for i
:= Low(S
) to High(S
) - 1 do
1077 if S
[i
] > S
[i
+ 1] then begin
1086 function b_Text_Format(S
: string): string;
1094 for I
:= 1 to Length(S
) do
1096 if (not Spec
) and (S
[I
] = '\') and (I
+ 1 <= Length(S
)) then
1106 Result
:= Result
+ #10;
1108 Result
:= Result
+ #1;
1110 Result
:= Result
+ #2;
1112 Result
:= Result
+ #3;
1114 Result
:= Result
+ #4;
1116 Result
:= Result
+ #18;
1118 Result
:= Result
+ #19;
1120 Result
:= Result
+ #20;
1122 Result
:= Result
+ #21;
1124 Result
:= Result
+ '\';
1126 Result
:= Result
+ '\' + S
[I
];
1130 Result
:= Result
+ S
[I
];
1132 // reset to white at end
1133 if Rst
then Result
:= Result
+ #2;
1136 function b_Text_Unformat(S
: string): string;
1143 for I
:= 1 to Length(S
) do
1145 if S
[I
] in [#1, #2, #3, #4, #10, #18, #19, #20, #21] then
1150 if (not Spec
) and (S
[I
] = '\') and (I
+ 1 <= Length(S
)) then
1167 '\': Result
:= Result
+ '\';
1169 Result
:= Result
+ '\' + S
[I
];
1173 Result
:= Result
+ S
[I
];