Castle Game EngineIntroduction Units Class Hierarchy Classes, Interfaces, Objects and Records Types Variables Constants Functions and Procedures Identifiers |
Unit CastleUtils
Description
Various basic utilities. Developed for "Castle Game Engine", but generally usable.
Lists of primitives, using FPC generics. Like TIntegerList, TFloatList etc.
Basic operations on numbers.
Some OS-dependent things.
Filenames operations (they somehow complement the standard set of routines in SysUtils).
Basic algorithms: Sort.
This unit is a bag for simple and generally useful things. As a rule (to not let myself put too much things here) this unit must not depend on the Classes unit (see CastleClassUtils for those). Or any higher-level GUI libs like LCL, VCL, or CLX. The only classes defined and used here are exceptions (the base Exception class comes from SysUtils unit) and primitives lists classes.
Initialization of this unit does some generally-useful things:
Calls Randomize (so that you never forget about it).
Sets DecimalSeparator to '.'.
Delphi and FPC define DecimalSeparator based on local settings (like configured user's country). But this makes things like StrToFloat and FloatToStr less predictable — they may give different results on different systems, which limits their use. E.g. FloatToStr(0.9) may output '0,9' on some system. And if you write '0,9' to a text file, it may not be understood by StrToFloat on some other system.
Initial (probably localized) value of DecimalSeparator is saved in LocaleDecimalSeparator variable.
Installs my handler for ExceptProc, see comments at HaltCodeOnException.
Some of the things from Pascal RTL / FCL get better replacemenets here:
Uses
- BaseUnix
- Unix
- Dl
- Variants
- SysUtils
- Math
- FGL
Overview
Classes, Interfaces, Objects and Records
Functions and Procedures
procedure Sort(Arr: pointer; ArrRecordSize: Cardinal; IsSmallerFunc: TIsSmallerFunc; IsSmallerFuncData: Pointer; FirstIndex, LastIndex: integer; CountToUseSimpleSort: Integer = DefaultCountToUseSimpleSort); overload; |
procedure Sort(Arr: pointer; ArrRecordSize: Cardinal; ArrStride: integer; IsSmallerFunc: TIsSmallerFunc; IsSmallerFuncData: Pointer; FirstIndex, LastIndex: integer; CountToUseSimpleSort: Integer = DefaultCountToUseSimpleSort); overload; |
procedure SortByObject(Arr: pointer; ArrRecordSize: Cardinal; IsSmallerFunc: TIsSmallerFuncByObject; FirstIndex, LastIndex: integer; CountToUseSimpleSort: Integer = DefaultCountToUseSimpleSort); overload; |
procedure SortByObject(Arr: pointer; ArrRecordSize: Cardinal; ArrStride: integer; IsSmallerFunc: TIsSmallerFuncByObject; FirstIndex, LastIndex: integer; CountToUseSimpleSort: Integer = DefaultCountToUseSimpleSort); overload; |
procedure Check(TrueValue: boolean; const ErrMessage: string); |
function ArrayPosStr(const A: string; const Arr: array of string): Integer; overload; |
function ArrayPosText(const A: string; const Arr: array of string; IgnoreCase: boolean = true): Integer; overload; |
function PArrayPosStr(const A: string; Arr: PString; ArrCount: Integer): Integer; overload; |
function PArrayPosText(const A: string; Arr: PString; ArrCount: Integer; IgnoreCase: boolean = true): Integer; overload; |
function Iff(boolval: boolean; trueval, falseval: string) : string; overload; |
function Iff(boolval: boolean; trueval, falseval: Integer) : Integer; overload; |
function Iff(boolval: boolean; trueval, falseval: Float) : Float; overload; |
function Iff(boolval: boolean; trueval, falseval: Cardinal): Cardinal; overload; |
function Iff(boolval: boolean; trueval, falseval: char) : char; overload; |
function SFPCVersion: string; |
function SCompilerDescription: string; |
function SCastleEngineProgramHelpSuffix(const DisplayProgramName: string; const Version: string; WrapLines: boolean): string; |
procedure OSCheck(TrueValue: boolean); overload; |
procedure OSCheck(TrueValue: boolean; const Place: string); overload; |
function ExceptMessage(E: TObject; ExceptAddr: Pointer = nil): string; overload; |
procedure OutputException(E: TObject; ExceptAddr: Pointer = nil); overload; |
procedure HaltBool(Value: boolean); |
procedure HaltOnException(proc: TProcedure; HaltCode: integer); overload; |
procedure HaltOnException(proc: TProcedure); overload; |
procedure ProgramBreak(AHaltCode: Integer = 0); overload; |
function CastleReadLink(const FileName: string): string; |
procedure SwapValues(var a, b: Byte ); overload; inline; |
procedure SwapValues(var a, b: Int64 ); overload; inline; |
procedure SwapValues(var a, b: Integer ); overload; inline; |
procedure SwapValues(var a, b: Cardinal); overload; inline; |
procedure SwapValues(var a, b: Single ); overload; inline; |
procedure SwapValues(var a, b: Double ); overload; inline; |
procedure SwapValues(var a, b: char ); overload; inline; |
procedure SwapValues(var a, b: Pointer ); overload; inline; |
procedure OrderUp(var Smaller, Larger: Int64 ); overload; inline; |
procedure OrderUp(var Smaller, Larger: Integer ); overload; inline; |
procedure OrderUp(var Smaller, Larger: Cardinal); overload; inline; |
procedure OrderUp(var Smaller, Larger: Single ); overload; inline; |
procedure OrderUp(var Smaller, Larger: Double ); overload; inline; |
procedure OrderUp(x, y: Integer; var Smaller, Larger: Integer ); overload; inline; |
procedure OrderUp(x, y: Cardinal; var Smaller, Larger: Cardinal); overload; inline; |
procedure OrderUp(x, y: Single; var Smaller, Larger: Single ); overload; inline; |
procedure OrderUp(x, y: Double; var Smaller, Larger: Double ); overload; inline; |
function min(const a, b: Int64 ): Int64 ; overload; inline; |
function min(const a, b: integer ): integer ; overload; inline; |
function min(const a, b: cardinal): cardinal; overload; inline; |
function min(const a, b: Single ): Single ; overload; inline; |
function min(const a, b: Double ): Double ; overload; inline; |
function min(const a, b, c: Int64 ): Int64 ; overload; inline; |
function min(const a, b, c: integer ): integer ; overload; inline; |
function min(const a, b, c: cardinal): cardinal; overload; inline; |
function min(const a, b, c: Single ): Single ; overload; inline; |
function min(const a, b, c: Double ): Double ; overload; inline; |
function max(const a, b: Int64 ): Int64 ; overload; inline; |
function max(const a, b: integer ): integer ; overload; inline; |
function max(const a, b: cardinal): cardinal; overload; inline; |
function max(const a, b: Single ): Single ; overload; inline; |
function max(const a, b: Double ): Double ; overload; inline; |
function max(const a, b, c: Int64 ): Int64 ; overload; inline; |
function max(const a, b, c: integer ): integer ; overload; inline; |
function max(const a, b, c: cardinal): cardinal; overload; inline; |
function max(const a, b, c: Single ): Single ; overload; inline; |
function max(const a, b, c: Double ): Double ; overload; inline; |
procedure MinTo1st(var a: Int64 ; const b: Int64 ); overload; inline; |
procedure MinTo1st(var a: Integer ; const b: Integer ); overload; inline; |
procedure MinTo1st(var a: Cardinal; const b: Cardinal); overload; inline; |
procedure MinTo1st(var a: Single ; const b: Single ); overload; inline; |
procedure MinTo1st(var a: Double ; const b: Double ); overload; inline; |
procedure MaxTo1st(var a: Int64 ; const b: Int64 ); overload; inline; |
procedure MaxTo1st(var a: Integer ; const b: Integer ); overload; inline; |
procedure MaxTo1st(var a: Cardinal; const b: Cardinal); overload; inline; |
procedure MaxTo1st(var a: Single ; const b: Single ); overload; inline; |
procedure MaxTo1st(var a: Double ; const b: Double ); overload; inline; |
function IndexMax(const a0, a1, a2: Double): Integer; overload; inline; |
function IndexMin(const a0, a1, a2: Double): Integer; overload; inline; |
function Between(const a, vBegin, vEnd: Int64 ): boolean; overload; inline; |
function Between(const a, vBegin, vEnd: integer ): boolean; overload; inline; |
function Between(const a, vBegin, vEnd: cardinal): boolean; overload; inline; |
function Between(const a, vBegin, vEnd: Float ): boolean; overload; inline; |
function Between(const a, vBegin, vEnd: Char ): boolean; overload; inline; |
function RoundClamp255(const A: Single): Byte; inline; |
function Clamped(const a, vBegin, vEnd: Int64 ): Int64 ; overload; inline; |
function Clamped(const a, vBegin, vEnd: integer ): integer ; overload; inline; |
function Clamped(const a, vBegin, vEnd: cardinal): cardinal; overload; inline; |
function Clamped(const a, vBegin, vEnd: Single ): Single ; overload; inline; |
function Clamped(const a, vBegin, vEnd: Double ): Double ; overload; inline; |
procedure Clamp(var a: Int64 ; const vBegin, vEnd: Int64 ); overload; inline; |
procedure Clamp(var a: integer ; const vBegin, vEnd: integer ); overload; inline; |
procedure Clamp(var a: cardinal; const vBegin, vEnd: cardinal); overload; inline; |
procedure Clamp(var a: Single ; const vBegin, vEnd: Single ); overload; inline; |
procedure Clamp(var a: Double ; const vBegin, vEnd: Double ); overload; inline; |
procedure RestOf3dCoords(coord: integer; out first, second: integer); |
function ChangeIntCycle(value, change, maxValue: integer): integer; |
function Lerp(const a: Single; const l, h: Integer): Single; overload; inline; |
function Lerp(const a: Single; const l, h: Cardinal): Single; overload; inline; |
function Lerp(const a, l, h: Single): Single; overload; inline; |
function Lerp(const a: Double; const l, h: Integer): Double; overload; inline; |
function Lerp(const a: Double; const l, h: Cardinal): Double; overload; inline; |
function Lerp(const a, l, h: Double): Double; overload; inline; |
function RoundUpToMultiply(value, multiplicator: Integer): Integer; |
function BiggestPowerOf2(Value: Cardinal): Cardinal; |
function Biggest2Exponent(Value: Cardinal): integer; |
function Smallest2Exponent(Value: Cardinal): Integer; |
function Smallest2Power(Value: Cardinal): Cardinal; |
function IsPowerOf2(Value: Cardinal): boolean; |
function DivRoundUp(Value, Divider: Cardinal): Cardinal; overload; |
function DivRoundUp(Value, Divider: Integer): Integer; overload; |
function MapRange(sourceVal, sourceBegin, sourceEnd, destBegin, destEnd: integer): float; overload; |
function MapRange(sourceVal, sourceBegin, sourceEnd, destBegin, destEnd: float ): float; overload; |
function RandomFloatRange(const RangeBegin, RangeEnd: Float): Float; |
function AngleRadPointToPoint(x1, y1, x2, y2: Single): Single; |
function NatNatPower(Base, Exponent: Cardinal): Cardinal; |
function RandomPlusMinus: integer; |
function ArcCot(x: Float): Float; |
function SmallFactorial(n: Integer): Int64; |
procedure CastleDivMod(Dividend: Integer; Divisor: Word; out Result, Remainder: SmallInt); |
procedure DivUnsignedMod(Dividend: Integer; Divisor: Word; out Result: Smallint; out Remainder: Word); |
function CeilDiv(const A, B: Cardinal): Cardinal; |
procedure FloatDivMod(const A, B: Double; out DivResult: Int64; out Remainder: Double); |
function FloatModulo(const A, B: Double): Double; |
procedure MinMax(const x0, x1, x2: Double; out min, max: Double); overload; |
procedure MinMax(const x0, x1, x2: Single; out min, max: Single); overload; |
function CastleCoTan(const Value: Float): Float; |
function IntSqrt(const Value: Cardinal): Cardinal; |
function DeleteFileExt(const FileName: string): string; |
function ExtractOnlyFilename(const FileName: string): string; |
function ChangeFilePath(const FileName, NewPath: string): string; |
function DuplicateSlash(const s: string): string; |
function IsPathDelim(c: char): boolean; |
function InclPathDelim(const s: string): string; |
function ExclPathDelim(const s: string): string; |
function RelativeFilename(const FileName: string): string; |
function NiceFileName(const FileName: string): string; |
function IsPathAbsolute(const Path: string): boolean; |
function IsPathAbsoluteOnDrive(const Path: string): boolean; |
function SpecialDirName(const DirectoryName: string): boolean; |
function AppendToFilename(const FileName, Suffix: string): string; |
function ExpandFilePath(const FilePath: string): string; |
function PointerAdd(p: pointer; add: integer): pointer; |
function GetClearMem(Size: integer; ClearValue: byte = 0): pointer; overload; |
procedure FreeMemNiling(var p: pointer); |
function CheckIsMemCharFilled(const Data; Size: Integer; AChar: Char): Integer; |
function IsMemCharFilled(const Data; Size: Integer; AChar: Char): boolean; |
function IsMemWordFilled(const Data; Size: Integer; Value: Word): boolean; |
function IsMemDWordFilled(const Data; Size: Integer; Value: DWord): boolean; |
procedure ErrorWrite(const s: string); overload; |
procedure WarningWrite(const s: string); overload; |
procedure InfoWrite(const s: string); overload; |
procedure ErrorWrite(const s: string; const args: array of const); overload; |
procedure WarningWrite(const s: string; const args: array of const); overload; |
procedure InfoWrite(const s: string; const args: array of const); overload; |
procedure InfoWriteParts(const TitleFormat: string; const Messages: array of string); |
Types
Constants
Variables
Description
Functions and Procedures
procedure Sort(Arr: pointer; ArrRecordSize: Cardinal; IsSmallerFunc: TIsSmallerFunc; IsSmallerFuncData: Pointer; FirstIndex, LastIndex: integer; CountToUseSimpleSort: Integer = DefaultCountToUseSimpleSort); overload; |
Sort given table of items.
Sorts items ascending, that is Arr[FirstIndex] <= ... <= Arr[LastIndex].
Parameters
- Arr
- Pointer to items array in memory.
- ArrRecordSize
- Size (in bytes) of every item. This is the size of item that will be moved around in the memory.
- IsSmallerFunc
- Comparison function, should return is "A < B" true.
I'm assuming here that IsSmallerFunc works like mathematical "<": it's not reflexive (IsSmallerFunc(A, A) = False ), for A <> B exactly one of IsSmallerFunc(A, B) or IsSmallerFunc(B, A) is true, and it's transitive.
Note that IsSmallerFunc gets only the pointers to the items. These may be pointers to the Arr, or a pointer to internal temporary copy of some array item. So IsSmallerFunc cannot modify the item underneath (it would not work for internal copy, and also would create problems with types that need initialization/finalization since our internal copy is done using low-level memory copying.)
- FirstIndex
- FirstIndex and LastIndex allow you to sort only given part of the array. We don't touch items outside of this range. Note that you could achieve the effect of FirstIndex > 0 also by increasing the Arr pointer, but FirstIndex is usually more comfortable.
If FirstIndex > LastIndex, we do nothing.
- ArrStride
- Distance (in bytes) between array items in memory. If you don't provide it, we'll assume ArrRecordSize. ArrStride is useful if your array is interleaved with another array, and you want to keep the other data untouched by sorting.
ArrStride must be > 0, actually it must be > ArrRecordSize for sensible behavior. (Unless ArrRecordSize is 0, then ArrStride may be 0 too.).
|
procedure Sort(Arr: pointer; ArrRecordSize: Cardinal; ArrStride: integer; IsSmallerFunc: TIsSmallerFunc; IsSmallerFuncData: Pointer; FirstIndex, LastIndex: integer; CountToUseSimpleSort: Integer = DefaultCountToUseSimpleSort); overload; |
|
procedure Check(TrueValue: boolean; const ErrMessage: string); |
Check condition.
Exceptions raised
- ECheckFailed
- Raised with ErrMessage if condition TrueValue if false.
|
function ArrayPosStr(const A: string; const Arr: array of string): Integer; overload; |
Search the array for a given value. Returns index (zero-based) or -1 if not found.
Useful for writing case as:
case ArrayPosStr(variable, [val1, val2]) of
0 : Something1;
1 : Something2;
else SomethingElse;
end;
|
function ArrayPosText(const A: string; const Arr: array of string; IgnoreCase: boolean = true): Integer; overload; |
|
function PArrayPosStr(const A: string; Arr: PString; ArrCount: Integer): Integer; overload; |
|
function PArrayPosText(const A: string; Arr: PString; ArrCount: Integer; IgnoreCase: boolean = true): Integer; overload; |
|
function Iff(boolval: boolean; trueval, falseval: string) : string; overload; |
|
function Iff(boolval: boolean; trueval, falseval: Integer) : Integer; overload; |
|
function Iff(boolval: boolean; trueval, falseval: Float) : Float; overload; |
|
function Iff(boolval: boolean; trueval, falseval: Cardinal): Cardinal; overload; |
|
function Iff(boolval: boolean; trueval, falseval: char) : char; overload; |
|
function SFPCVersion: string; |
Describe FPC version. In the form 'version.release.patch'.
This is actually a constant (for every run of a program it has always the same value) but I can't declare it as a Pascal constant because it must use "Format" function that is not allowed in constant expressions.
|
function SCompilerDescription: string; |
Short name and version of Pascal compiler used to compile this unit. It is a constant, actually, but I cannot declare it as a constant because it must call SFPCVersion that is not declared as a constant.
|
function SCastleEngineProgramHelpSuffix(const DisplayProgramName: string; const Version: string; WrapLines: boolean): string; |
Print some common info for programs released on [http://castle-engine.sourceforge.net/]. This is useful only for programs released on this WWW page by Michalis. Resulting string is multiline.
Parameters
- DisplayProgramName
- Usually ProgramName, but you can give here something else if you want.
- Version
- For my programs this usually looks like '%d.%d.%d' and conforms to [http://castle-engine.sourceforge.net/versioning.php]
- WrapLines
- If true then resulting string will not have lines longer than 80 characters. Suitable for printing program help message on stdout, e.g. in response to --help option.
|
procedure OSCheck(TrueValue: boolean); overload; |
If not TrueValue then RaiseLastOSError.
|
procedure OSCheck(TrueValue: boolean; const Place: string); overload; |
|
function ExceptMessage(E: TObject; ExceptAddr: Pointer = nil): string; overload; |
Nice exception description. Contains ProgramName, exception ClassName (if not descends from EWithHiddenClassName), exception Message (if descends from Exception), and ExceptAddr (and not-nil, and this is compiled with -dDEBUG), and BonusErrorMesssg.
|
procedure OutputException(E: TObject; ExceptAddr: Pointer = nil); overload; |
Show nice exception description on console or (for GUI Windows programs) by a message box. Equivalent to ErrorWrite(ExceptMessage(E)).
|
procedure HaltBool(Value: boolean); |
If Value then Halt(0), else Halt(1).
It is the standard convention of command-line programs to exit with code 0 on success and <> 0 on failure. Or (for some programs like `test') exit with code 0 to indicate true result and <> 0 to indicate false result. So you will probably want to pass here some boolean variable indicating "Success" or "TestPassed".
|
procedure HaltOnException(proc: TProcedure; HaltCode: integer); overload; |
Call Proc, catch all exceptions inside the Proc, and in case of exception make OutputException and Halt(HaltCode). The result is that HaltOnException doesn't raise any exception, never. It always deals with exceptions inside Proc itself.
Version without HaltCode parameter uses global HaltCodeOnException value.
For the special exception class BreakProgram, it does simply Halt(BreakProgram(E).ExitCode)) (no OutputException in this case).
When symbol DEBUG is defined, then HaltOnException works differently — it just calls Proc (and doesn't catch any exceptions).
This is particularly useful under Delphi/Win32. There main program should never exit with exception. Because such exception (because of Delphi stupidity ?) shows ugly Windows dialog box saying something like "Program exited unexpectedly, contact with author etc. bullshit". There is no way for me to avoid this dialog box, even by my own ExceptProc.
|
procedure HaltOnException(proc: TProcedure); overload; |
|
procedure ProgramBreak(AHaltCode: Integer = 0); overload; |
Raise BreakProgram with AHaltCode, causing the program to stop with given exit code nicely (finalizes all exceptions try..finally and such).
|
function CastleReadLink(const FileName: string): string; |
Return the symlink target path. Like Libc.ReadLink or FpReadLink, but more comfortable, it returns a normal Pascal string.
Exceptions raised
EOSError
- In case of any failure (non-existing FileName etc.)
|
procedure SwapValues(var a, b: Byte ); overload; inline; |
Swap variables values.
|
procedure SwapValues(var a, b: Int64 ); overload; inline; |
|
procedure SwapValues(var a, b: Integer ); overload; inline; |
|
procedure SwapValues(var a, b: Cardinal); overload; inline; |
|
procedure SwapValues(var a, b: Single ); overload; inline; |
|
procedure SwapValues(var a, b: Double ); overload; inline; |
|
procedure SwapValues(var a, b: char ); overload; inline; |
|
procedure SwapValues(var a, b: Pointer ); overload; inline; |
|
procedure OrderUp(var Smaller, Larger: Int64 ); overload; inline; |
Make sure the Smaller value is <= than the Larger value, by eventually swapping them.
|
procedure OrderUp(var Smaller, Larger: Integer ); overload; inline; |
|
procedure OrderUp(var Smaller, Larger: Cardinal); overload; inline; |
|
procedure OrderUp(var Smaller, Larger: Single ); overload; inline; |
|
procedure OrderUp(var Smaller, Larger: Double ); overload; inline; |
|
procedure OrderUp(x, y: Integer; var Smaller, Larger: Integer ); overload; inline; |
Assign the smaller value from X, Y to Smaller variable, the other one to Larger variable.
|
procedure OrderUp(x, y: Cardinal; var Smaller, Larger: Cardinal); overload; inline; |
|
procedure OrderUp(x, y: Single; var Smaller, Larger: Single ); overload; inline; |
|
procedure OrderUp(x, y: Double; var Smaller, Larger: Double ); overload; inline; |
|
function min(const a, b: Int64 ): Int64 ; overload; inline; |
Return minimum / maximum from 2 / 3 items.
|
function min(const a, b: integer ): integer ; overload; inline; |
|
function min(const a, b: cardinal): cardinal; overload; inline; |
|
function min(const a, b: Single ): Single ; overload; inline; |
|
function min(const a, b: Double ): Double ; overload; inline; |
|
function min(const a, b, c: Int64 ): Int64 ; overload; inline; |
|
function min(const a, b, c: integer ): integer ; overload; inline; |
|
function min(const a, b, c: cardinal): cardinal; overload; inline; |
|
function min(const a, b, c: Single ): Single ; overload; inline; |
|
function min(const a, b, c: Double ): Double ; overload; inline; |
|
function max(const a, b: Int64 ): Int64 ; overload; inline; |
|
function max(const a, b: integer ): integer ; overload; inline; |
|
function max(const a, b: cardinal): cardinal; overload; inline; |
|
function max(const a, b: Single ): Single ; overload; inline; |
|
function max(const a, b: Double ): Double ; overload; inline; |
|
function max(const a, b, c: Int64 ): Int64 ; overload; inline; |
|
function max(const a, b, c: integer ): integer ; overload; inline; |
|
function max(const a, b, c: cardinal): cardinal; overload; inline; |
|
function max(const a, b, c: Single ): Single ; overload; inline; |
|
function max(const a, b, c: Double ): Double ; overload; inline; |
|
procedure MinTo1st(var a: Int64 ; const b: Int64 ); overload; inline; |
Update value of A to be a minimum of A, B. Works like A := Min(A, B) , but is marginally faster, since you don't have to do anything when A is already smaller.
|
procedure MinTo1st(var a: Integer ; const b: Integer ); overload; inline; |
|
procedure MinTo1st(var a: Cardinal; const b: Cardinal); overload; inline; |
|
procedure MinTo1st(var a: Single ; const b: Single ); overload; inline; |
|
procedure MinTo1st(var a: Double ; const b: Double ); overload; inline; |
|
procedure MaxTo1st(var a: Int64 ; const b: Int64 ); overload; inline; |
Update value of A to be a maximum of A, B. Works like A := Max(A, B) , but is marginally faster, since you don't have to do anything when A is already larger.
|
procedure MaxTo1st(var a: Integer ; const b: Integer ); overload; inline; |
|
procedure MaxTo1st(var a: Cardinal; const b: Cardinal); overload; inline; |
|
procedure MaxTo1st(var a: Single ; const b: Single ); overload; inline; |
|
procedure MaxTo1st(var a: Double ; const b: Double ); overload; inline; |
|
function IndexMax(const a0, a1, a2: Double): Integer; overload; inline; |
Index (0, 1 or 2) of maximum / minimum of 3 numbers.
|
function IndexMin(const a0, a1, a2: Double): Integer; overload; inline; |
|
function Between(const a, vBegin, vEnd: Int64 ): boolean; overload; inline; |
|
function Between(const a, vBegin, vEnd: integer ): boolean; overload; inline; |
|
function Between(const a, vBegin, vEnd: cardinal): boolean; overload; inline; |
|
function Between(const a, vBegin, vEnd: Float ): boolean; overload; inline; |
|
function Between(const a, vBegin, vEnd: Char ): boolean; overload; inline; |
|
function RoundClamp255(const A: Single): Byte; inline; |
|
function Clamped(const a, vBegin, vEnd: Int64 ): Int64 ; overload; inline; |
|
function Clamped(const a, vBegin, vEnd: integer ): integer ; overload; inline; |
|
function Clamped(const a, vBegin, vEnd: cardinal): cardinal; overload; inline; |
|
function Clamped(const a, vBegin, vEnd: Single ): Single ; overload; inline; |
|
function Clamped(const a, vBegin, vEnd: Double ): Double ; overload; inline; |
|
procedure Clamp(var a: Int64 ; const vBegin, vEnd: Int64 ); overload; inline; |
|
procedure Clamp(var a: integer ; const vBegin, vEnd: integer ); overload; inline; |
|
procedure Clamp(var a: cardinal; const vBegin, vEnd: cardinal); overload; inline; |
|
procedure Clamp(var a: Single ; const vBegin, vEnd: Single ); overload; inline; |
|
procedure Clamp(var a: Double ; const vBegin, vEnd: Double ); overload; inline; |
|
procedure RestOf3dCoords(coord: integer; out first, second: integer); |
3D coordinates (0, 1 or 2) except the given coordinate. If Coord = 0, then it sets First = 1 and Second = 2. And so on — for each Coord value, we set First and Second to the remaining indexes.
|
function ChangeIntCycle(value, change, maxValue: integer): integer; |
Increase Value by Change, nicely wrapping in [0..MaxValue], accepting also negative Change. The final value is always in the [0..MaxValue] range, even when initial Value was outside.
|
function Lerp(const a: Single; const l, h: Integer): Single; overload; inline; |
Linear interpolation between two values. Returns (1-A)*L + A*H .
|
function Lerp(const a: Single; const l, h: Cardinal): Single; overload; inline; |
|
function Lerp(const a, l, h: Single): Single; overload; inline; |
|
function Lerp(const a: Double; const l, h: Integer): Double; overload; inline; |
|
function Lerp(const a: Double; const l, h: Cardinal): Double; overload; inline; |
|
function Lerp(const a, l, h: Double): Double; overload; inline; |
|
function RoundUpToMultiply(value, multiplicator: Integer): Integer; |
Smallest multiple of Multiplicator that is still >= Value.
|
function BiggestPowerOf2(Value: Cardinal): Cardinal; |
Largest power of 2 still <= Value. When Value = 0 returns 0.
|
function Biggest2Exponent(Value: Cardinal): integer; |
Exponent of the largest power of 2 that it's still <= Value. Like BiggestPowerOf2, except that this returns which power of 2 it is, while BiggestPowerOf2 just returns exactly this power. Bigget2Exponent(0) = -1.
|
function Smallest2Exponent(Value: Cardinal): Integer; |
Smallest exponent such that 2ˆthis exponent is >= Value. Smallest2Exponent (0) = -1 (this is different situation than Smallest2Exponent (1), when we return 0.
|
function Smallest2Power(Value: Cardinal): Cardinal; |
Smallest power of 2 that is >= Value. Like Smallest2Exponent, except here we return 2ˆSmallest2Exponent(Value). Returns 0 when Value = 0.
|
function IsPowerOf2(Value: Cardinal): boolean; |
Check is Value an exact power of 2.
|
function DivRoundUp(Value, Divider: Cardinal): Cardinal; overload; |
|
function DivRoundUp(Value, Divider: Integer): Integer; overload; |
|
function MapRange(sourceVal, sourceBegin, sourceEnd, destBegin, destEnd: integer): float; overload; |
Linearly map value from a one range to another.
Consider how SourceVal is placed in the [SourceBegin .. SourceEnd] (it may be outside of this range, it all still works OK). It has some distance to range start (SourceBegin), and some distance to range end (SourceEnd).
We want to find another number, that is identically placed in another range [DestBegin .. DestEnd].
Such that Distance(SourceVal, SourceBegin) / Distance(SourceVal, SourceEnd) = Distance(Result, DestBegin) / Distance(Result, DestEnd).
And such that it's on the same side of the range. So if SourceVal is beyond SourceEnd (that is, SourceBegin < SourceEnd < SourceVal or SourceBegin > SourceEnd > SourceVal ) then the result must be similarly beyond DestEnd.
As you can see, this works regardless if one, or both, of the ranges increase (range end is larger than range begin).
|
function MapRange(sourceVal, sourceBegin, sourceEnd, destBegin, destEnd: float ): float; overload; |
|
function RandomFloatRange(const RangeBegin, RangeEnd: Float): Float; |
Random float value in the given range. Make sure RangeBegin < RangeEnd.
|
function AngleRadPointToPoint(x1, y1, x2, y2: Single): Single; |
Angle between a 2D line segments and OX axis. Angle 0 means that Y1 = Y2 and X2 > X1, then the angle increases as you rotate CCW. In radians.
|
function NatNatPower(Base, Exponent: Cardinal): Cardinal; |
Calculate power Base to Exponent, knowing both arguments (and so, also the result) are >= 0.
|
function RandomPlusMinus: integer; |
Random -1 or +1.
|
function SmallFactorial(n: Integer): Int64; |
Trivial factorial with Int64 result. Beware, the results very quickly stop to fit inside Int64 range.
|
procedure DivUnsignedMod(Dividend: Integer; Divisor: Word; out Result: Smallint; out Remainder: Word); |
Like DivMod (return result of integer division and a remainder), but always return Remainder >= 0.
This is useful in case when Dividend < 0. Standard DivMod (and Pascal div and mod operators) return then Result rounded toward zero, and Remainder may be < 0. This procedure will return Result rounded toward negative infinity, and Remainder will always be >= 0.
|
function CeilDiv(const A, B: Cardinal): Cardinal; |
Returns Ceil(A / B), but calculated faster and more precisely (without floating-point help).
|
procedure FloatDivMod(const A, B: Double; out DivResult: Int64; out Remainder: Double); |
Calculate integer division and modulo on two float arguments. Current implementation assumes that A >= 0 and B > 0 (so Result is always >= 0).
Tries to secure against floating point imprecision. It's always guaranteed that Remainder >= 0 and <= B (and usually should be < B, but this cannot be guaranteed).
|
function FloatModulo(const A, B: Double): Double; |
Calculate float modulo of division on two float arguments. See FloatDivMod for more comments.
|
procedure MinMax(const x0, x1, x2: Double; out min, max: Double); overload; |
|
procedure MinMax(const x0, x1, x2: Single; out min, max: Single); overload; |
|
function IntSqrt(const Value: Cardinal): Cardinal; |
Floor from Sqrt(Value).
|
function DeleteFileExt(const FileName: string): string; |
Remove from the FileName the last extension (including the dot). Note that if the FileName had a couple of extensions (e.g. blah.x3d.gz ) this will remove only the last one. Will remove nothing if filename has no extension.
|
function ExtractOnlyFilename(const FileName: string): string; |
Extracts from FileName the name of file, without directory, without last extension and without any Windows drive letter.
|
function ChangeFilePath(const FileName, NewPath: string): string; |
Returns FileName with directory (path) part replaced with given NewPath. NewPath must contain trailing PathDelim.
|
function DuplicateSlash(const s: string): string; |
Duplicates (makes them double) the PathDelim characters in the string.
|
function IsPathDelim(c: char): boolean; |
Checks is C valid path delimiter under this platform.
For all platforms this just compares C with PathDelim, and under Windows additionally accepts also C = '/'. (Since under Windows the Unix-like '/' is not standard PathDelim, but it's accepted by all WinAPI functions and programs, and it's comfortable to use if you're accustomed to Unix.)
|
function InclPathDelim(const s: string): string; |
These do almost the same as standard Include/ExcludeTrailingPathDelimiter functions, but have shorter names. So InclPathDelim makes sure S has some path delimiter at the end (appends PathDelim if needed), and ExclPathDelim makes sure there's no path delimiter at the end (strips it if needed).
The difference from Delphi Include/ExcludeTrailingPathDelimiter is that my functions use IsPathDelim, so they take into account the fact that under Windows '/' is also a valid path delimiter. For FPC, default Include/ExcludeTrailingPathDelimiter already take this into account, so my versions are not really useful, they only have shorter names.
Also, my functions do not handle MBCS strings.
|
function ExclPathDelim(const s: string): string; |
|
function RelativeFilename(const FileName: string): string; |
Forces FileName to be relative (relative from CurrentDir).
Given FileName may be absolute (then it's directory part will be modified accordingly) or already relative (then it will simply be returned without any changes).
|
function NiceFileName(const FileName: string): string; |
Makes FileName relative or absolute, whichever is nicer to show the user.
Given FileName may be absolute or relative (with respect to CurrentDir). This function maybe will convert FileName to absolute filename and maybe will convert it to relative filename – whichever will be nicer to show the user.
It's not guaranteed what exactly this function considers as "nicer for the user". Current implementation simply assumes that if FileName is under current directory, then relative name is nicer, otherwise absolute name is nicer. In other words, it tries to make a relative name but without any leading "..".
Examples:
If CurrentDir = '/usr/share/' and
FileName = '/usr/share/some_file'
Result will be a relative filename 'some_file'
If CurrentDir = '/usr/share/' and
FileName = '/lib/bla/bla'
Result will be equal to FileName '/lib/bla/bla'
If CurrentDir = '/usr/share/' and
FileName = '../../lib/bla/bla'
Result will be absolute filename '/lib/bla/bla'
|
function IsPathAbsolute(const Path: string): boolean; |
Check is the given Path absolute.
Path may point to directory or normal file, it doesn't matter. Also it doesn't matter whether Path ends with PathDelim or not.
Note for Windows: while it's obvious that 'c:\autoexec.bat' is an absolute path, and 'autoexec.bat' is not, there's a question whether path like '\autoexec.bat' is absolute? It doesn't specify drive letter, but it does specify full directory hierarchy on some drive. This function treats this as not absolute, on the reasoning that "not all information is contained in Path".
See also
- IsPathAbsoluteOnDrive
- Just like IsPathAbsolute, but on Windows accepts also paths that specify full directory tree without drive letter.
|
function IsPathAbsoluteOnDrive(const Path: string): boolean; |
Just like IsPathAbsolute, but on Windows accepts also paths that specify full directory tree without drive letter.
See also
- IsPathAbsolute
- Check is the given Path absolute.
|
function SpecialDirName(const DirectoryName: string): boolean; |
Checks is the directory name special, like "." or "..".
The precise definition of "special" is that you cannot ever create or even have any filenames / directories named like this.
|
function AppendToFilename(const FileName, Suffix: string): string; |
Add Suffix to the filename, right before extension. Returns DeleteFileExt(FileName) + Suffix + ExtractFileExt(FileName) .
|
function ExpandFilePath(const FilePath: string): string; |
Make path absolute. Same as ExpandFileName, but knows that FilePath contains only a path and will always work as it should. (Delphi's and FPC's do not guarantee correct ExpandFileName result for paths ended with PathDelim.)
FilePath may, but doesn't have to, end with PathDelim. Result will always end with PathDelim.
Note: '' is treated as current dir (as it always should be, because ExtractFilePath('file') = '' and 'file' is in current dir).
|
function PointerAdd(p: pointer; add: integer): pointer; |
Pointer arithmetic. Will wrap over if you add too much. Add may be negative. This is just a shortcut for PtrInt(Result) := PtrInt(P)+Add , without any range / overflow checks.
|
function GetClearMem(Size: integer; ClearValue: byte = 0): pointer; overload; |
|
procedure FreeMemNiling(var p: pointer); |
Safer version of FreeMem, checks is parameter Nil , and sets it to Nil afterwards.
|
function CheckIsMemCharFilled(const Data; Size: Integer; AChar: Char): Integer; |
Check is memory filled with the given character. Returns -1 is True , or the number (between 0 .. Size - 1) or the first character different than AChar.
|
function IsMemCharFilled(const Data; Size: Integer; AChar: Char): boolean; |
Check is memory filled with the given character. Returns simple boolean, use CheckIsMemCharFilled to get more informative result.
|
function IsMemWordFilled(const Data; Size: Integer; Value: Word): boolean; |
Check is memory filled with the Word (2 byte sequence). Size if the number of words (not bytes), this is consequent with Size parameter from FillWord from FPC's RTL.
|
function IsMemDWordFilled(const Data; Size: Integer; Value: DWord): boolean; |
Check is memory filled with the DWord (4 byte sequence). Size if the number of dwords (not bytes), this is consequent with Size parameter from FillDWord from FPC's RTL.
|
procedure ErrorWrite(const s: string); overload; |
Write routines that use a dialog box or console to best present the message.
If we are under Windows and not IsConsole then we use dialog boxes through ErrorBox, WarningBox, InfoBox. Otherwise (not under Windows, or a console) we output the message (to standard output for InfoWrite, or ErrOutput for ErrorWrite and WarningWrite).
Notes for Windows: even when IsConsole = false, we can have GetStdHandle(STD_ERROR_HANDLE) and/or GetStdHandle(STD_OUTPUT_HANDLE) available. User can always run GUI program and redirect our stdin/out/err and then GUI app will have some of stdin, stdout, stderr available. In other words, GUI app *may* have stdin/out/err, but it doesn't have to. Depends on how the user run the app. But XxxWrite functions will always for GUI app (that have IsConsole = false) use XxxBox functions, never Writeln, even when stdin/out/err will be available. This ensures that program always behaves in the same way.
|
procedure WarningWrite(const s: string); overload; |
|
procedure InfoWrite(const s: string); overload; |
|
procedure ErrorWrite(const s: string; const args: array of const); overload; |
|
procedure WarningWrite(const s: string; const args: array of const); overload; |
|
procedure InfoWrite(const s: string; const args: array of const); overload; |
|
procedure InfoWriteParts(const TitleFormat: string; const Messages: array of string); |
Output messages, using console or dialog box.
If we're not on Windows or IsConsole, then we simply output Messages using Writeln.
If we're on Windows and not IsConsole, then every Messages is displayed in a separate dialog box. Dialog box uses our InfoBox routine, with Messages[I] being message content and title being Format(TitleFormat, [I + 1, Messages.Count]) .
This is good for outputting a lot of information.
|
Types
TIsSmallerFunc = function (const A, B, Data: Pointer): boolean; |
|
TIsSmallerFuncByObject = function (const A, B: Pointer): boolean of object; |
|
PBoolean = ˆBoolean; |
Pointer to a boolean. Defined as ˆByte in some Delphi Windows unit, for FPC 1.0.x PBoolean is not available at all.
|
TByteArray = array[0..MaxInt div SizeOf(Byte)-1] of Byte; |
|
TArray_PChar = array[0..MaxInt div SizeOf(PChar)-1]of PChar; |
|
TArray_TObject = array[0..MaxInt div SizeOf(Pointer)-1]of TObject; |
|
PtrObject = ˆTObject; |
Pointer to TObject. Don't call this PObject or PTObject to avoid possible name clashes with other units (pointers are often used in situations that prevent good type-checking, so better to avoid name clashes to avoid some nasty errors).
|
TArray_Single = packed array [0..MaxInt div SizeOf(Single) - 1] of Single; |
|
TArray_LongInt = packed array [0..MaxInt div SizeOf(LongInt) - 1] of LongInt; |
|
Constants
DefaultCountToUseSimpleSort = 10; |
When should the complicated sorting algorithm fallback to a simpler one. If number of items is <= CountToUseSimpleSort, then Sort will fallback to SimpleSort (= sort by choosing for now) instead of recursive QuickSort. Set CountToUseSimpleSort = 0 to make it never fall back to SimpleSort.
By default this is DefaultCountToUseSimpleSort .
|
NL = LineEnding; |
New line. Short name for LineEnding.
|
enatural = 2.71828182845905; |
|
sqrt2 = 1.4142135623730950488016887242097; |
|
Sqrt3 = 1.7320508075688773; |
|
HalfPi = 1.57079632679489661923; |
Half of Pi. Taken from FPC sources, file rtl/inc/genmath.inc
|
RootDir = '/'
; |
Root dir name. Empty if not applicable to this OS.
|
Variables
BonusErrorMessg: string =''; |
Additional message output when you end program with an exception.
|
HaltCodeOnException: Integer = 1; |
|
LocaleDecimalSeparator: char; |
|
Generated by PasDoc 0.12.1 on 2013-02-04 20:26:53
|