Standard library
The units PaskalCPP ships in res\libs\std: paths and files, maths, timing, the console, data built into a binary, streams, C stdio over those streams, C ABI hooks, IO and zip forms of the loaders of raylib, SFML, mojoAL, SQLite, tmxlite and LDtkLoader, a virtual-resolution window for raylib and Dear ImGui, Raven user interfaces inside raylib programs, and MIR's JIT with no C++ in the program.
Every unit is imported by its name, with no @addmodulepath: import Math;. A name is read bare when no other imported unit exports it (Clamp), or qualified (Math.Clamp); see Imports.
The sections for the units written in PaskalCPP are read from each unit's own /// doc comments every time these docs are built, so what you read here is what the unit says. FormatStr and sfml_ext are C++ and are described by hand at FormatStr and sfml_ext.
| Unit | What it gives |
|---|---|
| SysUtils | paths (ResolvePath, ExeDir), files and folders (FileExists, DeleteFile, CreateDir, RemoveDir), Delay, Halt, byte sizes, FormatStr |
| Math | constants, Sin / Cos / Sqrt / Abs, rounding (Round, Trunc, Floor, Ceil), Min / Max, clamping and easing, perceived volume, random numbers, 2D geometry |
| Diagnostics | a Stopwatch (Delphi's TStopwatch: StartNew, ElapsedMilliseconds, ...) on a monotonic clock |
| Console | terminal output with colours and cursor control, text measured in columns |
| ResData | data a build adds with @addresdata, read back by key |
| CustomIO | streams behind a table of callbacks: memory, files, folders, zip archives read and written (ZipDirectoryContents) |
| HookIO | C fopen and the stdio family on CustomIO streams, inside C libraries too |
| HookABI | hooks of C ABI functions, at link time and at run time |
| raylib_ext | raylib's loaders from any IO, a zip as raylib's file system, MPEG-1 video, the frame window (a virtual resolution sized for the DPI, letterboxed on resize: InitFrameWindow, BeginFrame), the window's DPI on every target (GetWindowDpi) |
| rlimgui_ext | Dear ImGui inside the frame window, at its virtual resolution (BeginFrameImGui, EndFrameImGui) |
| raven_raylib | Raven's user interfaces inside a raylib program, the frame window included, and raylib textures shown in Raven widgets (InitRaven, UpdateRaven, DrawRaven, CreateRavenTexture) |
| sfml_ext | SFML 3 additions: a DPI-scaling window, zip streams, video, a mixer, message boxes |
| mojoal_ext | an Ogg Vorbis sound into an OpenAL buffer from a path, any IO or a zip entry (LoadSound, LoadSoundIO, LoadSoundZip) |
| sqlite_ext | a read-only SQLite database opened from any IO or a zip entry (OpenDatabaseIO, OpenDatabaseZip) |
| tmxlite_ext | a Tiled .tmx map loaded with its tilesets and images from a path, an IO source or a zip, drawn with raylib (LoadTiledMap, DrawTiledMap) |
| ldtk_ext | an LDtk project loaded with its tilesets from a path, an IO source or a zip, its levels and layers drawn with raylib (LoadLdtkProject, DrawLdtkLevel) |
| mir_ext | MIR with no C++ in the program: contexts with recoverable errors, MIR text, C through c2mir and the binary form from a string, a file or a zip, functions built in code, hosts, linking and calls (MirNew, MirLoadModuleText, C2MirCompileZip, MirLink, MirCall) |
SysUtils
The SysUtils unit: import SysUtils; turns any spelling of a path into one full, normalized path (ResolvePath), with the same prefixes the compiler's own directives take ($P: $D: $S:), and tells where the running program lives (ExeDir), checks for and deletes a file (FileExists, DeleteFile), creates and removes a folder (CreateDir, RemoveDir), formats values into a string as println prints them (FormatStr), waits a given time (Delay) and ends the program with an exit code (Halt). A name is read bare when no other imported unit exports it (ResolvePath), or qualified (SysUtils.ResolvePath).
Import it with import SysUtils;.
Constants
| Name | Declaration | Description |
|---|---|---|
Kilobyte | : int64 = 1024 | The bytes in a kilobyte (1024, binary): 4 * Kilobyte is 4096. See Megabyte. |
Megabyte | : int64 = 1024 * 1024 | The bytes in a megabyte (1024 x 1024, binary). See Gigabyte. |
Gigabyte | : int64 = 1024 * 1024 * 1024 | The bytes in a gigabyte (1024 x 1024 x 1024, binary). Example: if LSize > 2 * Gigabyte then ... end; |
Routines
ResolvePath
routine ResolvePath(const APath: string): string;
Resolves a path to one full, normalized path.
The path may start with a prefix that names its base folder, matched at the very start and in either case:
$P:the folder of the running program's executable (asked of the OS, so it holds wherever the program was started from);$D:the current working directory;$S:the caller's base folder, written out (the same as no prefix).
A rooted path is only normalized; any other is resolved against its base (no base: the current working directory). . and .. are folded and repeated separators joined, as text: the disk is never touched, the path need not exist and symbolic links are not followed. Leading and trailing blanks are trimmed.
The result on Windows uses forward slashes up to 247 UTF-16 units (the plain Win32 limit) and the long-path spelling past it (\\?\C:\... or \\?\UNC\server\share\..., backslashes), so every file routine takes it at any length; on Linux it is the plain /... path. Resolving a result again gives it back unchanged. Text is UTF-8 in and out.
To hand the result to a C routine, keep it in a variable and pass that variable's .c_str() while the variable lives.
Parameters
APath: the path to resolve; empty (or only a prefix) gives ""
Returns: the full path, or "" for an empty path
Example: LZip := ResolvePath("$P:secret.zip"); // beside the program LCfg := ResolvePath("$D:../app.cfg"); // above the current folder
See also: ExeDir. Since: 0.2
routine ResolvePath(const APath: string; const ABaseDir: string): string;
Resolves a path against a given base folder; see ResolvePath(APath) for the prefixes and the result's form.
Parameters
APath: the path to resolve;$P:and$D:override ABaseDirABaseDir: the folder a relative path (or$S:) is resolved against; empty: the current working directory
Returns: the full path, or "" for an empty path
Example: LIcon := ResolvePath("icons/app.png", LDataDir);
Since: 0.2
routine ResolvePath(const APath: ptr to const char): string;
Resolves a C string path, as ResolvePath(APath) does for a string: for a path that comes from C (an argv entry, a C library's result).
Parameters
APath: a NUL-terminated UTF-8 path; nil gives ""
Returns: the full path, or "" for an empty or nil path
Since: 0.2
routine ResolvePath(const APath: ptr to const char; const ABaseDir: ptr to const char): string;
Resolves a C string path against a C string base folder, as ResolvePath(APath, ABaseDir) does for strings.
Parameters
APath: a NUL-terminated UTF-8 path; nil gives ""ABaseDir: a NUL-terminated UTF-8 base folder; nil or empty: the current working directory
Returns: the full path, or "" for an empty or nil path
Since: 0.2
ExeDir
routine ExeDir(): string;
The folder that holds the running program's executable, in the form ResolvePath returns, with no trailing separator (except at a root). Asked of the OS, so it is right however the program was started (argv[0] and paramstr(0) may be relative or a bare name).
Returns: the executable's folder, or "" when the OS cannot tell
See also: ResolvePath. Since: 0.2
FileExists
routine FileExists(const APath: string): bool;
Whether a file exists: true when the path names an existing file (a symbolic link: the file it points to), false for a folder, a missing path, "" or a path the OS cannot read. The path is UTF-8 on every target and goes through ResolvePath first, so a $P: / $D: prefix works as written.
Parameters
APath: the file's path
Returns: true when the file is there
Example: if not FileExists("$P:assets.zip") then ... end;
See also: ResolvePath. Since: 0.2
routine FileExists(const APath: ptr to const char): bool;
FileExists for a C string (the same rule).
Parameters
APath: the file's path
Returns: true when the file is there
Since: 0.2
DeleteFile
routine DeleteFile(const APath: string): bool;
Deletes a file, as Delphi's DeleteFile: a folder is never removed by it. The path is UTF-8 and goes through ResolvePath first.
Parameters
APath: the file to delete
Returns: true when the file was deleted; false when it is a folder, is missing, or the OS refuses it (a file open elsewhere on Windows)
Example: DeleteFile("$P:old_save.dat");
See also: FileExists. Since: 0.3
CreateDir
routine CreateDir(const APath: string): bool;
Creates one folder, as Delphi's CreateDir: its parent must exist already (nothing above it is made). The path is UTF-8 and goes through ResolvePath first.
Parameters
APath: the folder to create
Returns: true when the folder was made; false when it exists already (as a folder or a file), its parent is missing, or the OS refuses it
Example: CreateDir("$P:saves");
See also: RemoveDir. Since: 0.3
RemoveDir
routine RemoveDir(const APath: string): bool;
Removes an empty folder, as Delphi's RemoveDir: a folder that holds anything is left as it is. The path is UTF-8 and goes through ResolvePath first.
Parameters
APath: the folder to remove
Returns: true when the folder was removed; false when it is not empty, is a file, is missing, or the OS refuses it
Example: RemoveDir("$P:saves");
See also: CreateDir. Since: 0.3
Halt
routine Halt(const AExitCode: int32);
Ends the program at once with the given exit code (Delphi's Halt): std::exit, so the program's exit work still runs (output is flushed, files closed, the debug heap report printed); the caller's locals are not destroyed.
Parameters
AExitCode: the code the program ends with (0 is success)
Example: if not LOk then Halt(1); end;
Since: 0.3
Delay
routine Delay(const AMilliseconds: int32);
Waits the given number of milliseconds, then returns: at least that long (std::this_thread::sleep_for), the OS may wake the program a little later. A wait of 0 or less returns at once.
Parameters
AMilliseconds: how long to wait, in milliseconds
Example: Delay(500); // half a second
Since: 0.2
FormatStr
FormatStr(AFormat, ...): string
FormatStr(F, ...) gives as a string the text println(F, ...) prints: std::format's {} specifiers, every argument in println's form. The format is checked when the program is built, and a mistake in it is reported in PaskalCPP's words as println's are: more {} than arguments, a format that is not a string literal or a string const, an argument with no printed form. See Intrinsics.
It is a C++ variadic template, in the unit's header, so its body is built where it is called.
Example: LText := FormatStr("{} of {} done", LDone, LTotal);
Math
The Math unit: import Math; gives the maths a program reaches for beside the language's own operators. PerceivedVolume turns a level a person sets (a slider, 0 to 1) into the linear volume an audio API takes, so equal steps sound like equal steps; PerceivedLevel turns a volume back into its level. Beside them: the constants (Pi, DegToRad / RadToDeg, the Epsilons, NaN), the everyday functions under Delphi's names (Sin, Cos, Sqrt, Abs, and Round / Trunc / Floor / Ceil to int64), Clamp and Wrap, SameSign and SameValue, Lerp, AngleDifference, SmoothMove, the Easing curves (Ease, EaseBetween) and Random, a seeded generator whose numbers are the same on every target. And the 2D geometry of a game, with no graphics library: Vector2 (laid out as SFML's, raylib's and SDL's {x, y}), Rect and Extent, the oriented box Obb, and the collisions between them (points, circles, triangles, rectangles, segments, boxes). Angles are degrees. A name is read bare when no other imported unit exports it (PerceivedVolume), or qualified (Math.PerceivedVolume).
Import it with import Math;.
Types
Easing
Easing = choices(Linear, InQuad, OutQuad, InOutQuad, InCubic, OutCubic, InOutCubic, InQuart, OutQuart, InOutQuart, InQuint, OutQuint, InOutQuint, InSine, OutSine, InOutSine, InExpo, OutExpo, InOutExpo, InCircle, OutCircle, InOutCircle);
The shape of an easing curve (Robert Penner's): In starts slow, Out ends slow, InOut does both; Quad .. Quint are the powers 2 .. 5, Sine a quarter wave, Expo powers of 2, Circle a quarter circle.
See also: Ease. Since: 0.2
RandomGenerator
RandomGenerator = object
A source of random numbers: std::mt19937 with this unit's own mapping, so a seed gives the same numbers on every target and every standard library. Built with a seed it repeats that sequence; built without one it takes a seed from the system's entropy source. Integer ranges hold both ends, float ranges the low end only; bounds may come in either order.
Members
Engine: std::mt19937: The generator's engine, C++'s std::mt19937; use the methods, which keep Seed() trueSeedValue: uint32: The seed the sequence started from, as Seed() returns itinit(): A generator seeded from the system's entropy source. See Randomize.init(const ASeed: uint32): A generator that gives the sequence of ASeed. Parameters:ASeedthe seed.method SetSeed(const ASeed: uint32): Starts the sequence of ASeed again. Parameters:ASeedthe seed.const method Seed(): uint32: The seed the sequence started from (the last one set). Returns: the seedmethod Randomize(): Starts a fresh sequence from a seed taken from the system's entropy source. A generator built without a seed calls this on creation. Seed() then returns the new seed, so SetSeed(Seed()) repeats the sequence from here. Example:LRng.Randomize(); LAgain := LRng.Seed();SeeSetSeed,Seed, SetRandomSeed.method NextInt(const AMin: int32; const AMax: int32): int32: A whole number from AMin to AMax, both included. Parameters:AMinone end;AMaxthe other end. Returns: the numbermethod NextInt64(const AMin: int64; const AMax: int64): int64: NextInt for int64 bounds (a method name has one form per object). Parameters:AMinone end;AMaxthe other end. Returns: the numbermethod NextFloat(const AMin: float64; const AMax: float64): float64: A number from AMin (included) to AMax (left out); equal bounds give AMin. Parameters:AMinthe low end, included;AMaxthe high end, left out. Returns: the numbermethod NextFloat32(const AMin: float32; const AMax: float32): float32: NextFloat for float32 bounds: AMin (included) to AMax (left out). Parameters:AMinthe low end, included;AMaxthe high end, left out. Returns: the numbermethod NextBool(): bool: True or false, each half the time. Returns: the value
Example: LRng: RandomGenerator(42); LDie := LRng.NextInt(1, 6);
See also: RandomInt. Since: 0.2
Vector2
Vector2 = object
A 2D vector or point of float32 X and Y, laid out as SFML's sf::Vector2f, raylib's Vector2 and SDL's SDL_FPoint ({x, y}). Angles are degrees, SFML's way: 0 points along +X, 90 along +Y (down the screen, as sf::Transformable::setRotation turns). A zero vector is well defined everywhere: its length, heading and normal are 0.
Members
X: float32: The X coordinate (+X to the right)Y: float32: The Y coordinate (+Y down the screen)init(): The zero vector.init(const AX: float32; const AY: float32): The vector (AX, AY). Parameters:AXthe X part;AYthe Y part.const method Length(): float32: Its length. Returns: the lengthconst method LengthSquared(): float32: Its length squared (no square root: for comparing lengths). Returns: the length squaredconst method Distance(const AOther: Vector2): float32: The distance between this point and AOther. Parameters:AOtherthe other point. Returns: the distanceconst method Dot(const AOther: Vector2): float32: The dot product with AOther. Parameters:AOtherthe other vector. Returns: X x AOther.X + Y x AOther.Yconst method Cross(const AOther: Vector2): float32: The 2D cross product with AOther (the Z of the 3D one): positive when AOther turns the way the angles grow. Parameters:AOtherthe other vector. Returns: X x AOther.Y - Y x AOther.Xconst method Normalized(): Vector2: The same direction at length 1; a zero vector stays zero. Returns: the unit vectorconst method Truncated(const AMax: float32): Vector2: The same vector, shortened to AMax when it is longer; a max of 0 or less gives the zero vector. Parameters:AMaxthe longest length. Returns: the vector, at most AMax longconst method Project(const AOnto: Vector2): Vector2: This vector projected onto AOnto (its part along AOnto); onto a zero vector it is the zero vector. Parameters:AOntothe vector projected onto. Returns: the projectionconst method Perpendicular(): Vector2: The vector turned 90 degrees the way the angles grow: (-Y, X), as SFML. Returns: the perpendicular vectorconst method Rotated(const ADegrees: float32): Vector2: The vector turned by ADegrees (positive turns the way the angles grow); computed in float64. Parameters:ADegreesthe turn, in degrees. Returns: the turned vectorconst method Heading(): float32: The direction it points, in degrees: -180 (left out) to 180 (included), 0 along +X, 90 along +Y; a zero vector heads 0. Returns: the heading, in degreesconst method Thrust(const ADegrees: float32; const ASpeed: float32): Vector2: This point moved ASpeed along the heading ADegrees (one step of a thrust); computed in float64. Parameters:ADegreesthe heading, in degrees;ASpeedthe distance moved. Returns: the moved pointconst method Lerp(const ATo: Vector2; const AT: float32): Vector2: The point AT of the way to ATo (std::lerp on each part): 0 gives this point, 1 exactly ATo. Parameters:ATothe end point;ATthe fraction of the way. Returns: the point betweenoperator +(const A: Vector2; const B: Vector2): Vector2: The sum, component by component. Parameters:Athe first vector;Bthe second vector. Returns: (A.X + B.X, A.Y + B.Y)operator -(const A: Vector2; const B: Vector2): Vector2: The difference, component by component: the vector from B to A. Parameters:Athe vector subtracted from;Bthe vector subtracted. Returns: (A.X - B.X, A.Y - B.Y)operator -(const A: Vector2): Vector2: The vector turned around: the same length, the opposite way. Parameters:Athe vector. Returns: (-A.X, -A.Y)operator *(const A: Vector2; const AScale: float32): Vector2: The vector scaled. Parameters:Athe vector;AScalethe factor. Returns: (A.X * AScale, A.Y * AScale)operator *(const AScale: float32; const A: Vector2): Vector2: The vector scaled, the factor written first. Parameters:AScalethe factor;Athe vector. Returns: (A.X * AScale, A.Y * AScale)operator /(const A: Vector2; const AScale: float32): Vector2: The vector divided by a factor, by float rules: a factor of 0 gives infinities or NaN. Parameters:Athe vector;AScalethe divisor. Returns: (A.X / AScale, A.Y / AScale)operator =(const A: Vector2; const B: Vector2): bool: Whether two vectors are exactly equal, component by component (for a tolerance, use SameValue on each component). Parameters:Athe first vector;Bthe second vector. Returns: true when A.X = B.X and A.Y = B.Yoperator <>(const A: Vector2; const B: Vector2): bool: Whether two vectors differ in any component: the opposite of=. Parameters:Athe first vector;Bthe second vector. Returns: true when A.X <> B.X or A.Y <> B.Y
Example: LPos: Vector2(10.0f, 20.0f); LPos := LPos + LVel * LDelta;
See also: Rect. Since: 0.2
Rect
Rect = object
An axis-aligned rectangle: its corner (X, Y) and its size, laid out as sf::FloatRect and raylib's Rectangle. It follows SFML's rules exactly: a negative size spans the other way, a point on the far edges is outside ([X, X + Width)), and rectangles that only touch do not overlap.
Members
X: float32: The left edge (the corner's X)Y: float32: The top edge (the corner's Y)Width: float32: The width; negative spans to the left of XHeight: float32: The height; negative spans above Yinit(): The empty rectangle at (0, 0).init(const AX: float32; const AY: float32; const AWidth: float32; const AHeight: float32): The rectangle with corner (AX, AY) and size AWidth x AHeight. Parameters:AXthe corner's X;AYthe corner's Y;AWidththe width;AHeightthe height.const method Contains(const APoint: Vector2): bool: True when APoint is inside: [left, right) x [top, bottom). Parameters:APointthe point. Returns: whether the rectangle holds itconst method Intersection(const AOther: Rect; var AResult: Rect): bool: The rectangle both cover, in AResult (the empty one when they do not overlap; touching edges do not). Parameters:AOtherthe other rectangle;AResultthe overlap. Returns: whether they overlapconst method Overlaps(const AOther: Rect): bool: True when the rectangles share an area (touching is not enough). Parameters:AOtherthe other rectangle. Returns: whether they overlapconst method Center(): Vector2: The centre point. Returns: the centre
Example: LBox: Rect(0.0f, 0.0f, 32.0f, 32.0f); if LBox.Contains(LMouse) then ... end;
See also: Extent. Since: 0.2
Extent
Extent = object
A rectangle as its two corners: the smallest and the largest X and Y.
Members
MinX: float32: The smallest X (the left edge)MinY: float32: The smallest Y (the top edge)MaxX: float32: The largest X (the right edge)MaxY: float32: The largest Y (the bottom edge)init(): The empty extent at (0, 0).init(const AMinX: float32; const AMinY: float32; const AMaxX: float32; const AMaxY: float32): The extent from (AMinX, AMinY) to (AMaxX, AMaxY), as given. Parameters:AMinXthe smallest X;AMinYthe smallest Y;AMaxXthe largest X;AMaxYthe largest Y.const method ToRect(): Rect: The same area as a Rect: corner (MinX, MinY), size max - min. Returns: the rectangle
See also: Rect. Since: 0.2
LineHitKind
LineHitKind = choices(Miss, Point, Parallel, Collinear);
How two line segments meet (LineIntersection): Miss (they do not), Point (they cross or touch at one point), Parallel (parallel, apart), Collinear (on one line and overlapping).
Since: 0.2
LineHit
LineHit = object
Where two line segments meet: Kind, and Point when Kind is Point.
Members
Kind: LineHitKind: How the segments meetPoint: Vector2: The point where they meet; read it only when Kind is Pointinit(): No meeting: Kind Miss, Point (0, 0).
See also: LineIntersection. Since: 0.2
Obb
Obb = object
An oriented box: a centre, half its width and height, and the angle it is turned by, in degrees (positive the way the angles grow).
Members
Center: Vector2: The box's centreHalfSize: Vector2: Half its width (X) and half its height (Y)Angle: float32: The turn, in degrees (positive the way angles grow)init(): The box of no size at (0, 0).init(const ACenter: Vector2; const AHalfSize: Vector2; const ADegrees: float32): The box at ACenter, AHalfSize from its centre to its sides, turned by ADegrees. Parameters:ACenterthe centre;AHalfSizehalf the width and height;ADegreesthe turn, in degrees.
See also: ObbsOverlap. Since: 0.2
Constants
| Name | Declaration | Description |
|---|---|---|
Pi | : float64 = 3.141592653589793 | The ratio of a circle's circumference to its diameter. |
DegToRad | : float64 = 0.017453292519943295 | Degrees times DegToRad are radians: 90.0 * DegToRad is Pi / 2. See RadToDeg. |
RadToDeg | : float64 = 57.29577951308232 | Radians times RadToDeg are degrees: Pi * RadToDeg is 180. See DegToRad. |
Epsilon32 | : float32 = 0.00001f | The float32 tolerance SameValue uses when none is given (scaled by the values' size past 1). See SameValue. |
Epsilon64 | : float64 = 0.000000000001 | The float64 tolerance SameValue uses when none is given (scaled by the values' size past 1). See SameValue. |
NaN | : float64 = 0.0 / 0.0 | Not a number. It compares unequal to everything, itself included: test a value with X <> X. |
Routines
PerceivedVolume
routine PerceivedVolume(const ALevel: float64; const AMax: float64; const ARangeDb: float64): float64;
The linear volume for a level a person sets, so that equal steps of the level sound like equal steps of loudness. The level maps to decibels over ARangeDb (1 = 0 dB = AMax, the knee level 0.1 = -ARangeDb dB), and below the knee the volume fades in a straight line to exact silence at 0. A level past 1 gives AMax, at or below 0 (or NaN) gives 0. A range of 0 or less makes the curve linear (ALevel * AMax).
Parameters
ALevel: the level, 0 (silent) to 1 (full)AMax: the volume at level 1 (100 for SFML's setVolume)ARangeDb: the loudness range in decibels the level spans
Returns: the linear volume, 0 to AMax
Example: LSound.setVolume(PerceivedVolume(0.5, 100.0, 40.0));
See also: PerceivedLevel. Since: 0.2
routine PerceivedVolume(const ALevel: float64; const AMax: float64): float64;
PerceivedVolume over the default 50 dB range.
Parameters
ALevel: the level, 0 (silent) to 1 (full)AMax: the volume at level 1
Returns: the linear volume, 0 to AMax
Example: LMusic.setVolume(PerceivedVolume(LSlider, 100.0));
See also: PerceivedLevel. Since: 0.2
routine PerceivedVolume(const ALevel: float32; const AMax: float32; const ARangeDb: float32): float32;
PerceivedVolume for float32 values (computed in float64).
Parameters
ALevel: the level, 0 (silent) to 1 (full)AMax: the volume at level 1ARangeDb: the loudness range in decibels the level spans
Returns: the linear volume, 0 to AMax
Since: 0.2
routine PerceivedVolume(const ALevel: float32; const AMax: float32): float32;
PerceivedVolume for float32 values over the default 50 dB range.
Parameters
ALevel: the level, 0 (silent) to 1 (full)AMax: the volume at level 1
Returns: the linear volume, 0 to AMax
Since: 0.2
PerceivedLevel
routine PerceivedLevel(const AVolume: float64; const AMax: float64; const ARangeDb: float64): float64;
The level that gives a linear volume: PerceivedVolume's inverse over the same curve, so PerceivedLevel(PerceivedVolume(L, M, R), M, R) is L for any L in 0 .. 1. A volume of AMax or more gives 1, of 0 or less (or NaN) gives 0; a max of 0 or less gives 0.
Parameters
AVolume: the linear volumeAMax: the volume at level 1ARangeDb: the loudness range in decibels the level spans
Returns: the level, 0 to 1
Example: LSlider := PerceivedLevel(LMusic.getVolume(), 100.0, 40.0);
See also: PerceivedVolume. Since: 0.2
routine PerceivedLevel(const AVolume: float64; const AMax: float64): float64;
PerceivedLevel over the default 50 dB range.
Parameters
AVolume: the linear volumeAMax: the volume at level 1
Returns: the level, 0 to 1
See also: PerceivedVolume. Since: 0.2
routine PerceivedLevel(const AVolume: float32; const AMax: float32; const ARangeDb: float32): float32;
PerceivedLevel for float32 values (computed in float64).
Parameters
AVolume: the linear volumeAMax: the volume at level 1ARangeDb: the loudness range in decibels the level spans
Returns: the level, 0 to 1
Since: 0.2
routine PerceivedLevel(const AVolume: float32; const AMax: float32): float32;
PerceivedLevel for float32 values over the default 50 dB range.
Parameters
AVolume: the linear volumeAMax: the volume at level 1
Returns: the level, 0 to 1
Since: 0.2
Sin
routine Sin(const AValue: float64): float64;
The sine of an angle in radians (Sin(90.0 * DegToRad) is 1).
Parameters
AValue: the angle, radians
Returns: its sine, in [-1, 1]; NaN for a NaN or an infinity
Example: LY := CRadius * Sin(LAngle);
See also: Cos. Since: 0.3
routine Sin(const AValue: float32): float32;
Sin for a float32 angle, computed in float32.
Parameters
AValue: the angle, radians
Returns: its sine
Since: 0.3
Cos
routine Cos(const AValue: float64): float64;
The cosine of an angle in radians (Cos(Pi) is -1).
Parameters
AValue: the angle, radians
Returns: its cosine, in [-1, 1]; NaN for a NaN or an infinity
Example: LX := CRadius * Cos(LAngle);
See also: Sin. Since: 0.3
routine Cos(const AValue: float32): float32;
Cos for a float32 angle, computed in float32.
Parameters
AValue: the angle, radians
Returns: its cosine
Since: 0.3
Sqrt
routine Sqrt(const AValue: float64): float64;
The square root.
Parameters
AValue: the value
Returns: its non-negative square root; NaN for a negative value or a NaN
Example: LDistance := Sqrt(LDX * LDX + LDY * LDY);
Since: 0.3
routine Sqrt(const AValue: float32): float32;
Sqrt for a float32 value, computed in float32.
Parameters
AValue: the value
Returns: its square root
Since: 0.3
Abs
routine Abs(const AValue: float64): float64;
The absolute value: AValue without its sign.
Parameters
AValue: the value
Returns: |AValue|; NaN stays NaN
Example: LGap := Abs(LTarget - LPosition);
Since: 0.3
routine Abs(const AValue: float32): float32;
Abs for a float32 value.
Parameters
AValue: the value
Returns: |AValue|
Since: 0.3
routine Abs(const AValue: int64): int64;
Abs for an int64 value.
Parameters
AValue: the value
Returns: |AValue|
Raises: EXC_INTEGER_OVERFLOW (5) for the lowest int64, which has no positive counterpart
Since: 0.3
routine Abs(const AValue: int32): int32;
Abs for an int32 value.
Parameters
AValue: the value
Returns: |AValue|
Raises: EXC_INTEGER_OVERFLOW (5) for the lowest int32, which has no positive counterpart
Since: 0.3
Round
routine Round(const AValue: float64): int64;
The nearest whole number, as Delphi rounds: a value exactly halfway goes to the even neighbour (banker's rounding), so Round(2.5) is 2, Round(3.5) is 4 and Round(-2.5) is -2.
Parameters
AValue: the value
Returns: the nearest whole number
Raises: EXC_INTEGER_OVERFLOW (5) when the result does not fit int64, or AValue is a NaN or an infinity
Example: LSample := int16(Round(CAmplitude * Sin(LPhase)));
See also: Trunc. Since: 0.3
routine Round(const AValue: float32): int64;
Round for a float32 value (widened exactly to float64 first).
Parameters
AValue: the value
Returns: the nearest whole number, halfway to even
Raises: EXC_INTEGER_OVERFLOW (5) as Round
Since: 0.3
Trunc
routine Trunc(const AValue: float64): int64;
The whole part: the fraction dropped, toward zero (Trunc(-2.7) is -2).
Parameters
AValue: the value
Returns: the whole part
Raises: EXC_INTEGER_OVERFLOW (5) when it does not fit int64, or AValue is a NaN or an infinity
Example: LSeconds := Trunc(LElapsed);
See also: Round. Since: 0.3
routine Trunc(const AValue: float32): int64;
Trunc for a float32 value.
Parameters
AValue: the value
Returns: the whole part
Raises: EXC_INTEGER_OVERFLOW (5) as Trunc
Since: 0.3
Floor
routine Floor(const AValue: float64): int64;
The greatest whole number not above AValue (Floor(-2.5) is -3).
Parameters
AValue: the value
Returns: AValue rounded down
Raises: EXC_INTEGER_OVERFLOW (5) when it does not fit int64, or AValue is a NaN or an infinity
Example: LTileX := Floor(LWorldX / CTileSize);
See also: Ceil. Since: 0.3
routine Floor(const AValue: float32): int64;
Floor for a float32 value.
Parameters
AValue: the value
Returns: AValue rounded down
Raises: EXC_INTEGER_OVERFLOW (5) as Floor
Since: 0.3
Ceil
routine Ceil(const AValue: float64): int64;
The least whole number not below AValue (Ceil(-2.5) is -2).
Parameters
AValue: the value
Returns: AValue rounded up
Raises: EXC_INTEGER_OVERFLOW (5) when it does not fit int64, or AValue is a NaN or an infinity
Example: LPages := Ceil(LLines / CLinesPerPage);
See also: Floor. Since: 0.3
routine Ceil(const AValue: float32): int64;
Ceil for a float32 value.
Parameters
AValue: the value
Returns: AValue rounded up
Raises: EXC_INTEGER_OVERFLOW (5) as Ceil
Since: 0.3
Clamp
routine Clamp(const AValue: float64; const AMin: float64; const AMax: float64): float64;
AValue held inside the bounds: below the lower one it is the lower one, above the upper one the upper one. The bounds may come in either order. A NaN stays NaN.
Parameters
AValue: the valueAMin: one boundAMax: the other bound
Returns: AValue inside [AMin, AMax]
Example: LHealth := Clamp(LHealth - LDamage, 0, 100);
See also: Wrap. Since: 0.2
routine Clamp(const AValue: float32; const AMin: float32; const AMax: float32): float32;
Clamp for float32 values.
Parameters
AValue: the valueAMin: one boundAMax: the other bound
Returns: AValue inside [AMin, AMax]
Since: 0.2
routine Clamp(const AValue: int64; const AMin: int64; const AMax: int64): int64;
Clamp for int64 values.
Parameters
AValue: the valueAMin: one boundAMax: the other bound
Returns: AValue inside [AMin, AMax]
Since: 0.2
routine Clamp(const AValue: int32; const AMin: int32; const AMax: int32): int32;
Clamp for int32 values.
Parameters
AValue: the valueAMin: one boundAMax: the other bound
Returns: AValue inside [AMin, AMax]
Since: 0.2
Min
routine Min(const AA: float64; const AB: float64): float64;
The smaller of two values (Delphi's Min): AA when it is less than AB, else AB, so a NaN in either gives AB.
Parameters
AA: one valueAB: the other value
Returns: the smaller of AA and AB
Example: LZoom := Min(LFitX, LFitY);
See also: Max. Since: 0.3
routine Min(const AA: float32; const AB: float32): float32;
Min for float32 values.
Parameters
AA: one valueAB: the other value
Returns: the smaller of AA and AB
Since: 0.3
routine Min(const AA: int64; const AB: int64): int64;
Min for int64 values.
Parameters
AA: one valueAB: the other value
Returns: the smaller of AA and AB
Since: 0.3
routine Min(const AA: int32; const AB: int32): int32;
Min for int32 values.
Parameters
AA: one valueAB: the other value
Returns: the smaller of AA and AB
Since: 0.3
Max
routine Max(const AA: float64; const AB: float64): float64;
The larger of two values (Delphi's Max): AA when it is more than AB, else AB, so a NaN in either gives AB.
Parameters
AA: one valueAB: the other value
Returns: the larger of AA and AB
Example: LWidth := Max(LWidth, 1);
See also: Min. Since: 0.3
routine Max(const AA: float32; const AB: float32): float32;
Max for float32 values.
Parameters
AA: one valueAB: the other value
Returns: the larger of AA and AB
Since: 0.3
routine Max(const AA: int64; const AB: int64): int64;
Max for int64 values.
Parameters
AA: one valueAB: the other value
Returns: the larger of AA and AB
Since: 0.3
routine Max(const AA: int32; const AB: int32): int32;
Max for int32 values.
Parameters
AA: one valueAB: the other value
Returns: the larger of AA and AB
Since: 0.3
Wrap
routine Wrap(const AValue: float64; const AMin: float64; const AMax: float64): float64;
AValue wrapped around the range [AMin, AMax): going past the top comes in again at the bottom, as an angle does (Wrap(370.0, 0.0, 360.0) is 10), however far outside it is. The bounds may come in either order; equal bounds give AMin. A NaN stays NaN.
Parameters
AValue: the valueAMin: the bottom of the range, includedAMax: the top of the range, left out
Returns: AValue inside [AMin, AMax)
Example: LHeading := Wrap(LHeading + LTurn, 0.0, 360.0);
See also: Clamp. Since: 0.2
routine Wrap(const AValue: float32; const AMin: float32; const AMax: float32): float32;
Wrap for float32 values.
Parameters
AValue: the valueAMin: the bottom of the range, includedAMax: the top of the range, left out
Returns: AValue inside [AMin, AMax)
Since: 0.2
routine Wrap(const AValue: int64; const AMin: int64; const AMax: int64): int64;
AValue wrapped around the whole numbers AMin .. AMax, both included: one past the top is the bottom (Wrap(360, 0, 359) is 0), however far outside it is. The bounds may come in either order.
Parameters
AValue: the valueAMin: one end of the range, includedAMax: the other end, included
Returns: AValue inside [AMin, AMax]
Example: LFrame := Wrap(LFrame + 1, 0, LFrameCount - 1);
Since: 0.2
routine Wrap(const AValue: int32; const AMin: int32; const AMax: int32): int32;
Wrap for int32 values (both ends included).
Parameters
AValue: the valueAMin: one end of the range, includedAMax: the other end, included
Returns: AValue inside [AMin, AMax]
Since: 0.2
SameSign
routine SameSign(const AValue1: int64; const AValue2: int64): bool;
True when both values have the same sign: both above 0, both below 0, or both 0 (0 has its own sign, so 0 and 5 differ).
Parameters
AValue1: the first valueAValue2: the second value
Returns: whether their signs match
Since: 0.2
routine SameSign(const AValue1: int32; const AValue2: int32): bool;
SameSign for int32 values.
Parameters
AValue1: the first valueAValue2: the second value
Returns: whether their signs match
Since: 0.2
routine SameSign(const AValue1: float64; const AValue2: float64): bool;
SameSign for float64 values; -0.0 is 0, a NaN matches nothing.
Parameters
AValue1: the first valueAValue2: the second value
Returns: whether their signs match
Since: 0.2
routine SameSign(const AValue1: float32; const AValue2: float32): bool;
SameSign for float32 values.
Parameters
AValue1: the first valueAValue2: the second value
Returns: whether their signs match
Since: 0.2
SameValue
routine SameValue(const A: float64; const B: float64; const AEpsilon: float64): bool;
True when A and B are no more than AEpsilon apart. Equal values (equal infinities too) are the same; a NaN is never the same as anything.
Parameters
A: the first valueB: the second valueAEpsilon: the largest difference still counted as the same
Returns: whether A and B are the same within AEpsilon
Example: if SameValue(LSpeed, 0.0, 0.001) then ... end;
See also: Epsilon64. Since: 0.2
routine SameValue(const A: float64; const B: float64): bool;
SameValue with Epsilon64 as the tolerance, scaled by the larger value's size once it is past 1 (1e15 and 1e15 + 0.5 are the same; 1 and 1.0001 are not).
Parameters
A: the first valueB: the second value
Returns: whether A and B are the same
Since: 0.2
routine SameValue(const A: float32; const B: float32; const AEpsilon: float32): bool;
SameValue for float32 values.
Parameters
A: the first valueB: the second valueAEpsilon: the largest difference still counted as the same
Returns: whether A and B are the same within AEpsilon
Since: 0.2
routine SameValue(const A: float32; const B: float32): bool;
SameValue for float32 values with Epsilon32 as the tolerance, scaled by the larger value's size once it is past 1.
Parameters
A: the first valueB: the second value
Returns: whether A and B are the same
Since: 0.2
Lerp
routine Lerp(const AFrom: float64; const ATo: float64; const AT: float64): float64;
The value AT of the way from AFrom to ATo: 0 gives AFrom, 1 gives exactly ATo, values outside 0 .. 1 go on past them (std::lerp's rule).
Parameters
AFrom: the startATo: the endAT: the fraction of the way
Returns: AFrom + (ATo - AFrom) x AT
Example: LX := Lerp(LStartX, LEndX, LElapsed / LDuration);
See also: EaseBetween. Since: 0.2
routine Lerp(const AFrom: float32; const ATo: float32; const AT: float32): float32;
Lerp for float32 values.
Parameters
AFrom: the startATo: the endAT: the fraction of the way
Returns: AFrom + (ATo - AFrom) x AT
Since: 0.2
AngleDifference
routine AngleDifference(const ASource: float64; const ADest: float64): float64;
The shortest turn, in degrees, from the angle ASource to the angle ADest: -180 (included) to 180 (left out); positive turns the way the angles grow. AngleDifference(350.0, 10.0) is 20.
Parameters
ASource: the angle turned from, in degreesADest: the angle turned to, in degrees
Returns: the turn, in [-180, 180)
Since: 0.2
routine AngleDifference(const ASource: float32; const ADest: float32): float32;
AngleDifference for float32 values.
Parameters
ASource: the angle turned from, in degreesADest: the angle turned to, in degrees
Returns: the turn, in [-180, 180)
Since: 0.2
SmoothMove
routine SmoothMove(const AValue: float64; const AAmount: float64; const AMax: float64; const ADrag: float64): float64;
One step of a speed that is pushed and slows down by itself: a push (AAmount not 0) adds AAmount, up to AMax that way; no push slows the value toward 0 by ADrag, stopping at 0. Called once per update, the drag is per update. AMax and ADrag are taken as their size (their sign is ignored).
Parameters
AValue: the speed nowAAmount: the push this update, 0 for noneAMax: the largest speed either wayADrag: how much the speed falls per update with no push
Returns: the new speed
Example: LSpeed := SmoothMove(LSpeed, LPush, 8.0, 0.5);
Since: 0.2
routine SmoothMove(const AValue: float32; const AAmount: float32; const AMax: float32; const ADrag: float32): float32;
SmoothMove for float32 values.
Parameters
AValue: the speed nowAAmount: the push this update, 0 for noneAMax: the largest speed either wayADrag: how much the speed falls per update with no push
Returns: the new speed
Since: 0.2
Ease
routine Ease(const AKind: Easing; const AFraction: float64): float64;
The easing curve AKind at AFraction of the way: 0 to 1 in, 0 to 1 out. Every curve gives exactly 0 at 0 and exactly 1 at 1; a fraction below 0 (or NaN) is 0, past 1 is 1.
Parameters
AKind: the curveAFraction: how far along, 0 to 1 (elapsed / duration)
Returns: the eased fraction, 0 to 1
Example: LAlpha := Ease(Easing.OutCubic, LElapsed / LDuration);
See also: EaseBetween. Since: 0.2
routine Ease(const AKind: Easing; const AFraction: float32): float32;
Ease for a float32 fraction (computed in float64).
Parameters
AKind: the curveAFraction: how far along, 0 to 1
Returns: the eased fraction, 0 to 1
Since: 0.2
EaseBetween
routine EaseBetween(const AKind: Easing; const AFrom: float64; const ATo: float64; const AFraction: float64): float64;
The value AFraction of the way from AFrom to ATo along the easing curve AKind: exactly AFrom at 0 and exactly ATo at 1, the fraction held to 0 .. 1. Penner's ease(t, b, c, d) is EaseBetween(AKind, b, b + c, t / d).
Parameters
AKind: the curveAFrom: the start valueATo: the end valueAFraction: how far along, 0 to 1 (elapsed / duration)
Returns: the eased value between AFrom and ATo
Example: LY := EaseBetween(Easing.OutQuad, 0.0, 300.0, LElapsed / 2.0);
See also: Ease. Since: 0.2
routine EaseBetween(const AKind: Easing; const AFrom: float32; const ATo: float32; const AFraction: float32): float32;
EaseBetween for float32 values.
Parameters
AKind: the curveAFrom: the start valueATo: the end valueAFraction: how far along, 0 to 1
Returns: the eased value between AFrom and ATo
Since: 0.2
RandomInt
routine RandomInt(const AMin: int32; const AMax: int32): int32;
A whole number from AMin to AMax, both included, from the unit's own generator (seeded from the system at start-up; SetRandomSeed repeats a sequence).
Parameters
AMin: one endAMax: the other end
Returns: the number
Example: LDie := RandomInt(1, 6);
See also: RandomGenerator. Since: 0.2
routine RandomInt(const AMin: int64; const AMax: int64): int64;
RandomInt for int64 bounds.
Parameters
AMin: one endAMax: the other end
Returns: the number
Since: 0.2
RandomFloat
routine RandomFloat(const AMin: float64; const AMax: float64): float64;
A number from AMin (included) to AMax (left out), from the unit's own generator.
Parameters
AMin: the low end, includedAMax: the high end, left out
Returns: the number
Example: LX := RandomFloat(0.0, 640.0);
Since: 0.2
routine RandomFloat(const AMin: float32; const AMax: float32): float32;
RandomFloat for float32 bounds.
Parameters
AMin: the low end, includedAMax: the high end, left out
Returns: the number
Since: 0.2
RandomBool
routine RandomBool(): bool;
True or false, each half the time, from the unit's own generator.
Returns: the value
Since: 0.2
RandomSeed
routine RandomSeed(): uint32;
The seed the unit's own generator started from (the last one set).
Returns: the seed
Since: 0.2
SetRandomSeed
routine SetRandomSeed(const ASeed: uint32);
Starts the unit's own generator on the sequence of ASeed, so the next RandomInt / RandomFloat / RandomBool calls repeat it.
Parameters
ASeed: the seed
Since: 0.2
Randomize
routine Randomize();
Starts the unit's own generator on a fresh sequence, seeded from the system's entropy source. RandomSeed() then returns the new seed, so SetRandomSeed(RandomSeed()) repeats the sequence from here.
Example: Randomize(); LRoll := RandomInt(1, 6);
See also: SetRandomSeed, RandomSeed, RandomGenerator. Since: 0.2
PointInCircle
routine PointInCircle(const APoint: Vector2; const ACenter: Vector2; const ARadius: float32): bool;
True when APoint is in the circle (its edge included).
Parameters
APoint: the pointACenter: the circle's centreARadius: the circle's radius
Returns: whether the circle holds the point
Since: 0.2
PointInTriangle
routine PointInTriangle(const APoint: Vector2; const A: Vector2; const B: Vector2; const C: Vector2): bool;
True when APoint is strictly inside the triangle A B C (either winding; a point on an edge is outside, a flat triangle holds nothing).
Parameters
APoint: the pointA: a cornerB: a cornerC: a corner
Returns: whether the triangle holds the point
Since: 0.2
CirclesOverlap
routine CirclesOverlap(const ACenter1: Vector2; const ARadius1: float32; const ACenter2: Vector2; const ARadius2: float32): bool;
True when two circles overlap or touch.
Parameters
ACenter1: the first circle's centreARadius1: the first circle's radiusACenter2: the second circle's centreARadius2: the second circle's radius
Returns: whether they overlap
Since: 0.2
CircleOverlapsRect
routine CircleOverlapsRect(const ACenter: Vector2; const ARadius: float32; const ARect: Rect): bool;
True when a circle overlaps a rectangle (touching counts): the point of the rectangle nearest the centre is within the radius.
Parameters
ACenter: the circle's centreARadius: the circle's radiusARect: the rectangle
Returns: whether they overlap
Since: 0.2
LineIntersection
routine LineIntersection(const A1: Vector2; const A2: Vector2; const B1: Vector2; const B2: Vector2): LineHit;
Where the segment A1 - A2 meets the segment B1 - B2 (ends included). A segment of no length is a point, which meets the other segment when it lies on it.
Parameters
A1: the first segment's startA2: the first segment's endB1: the second segment's startB2: the second segment's end
Returns: the kind of meeting and, for Point, where
Since: 0.2
RadiusOverlap
routine RadiusOverlap(const ARadius1: float32; const ACenter1: Vector2; const ARadius2: float32; const ACenter2: Vector2; const AShrink: float32): bool;
True when two circles, each radius scaled by AShrink (1 = as given, 0.8 = a fifth smaller, for a forgiving hit), overlap: their centres are closer than the scaled radii's sum.
Parameters
ARadius1: the first radiusACenter1: the first centreARadius2: the second radiusACenter2: the second centreAShrink: the scale both radii take
Returns: whether they overlap
Since: 0.2
ObbsOverlap
routine ObbsOverlap(const A: Obb; const B: Obb): bool;
True when two oriented boxes overlap or touch (the separating axis test over both boxes' sides, angles exact, in float64).
Parameters
A: one boxB: the other box
Returns: whether they overlap
Since: 0.2
ExtentOf
routine ExtentOf(const ARect: Rect): Extent;
The Extent of ARect: its smallest and largest X and Y (a negative size spans the other way).
Parameters
ARect: the rectangle
Returns: its extent
See also: Extent. Since: 0.2
Diagnostics
The Diagnostics unit: import Diagnostics; gives a Stopwatch in the shape of Delphi's System.Diagnostics.TStopwatch: Start, Stop, Reset, Restart, IsRunning, Elapsed in milliseconds and in ticks, the tick Frequency. StartNew() makes one already running (Delphi's TStopwatch.StartNew: an object has no class methods here, so it is a routine of the unit). GetTimeStamp() reads the clock alone. The clock is std::chrono::steady_clock on every target: monotonic, never set back by a change of the system time.
Import it with import Diagnostics;.
Types
Stopwatch
Stopwatch = object
Measures time passed, as Delphi's TStopwatch: Start and Stop add up running spans, Elapsed* reads the total (the span still running included). Built stopped at zero; StartNew() gives one already running. Monotonic (std::chrono::steady_clock): a change of the system time never moves it.
Members
init(): A stopwatch stopped at zero.method Start(): Starts (or goes on) measuring; nothing when it runs already. Example:LWatch.Start();method Stop(): Stops measuring, keeping the total; nothing when it is stopped. Example:LWatch.Stop();method Reset(): Stops measuring and sets the total to zero. Example:LWatch.Reset();method Restart(): Sets the total to zero and starts measuring again (Reset, then Start). Example:LWatch.Restart();const method IsRunning(): bool: True while the stopwatch measures. Returns: true between Start and Stopconst method ElapsedTicks(): int64: The total measured, in ticks of the clock (Frequency per second), the running span included. Returns: the ticks, 0 or moreconst method ElapsedMilliseconds(): int64: The total measured, in whole milliseconds (rounded down), the running span included. Returns: the milliseconds, 0 or more Example:println("{} ms", LWatch.ElapsedMilliseconds());const method Frequency(): int64: The clock's ticks per second, as ElapsedTicks counts them. Returns: the frequency (1000000000 for a nanosecond clock)
Example: LWatch := StartNew(); Work(); println("{} ms", LWatch.ElapsedMilliseconds());
See also: StartNew. Since: 0.3
Routines
GetTimeStamp
routine GetTimeStamp(): int64;
The current value of the clock a Stopwatch runs on (std::chrono::steady_clock), in ticks (Frequency per second). Only the difference of two readings means anything (Delphi's TStopwatch.GetTimeStamp).
Returns: the clock's value in ticks
Example: LT0 := GetTimeStamp(); Work(); LTicks := GetTimeStamp() - LT0;
See also: Stopwatch. Since: 0.3
StartNew
routine StartNew(): Stopwatch;
A stopwatch already running (Delphi's TStopwatch.StartNew).
Returns: the running stopwatch
Example: LWatch := StartNew();
See also: Stopwatch. Since: 0.3
Console
The program's console: import Console; adds text and VT escape sequences on standard output and the keyboard on standard input: WriteLn("{} of {}", 3, 10). Console writes to the program's standard output: formatted Write / WriteLn (as FormatStr), the cursor (0-based positions, moves, save / restore, hide / show), clearing, scrolling, inserting / deleting lines, bold and colours (the 16 standard ones, the 256-colour palette or any 24-bit Rgb), the title and the terminal's size; text padded / aligned by display columns (wide characters count 2), rules, a progress bar and a spinner; it reads a key, waits for one or for Enter, and pauses before a console that closes with the program. Text is always written; escape sequences only on a terminal by default (a file or a pipe gets the text alone; SetEscapeMode changes that). The Csi consts and routines give the sequences to a program that writes them itself. sfml_ext converts between Rgb and sf::Color (sfx::fromSf / sfx::toSf).
Import it with import Console;.
Types
TextColor
TextColor = choices(Black, Red, Green, Yellow, Blue, Magenta, Cyan, White, BrightBlack, BrightRed, BrightGreen, BrightYellow, BrightBlue, BrightMagenta, BrightCyan, BrightWhite);
The 16 standard terminal colours, in their SGR order (int32(TextColor.Red) is 1): foreground 30-37 / 90-97, background 40-47 / 100-107.
See also: TextColorAt. Since: 0.2
EscapeMode
EscapeMode = choices(Auto, On, Off);
When escape sequences are written: Auto while standard output is a terminal (the default), On always, Off never. (Not Always / Never: X11's X.h defines Always.)
See also: SetEscapeMode. Since: 0.2
TextAlign
TextAlign = choices(Left, Center, Right);
Where a text sits inside a padded width.
See also: PadText. Since: 0.2
Rgb
Rgb = object
A 24-bit colour (SGR 38;2 / 48;2): red, green and blue, 0-255 each.
Members
R: uint8: The red component, 0 .. 255G: uint8: The green component, 0 .. 255B: uint8: The blue component, 0 .. 255init(): Black (0, 0, 0).init(const AR: uint8; const AG: uint8; const AB: uint8): The colour (AR, AG, AB). Parameters:ARred, 0-255;AGgreen, 0-255;ABblue, 0-255.
Example: LGold: Rgb(255, 215, 0);
Since: 0.2
Constants
| Name | Declaration | Description |
|---|---|---|
CsiEsc | : string = "\x1b" | The escape character (ESC, 0x1B), the start of every sequence. |
CsiCr | : string = "\r" | A carriage return: the cursor to the start of its line. |
CsiLf | : string = "\n" | A line feed, the line break WriteLn writes. |
CsiCrLf | : string = "\r\n" | A carriage return and a line feed. |
CsiSaveCursorPosition | : string = "\x1b[s" | Saves the cursor's position (CSI s). See CsiRestoreCursorPosition. |
CsiRestoreCursorPosition | : string = "\x1b[u" | Puts the cursor back where CsiSaveCursorPosition saved it (CSI u). |
CsiShowCursor | : string = "\x1b[?25h" | Shows the cursor. |
CsiHideCursor | : string = "\x1b[?25l" | Hides the cursor. |
CsiBlinkCursor | : string = "\x1b[?12h" | A blinking cursor. |
CsiSteadyCursor | : string = "\x1b[?12l" | A steady (not blinking) cursor. |
CsiClearScreen | : string = "\x1b[2J" | Clears the visible screen (the cursor stays). |
CsiClearScrollback | : string = "\x1b[3J" | Clears the scrollback above the screen. |
CsiClearLine | : string = "\x1b[2K" | Clears the cursor's line (the cursor stays). |
CsiClearToEndOfLine | : string = "\x1b[0K" | Clears from the cursor to the end of its line. |
CsiBold | : string = "\x1b[1m" | Bold text. |
CsiDim | : string = "\x1b[2m" | Dim text. |
CsiItalic | : string = "\x1b[3m" | Italic text. |
CsiUnderline | : string = "\x1b[4m" | Underlined text. |
CsiBlink | : string = "\x1b[5m" | Blinking text. |
CsiInvertColors | : string = "\x1b[7m" | Foreground and background swapped. See CsiNormalColors. |
CsiStrike | : string = "\x1b[9m" | Struck-through text. |
CsiNormalColors | : string = "\x1b[27m" | Ends CsiInvertColors. |
CsiFramed | : string = "\x1b[51m" | Framed text. |
CsiEncircled | : string = "\x1b[52m" | Encircled text. |
CsiResetFormat | : string = "\x1b[0m" | Resets bold, the colours and every other attribute. |
CsiResetForeground | : string = "\x1b[39m" | The default foreground colour. |
CsiResetBackground | : string = "\x1b[49m" | The default background colour. |
CsiFgBlack | : string = "\x1b[30m" | Black foreground (SGR 30). |
CsiFgRed | : string = "\x1b[31m" | Red foreground (SGR 31). |
CsiFgGreen | : string = "\x1b[32m" | Green foreground (SGR 32). |
CsiFgYellow | : string = "\x1b[33m" | Yellow foreground (SGR 33). |
CsiFgBlue | : string = "\x1b[34m" | Blue foreground (SGR 34). |
CsiFgMagenta | : string = "\x1b[35m" | Magenta foreground (SGR 35). |
CsiFgCyan | : string = "\x1b[36m" | Cyan foreground (SGR 36). |
CsiFgWhite | : string = "\x1b[37m" | White foreground (SGR 37). |
CsiBgBlack | : string = "\x1b[40m" | Black background (SGR 40). |
CsiBgRed | : string = "\x1b[41m" | Red background (SGR 41). |
CsiBgGreen | : string = "\x1b[42m" | Green background (SGR 42). |
CsiBgYellow | : string = "\x1b[43m" | Yellow background (SGR 43). |
CsiBgBlue | : string = "\x1b[44m" | Blue background (SGR 44). |
CsiBgMagenta | : string = "\x1b[45m" | Magenta background (SGR 45). |
CsiBgCyan | : string = "\x1b[46m" | Cyan background (SGR 46). |
CsiBgWhite | : string = "\x1b[47m" | White background (SGR 47). |
CsiFgBrightBlack | : string = "\x1b[90m" | Bright black (grey) foreground (SGR 90). |
CsiFgBrightRed | : string = "\x1b[91m" | Bright red foreground (SGR 91). |
CsiFgBrightGreen | : string = "\x1b[92m" | Bright green foreground (SGR 92). |
CsiFgBrightYellow | : string = "\x1b[93m" | Bright yellow foreground (SGR 93). |
CsiFgBrightBlue | : string = "\x1b[94m" | Bright blue foreground (SGR 94). |
CsiFgBrightMagenta | : string = "\x1b[95m" | Bright magenta foreground (SGR 95). |
CsiFgBrightCyan | : string = "\x1b[96m" | Bright cyan foreground (SGR 96). |
CsiFgBrightWhite | : string = "\x1b[97m" | Bright white foreground (SGR 97). |
CsiBgBrightBlack | : string = "\x1b[100m" | Bright black (grey) background (SGR 100). |
CsiBgBrightRed | : string = "\x1b[101m" | Bright red background (SGR 101). |
CsiBgBrightGreen | : string = "\x1b[102m" | Bright green background (SGR 102). |
CsiBgBrightYellow | : string = "\x1b[103m" | Bright yellow background (SGR 103). |
CsiBgBrightBlue | : string = "\x1b[104m" | Bright blue background (SGR 104). |
CsiBgBrightMagenta | : string = "\x1b[105m" | Bright magenta background (SGR 105). |
CsiBgBrightCyan | : string = "\x1b[106m" | Bright cyan background (SGR 106). |
CsiBgBrightWhite | : string = "\x1b[107m" | Bright white background (SGR 107). |
CsiBgDarkGrey | : string = "\x1b[48;5;238m" | A dark grey background: 256-colour palette entry 238. |
KeyEnter | : string = "\r" | What ReadKey gives for Enter, on every target. See IsEnterKey. |
KeyEscape | : string = "\x1b" | What ReadKey gives for Escape, on every target. See IsEscapeKey. |
KeyBackspace | : string = "\x08" | What ReadKey gives for Backspace, on every target. |
Routines
CsiCursorPosition
routine CsiCursorPosition(const AX: int32; const AY: int32): string;
The sequence that puts the cursor at column AX, line AY (0-based, (0, 0) the top left; a position below 0 counts as 0).
Parameters
AX: the columnAY: the line
Returns: the sequence (CSI is 1-based, row first: (4, 2) is ESC[3;5H)
Since: 0.2
CsiCursorColumn
routine CsiCursorColumn(const AX: int32): string;
The sequence that puts the cursor at column AX of its line (0-based; below 0 counts as 0).
Parameters
AX: the column
Returns: the sequence
Since: 0.2
CsiCursorUp
routine CsiCursorUp(const ALines: int32): string;
The sequence that moves the cursor up ALines lines.
Parameters
ALines: how far; <= 0 gives ""
Returns: the sequence
Since: 0.2
CsiCursorDown
routine CsiCursorDown(const ALines: int32): string;
The sequence that moves the cursor down ALines lines.
Parameters
ALines: how far; <= 0 gives ""
Returns: the sequence
Since: 0.2
CsiCursorForward
routine CsiCursorForward(const AColumns: int32): string;
The sequence that moves the cursor right AColumns columns.
Parameters
AColumns: how far; <= 0 gives ""
Returns: the sequence
Since: 0.2
CsiCursorBack
routine CsiCursorBack(const AColumns: int32): string;
The sequence that moves the cursor left AColumns columns.
Parameters
AColumns: how far; <= 0 gives ""
Returns: the sequence
Since: 0.2
CsiScrollUp
routine CsiScrollUp(const ALines: int32): string;
The sequence that scrolls the screen up ALines lines.
Parameters
ALines: how far; <= 0 gives ""
Returns: the sequence
Since: 0.2
CsiScrollDown
routine CsiScrollDown(const ALines: int32): string;
The sequence that scrolls the screen down ALines lines.
Parameters
ALines: how far; <= 0 gives ""
Returns: the sequence
Since: 0.2
CsiInsertLines
routine CsiInsertLines(const ALines: int32): string;
The sequence that inserts ALines blank lines at the cursor.
Parameters
ALines: how many; <= 0 gives ""
Returns: the sequence
Since: 0.2
CsiDeleteLines
routine CsiDeleteLines(const ALines: int32): string;
The sequence that deletes ALines lines at the cursor.
Parameters
ALines: how many; <= 0 gives ""
Returns: the sequence
Since: 0.2
CsiInsertChars
routine CsiInsertChars(const ACount: int32): string;
The sequence that inserts ACount blanks at the cursor.
Parameters
ACount: how many; <= 0 gives ""
Returns: the sequence
Since: 0.2
CsiDeleteChars
routine CsiDeleteChars(const ACount: int32): string;
The sequence that deletes ACount characters at the cursor.
Parameters
ACount: how many; <= 0 gives ""
Returns: the sequence
Since: 0.2
CsiEraseChars
routine CsiEraseChars(const ACount: int32): string;
The sequence that blanks ACount characters at the cursor.
Parameters
ACount: how many; <= 0 gives ""
Returns: the sequence
Since: 0.2
CsiForeground256
routine CsiForeground256(const AIndex: int32): string;
The foreground sequence of a 256-colour palette entry.
Parameters
AIndex: the entry, 0-255; another value gives ""
Returns: the sequence (ESC[38;5;<index>m)
Since: 0.2
CsiBackground256
routine CsiBackground256(const AIndex: int32): string;
The background sequence of a 256-colour palette entry.
Parameters
AIndex: the entry, 0-255; another value gives ""
Returns: the sequence (ESC[48;5;<index>m)
Since: 0.2
CsiForeground
routine CsiForeground(const AColor: TextColor): string;
The foreground sequence of a standard colour.
Parameters
AColor: the colour; a value outside TextColor gives ""
Returns: the sequence (SGR 30-37 / 90-97)
Since: 0.2
CsiBackground
routine CsiBackground(const AColor: TextColor): string;
The background sequence of a standard colour.
Parameters
AColor: the colour; a value outside TextColor gives ""
Returns: the sequence (SGR 40-47 / 100-107)
Since: 0.2
routine CsiForeground(const AColor: Rgb): string;
The foreground sequence of a 24-bit colour.
Parameters
AColor: the colour
Returns: the sequence (ESC[38;2;<r>;<g>;<b>m)
Since: 0.2
routine CsiBackground(const AColor: Rgb): string;
The background sequence of a 24-bit colour.
Parameters
AColor: the colour
Returns: the sequence (ESC[48;2;<r>;<g>;<b>m)
Since: 0.2
CsiTitle
routine CsiTitle(const ATitle: string): string;
The sequence that sets the window title (OSC 0, ended by BEL); C0 control characters and DEL in the title are left out, UTF-8 text stays.
Parameters
ATitle: the title
Returns: the sequence
See also: SetTitle. Since: 0.2
SetEscapeMode
routine SetEscapeMode(const AMode: EscapeMode);
Sets when escape sequences are written (Auto by default).
Parameters
AMode: the new mode
See also: EscapesEnabled. Since: 0.2
GetEscapeMode
routine GetEscapeMode(): EscapeMode;
The escape mode now.
Returns: the mode SetEscapeMode set last (Auto at start)
Since: 0.2
IsTerminal
routine IsTerminal(): bool;
Whether standard output is a terminal (a console on Windows), decided once.
Returns: true for a terminal, false for a file or a pipe
Since: 0.2
EscapesEnabled
routine EscapesEnabled(): bool;
Whether the escape mode writes escape sequences now: On yes, Off no, Auto while standard output is a terminal.
Returns: true when WriteEscape writes
Since: 0.2
WriteText
routine WriteText(const AText: string);
Writes text to standard output, always (the bytes as given). A terminal gets them at once.
Parameters
AText: the text
See also: WriteEscape. Since: 0.2
WriteEscape
routine WriteEscape(const ASequence: string);
Writes an escape sequence to standard output while EscapesEnabled, else nothing.
Parameters
ASequence: the sequence
See also: WriteText. Since: 0.2
SetCursorPosition
routine SetCursorPosition(const AX: int32; const AY: int32);
Puts the cursor at column AX, line AY (0-based; below 0 counts as 0).
Parameters
AX: the columnAY: the line
Since: 0.2
SetCursorColumn
routine SetCursorColumn(const AX: int32);
Puts the cursor at column AX of its line (0-based).
Parameters
AX: the column
Since: 0.2
MoveCursorUp
routine MoveCursorUp();
Moves the cursor up one line.
Since: 0.2
routine MoveCursorUp(const ALines: int32);
Moves the cursor up ALines lines (<= 0: not at all).
Parameters
ALines: how far
Since: 0.2
MoveCursorDown
routine MoveCursorDown();
Moves the cursor down one line.
Since: 0.2
routine MoveCursorDown(const ALines: int32);
Moves the cursor down ALines lines (<= 0: not at all).
Parameters
ALines: how far
Since: 0.2
MoveCursorForward
routine MoveCursorForward();
Moves the cursor right one column.
Since: 0.2
routine MoveCursorForward(const AColumns: int32);
Moves the cursor right AColumns columns (<= 0: not at all).
Parameters
AColumns: how far
Since: 0.2
MoveCursorBack
routine MoveCursorBack();
Moves the cursor left one column.
Since: 0.2
routine MoveCursorBack(const AColumns: int32);
Moves the cursor left AColumns columns (<= 0: not at all).
Parameters
AColumns: how far
Since: 0.2
SaveCursorPosition
routine SaveCursorPosition();
Saves the cursor's position.
See also: RestoreCursorPosition. Since: 0.2
RestoreCursorPosition
routine RestoreCursorPosition();
Puts the cursor back where SaveCursorPosition saved it.
Since: 0.2
HideCursor
routine HideCursor();
Hides the cursor.
Since: 0.2
ShowCursor
routine ShowCursor();
Shows the cursor.
Since: 0.2
ClearScreen
routine ClearScreen();
Clears the screen and its scrollback and puts the cursor at the top left.
Since: 0.2
ClearLine
routine ClearLine();
Clears the cursor's line; the cursor stays where it is.
Since: 0.2
routine ClearLine(const AToLineStart: bool);
Clears the cursor's line; AToLineStart also puts the cursor at its start (a carriage return, a cursor move: a file or a pipe does not get it).
Parameters
AToLineStart: true to move the cursor to the line's start
Since: 0.2
ClearToEndOfLine
routine ClearToEndOfLine();
Clears from the cursor to the end of its line.
Since: 0.2
InsertLines
routine InsertLines();
Inserts one blank line at the cursor.
Since: 0.2
routine InsertLines(const ALines: int32);
Inserts ALines blank lines at the cursor (<= 0: none).
Parameters
ALines: how many
Since: 0.2
DeleteLines
routine DeleteLines();
Deletes the cursor's line.
Since: 0.2
routine DeleteLines(const ALines: int32);
Deletes ALines lines at the cursor (<= 0: none).
Parameters
ALines: how many
Since: 0.2
ScrollUp
routine ScrollUp();
Scrolls the screen up one line.
Since: 0.2
routine ScrollUp(const ALines: int32);
Scrolls the screen up ALines lines (<= 0: not at all).
Parameters
ALines: how far
Since: 0.2
ScrollDown
routine ScrollDown();
Scrolls the screen down one line.
Since: 0.2
routine ScrollDown(const ALines: int32);
Scrolls the screen down ALines lines (<= 0: not at all).
Parameters
ALines: how far
Since: 0.2
InsertChars
routine InsertChars();
Inserts one blank at the cursor.
Since: 0.2
routine InsertChars(const ACount: int32);
Inserts ACount blanks at the cursor (<= 0: none).
Parameters
ACount: how many
Since: 0.2
DeleteChars
routine DeleteChars();
Deletes the character at the cursor.
Since: 0.2
routine DeleteChars(const ACount: int32);
Deletes ACount characters at the cursor (<= 0: none).
Parameters
ACount: how many
Since: 0.2
EraseChars
routine EraseChars();
Blanks the character at the cursor.
Since: 0.2
routine EraseChars(const ACount: int32);
Blanks ACount characters at the cursor (<= 0: none).
Parameters
ACount: how many
Since: 0.2
SetBold
routine SetBold();
Bold text from here (until ResetFormat or the next Write's reset).
Since: 0.2
ResetFormat
routine ResetFormat();
Resets bold, the colours and every other attribute.
Since: 0.2
SetForegroundColor
routine SetForegroundColor(const AColor: TextColor);
The text colour from here, a standard colour.
Parameters
AColor: the colour
Since: 0.2
routine SetForegroundColor(const AColor: Rgb);
The text colour from here, a 24-bit colour.
Parameters
AColor: the colour
Since: 0.2
SetBackgroundColor
routine SetBackgroundColor(const AColor: TextColor);
The background colour from here, a standard colour.
Parameters
AColor: the colour
Since: 0.2
routine SetBackgroundColor(const AColor: Rgb);
The background colour from here, a 24-bit colour.
Parameters
AColor: the colour
Since: 0.2
TextColorAt
routine TextColorAt(const AIndex: int32): TextColor;
The standard colour with the number AIndex, held to 0-15 (below 0 is Black, past 15 BrightWhite): a loop's counter picks colours in turn.
Parameters
AIndex: the colour's number (TextColor's order)
Returns: the colour
Example: SetForegroundColor(TextColorAt(LIndex mod 16));
Since: 0.2
GetTerminalWidth
routine GetTerminalWidth(): int32;
The terminal's visible width in columns; 80 when standard output is not a terminal.
Returns: the width
Since: 0.2
GetTerminalHeight
routine GetTerminalHeight(): int32;
The terminal's visible height in lines; 25 when standard output is not a terminal.
Returns: the height
Since: 0.2
DisplayWidth
routine DisplayWidth(const AText: string): int64;
The columns a text takes in a terminal: UTF-8 code points count 1, East Asian wide / fullwidth characters and emoji 2, combining marks, zero-width characters and control characters 0; a byte that is not UTF-8 counts 1.
Parameters
AText: UTF-8 text
Returns: the columns
Example: DisplayWidth("日本語") is 6
Since: 0.2
PadText
routine PadText(const AText: string; const AWidth: int32): string;
The text padded with spaces after it to AWidth columns; a text at least that wide is returned as it is.
Parameters
AText: the textAWidth: the columns to fill
Returns: the padded text
Since: 0.2
routine PadText(const AText: string; const AWidth: int32; const APad: string): string;
The text padded with APad after it to AWidth columns; see PadText(AText, AWidth, APad, AAlign).
Parameters
AText: the textAWidth: the columns to fillAPad: the pad character
Returns: the padded text
Since: 0.2
routine PadText(const AText: string; const AWidth: int32; const APad: string; const AAlign: TextAlign): string;
The text padded with APad to AWidth columns, placed by AAlign (Center: the odd column on the right). APad is one character; a wide one fills two columns, a column left over is a space; an empty pad is a space. A text at least AWidth wide is returned as it is.
Parameters
AText: the textAWidth: the columns to fillAPad: the pad characterAAlign: where the text sits
Returns: the padded text
Example: PadText("ab", 7, ".", TextAlign.Center) is "..ab..."
Since: 0.2
RuleText
routine RuleText(const AChar: string; const AWidth: int32): string;
AWidth columns of AChar, filled as PadText fills.
Parameters
AChar: the characterAWidth: the columns; <= 0 gives ""
Returns: the rule
Since: 0.2
ProgressBarText
routine ProgressBarText(const ACurrent: int64; const ATotal: int64; const AWidth: int32): string;
A progress bar, "[==== ] 50%": ACurrent of ATotal, held to 0..ATotal, floored (full and 100% only at the end); ATotal <= 0 counts as nothing done.
Parameters
ACurrent: the work doneATotal: all the workAWidth: the bar's columns between the brackets (below 0 counts as 0)
Returns: the bar text
Since: 0.2
SpinnerFrame
routine SpinnerFrame(const AFrame: int32): string;
The spinner's character for a frame: | / - \ in turn, any frame (negative ones too).
Parameters
AFrame: the frame number
Returns: the character
Since: 0.2
HorizontalRule
routine HorizontalRule();
A line of "-" as wide as the terminal, then a line break.
Since: 0.2
routine HorizontalRule(const AChar: string);
A line of AChar as wide as the terminal, then a line break.
Parameters
AChar: the character
Since: 0.2
routine HorizontalRule(const AChar: string; const AWidth: int32);
A line of AChar AWidth columns wide (<= 0: the terminal's width), then a line break.
Parameters
AChar: the characterAWidth: the columns
Since: 0.2
WritePadded
routine WritePadded(const AText: string; const AWidth: int32);
Writes PadText(AText, AWidth).
Parameters
AText: the textAWidth: the columns to fill
Since: 0.2
routine WritePadded(const AText: string; const AWidth: int32; const APad: string);
Writes PadText(AText, AWidth, APad).
Parameters
AText: the textAWidth: the columns to fillAPad: the pad character
Since: 0.2
routine WritePadded(const AText: string; const AWidth: int32; const APad: string; const AAlign: TextAlign);
Writes PadText(AText, AWidth, APad, AAlign).
Parameters
AText: the textAWidth: the columns to fillAPad: the pad characterAAlign: where the text sits
Since: 0.2
ProgressBar
routine ProgressBar(const ACurrent: int64; const ATotal: int64);
A carriage return, then ProgressBarText 40 columns wide in green: called again, it redraws the line.
Parameters
ACurrent: the work doneATotal: all the work
Since: 0.2
routine ProgressBar(const ACurrent: int64; const ATotal: int64; const AWidth: int32);
A carriage return, then ProgressBarText AWidth columns wide in green.
Parameters
ACurrent: the work doneATotal: all the workAWidth: the bar's columns
Since: 0.2
routine ProgressBar(const ACurrent: int64; const ATotal: int64; const AWidth: int32; const AColor: TextColor);
A carriage return, then ProgressBarText in a standard colour.
Parameters
ACurrent: the work doneATotal: all the workAWidth: the bar's columnsAColor: the bar's colour
Since: 0.2
routine ProgressBar(const ACurrent: int64; const ATotal: int64; const AWidth: int32; const AColor: Rgb);
A carriage return, then ProgressBarText in a 24-bit colour.
Parameters
ACurrent: the work doneATotal: all the workAWidth: the bar's columnsAColor: the bar's colour
Since: 0.2
WaitForAnyKey
routine WaitForAnyKey();
Waits for a key press on the console's keyboard (a modifier key alone does not count); returns at once when standard input is not a console / terminal.
Since: 0.2
AnyKeyPressed
routine AnyKeyPressed(): bool;
Whether a key press waits to be read (it is left there); other input events in front of it are taken off the queue.
Returns: true when a key waits
Since: 0.2
Pause
routine Pause(const AForce: bool; const AColor: TextColor; const AMessage: string);
Writes the message in the colour on a new line and waits for a key. Without AForce it pauses only when the program's console closes with it: on Windows a console no other process shares (the program was started from Explorer), never on Linux (a terminal outlives the program). Keys typed before are dropped first; no keyboard = no pause.
Parameters
AForce: true to pause alwaysAColor: the message's colourAMessage: the message; "" gives "Press any key to continue... "
Since: 0.2
routine Pause();
Pause(false, TextColor.White, "Press any key to continue... ").
Since: 0.2
routine Pause(const AForce: bool);
Pause(AForce, TextColor.White, "Press any key to continue... ").
Parameters
AForce: true to pause always
Since: 0.2
routine Pause(const AForce: bool; const AColor: TextColor);
Pause(AForce, AColor, "Press any key to continue... ").
Parameters
AForce: true to pause alwaysAColor: the message's colour
Since: 0.2
SetTitle
routine SetTitle(const ATitle: string);
Sets the console window's title: on Windows through the console API, on Linux as CsiTitle (written while EscapesEnabled).
Parameters
ATitle: the title (UTF-8)
Since: 0.2
ReadKey
routine ReadKey(): string;
Waits for a key that types a character and returns it as UTF-8 text, the same on both targets: Enter KeyEnter, Backspace KeyBackspace, Escape KeyEscape; keys that type nothing (an arrow, a modifier alone) are skipped.
Returns: the key's text; "" when standard input is not a console / terminal
See also: IsEnterKey. Since: 0.2
IsEnterKey
routine IsEnterKey(const AKey: string): bool;
Whether a ReadKey result is Enter.
Parameters
AKey: a ReadKey result
Returns: true for Enter
Example: if IsEnterKey(ReadKey()) then ... end;
Since: 0.2
IsEscapeKey
routine IsEscapeKey(const AKey: string): bool;
Whether a ReadKey result is Escape.
Parameters
AKey: a ReadKey result
Returns: true for Escape
Since: 0.2
WaitForKey
routine WaitForKey(const AKey: string);
Waits until ReadKey gives AKey; returns at once with no keyboard (ReadKey gives "").
Parameters
AKey: the key's text (KeyEnter, KeyEscape, "q" ...)
Since: 0.2
routine WaitForKey();
Waits until ReadKey gives Enter; returns at once with no keyboard.
Since: 0.2
WaitForEnter
routine WaitForEnter(const AMessage: string; const AQuitWord: string): bool;
Writes the message on a new line, reads a line from standard input and tells whether it equals AQuitWord, ASCII letters compared without case.
Parameters
AMessage: the message; "" gives "Press ENTER to continue..."AQuitWord: the word that answers true; "" never does
Returns: true when the line is AQuitWord
Example: if WaitForEnter("Again? (q quits) ", "q") then ... end;
Since: 0.2
routine WaitForEnter(): bool;
WaitForEnter("Press ENTER to continue...", "").
Returns: false
Since: 0.2
routine WaitForEnter(const AMessage: string): bool;
WaitForEnter(AMessage, "").
Parameters
AMessage: the message; "" gives "Press ENTER to continue..."
Returns: false
Since: 0.2
ResData
The ResData unit: import ResData; reads the data a build added with @addresdata "key" "path"; back by its key, on every target. Each exe and dll reads its own binary's data: the entries of every module it was built from and of every PaskalCPP lib it links. A name is read bare when no other imported unit exports it (FindResData), or qualified (ResData.FindResData).
Import it with import ResData;.
Types
ResDataEntry
ResDataEntry = record
The bytes one key holds: Data points at them and Size counts them. One zero byte follows them, not counted, so text added as a file reads as a C string. Data is nil (and Size 0) when the binary holds no such key. The bytes live as long as the program: never free them.
Members
Data: ptr to const uint8: The first byte; nil when the binary holds no such keySize: int64: How many bytes (the zero byte after them not counted)
Since: 0.2
Routines
FindResData
routine FindResData(const AKey: string): ResDataEntry;
The entry a key names, in the binary that calls (each exe and dll reads its own). Keys compare exactly, case included; the key may be built at run time.
Parameters
AKey: the key an@addresdatadirective of the build added
Returns: the entry, its Data nil when the binary holds no such key
Example: LFont := FindResData("fonts/main.ttf");
See also: HasResData. Since: 0.2
routine FindResData(const AKey: ptr to const char): ResDataEntry;
FindResData for a C string; nil names no key (an entry with Data nil).
Parameters
AKey: the key, a NUL-terminated UTF-8 text
Returns: the entry, its Data nil when the binary holds no such key
See also: HasResData. Since: 0.2
HasResData
routine HasResData(const AKey: string): bool;
Whether the binary that calls holds a key.
Parameters
AKey: the key an@addresdatadirective of the build added
Returns: true when FindResData gives the key's bytes
Example: if HasResData("fonts/main.ttf") then ... end;
See also: FindResData. Since: 0.2
routine HasResData(const AKey: ptr to const char): bool;
HasResData for a C string; nil names no key (false).
Parameters
AKey: the key, a NUL-terminated UTF-8 text
Returns: true when FindResData gives the key's bytes
See also: FindResData. Since: 0.2
ResDataCount
routine ResDataCount(): int64;
How many keys the binary that calls holds, the compiler's own (pcpp/exeicon) included.
Returns: the number of entries, 0 when the build added none
See also: ResDataKey. Since: 0.2
ResDataKey
routine ResDataKey(const AIndex: int64): string;
A key of the binary that calls, by its place in key order: byte-wise over the UTF-8 key, the same on every target, so ResDataKey(0) .. ResDataKey(ResDataCount() - 1) lists every key once.
Parameters
AIndex: the place, 0 .. ResDataCount() - 1
Returns: the key; '' outside 0 .. ResDataCount() - 1
Example: for LIndex := 0 to ResDataCount() - 1 do println("{}", ResDataKey(LIndex)); end;
See also: ResDataCount. Since: 0.2
CustomIO
The CustomIO unit: import CustomIO; gives streams in the style of SDL3's custom IO. An IO is a stream behind a table of callbacks (an IOInterface: Read, Write, Seek, Tell, Size, Flush, Close, Truncate), so a routine that takes an IO reads from memory, a file, a zip entry or anything a program writes itself: CreateIO(AInterface, AUserData) makes an IO from any interface. The IO routines (IORead, IOWrite, IOSeek, IOTell, IOSize, IOFlush, IOTruncate, IOClose, IOStatus) call through the table and keep the stream's state: a callback left nil is a clean failure, never a crash. IOReadFull / IOWriteFull move a count through any short reads or writes a stream gives; IOReadAll reads a stream to its end into a string; IOSameContent compares two streams to their ends. CreateMemoryIO makes an IO over the caller's memory (read-only, or read / write within its size) or over a buffer of its own that grows as it is written. CreateFileIO makes an IO over a file, opened in one of C's fopen modes (FileMode), its name UTF-8 on both targets. Beside the stream, an IOSource opens IOs by path (SDL3's SDL_Storage split): an IOSourceInterface (Open, Exists, Size, Close, Remove) behind CreateIOSource, used through IOSourceOpen, IOSourceExists, IOSourceSize, IOSourceRemove and IOSourceClose, which check and normalize every path once (relative, / separated, no climbing above the root) before a callback sees it. CreateFolderIOSource makes a source over a folder (Remove deletes the entry's file); CreateZipIOSource a read-only source over a zip archive, which it reads through an IO (a file, memory, an entry of another source), ZIP64 included, its entries (stored, deflated, ZipCrypto) read-only IOs that seek without starting over. CreateZipFileIO opens one entry of an archive directly. ZipDirectoryContents is the write side: every file under a folder into a new archive (deflated, optionally ZipCrypto encrypted, entry names below a root of the caller's choice, a ZipProgress routine per entry), the archive that CreateZipIOSource / CreateZipFileIO read back; ZipLastError says why one failed.
Import it with import CustomIO;.
Types
IOState
IOState = choices(Ready, Error, Eof, NotReady, ReadOnly, WriteOnly);
The state of an IO after its last operation, read with IOStatus. A short count from IORead / IOWrite says why here: Eof (no more to read), Error, ReadOnly (the IO cannot write), WriteOnly (it cannot read), NotReady (a non-blocking source has nothing yet).
See also: IOStatus. Since: 0.2
SeekOrigin
SeekOrigin = choices(FromStart, FromCurrent, FromEnd);
Where IOSeek counts its offset from.
See also: IOSeek. Since: 0.2
FileMode
FileMode = choices(Read, Write, ReadWrite, Append);
How CreateFileIO opens its file, by C's fopen rules: Read ("rb") the file must exist, read-only; Write ("wb") created or emptied, write-only; ReadWrite ("r+b") the file must exist, kept, read and write; Append ("ab") created when missing, write-only, every write lands at the end whatever the position.
See also: CreateFileIO. Since: 0.2
IOInterface
IOInterface = record
The table of callbacks behind an IO (SDL3's SDL_IOStreamInterface). Every callback takes the user pointer given to CreateIO. Fill the routines the stream supports and leave the rest nil: the IO routines turn a nil callback into a failure with the state set.
Members
Read: routine(const AUserData: ptr; const ABuffer: ptr; const ASize: int64; var AState: IOState): int64: Reads up to ASize bytes into ABuffer; returns the count read. A short count sets AState (Eof, Error, NotReady); AState comes in as Ready.Write: routine(const AUserData: ptr; const ABuffer: ptr; const ASize: int64; var AState: IOState): int64: Writes up to ASize bytes from ABuffer; returns the count written. A short count sets AState (Error, NotReady); AState comes in as Ready.Seek: routine(const AUserData: ptr; const AOffset: int64; const AOrigin: SeekOrigin): int64: Moves to AOffset from AOrigin; returns the new position, or -1.Tell: routine(const AUserData: ptr): int64: The current position, or -1.Size: routine(const AUserData: ptr): int64: The stream's size in bytes, or -1 when it has none.Flush: routine(const AUserData: ptr; var AState: IOState): bool: Writes out anything buffered; false on failure (AState says why).Close: routine(const AUserData: ptr): bool: Releases the stream's own resources; false when that failed.Truncate: routine(const AUserData: ptr; const ASize: int64; var AState: IOState): bool: Sets the stream's size to ASize bytes (ASize >= 0): shorter drops the tail, longer adds zero bytes; the position is the stream's own rule. False on failure (AState says why; it comes in as Ready). Optional: a stream that cannot change its size leaves it nil.
Example: LI.Read := MyRead; LI.Write := nil; LIO := CreateIO(LI, LData);
See also: CreateIO. Since: 0.2
IOStream
IOStream = record
What an IO points at: the callbacks, their user pointer and the state. Reach it only through the IO routines.
Members
Callbacks: IOInterface: The callbacks CreateIO was givenUserData: ptr: The user pointer every callback receivesState: IOState: The state after the last operation
See also: IO. Since: 0.2
IO
IO = ptr to IOStream;
A stream: made by CreateIO or a CreateIO routine, used through the IO routines, ended with IOClose. nil is no stream (a Create that failed).
Example: LIO := CreateMemoryIO(); IOWrite(LIO, LData, 4); IOClose(LIO);
See also: CreateIO, IOClose. Since: 0.2
IOSourceInterface
IOSourceInterface = record
The table of callbacks behind an IOSource (SDL3's SDL_StorageInterface, read side): a source opens IOs by path, so a format with several files (a glTF and its .bin, an .obj and its .mtl) opens its siblings through the source it came from. Every callback takes the user pointer given to CreateIOSource and an entry path already in canonical form (relative, / separated, no . or ..): the IOSource routines check and normalize a path before any callback sees it. Leave a callback nil when the source has no such operation.
Members
Open: routine(const AUserData: ptr; const APath: string; const AMode: FileMode): IO: Opens the entry in AMode; returns its IO, or nil (missing, or a mode the source does not offer).Exists: routine(const AUserData: ptr; const APath: string): bool: True when the entry exists and can be opened (a folder is not one).Size: routine(const AUserData: ptr; const APath: string): int64: The entry's size in bytes, or -1 when it does not exist.Close: routine(const AUserData: ptr): bool: Releases the source's own resources; false when that failed. IOs already opened stay valid until their own IOClose.Remove: routine(const AUserData: ptr; const APath: string): bool: Optional: deletes the entry; false when it does not exist or the source refuses (nil: the source deletes nothing, as a read-only one).
Example: LI.Open := MyOpen; LI.Exists := MyExists; LSrc := CreateIOSource(LI, LData);
See also: CreateIOSource. Since: 0.2
IOSourceRecord
IOSourceRecord = record
What an IOSource points at: the callbacks and their user pointer. Reach it only through the IOSource routines.
Members
Callbacks: IOSourceInterface: The callbacks CreateIOSource was givenUserData: ptr: The user pointer every callback receives
See also: IOSource. Since: 0.2
IOSource
IOSource = ptr to IOSourceRecord;
A source of IOs by path: made by CreateIOSource or a CreateIOSource routine, used through the IOSource routines, ended with IOSourceClose. nil is no source (a Create that failed).
Example: LSrc := CreateFolderIOSource("$P:assets"); LIO := IOSourceOpen(LSrc, "models/ship.bin");
See also: CreateIOSource, IOSourceClose. Since: 0.2
ZipProgress
ZipProgress = routine(const AUserData: ptr; const AEntry: string; const APercent: int32; const ANewFile: bool);
Called by ZipDirectoryContents for each entry it writes: once with APercent 0 and ANewFile true before the entry's first byte, then with the percent of its bytes written and ANewFile false (100 last; an empty file gets 0 then 100).
Parameters
AUserData: the pointer given to ZipDirectoryContentsAEntry: the entry's name in the archive (UTF-8,/separated)APercent: 0 to 100ANewFile: true on the entry's first call
Example: routine Show(const AUserData: ptr; const AEntry: string; const APercent: int32; const ANewFile: bool); begin if ANewFile then println("{}", AEntry); end; end;
See also: ZipDirectoryContents. Since: 0.3
Routines
CreateIO
routine CreateIO(const AInterface: IOInterface; const AUserData: ptr): IO;
Makes an IO from a table of callbacks and the user pointer they receive (SDL3's SDL_OpenIO). The interface is copied; the user pointer is the caller's and is never freed by the IO (its Close callback may free it).
Parameters
AInterface: the callbacksAUserData: the pointer every callback receives
Returns: the new IO, state Ready
Example: LIO := CreateIO(LCallbacks, address of LCounter);
See also: IOInterface, IOClose. Since: 0.2
IORead
routine IORead(const AIO: IO; const ABuffer: ptr; const ASize: int64): int64;
Reads up to ASize bytes into ABuffer. A short count means the end, an error or no data yet: IOStatus tells which (Eof, Error, NotReady, or WriteOnly when the IO cannot read).
Parameters
AIO: the streamABuffer: where the bytes go (at least ASize bytes)ASize: how many bytes to read
Returns: the count read, 0 to ASize (0 for a nil IO or ASize <= 0)
Example: LGot := IORead(LIO, address of LHeader, 16);
See also: IOStatus. Since: 0.2
IOWrite
routine IOWrite(const AIO: IO; const ABuffer: ptr; const ASize: int64): int64;
Writes up to ASize bytes from ABuffer. A short count means an error or no room yet: IOStatus tells which (Error, NotReady, or ReadOnly when the IO cannot write).
Parameters
AIO: the streamABuffer: the bytes to write (at least ASize bytes)ASize: how many bytes to write
Returns: the count written, 0 to ASize (0 for a nil IO or ASize <= 0)
Example: IOWrite(LIO, address of LHeader, 16);
See also: IOStatus. Since: 0.2
IOSeek
routine IOSeek(const AIO: IO; const AOffset: int64; const AOrigin: SeekOrigin): int64;
Moves the stream's position to AOffset counted from AOrigin. A move that succeeds sets the state Ready (an Eof is over).
Parameters
AIO: the streamAOffset: the offset, negative to go backAOrigin: what the offset counts from
Returns: the new position, or -1 (state Error) when it cannot move there
Example: IOSeek(LIO, -4, SeekOrigin.FromEnd);
See also: IOTell. Since: 0.2
IOTell
routine IOTell(const AIO: IO): int64;
The stream's current position.
Parameters
AIO: the stream
Returns: the position, or -1 when the IO has none (state Error)
See also: IOSeek. Since: 0.2
IOSize
routine IOSize(const AIO: IO): int64;
The stream's size in bytes.
Parameters
AIO: the stream
Returns: the size, or -1 when the IO has none (a pipe, a nil IO)
Since: 0.2
IOFlush
routine IOFlush(const AIO: IO): bool;
Writes out anything the stream has buffered. An IO with no Flush callback has nothing to flush.
Parameters
AIO: the stream
Returns: true when flushed (or nothing to flush), false on failure
See also: IOClose. Since: 0.2
IOTruncate
routine IOTruncate(const AIO: IO; const ASize: int64): bool;
Sets the stream's size to ASize bytes, as ftruncate does: shorter drops the tail, longer adds zero bytes. A stream that cannot write cannot change its size (state ReadOnly); one without a Truncate callback cannot either (state Error). Where the position lands is the stream's rule: a file IO keeps it (it may then lie past the end, as with fseek); a memory IO, which never sits past its end, moves back to the new end.
Parameters
AIO: the streamASize: the new size in bytes (>= 0)
Returns: true when the size was set; false for a nil IO, a negative size (state Error) or a refused or failed change (IOStatus tells which)
Example: IOTruncate(LIO, 0);
See also: IOSize. Since: 0.2
IOClose
routine IOClose(const AIO: IO): bool;
Ends the stream: calls its Close callback, then frees the IO. The IO is gone afterwards, whatever the result.
Parameters
AIO: the stream
Returns: false for a nil IO or when the Close callback failed
Example: if not IOClose(LIO) then println("close failed"); end;
See also: CreateIO. Since: 0.2
IOStatus
routine IOStatus(const AIO: IO): IOState;
The state after the stream's last operation: why a count came up short.
Parameters
AIO: the stream
Returns: the state (Error for a nil IO)
Example: if IOStatus(LIO) = IOState.Eof then ... end;
See also: IOState. Since: 0.2
IOReadFull
routine IOReadFull(const AIO: IO; const ABuffer: ptr; const ASize: int64): int64;
Reads ASize bytes into ABuffer, calling IORead until they are all in or a read gives nothing (the end, an error, a non-blocking source with nothing yet): a stream may answer one IORead with fewer bytes than it has. IOStatus says why a short count stopped.
Parameters
AIO: the streamABuffer: where the bytes go (at least ASize bytes)ASize: how many bytes to read (0 or more)
Returns: the count read: ASize, or fewer when the stream stopped first (0 for a nil IO or ASize <= 0)
Example: if IOReadFull(LIO, address of LHeader[0], 16) <> 16 then ... end;
See also: IORead, IOStatus. Since: 0.3
IOWriteFull
routine IOWriteFull(const AIO: IO; const ABuffer: ptr; const ASize: int64): int64;
Writes ASize bytes from ABuffer, calling IOWrite until they are all out or a write takes nothing (an error, a full or non-blocking stream): a stream may take fewer bytes than one IOWrite offers. IOStatus says why a short count stopped.
Parameters
AIO: the streamABuffer: the bytes (at least ASize)ASize: how many bytes to write (0 or more)
Returns: the count written: ASize, or fewer when the stream stopped first (0 for a nil IO or ASize <= 0)
Example: if IOWriteFull(LIO, LData.data(), int64(LData.size())) <> int64(LData.size()) then ... end;
See also: IOWrite, IOReadFull. Since: 0.3
IOReadAll
routine IOReadAll(const AIO: IO; var AData: string): bool;
Reads a stream from where it stands to its end into AData, as bytes (a string holds any bytes, zeros included). A stream with a size reads in one pass; one without (IOSize -1) reads in chunks until its end.
Parameters
AIO: the streamAData: the bytes read (empty on failure)
Returns: true when the stream was read to its end; false for a nil IO or a read that failed (state Error) or stopped short of the end
Example: if IOReadAll(CreateZipFileIO("$P:assets.zip", "intro.txt"), LText) then ... end;
See also: IOReadFull. Since: 0.3
IOSameContent
routine IOSameContent(const ALeft: IO; const ARight: IO): bool;
True when two streams hold the same bytes from where each stands to its end (both are read to the end; their positions move). A stream that fails a read before its end counts as different.
Parameters
ALeft: one streamARight: the other
Returns: true when both give the same bytes and end together; false when they differ or either is nil
Example: Check("entry intact", IOSameContent(LFile, LEntry));
See also: IOReadFull. Since: 0.3
CreateMemoryIO
routine CreateMemoryIO(const AData: ptr; const ASize: int64; const AReadOnly: bool): IO;
Makes an IO over the caller's memory: ASize bytes at AData, read-only or read / write. It never grows: a write past the end is a short count (state Error), a seek outside 0 .. ASize fails, IOTruncate moves the size only within those ASize bytes. The memory stays the caller's; it must outlive the IO.
Parameters
AData: the memory (nil only when ASize is 0)ASize: its size in bytesAReadOnly: true: IOWrite fails with state ReadOnly
Returns: the IO, or nil when AData / ASize are not a valid block
Example: LIO := CreateMemoryIO(address of LBuffer, 64, true);
See also: IOClose. Since: 0.2
routine CreateMemoryIO(const AData: ptr; const ASize: int64): IO;
Makes a read / write IO over the caller's memory (CreateMemoryIO with AReadOnly false).
Parameters
AData: the memory (nil only when ASize is 0)ASize: its size in bytes
Returns: the IO, or nil when AData / ASize are not a valid block
Since: 0.2
routine CreateMemoryIO(): IO;
Makes a read / write IO over a buffer of its own, empty at first, that grows as writes pass its end. IOClose frees the buffer.
Returns: the IO
Example: LIO := CreateMemoryIO(); IOWrite(LIO, LData, LCount);
See also: IOClose. Since: 0.2
CreateFileIO
routine CreateFileIO(const APath: string; const AMode: FileMode): IO;
Makes an IO over a file. The path is UTF-8 and resolved as ResolvePath resolves it ($P: beside the program, $D: the current folder); the mode is one of C's fopen modes (see FileMode). A Read IO fails IOWrite with state ReadOnly, a Write or Append one fails IORead with state WriteOnly. A file may be positioned past its end, as with fseek; a write there fills the gap with zero bytes. IOClose writes out what is buffered and closes the file.
Parameters
APath: the file (UTF-8)AMode: how to open it
Returns: the IO, or nil when the file cannot be opened in that mode (a missing file for Read / ReadWrite, a folder, no permission)
Example: LIO := CreateFileIO("$P:save.dat", FileMode.Write);
See also: FileMode, IOClose. Since: 0.2
CreateIOSource
routine CreateIOSource(const AInterface: IOSourceInterface; const AUserData: ptr): IOSource;
Makes an IOSource from a table of callbacks and the user pointer they receive. The interface is copied; the user pointer is the caller's and is never freed by the source (its Close callback may free it).
Parameters
AInterface: the callbacksAUserData: the pointer every callback receives
Returns: the new source
Example: LSrc := CreateIOSource(LCallbacks, LPack);
See also: IOSourceInterface, IOSourceClose. Since: 0.2
IOSourceOpen
routine IOSourceOpen(const ASource: IOSource; const APath: string; const AMode: FileMode): IO;
Opens an entry of the source as an IO. The path is relative to the source, / separated, UTF-8; . and .. are resolved (a .. above the source's root is refused). Refused, before the source is asked: an absolute or empty path, an empty segment (a//b, a trailing /), \, :, the other characters Windows refuses in a name, a segment ending in . or a space, and a Windows device name (nul, com1.txt), on both targets alike.
Parameters
ASource: the sourceAPath: the entryAMode: how to open it (a read-only source offers only Read)
Returns: the IO, or nil (refused path, missing entry, mode not offered, nil source or no Open callback)
Example: LIO := IOSourceOpen(LSrc, "save/slot1.dat", FileMode.Write);
See also: IOSourceExists. Since: 0.2
routine IOSourceOpen(const ASource: IOSource; const APath: string): IO;
Opens an entry of the source for reading (IOSourceOpen with FileMode.Read).
Parameters
ASource: the sourceAPath: the entry
Returns: the IO, or nil
Example: LIO := IOSourceOpen(LSrc, "models/ship.bin");
See also: IOSourceOpen. Since: 0.2
IOSourceExists
routine IOSourceExists(const ASource: IOSource; const APath: string): bool;
True when the source has the entry (a file it can open; a folder is not an entry). The path follows IOSourceOpen's rules; a refused path does not exist.
Parameters
ASource: the sourceAPath: the entry
Returns: true when the entry exists
Example: if IOSourceExists(LSrc, "models/ship.mtl") then ... end;
See also: IOSourceOpen. Since: 0.2
IOSourceSize
routine IOSourceSize(const ASource: IOSource; const APath: string): int64;
The size in bytes of an entry of the source, without opening it. The path follows IOSourceOpen's rules.
Parameters
ASource: the sourceAPath: the entry
Returns: the size, or -1 (no such entry, refused path, nil source or no Size callback)
Example: LBytes := IOSourceSize(LSrc, "models/ship.bin");
See also: IOSourceExists. Since: 0.2
IOSourceRemove
routine IOSourceRemove(const ASource: IOSource; const APath: string): bool;
Deletes an entry of the source. The path follows IOSourceOpen's rules. IOs already opened on the entry stay valid; whether the entry can go while one is open is the source's (a folder source on Windows refuses while a file IO on it is open).
Parameters
ASource: the sourceAPath: the entry
Returns: true when the entry was deleted; false for a missing entry, a refused path, a source that refused, a nil source or no Remove callback (a source that deletes nothing, such as a zip)
Example: if not IOSourceRemove(LSrc, "save/slot1.tmp") then ... end;
See also: IOSourceExists. Since: 0.2
IOSourceCanRemove
routine IOSourceCanRemove(const ASource: IOSource): bool;
True when the source can delete entries (it has a Remove callback), so a caller can refuse up front what IOSourceRemove would not do later (a zip source cannot).
Parameters
ASource: the source
Returns: true when IOSourceRemove can delete an entry of it; false for a nil source or one without a Remove callback
Example: if IOSourceCanRemove(LSrc) then ... end;
See also: IOSourceRemove. Since: 0.2
IOSourceClose
routine IOSourceClose(const ASource: IOSource): bool;
Ends the source: calls its Close callback, then frees the IOSource. IOs opened from it stay valid until their own IOClose.
Parameters
ASource: the source
Returns: false for a nil source or when the Close callback failed
Example: IOSourceClose(LSrc);
See also: CreateIOSource. Since: 0.2
CreateFolderIOSource
routine CreateFolderIOSource(const APath: string): IOSource;
Makes an IOSource over a folder: every entry is a file under it, its IOs file IOs (CreateFileIO's rules, every FileMode). The folder's path is UTF-8 and resolved as ResolvePath resolves it; entry paths are relative to it (IOSourceOpen's rules), so nothing outside the folder is reached by a ... Opening in Write or Append creates the file, never a folder; IOSourceRemove deletes the entry's file.
Parameters
APath: the folder (UTF-8)
Returns: the source, or nil when the path is not an existing folder
Example: LSrc := CreateFolderIOSource("$P:assets");
See also: IOSourceOpen, IOSourceClose. Since: 0.2
CreateZipIOSource
routine CreateZipIOSource(const AArchive: IO; const APassword: string): IOSource;
Makes a read-only IOSource over a zip archive read through an IO: the archive may be a file, memory, an entry of another source or any IO that reads and seeks. Its central directory is read once, here: ZIP64 archives, data before the archive (a self-extractor) and names in UTF-8, CP437 or an Info-ZIP Unicode Path field are read. Entry paths follow IOSourceOpen's rules and match the archive's names exactly (case included, on both targets); a folder is not an entry, a name no path can reach (absolute, .. above the root, \) is never found, and of two entries with one name the later is found. IOSourceSize gives an entry's uncompressed size; IOSourceOpen opens an entry (FileMode.Read only) as a read-only IO that seeks without reading from the start again (stored and deflated entries, ZipCrypto encrypted or not): an entry under 256 KB is read whole when opened, a larger one in place. An encrypted entry opens only with the right password. A CRC that does not match gives nil from the open (small entry) or fails the read that reaches the end (large entry, state Error). An entry IO stays valid after IOSourceClose. The archive IO stays the caller's: never closed by the source, its position moved by every read, it must outlive the source and its entry IOs.
Parameters
AArchive: the archiveAPassword: the password for its encrypted entries ("" for none)
Returns: the source, or nil when AArchive is nil or not a valid zip (no end record, cut short, a bad signature, several disks)
Example: LSrc := CreateZipIOSource(LMemoryIO, "secret");
See also: IOSourceOpen, IOSourceClose. Since: 0.2
routine CreateZipIOSource(const AArchive: IO): IOSource;
Makes a read-only IOSource over a zip archive read through an IO, with no password (CreateZipIOSource(AArchive, "")).
Parameters
AArchive: the archive
Returns: the source, or nil
Example: LSrc := CreateZipIOSource(LMemoryIO);
See also: CreateZipIOSource. Since: 0.2
routine CreateZipIOSource(const APath: string; const APassword: string): IOSource;
Makes a read-only IOSource over a zip file: CreateZipIOSource over the file opened as CreateFileIO(APath, FileMode.Read) opens it (UTF-8, ResolvePath's $P: / $D:). The source owns that file: it is closed once the source (IOSourceClose) and every entry IO opened from it (IOClose) are closed.
Parameters
APath: the zip file (UTF-8)APassword: the password for its encrypted entries ("" for none)
Returns: the source, or nil when the file cannot be opened or is not a valid zip
Example: LSrc := CreateZipIOSource("$P:assets.zip", "secret");
See also: CreateZipIOSource. Since: 0.2
routine CreateZipIOSource(const APath: string): IOSource;
Makes a read-only IOSource over a zip file, with no password (CreateZipIOSource(APath, "")).
Parameters
APath: the zip file (UTF-8)
Returns: the source, or nil
Example: LSrc := CreateZipIOSource("$P:assets.zip");
See also: CreateZipIOSource. Since: 0.2
CreateZipFileIO
routine CreateZipFileIO(const AArchive: IO; const AEntry: string; const APassword: string): IO;
Opens one entry of a zip archive read through an IO as a read-only IO: IOSourceOpen on CreateZipIOSource(AArchive, APassword), the source closed again at once (the entry IO keeps what it needs). Reading, seeking, passwords and CRC as CreateZipIOSource says.
Parameters
AArchive: the archive (the caller's: it must outlive the IO)AEntry: the entry's path (IOSourceOpen's rules)APassword: the password when the entry is encrypted ("" for none)
Returns: the IO, or nil (not a valid zip, no such entry, a missing or wrong password, an entry that cannot be read)
Example: LIO := CreateZipFileIO(LPackIO, "models/ship.bin", "secret");
See also: CreateZipIOSource, IOClose. Since: 0.2
routine CreateZipFileIO(const AArchive: IO; const AEntry: string): IO;
Opens one entry of a zip archive read through an IO, with no password (CreateZipFileIO(AArchive, AEntry, "")).
Parameters
AArchive: the archive (the caller's: it must outlive the IO)AEntry: the entry's path
Returns: the IO, or nil
Example: LIO := CreateZipFileIO(LPackIO, "readme.txt");
See also: CreateZipFileIO. Since: 0.2
routine CreateZipFileIO(const APath: string; const AEntry: string; const APassword: string): IO;
Opens one entry of a zip file as a read-only IO: the file opened as CreateZipIOSource(APath, APassword) opens it and closed when the IO is (IOClose).
Parameters
APath: the zip file (UTF-8)AEntry: the entry's path (IOSourceOpen's rules)APassword: the password when the entry is encrypted ("" for none)
Returns: the IO, or nil (the file cannot be opened or is not a valid zip, no such entry, a missing or wrong password, an entry that cannot be read)
Example: LIO := CreateZipFileIO("$P:assets.zip", "models/ship.bin", "secret");
See also: CreateZipIOSource, IOClose. Since: 0.2
routine CreateZipFileIO(const APath: string; const AEntry: string): IO;
Opens one entry of a zip file, with no password (CreateZipFileIO(APath, AEntry, "")).
Parameters
APath: the zip file (UTF-8)AEntry: the entry's path
Returns: the IO, or nil
Example: LIO := CreateZipFileIO("$P:assets.zip", "readme.txt");
See also: CreateZipFileIO. Since: 0.2
ZipDirectoryContents
routine ZipDirectoryContents(const AArchive: string; const AFolder: string; const APassword: string; const ARoot: string; const AProgress: ZipProgress; const AUserData: ptr): bool;
Writes every file under a folder (its subfolders too) into a new zip archive (Delphi's TZipFile.ZipDirectoryContents, archive first): deflated at the best level, each entry ZipCrypto encrypted with APassword unless it is "", with its file's modification time, the entries in byte order of their names (the same archive whatever order the system lists the files in). An entry is named by its file's path below ARoot with / (ARoot "" = AFolder itself): ZipDirectoryContents("$P:assets.zip", "$P:res/assets", "secret", "$P:") names them res/assets/... A name that is not ASCII is stored as UTF-8 (general purpose bit 11); a file of 4 GB or more is stored as ZIP64. Every path is UTF-8 and resolved as ResolvePath resolves it ($P:, $D:). An archive inside AFolder is left out; an existing archive is replaced. The archive and the files are always the disk's: a path source HookIO has set never redirects them. The result reads back with CreateZipIOSource / CreateZipFileIO.
Parameters
AArchive: the zip file to writeAFolder: the folder to packAPassword: the entries' password ("" for none)ARoot: the folder entry names are relative to ("" for AFolder)AProgress: called for each entry's progress (nil for none)AUserData: the pointer AProgress receives
Returns: true when every file is in the archive; false when AFolder is not an existing folder inside ARoot (no archive is written then), a file cannot be read or the archive cannot be written (an archive begun is then incomplete)
Example: ZipDirectoryContents("$P:assets.zip", "$P:res/assets", "secret", "$P:", ShowProgress, nil);
See also: ZipProgress, CreateZipIOSource. Since: 0.3
routine ZipDirectoryContents(const AArchive: string; const AFolder: string; const APassword: string; const ARoot: string): bool;
Writes every file under a folder into a new zip archive, its entries named below ARoot, with no progress routine (ZipDirectoryContents(AArchive, AFolder, APassword, ARoot, nil, nil)).
Parameters
AArchive: the zip file to writeAFolder: the folder to packAPassword: the entries' password ("" for none)ARoot: the folder entry names are relative to ("" for AFolder)
Returns: true when every file is in the archive
Example: ZipDirectoryContents("$P:assets.zip", "$P:res/assets", "secret", "$P:");
See also: ZipDirectoryContents. Since: 0.3
routine ZipDirectoryContents(const AArchive: string; const AFolder: string; const APassword: string): bool;
Writes every file under a folder into a new zip archive, its entries named below the folder itself, with no progress routine (ZipDirectoryContents(AArchive, AFolder, APassword, "", nil, nil)).
Parameters
AArchive: the zip file to writeAFolder: the folder to packAPassword: the entries' password ("" for none)
Returns: true when every file is in the archive
Example: ZipDirectoryContents("$P:save.zip", "$P:save", "secret");
See also: ZipDirectoryContents. Since: 0.3
routine ZipDirectoryContents(const AArchive: string; const AFolder: string): bool;
Writes every file under a folder into a new zip archive with no password, its entries named below the folder itself, with no progress routine (ZipDirectoryContents(AArchive, AFolder, "", "", nil, nil)).
Parameters
AArchive: the zip file to writeAFolder: the folder to pack
Returns: true when every file is in the archive
Example: ZipDirectoryContents("$P:logs.zip", "$P:logs");
See also: ZipDirectoryContents. Since: 0.3
ZipLastError
routine ZipLastError(): string;
Why the last ZipDirectoryContents on this thread failed: the step, the path and the system's own words where it gave any ("cannot create the archive ...: Permission denied", "... is not a folder", "... changed while it was packed"); "" when it succeeded.
Returns: the reason, or ""
Example: if not ZipDirectoryContents(LZip, LFolder) then println("{}", ZipLastError()); end;
See also: ZipDirectoryContents. Since: 0.3
HookIO
The HookIO unit: import HookIO; lets C stdio open CustomIO streams by path. Register an IO or an IOSource and get back its prefix, io://<n>. A path that starts with that prefix then names the registered stream wherever C code opens a file: fopen("io://<n>/...") in the program, or inside any C / C++ library linked into it (raylib, stb_vorbis, ...), opens the stream instead of a file on disk. The hooks are HookABI link-time hooks, so they bind every call in the final link; a DLL / .so loaded at run time is not reached.
Import it with import HookIO;.
Routines
RegisterIO
routine RegisterIO(const AIO: IO): string;
Registers an IO under a new prefix: from now on fopen("<prefix>/<name>"), in the program or in any C library linked into it, opens it (see the unit header for the modes). Every open gets its own handle with its own position. The IO stays the caller's: the registry never closes it.
Parameters
AIO: the stream
Returns: the prefix, io://<n>; "" when AIO is nil or out of memory
Example: LPrefix := RegisterIO(LMusic); LFile := fopen((LPrefix + "/song.ogg").c_str(), "rb");
See also: RegisterIOSource, UnregisterIO. Since: 0.2
RegisterIOSource
routine RegisterIOSource(const ASource: IOSource): string;
Registers an IOSource under a new prefix: from now on fopen("<prefix>/<entry>"), in the program or in any C library linked into it, opens that entry of the source (IOSourceOpen). The source stays the caller's: the registry never closes it.
Parameters
ASource: the source
Returns: the prefix, io://<n>; "" when ASource is nil or out of memory
Example: LPrefix := RegisterIOSource(CreateZipIOSource("$P:assets.zip"));
See also: RegisterIO, UnregisterIO. Since: 0.2
UnregisterIO
routine UnregisterIO(const APrefix: string): bool;
Removes a prefix: opening a path under it fails as a missing file does (ENOENT) from now on. Handles already open stay as they are; close them before closing what was registered.
Parameters
APrefix: exactly what RegisterIO / RegisterIOSource returned
Returns: true when APrefix was registered
Example: UnregisterIO(LPrefix); IOClose(LMusic);
See also: RegisterIO, RegisterIOSource. Since: 0.2
FileIO
routine FileIO(const AFile: ptr to FILE): IO;
The IO behind a handle that a hooked open returned: the registered IO, or the entry's IO for a source. For a C runtime FILE, or nil, it is nil.
Parameters
AFile: the handle
Returns: the IO, or nil when AFile is not a HookIO handle
Example: if FileIO(LFile) <> nil then ... end;
See also: RegisterIO. Since: 0.2
SetIOPathSource
routine SetIOPathSource(const ASource: IOSource): bool;
Makes an IOSource the path source: while it is set, a plain path (not io://) that any hooked open or query names, in the program or in any C library linked into it, is looked up in the source first, as an entry name ('\' as '/', every leading "./" or '/' dropped). When the source has that entry, the path opens or answers as <prefix>/<entry> would; otherwise the path goes to the real file system untouched. While a hooked open or query runs, the files a source opens itself (its real files, its archive) reach the real file system. One setting for the whole program; setting a source replaces the one before. The source stays the caller's: unset it (nil) before closing it. CustomIO's file IO and folder source always mean the disk: their own opens and queries are never looked up.
Parameters
ASource: the files, or nil to look up no plain path
Returns: false when the source could not be registered (out of memory): nothing changed
Example: SetIOPathSource(CreateZipIOSource("$P:assets.zip")); LFile := fopen("music/song.ogg", "rb");
See also: RegisterIOSource, SetIOThreadPathSource. Since: 0.2
SetIOThreadPathSource
routine SetIOThreadPathSource(const ASource: IOSource): bool;
Makes an IOSource the calling thread's own path source: while it is set, a plain path that a hooked open or query names on this thread is looked up in it, as SetIOPathSource describes, instead of in the program's path source; every other thread keeps the program's. A loader that pulls in files by plain relative paths (a map's tilesets and images) sets one for the load and unsets it after, without moving the program's path source under another thread (a music stream reading through it). Set and unset it on the same thread, unset it (nil) before the thread ends and before closing the source. The source stays the caller's.
Parameters
ASource: the files, or nil: the program's path source applies to this thread again
Returns: false when the source could not be registered (out of memory): nothing changed
Example: SetIOThreadPathSource(LZip); LOk := LMap.load("maps/level.tmx"); SetIOThreadPathSource(nil);
See also: SetIOPathSource, GetIOThreadPathSource. Since: 0.3
GetIOThreadPathSource
routine GetIOThreadPathSource(): IOSource;
The calling thread's own path source, as SetIOThreadPathSource last set it on this thread, so a loader can set its own for a call and put the caller's back after.
Returns: the source; nil when none is set on this thread (the program's path source, if any, applies)
Example: LBefore := GetIOThreadPathSource(); SetIOThreadPathSource(LZip); ... SetIOThreadPathSource(LBefore);
See also: SetIOThreadPathSource. Since: 0.3
HookABI
The HookABI unit: import HookABI; hooks C ABI functions.
Import it with import HookABI;.
Types
Hook
Hook = record
A run-time hook, filled by HookInstall: while installed, every call of the hooked name through a module's import slot (Linux a GOT entry, Windows an import address table entry) reaches the replacement instead. A Hook variable starts zeroed (not installed); keep it while installed.
Members
Original: ptr: The function the hooked name's slots reached before the install (the replacement calls it for the real work; calling the name itself from the replacement would reach the replacement again). Stays valid after HookUninstall: a replacement still running on another thread may call it.State: ptr: HookABI's record of the install; nil when not installed
See also: HookInstall, HookUninstall. Since: 0.2
Constants
| Name | Declaration | Description |
|---|---|---|
HookStatVersion | : int32 = 1 | glibc's stat version on x86_64 (_STAT_VER, which the glibc headers zig ships do not define): the first argument of __xstat, __fxstat, __lxstat, __xstat64, __fxstat64 and __lxstat64, the real functions of a Linux stat-family hook (see "Finding the real function" in the unit header). Linux only. Example: return LReal(HookStatVersion, APath, ABuf); |
Routines
HookReal
routine HookReal(var ASlot: ptr; const AName: ptr to const char): ptr;
Finds the real function a link-time hook of a C runtime name stands in for: on Linux the next definition of AName after the program (dlsym(RTLD_NEXT)), on Windows the export AName of ucrtbase.dll. The first call resolves it into ASlot; later calls read ASlot (one atomic load), so a hook may call this on every entry. Safe on several threads at once, and it never allocates, so it is safe inside the CRT and before the program starts.
Parameters
ASlot: the hook's own pointer, nil until the first call; keep one per hooked name, at module levelAName: the real function's C name: the hooked name, or, for a name a static C runtime object defines (an empty Real in HookABI.bindlist.h), the function that object calls (Linux: hook stat, real "__xstat", called with HookStatVersion first; Windows: hook stat64i32, real "_stat64i32")
Returns: the real function, to be cast to the hook's routine type with reinterpret_cast; nil when the C runtime has no AName (the slot stays nil and the next call looks again): the hook must not call it then
Example: LReal := reinterpret_cast<FopenFn>(HookReal(GRealFopen, "fopen"));
See also: HookReal(ASlot, ALibrary, AName) for a function of another library. Since: 0.2
routine HookReal(var ASlot: ptr; const ALibrary: ptr to const char; const AName: ptr to const char): ptr;
Finds the real function of a hooked name in one named library, for a function outside the C runtime (a Win32 API in kernel32.dll, a function of a shared library). The library must already be loaded: this never loads one (Windows GetModuleHandleW, Linux dlopen with RTLD_NOLOAD). The first call resolves into ASlot, later calls read it, as the two-argument form; safe on several threads at once. On Linux the first call goes through the dynamic loader (dlopen / dlclose), so a hook that the loader itself may enter (malloc and its family) resolves with the two-argument form instead.
Parameters
ASlot: the hook's own pointer, nil until the first call; keep one per hooked name, at module levelALibrary: the library's file name, UTF-8 (Windows: "kernel32.dll"; Linux: the soname, "libc.so.6")AName: the real function's C name
Returns: the real function, to be cast to the hook's routine type with reinterpret_cast; nil when the library is not loaded or has no AName (the slot stays nil and the next call looks again): the hook must not call it then
Example: LReal := reinterpret_cast<GetAttrFn>(HookReal(GRealGetAttr, "kernel32.dll", "GetFileAttributesA"));
See also: HookReal(ASlot, AName) for a C runtime name. Since: 0.2
HookInstall
routine HookInstall(var AHook: Hook; const AName: ptr to const char; const AReplacement: ptr): bool;
Installs a run-time hook: AName's import slot in every module loaded now takes AReplacement, and so does every module the program loads later (Linux: through the program's own dlopen; Windows: by the loader's DLL notification). Code that calls AName directly, not through an import slot (the module that defines it, a link-time hook), is not reached: that is the link-time level's job. One install per name at a time. Thread-safe; installs and uninstalls run one at a time.
Parameters
AHook: the record to fill: zeroed, or uninstalledAName: the function's C name, as the modules import itAReplacement: a function of the same C signature and calling convention (aroutine clink, cast to ptr)
Returns: true when installed (AHook.Original and AHook.State set; a name no module imports yet is installed for the modules loaded later); false with errno: EINVAL (nil or empty AName, nil AReplacement), EEXIST (AHook is installed, or AName already is), ENOENT (no loaded module defines AName), EACCES (a slot could not be written: every slot written is put back), ENOMEM
Example: if HookInstall(GGetenv, "getenv", cpp("reinterpret_cast<void*>(&MyGetenv)")) then ... end;
See also: HookUninstall. Since: 0.2
HookUninstall
routine HookUninstall(var AHook: Hook): bool;
Uninstalls a run-time hook: every slot it wrote whose module is still loaded gets back exactly what it held before; nothing else is written. AHook.State becomes nil; AHook.Original stays.
Parameters
AHook: a record HookInstall filled
Returns: true when uninstalled; false with errno: EINVAL (AHook is not installed), EACCES (a slot could not be written back: the hook stays installed, the slots that went back stay back), ENOMEM
Example: HookUninstall(GGetenv);
See also: HookInstall. Since: 0.2
raylib_ext
The raylib_ext unit: import raylib_ext; gives raylib's file loaders an IO form, MPEG-1 video, and the frame window. The frame window (sfml_ext's sfx::RenderWindow, raylib style): InitFrameWindow opens raylib's window at a base (virtual) size x the monitor's scale (DPI / 96; Windows the window's monitor, Linux X11's Xft.dpi, 96 unset: one rule on every target), centred, resizable, and follows a DPI change. BeginFrame / EndFrame (inside BeginDrawing) draw in base units through a letterboxed Camera2D, the aspect kept on resize, maximize and ToggleFrameFullscreen, bars outside it; BeginFrameMode2D / BeginFrameMode3D draw the program's own Camera2D / Camera3D through the letterbox (the 3D scene at the base size's aspect); RestoreFrameClip turns the frame's clip on again for code that turned it off (rlimgui_ext's ImGui); GetFrameMousePosition is the mouse in base units. GetLetterboxRect, GetScaledFrameSize and GetFramePoint are its rules, usable with no window.
Import it with import raylib_ext;.
Types
VideoStatus
VideoStatus = choices(VideoStopped, VideoPlaying, VideoPaused);
Where a video stands: VideoStopped (at its start, no frame shown until it plays), VideoPlaying, or VideoPaused (where it was, its frame still drawn). A video starts stopped; one that does not loop is stopped again at its end.
Example: if GetVideoStatus(LIntro) = VideoStatus.VideoStopped then PlayVideo(LIntro); end;
See also: GetVideoStatus. Since: 0.2
VideoStatusCallback
VideoStatusCallback = routine(const AStatus: VideoStatus; const AName: ptr to const char);
Called on every change of a video's status: by PlayVideo, PauseVideo and StopVideo when they change it, and by UpdateVideo at the end of a video that does not loop (VideoStopped). A call that changes nothing (PlayVideo on a playing video) calls nothing, and neither does UnloadVideo.
Example: routine OnVideo(const AStatus: VideoStatus; const AName: ptr to const char); begin ... end;
See also: SetVideoStatusCallback. Since: 0.2
Video
Video = record
An MPEG-1 video (pl_mpeg) with its MP2 audio, used as raylib's Music is: load it with LoadVideo, LoadVideoIO or LoadVideoZip, PlayVideo it, call UpdateVideo once a frame and DrawVideo it, then UnloadVideo it. The record is a handle: copies name the same video. Every routine takes a video that did not load (ctxData nil) and does nothing with it, giving 0, false or VideoStopped.
Members
ctxData: ptr: The player; nil when the video did not load (IsVideoValid)width: int32: The frame width in pixels; 0 when the video did not loadheight: int32: The frame height in pixels; 0 when the video did not load
Example: LIntro := LoadVideoZip("$P:assets.zip", "res/assets/videos/intro.mpg", ""); PlayVideo(LIntro);
See also: LoadVideo. Since: 0.2
Routines
LoadFileDataIO
routine LoadFileDataIO(const AIO: IO; var ADataSize: int32): ptr to uint8;
Loads an IO's bytes as LoadFileData loads a file's (raylib's own LoadFileData reads it through the hooks), in memory that UnloadFileData frees. The IO stays the caller's.
Parameters
AIO: the stream (CreateZipFileIO's, CreateFileIO's, any IO)ADataSize: the byte count; 0 on a failure
Returns: the bytes, or nil (with raylib's warning) when the IO is nil, empty, or cannot be read
Example: LData := LoadFileDataIO(CreateZipFileIO("$P:assets.zip", "level1.bin"), LSize);
See also: LoadFileTextIO. Since: 0.2
LoadFileTextIO
routine LoadFileTextIO(const AIO: IO): ptr to char;
Loads an IO's bytes as text, as LoadFileText loads a file (raylib's own LoadFileText reads it through the hooks, in text mode on Windows), '\0'-terminated, in memory that UnloadFileText frees. The IO stays the caller's.
Parameters
AIO: the stream
Returns: the text, or nil (with raylib's warning) when the IO is nil or cannot be read
Example: LText := LoadFileTextIO(CreateZipFileIO("$P:assets.zip", "intro.txt"));
See also: LoadFileDataIO. Since: 0.2
LoadImageIO
routine LoadImageIO(const AIO: IO; const AFileType: ptr to const char): Image;
Loads an image from an IO as LoadImage loads one from a file (raylib's own LoadImage reads it through the hooks); unload with UnloadImage.
Parameters
AIO: the streamAFileType: the file type, its extension: ".png", ".jpg", ...
Returns: the image; an empty one (data nil) when the IO cannot be read or its bytes do not decode
Example: LImage := LoadImageIO(CreateZipFileIO("$P:assets.zip", "hero.png"), ".png");
See also: LoadTextureIO. Since: 0.2
LoadImageRawIO
routine LoadImageRawIO(const AIO: IO; const AWidth: int32; const AHeight: int32; const AFormat: int32; const AHeaderSize: int32): Image;
Loads raw pixel data from an IO as LoadImageRaw loads it from a file (raylib's own LoadImageRaw reads it through the hooks): the pixels after AHeaderSize bytes; unload with UnloadImage.
Parameters
AIO: the streamAWidth: the image width in pixelsAHeight: the image height in pixelsAFormat: a PixelFormat valueAHeaderSize: bytes to skip before the pixels
Returns: the image; an empty one when LoadImageRaw gives one for a file of the same bytes, or the IO cannot be read
Example: LImage := LoadImageRawIO(LIO, 64, 64, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, 16);
See also: LoadImageIO. Since: 0.2
LoadImageAnimIO
routine LoadImageAnimIO(const AIO: IO; const AFileType: ptr to const char; var AFrames: int32): Image;
Loads an image sequence from an IO as LoadImageAnim loads one from a file (raylib's own LoadImageAnim reads it through the hooks; frames appended to the image data); unload with UnloadImage.
Parameters
AIO: the streamAFileType: the file type: ".gif" (any other image type loads one frame)AFrames: the frame count; 0 on a failure
Returns: the image; an empty one on a failure
Example: LAnim := LoadImageAnimIO(LIO, ".gif", LFrames);
See also: LoadImageIO. Since: 0.2
LoadTextureIO
routine LoadTextureIO(const AIO: IO; const AFileType: ptr to const char): Texture2D;
Loads a texture from an IO as LoadTexture loads one from a file (raylib's own LoadTexture reads it through the hooks); unload with UnloadTexture. Needs a window, as LoadTexture does.
Parameters
AIO: the streamAFileType: the file type: ".png", ...
Returns: the texture; an empty one (id 0) on a failure
Example: LTexture := LoadTextureIO(CreateZipFileIO("$P:assets.zip", "hero.png"), ".png");
See also: LoadImageIO. Since: 0.2
LoadFontIO
routine LoadFontIO(const AIO: IO; const AFileType: ptr to const char): Font;
Loads a font from an IO as LoadFont loads one from a file (raylib's own LoadFont reads it through the hooks): a TTF / OTF at raylib's default size and characters, any image type as an image font. A .fnt reads its page images by name beside it, which one IO cannot hold, so it is refused here (an empty font and a warning): route it through an IOSource. Unload with UnloadFont; needs a window, as LoadFont does.
Parameters
AIO: the streamAFileType: the file type: ".ttf", ".otf", ".png", ...
Returns: the font; on a failure what LoadFont gives for such a file
Example: LFont := LoadFontIO(CreateZipFileIO("$P:assets.zip", "ui.ttf"), ".ttf");
See also: LoadFontExIO. Since: 0.2
LoadFontExIO
routine LoadFontExIO(const AIO: IO; const AFileType: ptr to const char; const AFontSize: int32; const ACodepoints: ptr to const int32; const ACodepointCount: int32): Font;
Loads a font from an IO as LoadFontEx loads one from a file (raylib's own LoadFontEx reads it through the hooks), at AFontSize with the given codepoints (nil and 0 for raylib's default set); unload with UnloadFont. Needs a window.
Parameters
AIO: the streamAFileType: the file type: ".ttf", ".otf"AFontSize: the size the glyphs are made atACodepoints: the codepoints, or nilACodepointCount: how many, or 0
Returns: the font; on a failure what LoadFontEx gives for such a file
Example: LFont := LoadFontExIO(LIO, ".ttf", 48, nil, 0);
See also: LoadFontIO. Since: 0.2
LoadWaveIO
routine LoadWaveIO(const AIO: IO; const AFileType: ptr to const char): Wave;
Loads wave data from an IO as LoadWave loads it from a file (raylib's own LoadWave reads it through the hooks); unload with UnloadWave.
Parameters
AIO: the streamAFileType: the file type raylib decodes by: ".wav", ".ogg", ".mp3", ".qoa", ".flac"
Returns: the wave; an empty one (data nil) on a failure
Example: LWave := LoadWaveIO(CreateZipFileIO("$P:assets.zip", "hit.wav"), ".wav");
See also: LoadSoundIO. Since: 0.2
LoadSoundIO
routine LoadSoundIO(const AIO: IO; const AFileType: ptr to const char): Sound;
Loads a sound (a sound effect, fully in memory) from an IO as LoadSound loads one from a file (raylib's own LoadSound reads it through the hooks); unload with UnloadSound. Needs the audio device, as LoadSound does.
Parameters
AIO: the streamAFileType: the file type: ".wav", ".ogg", ".mp3", ".qoa", ".flac"
Returns: the sound; an empty one on a failure
Example: LHit := LoadSoundIO(CreateZipFileIO("$P:assets.zip", "hit.wav"), ".wav");
See also: LoadWaveIO. Since: 0.2
LoadMusicStreamIO
routine LoadMusicStreamIO(const AIO: IO; const AFileType: ptr to const char): Music;
Loads a music stream from an IO as LoadMusicStream loads one from a file: raylib's own LoadMusicStream opens it through the hooks, and every read and seek while it plays goes to the IO (nothing is read ahead into memory but what raylib itself reads). The IO stays registered until UnloadMusicStreamIO, so it must stay open while the music plays. Unload with UnloadMusicStreamIO, never UnloadMusicStream. Needs the audio device.
Parameters
AIO: the streamAFileType: the file type: ".ogg", ".mp3", ".wav", ".qoa", ".flac", ".xm", ".mod"
Returns: the music; an empty one (ctxData nil) on a failure
Example: LSong := LoadMusicStreamIO(CreateZipFileIO("$P:assets.zip", "song.ogg"), ".ogg");
See also: UnloadMusicStreamIO. Since: 0.2
UnloadMusicStreamIO
routine UnloadMusicStreamIO(const AMusic: Music);
Unloads a music stream LoadMusicStreamIO gave (UnloadMusicStream), then ends its IO's registration. The IO stays the caller's, to close after.
Parameters
AMusic: the music
Example: UnloadMusicStreamIO(LSong); IOClose(LSongIO);
See also: LoadMusicStreamIO. Since: 0.2
LoadShaderIO
routine LoadShaderIO(const AVertex: IO; const AFragment: IO): Shader;
Loads a shader from two IOs as LoadShader loads one from two files (raylib's own LoadShader reads them through the hooks); unload with UnloadShader. Needs a window.
Parameters
AVertex: the vertex shader's source, or nil for raylib's default vertex shader (as LoadShader with NULL)AFragment: the fragment shader's source, or nil for the default
Returns: the shader; raylib's default shader on a failure, as LoadShader gives
Example: LShader := LoadShaderIO(nil, CreateZipFileIO("$P:assets.zip", "glow.fs"));
Since: 0.2
LoadAutomationEventListIO
routine LoadAutomationEventListIO(const AIO: IO): AutomationEventList;
Loads an automation event list from an IO as LoadAutomationEventList loads one from a file (raylib's own loader reads it through the hooks); unload with UnloadAutomationEventList.
Parameters
AIO: the stream (raylib's .rae events); nil gives an empty list with raylib's capacity, as LoadAutomationEventList(NULL)
Returns: the list
Example: LEvents := LoadAutomationEventListIO(CreateZipFileIO("$P:demo.zip", "run.rae"));
Since: 0.2
LoadModelIO
routine LoadModelIO(const ASource: IOSource; const APath: string): Model;
Loads a model from an IOSource as LoadModel loads one from a file: raylib's own LoadModel opens APath in the source through the hooks, and every file it reads beside it (a glTF's .bin, an OBJ's .mtl, textures) is read from the source by its path too. Unload with UnloadModel; needs a window.
Parameters
ASource: the files (CreateZipIOSource's, a folder's, any source)APath: the model's path in the source: "models/hero.gltf"
Returns: the model; what LoadModel gives for a missing file on a failure
Example: LHero := LoadModelIO(CreateZipIOSource("$P:assets.zip"), "models/hero.gltf");
See also: LoadMaterialsIO. Since: 0.2
LoadMaterialsIO
routine LoadMaterialsIO(const ASource: IOSource; const APath: string; var AMaterialCount: int32): ptr to Material;
Loads the materials of a model file in an IOSource as LoadMaterials does from a file (through the hooks, siblings from the source too).
Parameters
ASource: the filesAPath: the material file's path in the source: "models/hero.mtl"AMaterialCount: the count; 0 on a failure
Returns: the materials, or what LoadMaterials gives for a missing file
Example: LMats := LoadMaterialsIO(LSource, "models/hero.mtl", LCount);
See also: LoadModelIO. Since: 0.2
LoadModelAnimationsIO
routine LoadModelAnimationsIO(const ASource: IOSource; const APath: string; var AAnimCount: int32): ptr to ModelAnimation;
Loads the animations of a model file in an IOSource as LoadModelAnimations does from a file (through the hooks, siblings from the source too); unload with UnloadModelAnimations.
Parameters
ASource: the filesAPath: the model's path in the source: "models/hero.glb"AAnimCount: the count; 0 on a failure
Returns: the animations, or what LoadModelAnimations gives for a missing file
Example: LAnims := LoadModelAnimationsIO(LSource, "models/hero.glb", LCount);
See also: LoadModelIO. Since: 0.2
SetRaylibIOSource
routine SetRaylibIOSource(const ASource: IOSource): bool;
Makes an IOSource raylib's file system: raylib's file callbacks (SetLoadFileDataCallback, SetLoadFileTextCallback and the Save pair) then open every file name raylib loads or saves in the source, by that name as a path in it ('\' as '/', a leading "./" or '/' dropped), through the hooks; text loads and saves in text mode, as raylib's own. Paths the IO forms hand raylib (io://...) still reach their IO. nil restores raylib's own file functions (the callbacks set to NULL). raylib keeps one set of callbacks for the process with no user data, so this is one setting for the whole program, and not for several threads at once, as raylib's callbacks are not. The source stays the caller's: unset it (nil) before closing it. Setting it replaces callbacks set by SetLoadFileDataCallback and the others, and nil leaves none set. It also makes the source HookIO's path source (SetIOPathSource), so the files raylib's decoders open by plain path themselves (music streams) come from it too; nil unsets that path source when it is still the one set here (one the program set since with SetIOPathSource stays).
Parameters
ASource: the files, or nil
Returns: false when the source could not be registered (out of memory): nothing changed
Example: SetRaylibIOSource(CreateZipIOSource("$P:assets.zip")); LHero := LoadModel("models/hero.gltf");
See also: LoadModelIO. Since: 0.2
LoadVideoIO
routine LoadVideoIO(const AIO: IO; const AName: string): Video;
Loads a video from an IO: an MPEG-1 video (with or without MP2 audio) read through the IO while it plays, so the IO must stay open until UnloadVideo (which leaves it open: it stays the caller's). The audio plays through raylib's audio device when it is ready (InitAudioDevice first); without it the video plays silently. A window is not needed to load: frames are uploaded once one is open.
Parameters
AIO: the video's bytes (CreateZipFileIO's, CreateFileIO's, any IO)AName: the name the status callback is given
Returns: the video; ctxData nil when the IO holds no MPEG-1 video
Example: LIntro := LoadVideoIO(CreateZipFileIO("$P:assets.zip", "intro.mpg"), "intro.mpg");
See also: UnloadVideo. Since: 0.2
LoadVideo
routine LoadVideo(const AFileName: string): Video;
Loads a video from a file (UTF-8 path; $P: / $D: prefixes resolved): LoadVideoIO's rules over a file IO the video owns.
Parameters
AFileName: the .mpg file
Returns: the video; ctxData nil when the file is missing or no MPEG-1 video
Example: LIntro := LoadVideo("$P:../res/assets/videos/intro.mpg");
See also: LoadVideoIO. Since: 0.2
LoadVideoZip
routine LoadVideoZip(const AArchive: string; const AEntry: string; const APassword: string): Video;
Loads a video from a zip entry (a password for an encrypted archive): LoadVideoIO's rules over the entry's IO, which the video owns.
Parameters
AArchive: the zip fileAEntry: the entry's path in itAPassword: the archive's password, "" for none
Returns: the video; ctxData nil when the archive or entry is missing or holds no MPEG-1 video
Example: LIntro := LoadVideoZip("$P:assets.zip", "res/assets/videos/intro.mpg", "");
See also: LoadVideoIO. Since: 0.2
UnloadVideo
routine UnloadVideo(const AVideo: Video);
Unloads a video: stopped, its textures, shader and audio stream freed, its own IO closed (LoadVideo / LoadVideoZip; LoadVideoIO's stays the caller's, to close after this). The status callback is not called. A video that did not load is left as it is.
Parameters
AVideo: the video
Example: UnloadVideo(LIntro); IOClose(LIO);
See also: LoadVideo. Since: 0.2
IsVideoValid
routine IsVideoValid(const AVideo: Video): bool;
Whether the video loaded: a load that found no MPEG-1 video (a missing file or entry, other data) gives a video whose ctxData is nil.
Parameters
AVideo: the video
Returns: true when the video loaded
Example: if not IsVideoValid(LIntro) then println("no intro"); end;
See also: LoadVideo. Since: 0.2
PlayVideo
routine PlayVideo(const AVideo: Video);
Plays the video: from where it was paused, or from its start when it is stopped. Its audio resumes with it. On a playing video it does nothing. The status callback is called with VideoPlaying when the status changed.
Parameters
AVideo: the video
Example: PlayVideo(LIntro);
See also: PauseVideo, UpdateVideo. Since: 0.2
PauseVideo
routine PauseVideo(const AVideo: Video);
Pauses a playing video where it is: its frame stays drawn, its audio pauses. On a video that is not playing it does nothing. The status callback is called with VideoPaused when the status changed.
Parameters
AVideo: the video
Example: if IsKeyPressed(KEY_SPACE) then PauseVideo(LIntro); end;
See also: PlayVideo. Since: 0.2
StopVideo
routine StopVideo(const AVideo: Video);
Stops the video back at its start: its audio stopped and emptied, no frame drawn until it plays again. On a stopped video it does nothing. The status callback is called with VideoStopped when the status changed.
Parameters
AVideo: the video
Example: StopVideo(LIntro);
See also: PlayVideo. Since: 0.2
UpdateVideo
routine UpdateVideo(const AVideo: Video);
Advances a playing video by the real time since its last update; call it once a frame. It decodes, uploads the newest frame (once a window is open) and feeds the audio. The end of a video that does not loop stops it at its start and calls the status callback with VideoStopped; a looping one starts again. A video that is not playing is left as it is.
Parameters
AVideo: the video
Example: UpdateVideo(LIntro); BeginDrawing(); DrawVideo(LIntro, 0, 0, WHITE); EndDrawing();
See also: DrawVideo. Since: 0.2
routine UpdateVideo(const AVideo: Video; const ASeconds: float64);
UpdateVideo by a given step instead of the real time, for a fixed time step or a frame-by-frame tool.
Parameters
AVideo: the videoASeconds: the time to advance, in seconds (0 or less: nothing decoded)
Example: UpdateVideo(LIntro, 1.0 / 60.0);
See also: GetVideoFrameRate. Since: 0.2
GetVideoStatus
routine GetVideoStatus(const AVideo: Video): VideoStatus;
The video's status.
Parameters
AVideo: the video
Returns: VideoStopped, VideoPlaying or VideoPaused; VideoStopped for a video that did not load
Example: if GetVideoStatus(LIntro) = VideoStatus.VideoPaused then PlayVideo(LIntro); end;
See also: VideoStatus. Since: 0.2
IsVideoPlaying
routine IsVideoPlaying(const AVideo: Video): bool;
Whether the video plays.
Parameters
AVideo: the video
Returns: true while its status is VideoPlaying
Example: while IsVideoPlaying(LIntro) and not WindowShouldClose() do ... end;
See also: GetVideoStatus. Since: 0.2
SetVideoLooping
routine SetVideoLooping(const AVideo: Video; const ALoop: bool);
Sets whether the video starts again at its end instead of stopping. A video loads not looping.
Parameters
AVideo: the videoALoop: true to loop
Example: SetVideoLooping(LBackground, true);
See also: IsVideoLooping. Since: 0.2
IsVideoLooping
routine IsVideoLooping(const AVideo: Video): bool;
Whether the video starts again at its end.
Parameters
AVideo: the video
Returns: true when it loops; false for a video that did not load
See also: SetVideoLooping. Since: 0.2
SetVideoVolume
routine SetVideoVolume(const AVideo: Video; const AVolume: float32);
Sets the video's volume as a level a person sets: 0 (silent) to 1 (full), clamped, NaN as 0. The audio stream gets the linear volume the level stands for (Math's PerceivedVolume), so equal steps sound equal. A video loads at volume 1.
Parameters
AVideo: the videoAVolume: the level, 0 .. 1
Example: SetVideoVolume(LIntro, 0.5);
See also: GetVideoVolume. Since: 0.2
GetVideoVolume
routine GetVideoVolume(const AVideo: Video): float32;
The video's volume level as set (after clamping), not the linear volume the stream plays at.
Parameters
AVideo: the video
Returns: the level, 0 .. 1; 0 for a video that did not load
See also: SetVideoVolume. Since: 0.2
SetVideoStatusCallback
routine SetVideoStatusCallback(const AVideo: Video; const ACallback: VideoStatusCallback);
Sets the routine called on every status change of the video, with the name the video was loaded under, replacing the one set before.
Parameters
AVideo: the videoACallback: the routine; nil for none
Example: SetVideoStatusCallback(LIntro, OnVideo);
See also: VideoStatusCallback. Since: 0.2
GetVideoFrameRate
routine GetVideoFrameRate(const AVideo: Video): float64;
The video's frame rate.
Parameters
AVideo: the video
Returns: frames a second; 0 for a video that did not load
Example: UpdateVideo(LIntro, 1.0 / GetVideoFrameRate(LIntro));
See also: GetVideoDuration. Since: 0.2
GetVideoDuration
routine GetVideoDuration(const AVideo: Video): float64;
The video's length: the last frame's start plus one frame.
Parameters
AVideo: the video
Returns: the length in seconds; 0 for a video that did not load
Example: LProgress := GetVideoTime(LIntro) / GetVideoDuration(LIntro);
See also: GetVideoTime. Since: 0.2
GetVideoTime
routine GetVideoTime(const AVideo: Video): float64;
Where the video is, from its start: 0 when it is stopped.
Parameters
AVideo: the video
Returns: the time in seconds; 0 for a video that did not load
See also: GetVideoDuration. Since: 0.2
HasVideoAudio
routine HasVideoAudio(const AVideo: Video): bool;
Whether the video has an MP2 audio track. A video with one plays it through raylib's audio device when that is ready (InitAudioDevice), else silently.
Parameters
AVideo: the video
Returns: true when it has an audio track; false for a video that did not load
See also: GetVideoSampleRate. Since: 0.2
GetVideoSampleRate
routine GetVideoSampleRate(const AVideo: Video): int32;
The audio track's sample rate.
Parameters
AVideo: the video
Returns: samples a second; 0 with no audio track or a video that did not load
See also: HasVideoAudio. Since: 0.2
IsVideoShaderUsed
routine IsVideoShaderUsed(const AVideo: Video): bool;
Whether the video's frames are drawn through its YCbCr shader on the GPU (else converted to RGBA on the CPU). It is decided at the first frame decoded with a window open: the shader when it loads.
Parameters
AVideo: the video
Returns: true when the shader draws it; false before that first frame and for a video that did not load
See also: DrawVideo. Since: 0.2
DrawVideo
routine DrawVideo(const AVideo: Video; const APosX: int32; const APosY: int32; const ATint: Color);
Draws the current frame at its own size with its top left at (APosX, APosY), as DrawTexture draws; call it between BeginDrawing and EndDrawing. Nothing is drawn before the first frame (a stopped video, one not updated yet) or for a video that did not load.
Parameters
AVideo: the videoAPosX: the left edge, in screen pixelsAPosY: the top edge, in screen pixelsATint: the colour the frame is multiplied by (WHITE: as decoded)
Example: DrawVideo(LIntro, 0, 0, WHITE);
See also: DrawVideoPro. Since: 0.2
DrawVideoPro
routine DrawVideoPro(const AVideo: Video; const ASource: Rectangle; const ADest: Rectangle; const AOrigin: ::Vector2; const ARotation: float32; const ATint: Color);
Draws part of the current frame placed, scaled and rotated, as DrawTexturePro draws. Nothing is drawn before the first frame or for a video that did not load.
Parameters
AVideo: the videoASource: the part of the frame, in the frame's pixels (0, 0, width, height: all of it)ADest: where it goes on the screen, and at what sizeAOrigin: the rotation centre, relative to ADest's top leftARotation: the rotation, in degreesATint: the colour the frame is multiplied by (WHITE: as decoded)
Example: DrawVideoPro(LIntro, LFrame, LScreen, LOrigin, 0.0f, WHITE);
See also: DrawVideo. Since: 0.2
InitFrameWindow
routine InitFrameWindow(const ABaseWidth: int32; const ABaseHeight: int32; const ATitle: ptr to const char): bool;
Opens the frame window: raylib's window at a base (virtual) size the program draws in, whatever the window's real size. It opens at the base size x the monitor's scale (DPI / 96), centred on the monitor's work area, resizable, and follows a DPI change (a move to another monitor). The DPI is the OS's, the same rule on every target: Windows the window's monitor, Linux X11's Xft.dpi (96 when the desktop sets none). Draw between BeginFrame and EndFrame in base units; on resize, maximize or fullscreen the frame is scaled with its aspect kept, bars outside it. SetConfigFlags before it still applies (vsync, MSAA, ...); FLAG_WINDOW_HIGHDPI is not needed, and when set raylib's own scaling is used instead (never both). CloseWindow closes the frame too (GetFrameWidth 0 again, the frame and bar colours kept), and a new frame window may then be opened.
Parameters
ABaseWidth: the frame's width in base units (more than 0)ABaseHeight: the frame's height in base units (more than 0)ATitle: the window's title
Returns: true when the window is open; false (no window) for a size of 0 or less, a window already open, or a window raylib could not make
Example: if not InitFrameWindow(800, 450, "Game") then return; end;
See also: BeginFrame. Since: 0.3
BeginFrame
routine BeginFrame();
Starts drawing the frame, inside BeginDrawing / EndDrawing: the window cleared with the bar colour, the letterbox fitted to the window's size now (a resize needs no call), drawing clipped to it and in base units (GetFrameCamera's Camera2D), the frame filled with its colour, and the mouse taken (GetFrameMousePosition). Does nothing with no frame window.
Example: BeginDrawing(); BeginFrame(); DrawCircle(400, 225, 50.0f, RED); EndFrame(); EndDrawing();
See also: EndFrame. Since: 0.3
EndFrame
routine EndFrame();
Ends drawing the frame: the camera and the clip set back, so drawing after it (a HUD in window units) covers the whole window.
Example: EndFrame(); DrawFPS(10, 10); EndDrawing();
See also: BeginFrame. Since: 0.3
BeginFrameMode2D
routine BeginFrameMode2D(const ACamera: Camera2D);
A Camera2D of the program's own inside the frame (a scrolling map, a zoom): ACamera is in base units (its offset too) and is drawn through the frame's letterbox. raylib's BeginMode2D replaces the frame's camera, so use this pair inside BeginFrame / EndFrame. With no frame window it is raylib's BeginMode2D.
Parameters
ACamera: the program's camera, in base units
Example: BeginFrameMode2D(LCamera); DrawTexture(LMap, 0, 0, WHITE); EndFrameMode2D();
See also: EndFrameMode2D. Since: 0.3
EndFrameMode2D
routine EndFrameMode2D();
Ends BeginFrameMode2D: drawing is in base units through the frame's own camera again. With no frame window it is raylib's EndMode2D.
Example: EndFrameMode2D(); DrawText("HUD", 10, 10, 20, WHITE);
See also: BeginFrameMode2D. Since: 0.3
BeginFrameMode3D
routine BeginFrameMode3D(const ACamera: Camera3D);
A Camera3D drawn through the frame's letterbox: the scene fills the letterbox at the base size's aspect, kept on resize, maximize and fullscreen, as the frame's 2D drawing is. raylib's BeginMode3D takes the whole window's aspect, so use this pair inside BeginFrame / EndFrame. With no frame window it is raylib's BeginMode3D.
Parameters
ACamera: the program's 3D camera
Example: BeginFrameMode3D(LCamera); DrawGrid(10, 1.0f); EndFrameMode3D();
See also: EndFrameMode3D. Since: 0.3
EndFrameMode3D
routine EndFrameMode3D();
Ends BeginFrameMode3D: drawing is in base units through the frame's own camera and clip again, as BeginFrame set them. With no frame window it is raylib's EndMode3D.
Example: EndFrameMode3D(); DrawText("HUD", 10, 10, 20, WHITE);
See also: BeginFrameMode3D. Since: 0.3
RestoreFrameClip
routine RestoreFrameClip();
Turns the frame's clip on again, as BeginFrame set it (drawing held to the letterbox): for code between BeginFrame and EndFrame that turned scissoring off or clipped elsewhere (raylib's EndScissorMode, a renderer such as rlImGui's). The camera is left as it is. Does nothing with no frame window.
Example: EndScissorMode(); RestoreFrameClip(); DrawText("clipped again", 10, 10, 20, WHITE);
See also: BeginFrame. Since: 0.3
GetFrameWidth
routine GetFrameWidth(): int32;
The frame's base width (InitFrameWindow's); 0 with no frame window.
Returns: the width in base units
Example: LWidth := GetFrameWidth();
See also: GetFrameHeight. Since: 0.3
GetFrameHeight
routine GetFrameHeight(): int32;
The frame's base height (InitFrameWindow's); 0 with no frame window.
Returns: the height in base units
Example: LHeight := GetFrameHeight();
See also: GetFrameWidth. Since: 0.3
GetFrameDpi
routine GetFrameDpi(): int32;
The monitor's DPI the frame window is sized for (96 = scale 1).
Returns: the DPI
Example: println(GetFrameDpi());
See also: GetFrameScale. Since: 0.3
GetFrameScale
routine GetFrameScale(): float32;
The monitor's scale the frame window is sized for: GetFrameDpi / 96.
Returns: the scale (1.0 at 96 DPI, 1.5 at 144)
Example: LScale := GetFrameScale();
See also: GetFrameDpi. Since: 0.3
GetWindowDpi
routine GetWindowDpi(): int32;
The DPI of raylib's window as the OS reports it now, frame window or not: the frame's own rule on every target (Windows the window's monitor, the system's with no window; Linux X11's Xft.dpi, 96 when the desktop sets none or there is no window). raylib's GetWindowScaleDPI reports 1.0 unless FLAG_WINDOW_HIGHDPI is set; this is the monitor's whatever the flags.
Returns: the DPI (96 = scale 1, 144 = scale 1.5)
Example: LScale := float32(GetWindowDpi()) / 96.0f;
See also: GetFrameDpi. Since: 0.3
GetFrameMousePosition
routine GetFrameMousePosition(): ::Vector2;
The mouse at BeginFrame, in base units, clamped to the frame (0 to the base size - 1) and rounded: the same point wherever the window's size.
Returns: the mouse position in the frame
Example: LMouse := GetFrameMousePosition();
See also: BeginFrame. Since: 0.3
GetFrameCamera
routine GetFrameCamera(): Camera2D;
The Camera2D BeginFrame draws through (its offset is the letterbox's top left, its zoom the window units per base unit): for GetScreenToWorld2D / GetWorldToScreen2D on other points.
Returns: the frame's camera as BeginFrame last set it
Example: LWorld := GetScreenToWorld2D(LTouch, GetFrameCamera());
See also: BeginFrame. Since: 0.3
SetFrameColor
routine SetFrameColor(const AColor: Color);
Sets the colour the frame is filled with at BeginFrame (WHITE by default).
Parameters
AColor: the colour
Example: SetFrameColor(RAYWHITE);
See also: SetFrameBarColor. Since: 0.3
GetFrameColor
routine GetFrameColor(): Color;
The colour the frame is filled with at BeginFrame.
Returns: the colour
Example: LColor := GetFrameColor();
See also: SetFrameColor. Since: 0.3
SetFrameBarColor
routine SetFrameBarColor(const AColor: Color);
Sets the colour of the bars around the frame (BLACK by default).
Parameters
AColor: the colour
Example: SetFrameBarColor(DARKGRAY);
See also: SetFrameColor. Since: 0.3
GetFrameBarColor
routine GetFrameBarColor(): Color;
The colour of the bars around the frame.
Returns: the colour
Example: LColor := GetFrameBarColor();
See also: SetFrameBarColor. Since: 0.3
ToggleFrameFullscreen
routine ToggleFrameFullscreen();
Toggles fullscreen: a borderless window over the whole monitor it is on (the context kept); toggled back, the window returns to its place and size. The frame keeps its aspect either way. Does nothing with no frame window.
Example: if IsKeyPressed(KEY_F11) then ToggleFrameFullscreen(); end;
See also: InitFrameWindow. Since: 0.3
GetLetterboxRect
routine GetLetterboxRect(const AWindowWidth: int32; const AWindowHeight: int32; const ABaseWidth: int32; const ABaseHeight: int32): Rectangle;
The letterbox rule itself, for any size (no window needed): the rectangle, in window units, that fits the base size's aspect into the window, centred, bars outside it. A size of 0 or less: the whole window.
Parameters
AWindowWidth: the window's widthAWindowHeight: the window's heightABaseWidth: the frame's base widthABaseHeight: the frame's base height
Returns: the frame's rectangle in the window
Example: LBox := GetLetterboxRect(1920, 1080, 800, 600);
See also: GetScaledFrameSize. Since: 0.3
GetScaledFrameSize
routine GetScaledFrameSize(const ABaseWidth: int32; const ABaseHeight: int32; const ADpi: int32): ::Vector2;
The DPI rule itself (no window needed): the window size InitFrameWindow opens for a base size at a DPI, each side base x DPI / 96, rounded.
Parameters
ABaseWidth: the frame's base widthABaseHeight: the frame's base heightADpi: the monitor's DPI
Returns: the window size (x = width, y = height)
Example: LSize := GetScaledFrameSize(800, 450, 144);
See also: GetLetterboxRect. Since: 0.3
GetFramePoint
routine GetFramePoint(const APoint: ::Vector2; const ALetterbox: Rectangle; const ABaseWidth: int32; const ABaseHeight: int32): ::Vector2;
The mouse rule itself (no window needed): a window point in base units through a letterbox (GetLetterboxRect's) of a base-size frame, clamped to the frame (0 to the base size - 1) and rounded.
Parameters
APoint: the point in window unitsALetterbox: the frame's rectangle in the windowABaseWidth: the frame's base widthABaseHeight: the frame's base height
Returns: the point in the frame; (0, 0) for an empty letterbox or base
Example: LAt := GetFramePoint(GetMousePosition(), LBox, 800, 600);
See also: GetFrameMousePosition. Since: 0.3
rlimgui_ext
The rlimgui_ext unit: import rlimgui_ext; runs Dear ImGui inside raylib_ext's frame window, at the frame's virtual resolution. BeginFrameImGui / EndFrameImGui take the place of rlImGuiBegin / rlImGuiEnd between BeginFrame and EndFrame: ImGui's display is the frame's base size, its mouse is the mouse in base units (no mouse while it is in the bars or the window has no focus), and what it draws is scaled and letterboxed with the frame on resize, maximize and fullscreen, its clip rectangles kept inside the frame. Its fonts are rasterized at the frame's real pixel density, so text stays sharp as the frame grows.
Import it with import rlimgui_ext;.
Routines
BeginFrameImGui
routine BeginFrameImGui();
Starts a Dear ImGui frame inside the frame window, in place of rlImGuiBegin: call it between BeginFrame and EndFrame (not inside BeginFrameMode2D), after rlImGuiSetup. ImGui's display is the frame's base size (GetFrameWidth x GetFrameHeight), its mouse is the mouse in base units (none while it is in the bars or the window has no focus), and its fonts are rasterized at the frame's real pixel density. The first call sets the default font's base size back from rlImGuiSetup's monitor scaling (the frame scales the window instead), unless the program set style.FontSizeBase itself. With no frame window open it is rlImGuiBegin.
Example: BeginFrame(); BeginFrameImGui(); ImGui::ShowDemoWindow(); EndFrameImGui(); EndFrame();
See also: EndFrameImGui. Since: 0.3
EndFrameImGui
routine EndFrameImGui();
Ends the Dear ImGui frame BeginFrameImGui started and draws it in the frame, in place of rlImGuiEnd: scaled and letterboxed with the frame, its clip rectangles kept inside it. Drawing after it is in base units again, clipped to the frame, until EndFrame. With no frame window open it is rlImGuiEnd.
Example: EndFrameImGui(); EndFrame(); EndDrawing();
See also: BeginFrameImGui. Since: 0.3
raven_raylib
The raven_raylib unit: import raven_raylib; puts a Raven user interface inside a raylib program. raylib keeps the window, the loop, audio and the game's drawing; Raven builds and lays out its widgets (the raven unit's API, XML windows and themes included) and draws them in the raylib frame, over the game.
Import it with import raven_raylib;.
Routines
InitRaven
routine InitRaven(const AAppName: ptr to const char): bool;
Starts Raven inside the raylib program, on this unit's rlgl backend: headless (no OS window of Raven's own), R_BACKEND_CUSTOM, its render thread off. Call it once after InitWindow or InitFrameWindow, then make the UI window with Rwindow_create (its size follows raylib's window, so any size will do) and its widgets with the raven unit's API.
Parameters
AAppName: the application's name, as RInitDesc.app_name
Returns: true when Raven is up; false when raylib has no window yet, Raven is already running, or Raven could not start (its error callback says why)
Example: InitWindow(800, 450, "Game"); if not InitRaven("Game") then return; end;
See also: UpdateRaven. Since: 0.3
UpdateRaven
routine UpdateRaven(const AWindow: Rid): bool;
Runs one Raven frame for AWindow, before BeginDrawing: the window takes raylib's window size (or the frame's base size inside the frame window) and its UI scale, then raylib's input this frame (keys with modifiers, mouse, wheel, typed text, the clipboard both ways), then Rdraw_frame lays out and paints what changed and runs Raven's callbacks, timers and tasks.
Parameters
AWindow: the UI window (Rwindow_create's)
Returns: false once Rquit was called, the last Raven window is closed, or Raven is not running (InitRaven not called, CloseRaven called)
Example: while not WindowShouldClose() and UpdateRaven(LUi) do ... end;
See also: DrawRaven. Since: 0.3
DrawRaven
routine DrawRaven(const AWindow: Rid);
Draws AWindow's last Raven frame over what the program drew, inside BeginDrawing / EndDrawing: in raylib's window units, or with the frame window open between BeginFrame and EndFrame (base units, scaled and letterboxed with the frame). It draws through whatever raylib has bound, so a render texture or a camera takes it too. Does nothing before the window's first UpdateRaven or with Raven not running.
Parameters
AWindow: the UI window (Rwindow_create's)
Example: BeginDrawing(); ClearBackground(BLACK); DrawGame(); DrawRaven(LUi); EndDrawing();
See also: UpdateRaven. Since: 0.3
CreateRavenTexture
routine CreateRavenTexture(const ATexture: Texture2D): Rid;
Makes a Raven texture that shows ATexture, a raylib texture (one the program loaded, or a render texture's .texture). Raven draws raylib's texture as it is in every frame, so what the program draws into a render texture shows at once in a Viewport (Rviewport_set_texture; a render texture is bottom-up: Rviewport_set_flip_y(viewport, R_TRUE)) or an Image. raylib keeps the texture: Raven never copies, updates, re-filters or unloads it, and Rtexture_update on the Raven texture does nothing. Before the program unloads ATexture, it points the Raven texture at its new one (SetRavenTexture) or destroys it (Rtexture_destroy, which leaves raylib's texture alone).
Parameters
ATexture: the raylib texture to show
Returns: the Raven texture; R_INVALID_ID when Raven is not running or ATexture is no texture (id 0, a size of 0)
Example: LRaven := CreateRavenTexture(LTarget.texture); Rviewport_set_texture(LView, LRaven);
See also: SetRavenTexture. Since: 0.3
SetRavenTexture
routine SetRavenTexture(const ARavenTexture: Rid; const ATexture: Texture2D): bool;
Points a Raven texture made by CreateRavenTexture at another raylib texture: after a render texture is made again at a new size, the Viewport or Image showing it keeps its Raven texture.
Parameters
ARavenTexture: CreateRavenTexture's Raven textureATexture: the raylib texture it shows from now on
Returns: true when done; false when Raven is not running, ATexture is no texture (id 0), or ARavenTexture is not a texture CreateRavenTexture made (one Raven made from its own pixels is never re-pointed)
Example: LTarget := LoadRenderTexture(LWidth, LHeight); SetRavenTexture(LRaven, LTarget.texture);
See also: CreateRavenTexture. Since: 0.3
CloseRaven
routine CloseRaven();
Ends Raven (Rshutdown): its windows, widgets, textures and the backend's GL objects are freed. Call it before CloseWindow; InitRaven may start it again after. Does nothing with Raven not running.
Example: CloseRaven(); CloseWindow();
See also: InitRaven. Since: 0.3
sfml_ext
import sfml_ext; adds the C++ namespace sfx to SFML 3 (import sfml; gives SFML itself, see Vendor libraries):
sfx::RenderWindow: ansf::RenderWindowwith DPI scaling, a letterbox frame, window states, draw helpers and the program's own icon on both targets.sfx::ZipStream: an entry of a .zip archive as ansf::InputStream.sfx::Video,sfx::Mixerandsfx::messageBox().- A default font built into the program:
sfx::openDefaultFont(). - SFML's error reports caught:
sfx::getLastError(),sfx::setErrorCallback(). sfx::toSf()/sfx::fromSf()between SFML's types andMath'sVector2/RectandConsole'sRgb.
The examples sfml\DefaultFont, ExtWindow, MessageBoxes, Mixer, VideoPlayer, ZipAssets and ZipPlayer in res\examples show it.
mojoal_ext
The mojoal_ext unit: import mojoal_ext; loads a sound file into an OpenAL buffer in one call, from a file, from any CustomIO IO, or from an entry of a zip archive. LoadSound, LoadSoundIO and LoadSoundZip decode Ogg Vorbis (stb_vorbis) to 16-bit samples and hand them to alBufferData: the result is an OpenAL buffer name, ready for alSourcei(LSource, AL_BUFFER, ALint(LBuffer)), and deleted with alDeleteBuffers like any other. With AMono the channels are averaged into one, which is what OpenAL places in 3D (a stereo buffer plays as it is, never positioned); without it a mono or stereo sound keeps its channels. A sound of more than two channels is always mixed to mono: OpenAL 1.1 has no format for it.
Import it with import mojoal_ext;.
Routines
LoadSound
routine LoadSound(const APath: string; const AMono: bool): ALuint;
Loads an Ogg Vorbis file into a new OpenAL buffer. An OpenAL context must be current.
Parameters
APath: the file ($P:and the other SysUtils.ResolvePath forms are resolved first)AMono: true: the channels are averaged into one, so the buffer can be placed in 3D; false: a mono or stereo sound keeps its channels
Returns: the buffer name; 0 when the file cannot be read or decoded, or OpenAL refuses the buffer
Example: LEngine := LoadSound("$P:../../res/assets/audio/sfx/engine_player.ogg", true);
See also: LoadSoundIO, LoadSoundZip. Since: 0.3
LoadSoundIO
routine LoadSoundIO(const AIO: IO; const AMono: bool): ALuint;
Loads an Ogg Vorbis stream from an IO into a new OpenAL buffer, as LoadSound loads a file (stb_vorbis reads the IO through the HookIO hooks). The IO is read from its start and stays the caller's. An OpenAL context must be current.
Parameters
AIO: the stream (CreateZipFileIO's, CreateFileIO's, any IO)AMono: true: the channels are averaged into one, for 3D
Returns: the buffer name; 0 when the IO is nil, cannot be read or does not decode, or OpenAL refuses the buffer
Example: LHit := LoadSoundIO(CreateZipFileIO("$P:assets.zip", "hit.ogg"), true);
See also: LoadSound. Since: 0.3
LoadSoundZip
routine LoadSoundZip(const AArchive: string; const AEntry: string; const APassword: string; const AMono: bool): ALuint;
Loads an Ogg Vorbis entry of a zip archive into a new OpenAL buffer (CreateZipFileIO opens the entry, LoadSoundIO decodes it, the entry's IO is closed after). An OpenAL context must be current.
Parameters
AArchive: the zip file ($P:resolved, as CreateZipFileIO does)AEntry: the entry's path in the archive,/separatedAPassword: the archive's password ("" for none)AMono: true: the channels are averaged into one, for 3D
Returns: the buffer name; 0 when the archive or entry cannot be opened (a wrong password included) or does not decode, or OpenAL refuses the buffer
Example: LEngine := LoadSoundZip("$P:../../assets.zip", "res/assets/audio/sfx/engine_player.ogg", "PaskalCPP", true);
See also: LoadSoundIO. Since: 0.3
routine LoadSoundZip(const AArchive: string; const AEntry: string; const AMono: bool): ALuint;
LoadSoundZip for an archive with no password.
Parameters
AArchive: the zip fileAEntry: the entry's path in the archiveAMono: true: the channels are averaged into one, for 3D
Returns: the buffer name; 0 on a failure, as LoadSoundZip
Since: 0.3
sqlite_ext
The sqlite_ext unit: import sqlite_ext; opens a SQLite database held in any CustomIO IO, or in an entry of a zip archive, read-only. SQLite opens files through its own VFS (the OS's open / read calls, not C's stdio), so the HookIO hooks never reach it: an io:// path given to sqlite3_open_v2 is a file that does not exist. These forms read the database's bytes from the IO into memory instead (sqlite3_malloc64) and hand them to sqlite3_deserialize on a fresh in-memory connection, with SQLITE_DESERIALIZE_READONLY and SQLITE_DESERIALIZE_FREEONCLOSE: every query works as on the file, a write fails with SQLITE_READONLY, and the memory is freed with the connection (sqlite3_close). The IO is read from its start and stays the caller's; it may be closed as soon as the call returns. A file on disk needs no form of its own: sqlite3_open_v2 with SQLITE_OPEN_READONLY is that.
Import it with import sqlite_ext;.
Routines
OpenDatabaseIO
routine OpenDatabaseIO(const AIO: IO; var ADb: ptr to sqlite3): int32;
Opens the SQLite database an IO holds, read-only, in memory: its bytes are read in and deserialized onto a new connection (writes fail with SQLITE_READONLY). The IO is read from its start and stays the caller's. Close the connection with sqlite3_close whatever the result.
Parameters
AIO: the database's bytes (CreateZipFileIO's, CreateFileIO's, any IO)ADb: the connection; nil only when SQLite had no memory for one
Returns: SQLITE_OK; SQLITE_IOERR when the IO is nil or cannot be read whole (the connection is open, empty, and sqlite3_errmsg has no text for this: the code is the answer); another code when SQLite refuses (sqlite3_errmsg(ADb) says why)
Example: LResult := OpenDatabaseIO(CreateFileIO("$P:levels.db", FileMode.Read), LDb);
See also: OpenDatabaseZip. Since: 0.3
OpenDatabaseZip
routine OpenDatabaseZip(const AArchive: string; const AEntry: string; const APassword: string; var ADb: ptr to sqlite3): int32;
Opens the SQLite database in an entry of a zip archive, read-only, in memory (CreateZipFileIO opens the entry, OpenDatabaseIO reads it, the entry's IO is closed after). Close the connection with sqlite3_close whatever the result.
Parameters
AArchive: the zip file ($P:resolved, as CreateZipFileIO does)AEntry: the entry's path in the archive,/separatedAPassword: the archive's password ("" for none)ADb: the connection; nil only when SQLite had no memory for one
Returns: SQLITE_OK; SQLITE_IOERR when the archive or entry cannot be opened (a wrong password included) or read; another code when SQLite refuses
Example: LResult := OpenDatabaseZip("$P:../../assets.zip", "res/assets/data/sample.db", "PaskalCPP", LDb);
See also: OpenDatabaseIO. Since: 0.3
routine OpenDatabaseZip(const AArchive: string; const AEntry: string; var ADb: ptr to sqlite3): int32;
OpenDatabaseZip for an archive with no password.
Parameters
AArchive: the zip fileAEntry: the entry's path in the archiveADb: the connection
Returns: as OpenDatabaseZip
Since: 0.3
tmxlite_ext
The tmxlite_ext unit: import tmxlite_ext; loads a Tiled map with the textures it draws from and draws it with raylib, in a few lines: LoadTiledMap(path, LMap), DrawTiledMap(LMap, x, y, WHITE) once a frame, UnloadTiledMap(LMap).
Import it with import tmxlite_ext;.
Types
TiledMapImage
TiledMapImage = record
One image a map draws from, loaded once however many tiles use it.
Members
Path: string: The image's path as tmxlite resolved it (a disk path, or the entry's path in the source)HasKey: bool: True when the tileset or image layer names a colour to make clearKeyColour: Color: That colour (Tiled's "transparent colour"); its alpha is ignoredTextureHandle: Texture2D: The texture, unloaded by UnloadTiledMap
See also: TiledMap. Since: 0.3
TiledMapTile
TiledMapTile = record
Where one global tile id's pixels are.
Members
ImageIndex: int32: Its image in TiledMap.Images; -1: the id draws nothingSource: Rectangle: Its pixels in that imageOffsetX: float32: Its tileset's tile offset to the right, in pixelsOffsetY: float32: Its tileset's tile offset down, in pixels
See also: TiledMap. Since: 0.3
TiledMap
TiledMap = record
A Tiled map, loaded with what it draws from: LoadTiledMap, LoadTiledMapIO or LoadTiledMapZip fill it, DrawTiledMap and DrawTiledLayer draw it, UnloadTiledMap frees its textures. It is used in place (a var or const parameter), never copied: tmxlite's map cannot be.
Members
Map: tmx::Map: The map as tmxlite read it: layers, objects, tilesets, propertiesImages: array of TiledMapImage: Every image the map draws fromTiles: array of TiledMapTile: Indexed by global tile id - 1
Example: LoadTiledMap("$P:../../res/assets/maps/overworld.tmx", LWorld); DrawTiledMap(LWorld, 0.0f, 0.0f, WHITE);
See also: LoadTiledMap. Since: 0.3
Routines
LoadTiledMap
routine LoadTiledMap(const APath: string; var AMap: TiledMap): bool;
Loads a Tiled map file with everything it draws from: its external tilesets and object templates (tmxlite), and every tileset and image layer image as a texture. Whatever AMap held is unloaded first. Needs a window (the textures).
Parameters
APath: the .tmx file ($P:and the other SysUtils.ResolvePath forms are resolved first); the files it names are read relative to itAMap: filled with the map
Returns: true when the map and every file it names were read; false, AMap empty, when one could not be read or decoded, or no texture could be made
Example: if not LoadTiledMap("$P:../../res/assets/maps/overworld.tmx", LWorld) then return; end;
See also: LoadTiledMapZip, UnloadTiledMap. Since: 0.3
LoadTiledMapIO
routine LoadTiledMapIO(const ASource: IOSource; const APath: string; var AMap: TiledMap): bool;
Loads a Tiled map from an IOSource, as LoadTiledMap loads one from a file: the map, its tilesets, templates and images are the source's entries, found relative to the map as Tiled wrote them ("../images/x.png" beside "maps/level.tmx" is "images/x.png"). tmxlite reads them through the HookIO hooks with ASource as this thread's path source for the call (SetIOThreadPathSource); the one the thread had is put back after, and other threads never see it. The source stays the caller's. Needs a window.
Parameters
ASource: the files (CreateZipIOSource's, CreateFolderIOSource's, any source)APath: the map's path in the source,/separatedAMap: filled with the map
Returns: true when the map and every file it names were read; false, AMap empty, when ASource is nil or one could not be read or decoded
Example: LoadTiledMapIO(CreateZipIOSource("$P:assets.zip"), "maps/level.tmx", LLevel);
See also: LoadTiledMap. Since: 0.3
LoadTiledMapZip
routine LoadTiledMapZip(const AArchive: string; const AEntry: string; const APassword: string; var AMap: TiledMap): bool;
Loads a Tiled map from an entry of a zip archive, with its tilesets, templates and images from the same archive (CreateZipIOSource opens it, LoadTiledMapIO loads the map, the archive is closed after: the textures are the map's own). Needs a window.
Parameters
AArchive: the zip file ($P:resolved, as CreateZipIOSource does)AEntry: the map's path in the archive,/separatedAPassword: the archive's password ("" for none)AMap: filled with the map
Returns: true when the map and every file it names were read; false, AMap empty, when the archive or an entry cannot be opened (a wrong password included), read or decoded
Example: LoadTiledMapZip("$P:../../assets.zip", "res/assets/maps/overworld.tmx", "PaskalCPP", LWorld);
See also: LoadTiledMapIO. Since: 0.3
routine LoadTiledMapZip(const AArchive: string; const AEntry: string; var AMap: TiledMap): bool;
LoadTiledMapZip for an archive with no password.
Parameters
AArchive: the zip fileAEntry: the map's path in the archiveAMap: filled with the map
Returns: true when the map and every file it names were read
Since: 0.3
UnloadTiledMap
routine UnloadTiledMap(var AMap: TiledMap);
Unloads a map's textures and empties it (a map that did not load, or was unloaded already, is fine). Needs the window that loaded it still open.
Parameters
AMap: the map
Example: UnloadTiledMap(LWorld);
See also: LoadTiledMap. Since: 0.3
IsTiledMapValid
routine IsTiledMapValid(const AMap: TiledMap): bool;
True when a map is loaded (a Load call succeeded and it was not unloaded since).
Parameters
AMap: the map
Returns: false for an empty map
Since: 0.3
DrawTiledMap
routine DrawTiledMap(const AMap: TiledMap; const APosX: float32; const APosY: float32; const ATint: Color);
Draws a map: every visible tile layer and image layer in the map's order, groups with their children (see the unit header for how each is placed, flipped, faded and tinted). Object layers are not drawn. Call it between BeginDrawing and EndDrawing (or inside BeginMode2D for a camera, BeginTextureMode for a render texture).
Parameters
AMap: the map; an empty one draws nothingAPosX: where the map's left edge goes, in pixelsAPosY: where the map's top edge goes, in pixelsATint: multiplied into every pixel (WHITE: as it is)
Example: DrawTiledMap(LWorld, 0.0f, 0.0f, WHITE);
See also: DrawTiledLayer. Since: 0.3
DrawTiledLayer
routine DrawTiledLayer(const AMap: TiledMap; const ALayer: int32; const APosX: float32; const APosY: float32; const ATint: Color);
Draws one top-level layer of a map as DrawTiledMap draws it, whether or not it is marked visible (a group's children still follow their own visibility): a layer kept hidden in Tiled (a collision layer) can still be drawn on demand, and the program can draw its own sprites between two layers.
Parameters
AMap: the mapALayer: the layer's index in AMap.Map.getLayers() (GetTiledLayerIndex finds it by name); out of range draws nothingAPosX: where the map's left edge goes, in pixelsAPosY: where the map's top edge goes, in pixelsATint: multiplied into every pixel
Example: DrawTiledLayer(LWorld, GetTiledLayerIndex(LWorld, "ground"), 0.0f, 0.0f, WHITE);
See also: DrawTiledMap. Since: 0.3
GetTiledLayerIndex
routine GetTiledLayerIndex(const AMap: TiledMap; const ALayerName: string): int32;
The index of a map's top-level layer by its name, for DrawTiledLayer and AMap.Map.getLayers().
Parameters
AMap: the mapALayerName: the layer's name in Tiled (case-sensitive)
Returns: the first layer of that name; -1 when there is none
Example: LGround := GetTiledLayerIndex(LWorld, "ground");
See also: DrawTiledLayer. Since: 0.3
GetTiledMapSize
routine GetTiledMapSize(const AMap: TiledMap): ::Vector2;
A map's size in pixels as Tiled gives it for its orientation: orthogonal tiles across times tile width (and down), isometric (across + down) half tiles each way, staggered and hexagonal by Tiled's own stagger rules. For an infinite map it is the size its width and height in tiles give.
Parameters
AMap: the map; an empty one is 0 x 0
Returns: the width (x) and height (y)
Example: LTarget := LoadRenderTexture(int32(GetTiledMapSize(LWorld).x), int32(GetTiledMapSize(LWorld).y));
See also: DrawTiledMap. Since: 0.3
ldtk_ext
The ldtk_ext unit: import ldtk_ext; loads an LDtk project with the textures its levels draw from and draws its levels with raylib, in a few lines: LoadLdtkProject(path, LProject), DrawLdtkLevel(LProject, "Level_0", x, y, WHITE) once a frame, UnloadLdtkProject(LProject).
Import it with import ldtk_ext;.
Types
LdtkImage
LdtkImage = record
One image a project draws from, loaded once however many tilesets name it.
Members
Path: string: The image's path as the project names it, joined to the project's folder (a disk path, or the entry's path in the source)TextureHandle: Texture2D: The texture, unloaded by UnloadLdtkProject
See also: LdtkProject. Since: 0.3
LdtkTileset
LdtkTileset = record
Which image one of the project's tilesets draws from.
Members
Uid: int32: The tileset's uid (ldtk::Tileset::uid)ImageIndex: int32: Its image in LdtkProject.Images
See also: LdtkProject. Since: 0.3
LdtkProject
LdtkProject = record
An LDtk project, loaded with what its levels draw from: LoadLdtkProject, LoadLdtkProjectIO or LoadLdtkProjectZip fill it, DrawLdtkLevel and DrawLdtkLayer draw its levels, UnloadLdtkProject frees its textures. It is used in place (a var or const parameter), never copied: LDtkLoader's project cannot be.
Members
Project: std::optional<ldtk::Project>: The project as LDtkLoader read it (Project.value()): worlds, levels, layers, entities, fields, tilesets; empty when nothing is loadedImages: array of LdtkImage: Every image the project draws fromTilesets: array of LdtkTileset: Every tileset that has an image, with that imageErrorMessage: string: Why the last load failed; "" after a load that succeeded
Example: LoadLdtkProject("$P:../../res/assets/maps/overworld.ldtk", LWorld); DrawLdtkLevel(LWorld, "Town", 0.0f, 0.0f, WHITE);
See also: LoadLdtkProject. Since: 0.3
Routines
LoadLdtkProject
routine LoadLdtkProject(const APath: string; var AProject: LdtkProject): bool;
Loads an LDtk project file with everything its levels draw from: the level files of a project that saves its levels separately (LDtkLoader), and every tileset image as a texture. Whatever AProject held is unloaded first. Needs a window (the textures).
Parameters
APath: the .ldtk file ($P:and the other SysUtils.ResolvePath forms are resolved first); the files it names are read relative to itAProject: filled with the project
Returns: true when the project and every file it names were read; false, AProject empty and the reason in AProject.ErrorMessage, when one could not be read, parsed or decoded, or no texture could be made
Example: if not LoadLdtkProject("$P:../../res/assets/maps/overworld.ldtk", LWorld) then println("{}", LWorld.ErrorMessage); end;
See also: LoadLdtkProjectZip, UnloadLdtkProject. Since: 0.3
LoadLdtkProjectIO
routine LoadLdtkProjectIO(const ASource: IOSource; const APath: string; var AProject: LdtkProject): bool;
Loads an LDtk project from an IOSource, as LoadLdtkProject loads one from a file: the project, its level files and its tileset images are the source's entries, found relative to the project as LDtk wrote them ("../tilesets/x.png" beside "maps/world.ldtk" is "tilesets/x.png"). LDtkLoader reads them through the HookIO hooks with ASource as this thread's path source for the call (SetIOThreadPathSource); the one the thread had is put back after, and other threads never see it. The source stays the caller's. Needs a window.
Parameters
ASource: the files (CreateZipIOSource's, CreateFolderIOSource's, any source)APath: the project's path in the source,/separatedAProject: filled with the project
Returns: true when the project and every file it names were read; false, AProject empty and the reason in AProject.ErrorMessage, when ASource is nil or one could not be read, parsed or decoded
Example: LoadLdtkProjectIO(CreateZipIOSource("$P:assets.zip"), "maps/world.ldtk", LWorld);
See also: LoadLdtkProject. Since: 0.3
LoadLdtkProjectZip
routine LoadLdtkProjectZip(const AArchive: string; const AEntry: string; const APassword: string; var AProject: LdtkProject): bool;
Loads an LDtk project from an entry of a zip archive, with its level files and tileset images from the same archive (CreateZipIOSource opens it, LoadLdtkProjectIO loads the project, the archive is closed after: the textures are the project's own). Needs a window.
Parameters
AArchive: the zip file ($P:resolved, as CreateZipIOSource does)AEntry: the project's path in the archive,/separatedAPassword: the archive's password ("" for none)AProject: filled with the project
Returns: true when the project and every file it names were read; false, AProject empty and the reason in AProject.ErrorMessage, when the archive or an entry cannot be opened (a wrong password included), read, parsed or decoded
Example: LoadLdtkProjectZip("$P:../../assets.zip", "res/assets/maps/overworld.ldtk", "PaskalCPP", LWorld);
See also: LoadLdtkProjectIO. Since: 0.3
routine LoadLdtkProjectZip(const AArchive: string; const AEntry: string; var AProject: LdtkProject): bool;
LoadLdtkProjectZip for an archive with no password.
Parameters
AArchive: the zip fileAEntry: the project's path in the archiveAProject: filled with the project
Returns: true when the project and every file it names were read
Since: 0.3
UnloadLdtkProject
routine UnloadLdtkProject(var AProject: LdtkProject);
Unloads a project's textures and empties it (a project that did not load, or was unloaded already, is fine). Needs the window that loaded it still open.
Parameters
AProject: the project
Example: UnloadLdtkProject(LWorld);
See also: LoadLdtkProject. Since: 0.3
IsLdtkProjectValid
routine IsLdtkProjectValid(const AProject: LdtkProject): bool;
True when a project is loaded (a Load call succeeded and it was not unloaded since).
Parameters
AProject: the project
Returns: false for an empty project
Since: 0.3
FindLdtkLevel
routine FindLdtkLevel(const AProject: LdtkProject; const ALevelName: string): ptr to const ldtk::Level;
A level of a project by its name, in any of its worlds: LDtkLoader's getLevel without the exception for a name that is not there.
Parameters
AProject: the projectALevelName: the level's identifier in LDtk (case-sensitive)
Returns: the level; nil when there is none, or the project is empty
Example: LLevel := FindLdtkLevel(LWorld, "Town"); if LLevel <> nil then println("{}", LLevel^.size.x); end;
See also: FindLdtkLayer. Since: 0.3
FindLdtkLayer
routine FindLdtkLayer(const ALevel: ptr to const ldtk::Level; const ALayerName: string): ptr to const ldtk::Layer;
A layer of a level by its name: LDtkLoader's getLayer without the exception for a name that is not there.
Parameters
ALevel: the level (FindLdtkLevel's); nil gives nilALayerName: the layer's identifier in LDtk (case-sensitive)
Returns: the layer; nil when there is none
Example: LObjects := FindLdtkLayer(FindLdtkLevel(LWorld, "Town"), "Entities");
See also: FindLdtkLevel. Since: 0.3
DrawLdtkLevel
routine DrawLdtkLevel(const AProject: LdtkProject; const ALevelName: string; const APosX: float32; const APosY: float32; const ATint: Color);
Draws a level: every visible layer that has tiles, bottom layer first (see the unit header for how each tile is placed, mirrored and faded). Entity layers are not drawn. Call it between BeginDrawing and EndDrawing (or inside BeginMode2D for a camera, BeginTextureMode for a render texture).
Parameters
AProject: the projectALevelName: the level's identifier; a name the project does not have draws nothingAPosX: where the level's left edge goes, in pixelsAPosY: where the level's top edge goes, in pixelsATint: multiplied into every pixel (WHITE: as it is)
Example: DrawLdtkLevel(LWorld, "Town", 0.0f, 0.0f, WHITE);
See also: DrawLdtkLayer. Since: 0.3
DrawLdtkLayer
routine DrawLdtkLayer(const AProject: LdtkProject; const ALevelName: string; const ALayerName: string; const APosX: float32; const APosY: float32; const ATint: Color);
Draws one layer of a level as DrawLdtkLevel draws it, whether or not it is marked visible: a layer kept hidden in LDtk can still be drawn on demand, and the program can draw its own sprites between two layers.
Parameters
AProject: the projectALevelName: the level's identifierALayerName: the layer's identifier; a name the level does not have draws nothingAPosX: where the level's left edge goes, in pixelsAPosY: where the level's top edge goes, in pixelsATint: multiplied into every pixel
Example: DrawLdtkLayer(LWorld, "Town", "Ground", 0.0f, 0.0f, WHITE);
See also: DrawLdtkLevel. Since: 0.3
GetLdtkLevelSize
routine GetLdtkLevelSize(const AProject: LdtkProject; const ALevelName: string): ::Vector2;
A level's size in pixels (LDtk's level width and height).
Parameters
AProject: the projectALevelName: the level's identifier
Returns: the width (x) and height (y); 0 x 0 when the project has no level of that name
Example: LTarget := LoadRenderTexture(int32(GetLdtkLevelSize(LWorld, "Town").x), int32(GetLdtkLevelSize(LWorld, "Town").y));
See also: DrawLdtkLevel. Since: 0.3
mir_ext
The mir_ext unit: import mir_ext; puts MIR's C boundary behind PaskalCPP routines, so a program using MIR (the mir unit) writes no C++ of its own. A context: MirNew() (MIR_init, MIR_gen_init and this unit's error handler), MirFree(). MIR's errors never end the program inside these routines: a routine that hits one returns nil / false and MirLastError() gives MIR's message; that context is then spent (MIR leaves it half built): make a fresh one. Modules: MirLoadModuleText (MIR's text form), C2MirCompileString / IO / File / Zip (C11 through c2mir), MirReadIO / File / Zip (MIR's binary form) each load what they bring in and return its last module; MirWriteIO / File write every module of a context in the binary form. The Zip forms read one entry of a zip archive (CustomIO's CreateZipFileIO: password, $P: paths), so a program ships its C or .bmir in bin\assets.zip. Hosts and calls: MirLoadHost registers a routine clink of 0 to 3 int64 parameters for JIT'd code to import (MIR_load_external), MirLoadStdC the C runtime routines c2mir's code imports (memcpy, memset, memmove); MirLink links every loaded module (MirLinkMode: lazy, eager, lazy per basic block, or MIR's interpreter); MirFuncItem / MirFuncAddr find a function by name (mir.h's MIR_get_global_item is declared but not defined in v1.0.0: PaskalCPP-Libs src\mir\FIXES.md, B); MirCall calls a function address with 0 to 3 int64 arguments. MirLastModule is the newest module of a context. Building: inside MIR_new_module, MirNewFunc starts a function of int64s (0 to 3 parameters), MirEmit / MirEmitRet / MirEmitLabel append its code, MirFinishFunc and MirFinishModule end and check them (the module loaded). MirPrintModule prints a module in MIR's text form. Rules from research\mir\findings.md: a host routine must not let a C++ exception escape into JIT'd code; MIR's error callback leaves by longjmp (_setjmp(buf, NULL) on Windows: no unwinding over MIR's frames).
Import it with import mir_ext;.
Types
MirLinkMode
MirLinkMode = choices(Lazy, Eager, LazyBB, Interp);
How MirLink makes a function's code: Lazy generates each function on its first call, Eager every function at link, LazyBB each basic block when it is first reached, Interp runs MIR's interpreter (no native code: the fallback where JIT is not allowed). A function address calls the same way in every mode.
See also: MirLink. Since: 0.3
MirHost0
MirHost0 = routine clink(): int64;
A host routine JIT'd code may import, taking no argument.
See also: MirLoadHost. Since: 0.3
MirHost1
MirHost1 = routine clink(AA: int64): int64;
A host routine JIT'd code may import, taking one int64.
See also: MirLoadHost. Since: 0.3
MirHost2
MirHost2 = routine clink(AA: int64; AB: int64): int64;
A host routine JIT'd code may import, taking two int64s.
See also: MirLoadHost. Since: 0.3
MirHost3
MirHost3 = routine clink(AA: int64; AB: int64; AC: int64): int64;
A host routine JIT'd code may import, taking three int64s.
See also: MirLoadHost. Since: 0.3
Routines
MirNew
routine MirNew(): MIR_context_t;
A fresh MIR context: MIR_init, this unit's error handler (a MIR error inside a mir_ext routine makes it fail, MirLastError says why) and the native generator ready (MIR_gen_init).
Returns: the context; end it with MirFree
Example: LCtx := MirNew(); ... MirFree(LCtx);
See also: MirFree. Since: 0.3
MirFree
routine MirFree(const ACtx: MIR_context_t);
Ends a context made by MirNew (MIR_gen_finish, MIR_finish); every function address taken from it is invalid afterwards. nil does nothing.
Parameters
ACtx: the context
Example: MirFree(LCtx);
See also: MirNew. Since: 0.3
MirLastError
routine MirLastError(): string;
MIR's message for the last mir_ext routine that failed on this thread ("" when the last one succeeded). After a MIR error the context is spent (MIR leaves it half built): use a fresh one.
Returns: the message
Example: if LModule = nil then println("MIR: {}", MirLastError()); end;
Since: 0.3
MirLastModule
routine MirLastModule(const ACtx: MIR_context_t): MIR_module_t;
The newest module of a context (the last one scanned, read, compiled or built), or nil when it has none.
Parameters
ACtx: the context
Returns: the module, or nil
Since: 0.3
MirLoadModuleText
routine MirLoadModuleText(const ACtx: MIR_context_t; const AText: string): MIR_module_t;
Scans MIR's text form (MIR_scan_string) and loads every module it holds. Register the hosts its code imports (MirLoadHost) before MirLink.
Parameters
ACtx: the contextAText: the module(s) in MIR's text form
Returns: the last module loaded, or nil on a MIR error (a syntax error, no module in the text: MirLastError says which)
Example: LModule := MirLoadModuleText(LCtx, CSource);
See also: MirLink. Since: 0.3
MirLoadHost
routine MirLoadHost(const ACtx: MIR_context_t; const AName: string; const AHost: MirHost0);
Registers a host routine taking no argument under AName, for JIT'd code that imports it (MIR_load_external). It must not let a C++ exception escape: nothing unwinds through JIT'd code.
Parameters
ACtx: the contextAName: the name the code importsAHost: the routine
Example: MirLoadHost(LCtx, "tick", Tick);
See also: MirLink. Since: 0.3
routine MirLoadHost(const ACtx: MIR_context_t; const AName: string; const AHost: MirHost1);
Registers a host routine taking one int64 (see the no-argument form).
Parameters
ACtx: the contextAName: the name the code importsAHost: the routine
Example: MirLoadHost(LCtx, "square", Square);
See also: MirLoadHost. Since: 0.3
routine MirLoadHost(const ACtx: MIR_context_t; const AName: string; const AHost: MirHost2);
Registers a host routine taking two int64s (see the no-argument form).
Parameters
ACtx: the contextAName: the name the code importsAHost: the routine
Example: MirLoadHost(LCtx, "host_mul", HostMul);
See also: MirLoadHost. Since: 0.3
routine MirLoadHost(const ACtx: MIR_context_t; const AName: string; const AHost: MirHost3);
Registers a host routine taking three int64s (see the no-argument form).
Parameters
ACtx: the contextAName: the name the code importsAHost: the routine
Example: MirLoadHost(LCtx, "clamp", Clamp);
See also: MirLoadHost. Since: 0.3
MirLoadStdC
routine MirLoadStdC(const ACtx: MIR_context_t);
Registers the C runtime routines c2mir's code imports: memcpy, memset and memmove (struct copies and clears are lowered to them). Call it before MirLink for code from C.
Parameters
ACtx: the context
Example: MirLoadStdC(LCtx);
See also: C2MirCompileString. Since: 0.3
MirLink
routine MirLink(const ACtx: MIR_context_t; const AMode: MirLinkMode): bool;
Links every loaded module (MIR_link): imports are resolved to the hosts registered, and code is made the way AMode says.
Parameters
ACtx: the contextAMode: lazy, eager, per basic block or the interpreter
Returns: true when linked; false on a MIR error (an import with no host registered: MirLastError says which)
Example: if not MirLink(LCtx, MirLinkMode.Eager) then ... end;
See also: MirLinkMode, MirFuncAddr. Since: 0.3
MirFuncItem
routine MirFuncItem(const ACtx: MIR_context_t; const AModule: MIR_module_t; const AName: string): MIR_item_t;
A function of a module by name (the item MIR_interp or MIR_output_item take), or nil.
Parameters
ACtx: the contextAModule: the moduleAName: the function's name
Returns: the item, or nil when the module has no function AName
See also: MirFuncAddr. Since: 0.3
MirFuncAddr
routine MirFuncAddr(const ACtx: MIR_context_t; const AModule: MIR_module_t; const AName: string): ptr;
The address to call a function of a module at (after MirLink), or nil.
Parameters
ACtx: the contextAModule: the moduleAName: the function's name
Returns: the address, or nil when the module has no function AName
Example: LSum := MirFuncAddr(LCtx, LModule, "sum");
See also: MirCall. Since: 0.3
MirCall
routine MirCall(const AAddress: ptr): int64;
Calls a function taking no argument and returning an int64.
Parameters
AAddress: the function's address (MirFuncAddr, not nil)
Returns: its result
See also: MirFuncAddr. Since: 0.3
routine MirCall(const AAddress: ptr; const AA: int64): int64;
Calls a function taking one int64 and returning an int64.
Parameters
AAddress: the function's address (MirFuncAddr, not nil)AA: the argument
Returns: its result
Example: println("{}", MirCall(LSum, 1000));
See also: MirFuncAddr. Since: 0.3
routine MirCall(const AAddress: ptr; const AA: int64; const AB: int64): int64;
Calls a function taking two int64s and returning an int64.
Parameters
AAddress: the function's address (MirFuncAddr, not nil)AA: the first argumentAB: the second argument
Returns: its result
See also: MirFuncAddr. Since: 0.3
routine MirCall(const AAddress: ptr; const AA: int64; const AB: int64; const AC: int64): int64;
Calls a function taking three int64s and returning an int64.
Parameters
AAddress: the function's address (MirFuncAddr, not nil)AA: the first argumentAB: the second argumentAC: the third argument
Returns: its result
See also: MirFuncAddr. Since: 0.3
C2MirCompileString
routine C2MirCompileString(const ACtx: MIR_context_t; const ASource: string; const AName: string): MIR_module_t;
Compiles C11 source with c2mir and loads its module. When the C does not compile, c2mir's messages (each with the source's name, line and column) are MirLastError's text and nothing reaches stderr; the warnings of a compile that succeeds go to stderr. Register MirLoadStdC (and any host the C calls) before MirLink.
Parameters
ACtx: the contextASource: the C sourceAName: the source's name in c2mir's messages
Returns: the module, or nil when the C does not compile or on a MIR error (MirLastError says why)
Example: LModule := C2MirCompileString(LCtx, "long long sq (long long x) { return x * x; }", "sq.c");
See also: C2MirCompileFile. Since: 0.3
C2MirCompileIO
routine C2MirCompileIO(const ACtx: MIR_context_t; const AIO: IO; const AName: string): MIR_module_t;
C2MirCompileString over the bytes of a stream, read to its end.
Parameters
ACtx: the contextAIO: the C source's stream (the caller's: not closed)AName: the source's name in c2mir's messages
Returns: the module, or nil (the stream cannot be read, the C does not compile, a MIR error)
See also: C2MirCompileString. Since: 0.3
C2MirCompileFile
routine C2MirCompileFile(const ACtx: MIR_context_t; const APath: string): MIR_module_t;
C2MirCompileString over a C file (UTF-8 path, $P: / $D: as CreateFileIO resolves them); the path is its name in c2mir's messages.
Parameters
ACtx: the contextAPath: the C file
Returns: the module, or nil (a missing file, the C does not compile, a MIR error)
Example: LModule := C2MirCompileFile(LCtx, "$P:square.c");
See also: C2MirCompileString. Since: 0.3
C2MirCompileZip
routine C2MirCompileZip(const ACtx: MIR_context_t; const AArchive: string; const AEntry: string; const APassword: string): MIR_module_t;
C2MirCompileString over one entry of a zip archive (CreateZipFileIO: $P: paths, ZipCrypto passwords); the entry is its name in c2mir's messages.
Parameters
ACtx: the contextAArchive: the zip fileAEntry: the C source's entryAPassword: the entry's password ("" for none)
Returns: the module, or nil (no such entry, a wrong password, the C does not compile, a MIR error)
Example: LModule := C2MirCompileZip(LCtx, "$P:assets.zip", "res/assets/scripts/mir/square.c", "PaskalCPP");
See also: C2MirCompileString. Since: 0.3
MirWriteIO
routine MirWriteIO(const ACtx: MIR_context_t; const AIO: IO): bool;
Writes every module of the context in MIR's binary form (MIR_write_with_func) to a stream.
Parameters
ACtx: the contextAIO: where the bytes go (the caller's: not closed)
Returns: true when written; false on a MIR error or a short write
See also: MirReadIO. Since: 0.3
MirWriteFile
routine MirWriteFile(const ACtx: MIR_context_t; const APath: string): bool;
MirWriteIO into a file (created or emptied; UTF-8 path, $P: / $D:). The binary form belongs to the MIR the program links: it is read back by the same MIR version.
Parameters
ACtx: the contextAPath: the file (.bmir by custom)
Returns: true when written
Example: MirWriteFile(LCtx, "$P:demo.bmir");
See also: MirReadFile. Since: 0.3
MirReadIO
routine MirReadIO(const ACtx: MIR_context_t; const AIO: IO): MIR_module_t;
Reads MIR's binary form from a stream to its end (MIR_read_with_func) and loads every module it holds.
Parameters
ACtx: the contextAIO: the binary form's stream (the caller's: not closed)
Returns: the last module loaded, or nil (the stream cannot be read, a cut or foreign binary: a MIR error)
See also: MirWriteIO. Since: 0.3
MirReadFile
routine MirReadFile(const ACtx: MIR_context_t; const APath: string): MIR_module_t;
MirReadIO from a file (UTF-8 path, $P: / $D:).
Parameters
ACtx: the contextAPath: the file
Returns: the last module loaded, or nil (a missing file, a bad binary)
Example: LModule := MirReadFile(LCtx, "$P:demo.bmir");
See also: MirWriteFile. Since: 0.3
MirReadZip
routine MirReadZip(const ACtx: MIR_context_t; const AArchive: string; const AEntry: string; const APassword: string): MIR_module_t;
MirReadIO from one entry of a zip archive (CreateZipFileIO: $P: paths, ZipCrypto passwords).
Parameters
ACtx: the contextAArchive: the zip fileAEntry: the binary form's entryAPassword: the entry's password ("" for none)
Returns: the last module loaded, or nil (no such entry, a wrong password, a bad binary)
Example: LModule := MirReadZip(LCtx, "$P:assets.zip", "res/assets/data/mir/demo.bmir", "PaskalCPP");
See also: MirReadFile. Since: 0.3
MirNewFunc
routine MirNewFunc(const ACtx: MIR_context_t; const AName: string): MIR_item_t;
Starts a function of int64s inside the module being built (MIR_new_module ... MirFinishModule): one int64 result, no parameter. Its locals come from MIR_new_func_reg, its code from MirEmit / MirEmitRet / MirEmitLabel, and MirFinishFunc ends it.
Parameters
ACtx: the contextAName: the function's name
Returns: the function's item
Example: LFunc := MirNewFunc(LCtx, "answer");
See also: MirFinishFunc. Since: 0.3
routine MirNewFunc(const ACtx: MIR_context_t; const AName: string; const AA: string): MIR_item_t;
Starts a function of int64s with one int64 parameter (see the no-parameter form); the parameter's register is MIR_reg(ACtx, AA, ...).
Parameters
ACtx: the contextAName: the function's nameAA: the parameter's name
Returns: the function's item
Example: LFunc := MirNewFunc(LCtx, "sum_to", "n");
See also: MirNewFunc. Since: 0.3
routine MirNewFunc(const ACtx: MIR_context_t; const AName: string; const AA: string; const AB: string): MIR_item_t;
Starts a function of int64s with two int64 parameters (see the no-parameter form).
Parameters
ACtx: the contextAName: the function's nameAA: the first parameter's nameAB: the second parameter's name
Returns: the function's item
See also: MirNewFunc. Since: 0.3
routine MirNewFunc(const ACtx: MIR_context_t; const AName: string; const AA: string; const AB: string; const AC: string): MIR_item_t;
Starts a function of int64s with three int64 parameters (see the no-parameter form).
Parameters
ACtx: the contextAName: the function's nameAA: the first parameter's nameAB: the second parameter's nameAC: the third parameter's name
Returns: the function's item
See also: MirNewFunc. Since: 0.3
MirEmit
routine MirEmit(const ACtx: MIR_context_t; const AFunc: MIR_item_t; const ACode: MIR_insn_code_t; const AA: MIR_op_t);
Appends an instruction of one operand to a function (MIR_new_insn_arr, MIR_append_insn): MIR_JMP label. MIR checks the operands when the function is finished (MirFinishFunc).
Parameters
ACtx: the contextAFunc: the function (MirNewFunc's item)ACode: the instruction (MIR_JMP, ...)AA: its operand
Example: MirEmit(LCtx, LFunc, MIR_JMP, MIR_new_label_op(LCtx, LLoop));
See also: MirFinishFunc. Since: 0.3
routine MirEmit(const ACtx: MIR_context_t; const AFunc: MIR_item_t; const ACode: MIR_insn_code_t; const AA: MIR_op_t; const AB: MIR_op_t);
Appends an instruction of two operands: MIR_MOV dest, src, MIR_NEG dest, src.
Parameters
ACtx: the contextAFunc: the functionACode: the instructionAA: its first operandAB: its second operand
See also: MirEmit. Since: 0.3
routine MirEmit(const ACtx: MIR_context_t; const AFunc: MIR_item_t; const ACode: MIR_insn_code_t; const AA: MIR_op_t; const AB: MIR_op_t; const AC: MIR_op_t);
Appends an instruction of three operands: MIR_ADD dest, a, b, MIR_BGE label, a, b.
Parameters
ACtx: the contextAFunc: the functionACode: the instructionAA: its first operandAB: its second operandAC: its third operand
See also: MirEmit. Since: 0.3
MirEmitRet
routine MirEmitRet(const ACtx: MIR_context_t; const AFunc: MIR_item_t; const AValue: MIR_op_t);
Appends a return of one value (MIR_new_ret_insn).
Parameters
ACtx: the contextAFunc: the functionAValue: the value returned
See also: MirEmit. Since: 0.3
MirEmitLabel
routine MirEmitLabel(const ACtx: MIR_context_t; const AFunc: MIR_item_t; const ALabel: MIR_label_t);
Places a label (MIR_new_label's) at the end of a function's code.
Parameters
ACtx: the contextAFunc: the functionALabel: the label
See also: MirEmit. Since: 0.3
MirFinishFunc
routine MirFinishFunc(const ACtx: MIR_context_t): bool;
Ends the function being built (MIR_finish_func), which checks it.
Parameters
ACtx: the context
Returns: true when the function is sound; false on a MIR error (a wrong operand count, an undeclared register: MirLastError says which)
See also: MirNewFunc. Since: 0.3
MirFinishModule
routine MirFinishModule(const ACtx: MIR_context_t): MIR_module_t;
Ends the module being built (MIR_finish_module) and loads it.
Parameters
ACtx: the context
Returns: the module, or nil on a MIR error
Example: LModule := MirFinishModule(LCtx);
See also: MirLink. Since: 0.3
MirPrintModule
routine MirPrintModule(const ACtx: MIR_context_t; const AModule: MIR_module_t);
Prints a module in MIR's text form (MIR_output_module) to the program's standard output, in order with its own printed lines.
Parameters
ACtx: the contextAModule: the module (nil prints nothing)
See also: MirLoadModuleText. Since: 0.3