Skip to content
PaskalCPP
Libraries

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.

UnitWhat it gives
SysUtilspaths (ResolvePath, ExeDir), files and folders (FileExists, DeleteFile, CreateDir, RemoveDir), Delay, Halt, byte sizes, FormatStr
Mathconstants, Sin / Cos / Sqrt / Abs, rounding (Round, Trunc, Floor, Ceil), Min / Max, clamping and easing, perceived volume, random numbers, 2D geometry
Diagnosticsa Stopwatch (Delphi's TStopwatch: StartNew, ElapsedMilliseconds, ...) on a monotonic clock
Consoleterminal output with colours and cursor control, text measured in columns
ResDatadata a build adds with @addresdata, read back by key
CustomIOstreams behind a table of callbacks: memory, files, folders, zip archives read and written (ZipDirectoryContents)
HookIOC fopen and the stdio family on CustomIO streams, inside C libraries too
HookABIhooks of C ABI functions, at link time and at run time
raylib_extraylib'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_extDear ImGui inside the frame window, at its virtual resolution (BeginFrameImGui, EndFrameImGui)
raven_raylibRaven's user interfaces inside a raylib program, the frame window included, and raylib textures shown in Raven widgets (InitRaven, UpdateRaven, DrawRaven, CreateRavenTexture)
sfml_extSFML 3 additions: a DPI-scaling window, zip streams, video, a mixer, message boxes
mojoal_extan Ogg Vorbis sound into an OpenAL buffer from a path, any IO or a zip entry (LoadSound, LoadSoundIO, LoadSoundZip)
sqlite_exta read-only SQLite database opened from any IO or a zip entry (OpenDatabaseIO, OpenDatabaseZip)
tmxlite_exta Tiled .tmx map loaded with its tilesets and images from a path, an IO source or a zip, drawn with raylib (LoadTiledMap, DrawTiledMap)
ldtk_extan 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_extMIR 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

NameDeclarationDescription
Kilobyte: int64 = 1024The bytes in a kilobyte (1024, binary): 4 * Kilobyte is 4096. See Megabyte.
Megabyte: int64 = 1024 * 1024The bytes in a megabyte (1024 x 1024, binary). See Gigabyte.
Gigabyte: int64 = 1024 * 1024 * 1024The bytes in a gigabyte (1024 x 1024 x 1024, binary). Example: if LSize > 2 * Gigabyte then ... end;

Routines

ResolvePath

text
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

text
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 ABaseDir
  • ABaseDir: 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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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() true
  • SeedValue: uint32: The seed the sequence started from, as Seed() returns it
  • init(): A generator seeded from the system's entropy source. See Randomize.
  • init(const ASeed: uint32): A generator that gives the sequence of ASeed. Parameters: ASeed the seed.
  • method SetSeed(const ASeed: uint32): Starts the sequence of ASeed again. Parameters: ASeed the seed.
  • const method Seed(): uint32: The seed the sequence started from (the last one set). Returns: the seed
  • method 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(); See SetSeed, Seed, SetRandomSeed.
  • method NextInt(const AMin: int32; const AMax: int32): int32: A whole number from AMin to AMax, both included. Parameters: AMin one end; AMax the other end. Returns: the number
  • method NextInt64(const AMin: int64; const AMax: int64): int64: NextInt for int64 bounds (a method name has one form per object). Parameters: AMin one end; AMax the other end. Returns: the number
  • method NextFloat(const AMin: float64; const AMax: float64): float64: A number from AMin (included) to AMax (left out); equal bounds give AMin. Parameters: AMin the low end, included; AMax the high end, left out. Returns: the number
  • method NextFloat32(const AMin: float32; const AMax: float32): float32: NextFloat for float32 bounds: AMin (included) to AMax (left out). Parameters: AMin the low end, included; AMax the high end, left out. Returns: the number
  • method 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

text
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: AX the X part; AY the Y part.
  • const method Length(): float32: Its length. Returns: the length
  • const method LengthSquared(): float32: Its length squared (no square root: for comparing lengths). Returns: the length squared
  • const method Distance(const AOther: Vector2): float32: The distance between this point and AOther. Parameters: AOther the other point. Returns: the distance
  • const method Dot(const AOther: Vector2): float32: The dot product with AOther. Parameters: AOther the other vector. Returns: X x AOther.X + Y x AOther.Y
  • const 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: AOther the other vector. Returns: X x AOther.Y - Y x AOther.X
  • const method Normalized(): Vector2: The same direction at length 1; a zero vector stays zero. Returns: the unit vector
  • const 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: AMax the longest length. Returns: the vector, at most AMax long
  • const 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: AOnto the vector projected onto. Returns: the projection
  • const method Perpendicular(): Vector2: The vector turned 90 degrees the way the angles grow: (-Y, X), as SFML. Returns: the perpendicular vector
  • const method Rotated(const ADegrees: float32): Vector2: The vector turned by ADegrees (positive turns the way the angles grow); computed in float64. Parameters: ADegrees the turn, in degrees. Returns: the turned vector
  • const 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 degrees
  • const 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: ADegrees the heading, in degrees; ASpeed the distance moved. Returns: the moved point
  • const 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: ATo the end point; AT the fraction of the way. Returns: the point between
  • operator +(const A: Vector2; const B: Vector2): Vector2: The sum, component by component. Parameters: A the first vector; B the 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: A the vector subtracted from; B the 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: A the vector. Returns: (-A.X, -A.Y)
  • operator *(const A: Vector2; const AScale: float32): Vector2: The vector scaled. Parameters: A the vector; AScale the factor. Returns: (A.X * AScale, A.Y * AScale)
  • operator *(const AScale: float32; const A: Vector2): Vector2: The vector scaled, the factor written first. Parameters: AScale the factor; A the 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: A the vector; AScale the 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: A the first vector; B the second vector. Returns: true when A.X = B.X and A.Y = B.Y
  • operator <>(const A: Vector2; const B: Vector2): bool: Whether two vectors differ in any component: the opposite of =. Parameters: A the first vector; B the 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

text
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 X
  • Height: float32: The height; negative spans above Y
  • init(): 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: AX the corner's X; AY the corner's Y; AWidth the width; AHeight the height.
  • const method Contains(const APoint: Vector2): bool: True when APoint is inside: [left, right) x [top, bottom). Parameters: APoint the point. Returns: whether the rectangle holds it
  • const 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: AOther the other rectangle; AResult the overlap. Returns: whether they overlap
  • const method Overlaps(const AOther: Rect): bool: True when the rectangles share an area (touching is not enough). Parameters: AOther the other rectangle. Returns: whether they overlap
  • const 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

text
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: AMinX the smallest X; AMinY the smallest Y; AMaxX the largest X; AMaxY the 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

text
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

text
LineHit = object

Where two line segments meet: Kind, and Point when Kind is Point.

Members

  • Kind: LineHitKind: How the segments meet
  • Point: Vector2: The point where they meet; read it only when Kind is Point
  • init(): No meeting: Kind Miss, Point (0, 0).

See also: LineIntersection. Since: 0.2

Obb

text
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 centre
  • HalfSize: 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: ACenter the centre; AHalfSize half the width and height; ADegrees the turn, in degrees.

See also: ObbsOverlap. Since: 0.2

Constants

NameDeclarationDescription
Pi: float64 = 3.141592653589793The ratio of a circle's circumference to its diameter.
DegToRad: float64 = 0.017453292519943295Degrees times DegToRad are radians: 90.0 * DegToRad is Pi / 2. See RadToDeg.
RadToDeg: float64 = 57.29577951308232Radians times RadToDeg are degrees: Pi * RadToDeg is 180. See DegToRad.
Epsilon32: float32 = 0.00001fThe float32 tolerance SameValue uses when none is given (scaled by the values' size past 1). See SameValue.
Epsilon64: float64 = 0.000000000001The float64 tolerance SameValue uses when none is given (scaled by the values' size past 1). See SameValue.
NaN: float64 = 0.0 / 0.0Not a number. It compares unequal to everything, itself included: test a value with X <> X.

Routines

PerceivedVolume

text
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

text
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

text
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 1
  • ARangeDb: the loudness range in decibels the level spans

Returns: the linear volume, 0 to AMax

Since: 0.2

text
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

text
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 volume
  • AMax: the volume at level 1
  • ARangeDb: 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

text
routine PerceivedLevel(const AVolume: float64; const AMax: float64): float64;

PerceivedLevel over the default 50 dB range.

Parameters

  • AVolume: the linear volume
  • AMax: the volume at level 1

Returns: the level, 0 to 1

See also: PerceivedVolume. Since: 0.2

text
routine PerceivedLevel(const AVolume: float32; const AMax: float32; const ARangeDb: float32): float32;

PerceivedLevel for float32 values (computed in float64).

Parameters

  • AVolume: the linear volume
  • AMax: the volume at level 1
  • ARangeDb: the loudness range in decibels the level spans

Returns: the level, 0 to 1

Since: 0.2

text
routine PerceivedLevel(const AVolume: float32; const AMax: float32): float32;

PerceivedLevel for float32 values over the default 50 dB range.

Parameters

  • AVolume: the linear volume
  • AMax: the volume at level 1

Returns: the level, 0 to 1

Since: 0.2

Sin

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
routine Abs(const AValue: float32): float32;

Abs for a float32 value.

Parameters

  • AValue: the value

Returns: |AValue|

Since: 0.3

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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 value
  • AMin: one bound
  • AMax: the other bound

Returns: AValue inside [AMin, AMax]

Example: LHealth := Clamp(LHealth - LDamage, 0, 100);

See also: Wrap. Since: 0.2

text
routine Clamp(const AValue: float32; const AMin: float32; const AMax: float32): float32;

Clamp for float32 values.

Parameters

  • AValue: the value
  • AMin: one bound
  • AMax: the other bound

Returns: AValue inside [AMin, AMax]

Since: 0.2

text
routine Clamp(const AValue: int64; const AMin: int64; const AMax: int64): int64;

Clamp for int64 values.

Parameters

  • AValue: the value
  • AMin: one bound
  • AMax: the other bound

Returns: AValue inside [AMin, AMax]

Since: 0.2

text
routine Clamp(const AValue: int32; const AMin: int32; const AMax: int32): int32;

Clamp for int32 values.

Parameters

  • AValue: the value
  • AMin: one bound
  • AMax: the other bound

Returns: AValue inside [AMin, AMax]

Since: 0.2

Min

text
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 value
  • AB: the other value

Returns: the smaller of AA and AB

Example: LZoom := Min(LFitX, LFitY);

See also: Max. Since: 0.3

text
routine Min(const AA: float32; const AB: float32): float32;

Min for float32 values.

Parameters

  • AA: one value
  • AB: the other value

Returns: the smaller of AA and AB

Since: 0.3

text
routine Min(const AA: int64; const AB: int64): int64;

Min for int64 values.

Parameters

  • AA: one value
  • AB: the other value

Returns: the smaller of AA and AB

Since: 0.3

text
routine Min(const AA: int32; const AB: int32): int32;

Min for int32 values.

Parameters

  • AA: one value
  • AB: the other value

Returns: the smaller of AA and AB

Since: 0.3

Max

text
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 value
  • AB: the other value

Returns: the larger of AA and AB

Example: LWidth := Max(LWidth, 1);

See also: Min. Since: 0.3

text
routine Max(const AA: float32; const AB: float32): float32;

Max for float32 values.

Parameters

  • AA: one value
  • AB: the other value

Returns: the larger of AA and AB

Since: 0.3

text
routine Max(const AA: int64; const AB: int64): int64;

Max for int64 values.

Parameters

  • AA: one value
  • AB: the other value

Returns: the larger of AA and AB

Since: 0.3

text
routine Max(const AA: int32; const AB: int32): int32;

Max for int32 values.

Parameters

  • AA: one value
  • AB: the other value

Returns: the larger of AA and AB

Since: 0.3

Wrap

text
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 value
  • AMin: the bottom of the range, included
  • AMax: 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

text
routine Wrap(const AValue: float32; const AMin: float32; const AMax: float32): float32;

Wrap for float32 values.

Parameters

  • AValue: the value
  • AMin: the bottom of the range, included
  • AMax: the top of the range, left out

Returns: AValue inside [AMin, AMax)

Since: 0.2

text
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 value
  • AMin: one end of the range, included
  • AMax: the other end, included

Returns: AValue inside [AMin, AMax]

Example: LFrame := Wrap(LFrame + 1, 0, LFrameCount - 1);

Since: 0.2

text
routine Wrap(const AValue: int32; const AMin: int32; const AMax: int32): int32;

Wrap for int32 values (both ends included).

Parameters

  • AValue: the value
  • AMin: one end of the range, included
  • AMax: the other end, included

Returns: AValue inside [AMin, AMax]

Since: 0.2

SameSign

text
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 value
  • AValue2: the second value

Returns: whether their signs match

Since: 0.2

text
routine SameSign(const AValue1: int32; const AValue2: int32): bool;

SameSign for int32 values.

Parameters

  • AValue1: the first value
  • AValue2: the second value

Returns: whether their signs match

Since: 0.2

text
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 value
  • AValue2: the second value

Returns: whether their signs match

Since: 0.2

text
routine SameSign(const AValue1: float32; const AValue2: float32): bool;

SameSign for float32 values.

Parameters

  • AValue1: the first value
  • AValue2: the second value

Returns: whether their signs match

Since: 0.2

SameValue

text
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 value
  • B: the second value
  • AEpsilon: 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

text
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 value
  • B: the second value

Returns: whether A and B are the same

Since: 0.2

text
routine SameValue(const A: float32; const B: float32; const AEpsilon: float32): bool;

SameValue for float32 values.

Parameters

  • A: the first value
  • B: the second value
  • AEpsilon: the largest difference still counted as the same

Returns: whether A and B are the same within AEpsilon

Since: 0.2

text
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 value
  • B: the second value

Returns: whether A and B are the same

Since: 0.2

Lerp

text
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 start
  • ATo: the end
  • AT: the fraction of the way

Returns: AFrom + (ATo - AFrom) x AT

Example: LX := Lerp(LStartX, LEndX, LElapsed / LDuration);

See also: EaseBetween. Since: 0.2

text
routine Lerp(const AFrom: float32; const ATo: float32; const AT: float32): float32;

Lerp for float32 values.

Parameters

  • AFrom: the start
  • ATo: the end
  • AT: the fraction of the way

Returns: AFrom + (ATo - AFrom) x AT

Since: 0.2

AngleDifference

text
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 degrees
  • ADest: the angle turned to, in degrees

Returns: the turn, in [-180, 180)

Since: 0.2

text
routine AngleDifference(const ASource: float32; const ADest: float32): float32;

AngleDifference for float32 values.

Parameters

  • ASource: the angle turned from, in degrees
  • ADest: the angle turned to, in degrees

Returns: the turn, in [-180, 180)

Since: 0.2

SmoothMove

text
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 now
  • AAmount: the push this update, 0 for none
  • AMax: the largest speed either way
  • ADrag: 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

text
routine SmoothMove(const AValue: float32; const AAmount: float32; const AMax: float32; const ADrag: float32): float32;

SmoothMove for float32 values.

Parameters

  • AValue: the speed now
  • AAmount: the push this update, 0 for none
  • AMax: the largest speed either way
  • ADrag: how much the speed falls per update with no push

Returns: the new speed

Since: 0.2

Ease

text
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 curve
  • AFraction: 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

text
routine Ease(const AKind: Easing; const AFraction: float32): float32;

Ease for a float32 fraction (computed in float64).

Parameters

  • AKind: the curve
  • AFraction: how far along, 0 to 1

Returns: the eased fraction, 0 to 1

Since: 0.2

EaseBetween

text
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 curve
  • AFrom: the start value
  • ATo: the end value
  • AFraction: 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

text
routine EaseBetween(const AKind: Easing; const AFrom: float32; const ATo: float32; const AFraction: float32): float32;

EaseBetween for float32 values.

Parameters

  • AKind: the curve
  • AFrom: the start value
  • ATo: the end value
  • AFraction: how far along, 0 to 1

Returns: the eased value between AFrom and ATo

Since: 0.2

RandomInt

text
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 end
  • AMax: the other end

Returns: the number

Example: LDie := RandomInt(1, 6);

See also: RandomGenerator. Since: 0.2

text
routine RandomInt(const AMin: int64; const AMax: int64): int64;

RandomInt for int64 bounds.

Parameters

  • AMin: one end
  • AMax: the other end

Returns: the number

Since: 0.2

RandomFloat

text
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, included
  • AMax: the high end, left out

Returns: the number

Example: LX := RandomFloat(0.0, 640.0);

Since: 0.2

text
routine RandomFloat(const AMin: float32; const AMax: float32): float32;

RandomFloat for float32 bounds.

Parameters

  • AMin: the low end, included
  • AMax: the high end, left out

Returns: the number

Since: 0.2

RandomBool

text
routine RandomBool(): bool;

True or false, each half the time, from the unit's own generator.

Returns: the value

Since: 0.2

RandomSeed

text
routine RandomSeed(): uint32;

The seed the unit's own generator started from (the last one set).

Returns: the seed

Since: 0.2

SetRandomSeed

text
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

text
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

text
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 point
  • ACenter: the circle's centre
  • ARadius: the circle's radius

Returns: whether the circle holds the point

Since: 0.2

PointInTriangle

text
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 point
  • A: a corner
  • B: a corner
  • C: a corner

Returns: whether the triangle holds the point

Since: 0.2

CirclesOverlap

text
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 centre
  • ARadius1: the first circle's radius
  • ACenter2: the second circle's centre
  • ARadius2: the second circle's radius

Returns: whether they overlap

Since: 0.2

CircleOverlapsRect

text
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 centre
  • ARadius: the circle's radius
  • ARect: the rectangle

Returns: whether they overlap

Since: 0.2

LineIntersection

text
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 start
  • A2: the first segment's end
  • B1: the second segment's start
  • B2: the second segment's end

Returns: the kind of meeting and, for Point, where

Since: 0.2

RadiusOverlap

text
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 radius
  • ACenter1: the first centre
  • ARadius2: the second radius
  • ACenter2: the second centre
  • AShrink: the scale both radii take

Returns: whether they overlap

Since: 0.2

ObbsOverlap

text
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 box
  • B: the other box

Returns: whether they overlap

Since: 0.2

ExtentOf

text
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

text
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 Stop
  • const method ElapsedTicks(): int64: The total measured, in ticks of the clock (Frequency per second), the running span included. Returns: the ticks, 0 or more
  • const 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

text
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

text
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

text
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

text
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

text
TextAlign = choices(Left, Center, Right);

Where a text sits inside a padded width.

See also: PadText. Since: 0.2

Rgb

text
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 .. 255
  • G: uint8: The green component, 0 .. 255
  • B: uint8: The blue component, 0 .. 255
  • init(): Black (0, 0, 0).
  • init(const AR: uint8; const AG: uint8; const AB: uint8): The colour (AR, AG, AB). Parameters: AR red, 0-255; AG green, 0-255; AB blue, 0-255.

Example: LGold: Rgb(255, 215, 0);

Since: 0.2

Constants

NameDeclarationDescription
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

text
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 column
  • AY: the line

Returns: the sequence (CSI is 1-based, row first: (4, 2) is ESC[3;5H)

Since: 0.2

CsiCursorColumn

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
routine GetEscapeMode(): EscapeMode;

The escape mode now.

Returns: the mode SetEscapeMode set last (Auto at start)

Since: 0.2

IsTerminal

text
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

text
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

text
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

text
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

text
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 column
  • AY: the line

Since: 0.2

SetCursorColumn

text
routine SetCursorColumn(const AX: int32);

Puts the cursor at column AX of its line (0-based).

Parameters

  • AX: the column

Since: 0.2

MoveCursorUp

text
routine MoveCursorUp();

Moves the cursor up one line.

Since: 0.2

text
routine MoveCursorUp(const ALines: int32);

Moves the cursor up ALines lines (<= 0: not at all).

Parameters

  • ALines: how far

Since: 0.2

MoveCursorDown

text
routine MoveCursorDown();

Moves the cursor down one line.

Since: 0.2

text
routine MoveCursorDown(const ALines: int32);

Moves the cursor down ALines lines (<= 0: not at all).

Parameters

  • ALines: how far

Since: 0.2

MoveCursorForward

text
routine MoveCursorForward();

Moves the cursor right one column.

Since: 0.2

text
routine MoveCursorForward(const AColumns: int32);

Moves the cursor right AColumns columns (<= 0: not at all).

Parameters

  • AColumns: how far

Since: 0.2

MoveCursorBack

text
routine MoveCursorBack();

Moves the cursor left one column.

Since: 0.2

text
routine MoveCursorBack(const AColumns: int32);

Moves the cursor left AColumns columns (<= 0: not at all).

Parameters

  • AColumns: how far

Since: 0.2

SaveCursorPosition

text
routine SaveCursorPosition();

Saves the cursor's position.

See also: RestoreCursorPosition. Since: 0.2

RestoreCursorPosition

text
routine RestoreCursorPosition();

Puts the cursor back where SaveCursorPosition saved it.

Since: 0.2

HideCursor

text
routine HideCursor();

Hides the cursor.

Since: 0.2

ShowCursor

text
routine ShowCursor();

Shows the cursor.

Since: 0.2

ClearScreen

text
routine ClearScreen();

Clears the screen and its scrollback and puts the cursor at the top left.

Since: 0.2

ClearLine

text
routine ClearLine();

Clears the cursor's line; the cursor stays where it is.

Since: 0.2

text
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

text
routine ClearToEndOfLine();

Clears from the cursor to the end of its line.

Since: 0.2

InsertLines

text
routine InsertLines();

Inserts one blank line at the cursor.

Since: 0.2

text
routine InsertLines(const ALines: int32);

Inserts ALines blank lines at the cursor (<= 0: none).

Parameters

  • ALines: how many

Since: 0.2

DeleteLines

text
routine DeleteLines();

Deletes the cursor's line.

Since: 0.2

text
routine DeleteLines(const ALines: int32);

Deletes ALines lines at the cursor (<= 0: none).

Parameters

  • ALines: how many

Since: 0.2

ScrollUp

text
routine ScrollUp();

Scrolls the screen up one line.

Since: 0.2

text
routine ScrollUp(const ALines: int32);

Scrolls the screen up ALines lines (<= 0: not at all).

Parameters

  • ALines: how far

Since: 0.2

ScrollDown

text
routine ScrollDown();

Scrolls the screen down one line.

Since: 0.2

text
routine ScrollDown(const ALines: int32);

Scrolls the screen down ALines lines (<= 0: not at all).

Parameters

  • ALines: how far

Since: 0.2

InsertChars

text
routine InsertChars();

Inserts one blank at the cursor.

Since: 0.2

text
routine InsertChars(const ACount: int32);

Inserts ACount blanks at the cursor (<= 0: none).

Parameters

  • ACount: how many

Since: 0.2

DeleteChars

text
routine DeleteChars();

Deletes the character at the cursor.

Since: 0.2

text
routine DeleteChars(const ACount: int32);

Deletes ACount characters at the cursor (<= 0: none).

Parameters

  • ACount: how many

Since: 0.2

EraseChars

text
routine EraseChars();

Blanks the character at the cursor.

Since: 0.2

text
routine EraseChars(const ACount: int32);

Blanks ACount characters at the cursor (<= 0: none).

Parameters

  • ACount: how many

Since: 0.2

SetBold

text
routine SetBold();

Bold text from here (until ResetFormat or the next Write's reset).

Since: 0.2

ResetFormat

text
routine ResetFormat();

Resets bold, the colours and every other attribute.

Since: 0.2

SetForegroundColor

text
routine SetForegroundColor(const AColor: TextColor);

The text colour from here, a standard colour.

Parameters

  • AColor: the colour

Since: 0.2

text
routine SetForegroundColor(const AColor: Rgb);

The text colour from here, a 24-bit colour.

Parameters

  • AColor: the colour

Since: 0.2

SetBackgroundColor

text
routine SetBackgroundColor(const AColor: TextColor);

The background colour from here, a standard colour.

Parameters

  • AColor: the colour

Since: 0.2

text
routine SetBackgroundColor(const AColor: Rgb);

The background colour from here, a 24-bit colour.

Parameters

  • AColor: the colour

Since: 0.2

TextColorAt

text
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

text
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

text
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

text
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

text
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 text
  • AWidth: the columns to fill

Returns: the padded text

Since: 0.2

text
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 text
  • AWidth: the columns to fill
  • APad: the pad character

Returns: the padded text

Since: 0.2

text
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 text
  • AWidth: the columns to fill
  • APad: the pad character
  • AAlign: where the text sits

Returns: the padded text

Example: PadText("ab", 7, ".", TextAlign.Center) is "..ab..."

Since: 0.2

RuleText

text
routine RuleText(const AChar: string; const AWidth: int32): string;

AWidth columns of AChar, filled as PadText fills.

Parameters

  • AChar: the character
  • AWidth: the columns; <= 0 gives ""

Returns: the rule

Since: 0.2

ProgressBarText

text
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 done
  • ATotal: all the work
  • AWidth: the bar's columns between the brackets (below 0 counts as 0)

Returns: the bar text

Since: 0.2

SpinnerFrame

text
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

text
routine HorizontalRule();

A line of "-" as wide as the terminal, then a line break.

Since: 0.2

text
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

text
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 character
  • AWidth: the columns

Since: 0.2

WritePadded

text
routine WritePadded(const AText: string; const AWidth: int32);

Writes PadText(AText, AWidth).

Parameters

  • AText: the text
  • AWidth: the columns to fill

Since: 0.2

text
routine WritePadded(const AText: string; const AWidth: int32; const APad: string);

Writes PadText(AText, AWidth, APad).

Parameters

  • AText: the text
  • AWidth: the columns to fill
  • APad: the pad character

Since: 0.2

text
routine WritePadded(const AText: string; const AWidth: int32; const APad: string; const AAlign: TextAlign);

Writes PadText(AText, AWidth, APad, AAlign).

Parameters

  • AText: the text
  • AWidth: the columns to fill
  • APad: the pad character
  • AAlign: where the text sits

Since: 0.2

ProgressBar

text
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 done
  • ATotal: all the work

Since: 0.2

text
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 done
  • ATotal: all the work
  • AWidth: the bar's columns

Since: 0.2

text
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 done
  • ATotal: all the work
  • AWidth: the bar's columns
  • AColor: the bar's colour

Since: 0.2

text
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 done
  • ATotal: all the work
  • AWidth: the bar's columns
  • AColor: the bar's colour

Since: 0.2

WaitForAnyKey

text
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

text
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

text
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 always
  • AColor: the message's colour
  • AMessage: the message; "" gives "Press any key to continue... "

Since: 0.2

text
routine Pause();

Pause(false, TextColor.White, "Press any key to continue... ").

Since: 0.2

text
routine Pause(const AForce: bool);

Pause(AForce, TextColor.White, "Press any key to continue... ").

Parameters

  • AForce: true to pause always

Since: 0.2

text
routine Pause(const AForce: bool; const AColor: TextColor);

Pause(AForce, AColor, "Press any key to continue... ").

Parameters

  • AForce: true to pause always
  • AColor: the message's colour

Since: 0.2

SetTitle

text
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

text
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

text
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

text
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

text
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

text
routine WaitForKey();

Waits until ReadKey gives Enter; returns at once with no keyboard.

Since: 0.2

WaitForEnter

text
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

text
routine WaitForEnter(): bool;

WaitForEnter("Press ENTER to continue...", "").

Returns: false

Since: 0.2

text
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

text
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 key
  • Size: int64: How many bytes (the zero byte after them not counted)

Since: 0.2

Routines

FindResData

text
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 @addresdata directive 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

text
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

text
routine HasResData(const AKey: string): bool;

Whether the binary that calls holds a key.

Parameters

  • AKey: the key an @addresdata directive 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

text
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

text
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

text
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

text
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

text
SeekOrigin = choices(FromStart, FromCurrent, FromEnd);

Where IOSeek counts its offset from.

See also: IOSeek. Since: 0.2

FileMode

text
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

text
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

text
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 given
  • UserData: ptr: The user pointer every callback receives
  • State: IOState: The state after the last operation

See also: IO. Since: 0.2

IO

text
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

text
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

text
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 given
  • UserData: ptr: The user pointer every callback receives

See also: IOSource. Since: 0.2

IOSource

text
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

text
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 ZipDirectoryContents
  • AEntry: the entry's name in the archive (UTF-8, / separated)
  • APercent: 0 to 100
  • ANewFile: 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

text
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 callbacks
  • AUserData: 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

text
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 stream
  • ABuffer: 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

text
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 stream
  • ABuffer: 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

text
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 stream
  • AOffset: the offset, negative to go back
  • AOrigin: 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

text
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

text
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

text
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

text
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 stream
  • ASize: 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

text
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

text
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

text
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 stream
  • ABuffer: 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

text
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 stream
  • ABuffer: 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

text
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 stream
  • AData: 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

text
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 stream
  • ARight: 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

text
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 bytes
  • AReadOnly: 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

text
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

text
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

text
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

text
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 callbacks
  • AUserData: the pointer every callback receives

Returns: the new source

Example: LSrc := CreateIOSource(LCallbacks, LPack);

See also: IOSourceInterface, IOSourceClose. Since: 0.2

IOSourceOpen

text
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 source
  • APath: the entry
  • AMode: 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

text
routine IOSourceOpen(const ASource: IOSource; const APath: string): IO;

Opens an entry of the source for reading (IOSourceOpen with FileMode.Read).

Parameters

  • ASource: the source
  • APath: the entry

Returns: the IO, or nil

Example: LIO := IOSourceOpen(LSrc, "models/ship.bin");

See also: IOSourceOpen. Since: 0.2

IOSourceExists

text
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 source
  • APath: the entry

Returns: true when the entry exists

Example: if IOSourceExists(LSrc, "models/ship.mtl") then ... end;

See also: IOSourceOpen. Since: 0.2

IOSourceSize

text
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 source
  • APath: 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

text
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 source
  • APath: 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

text
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

text
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

text
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

text
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 archive
  • APassword: 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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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 write
  • AFolder: the folder to pack
  • APassword: 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

text
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 write
  • AFolder: the folder to pack
  • APassword: 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

text
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 write
  • AFolder: the folder to pack
  • APassword: 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

text
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 write
  • AFolder: 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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

NameDeclarationDescription
HookStatVersion: int32 = 1glibc'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

text
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 level
  • AName: 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

text
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 level
  • ALibrary: 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

text
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 uninstalled
  • AName: the function's C name, as the modules import it
  • AReplacement: a function of the same C signature and calling convention (a routine 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

text
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

text
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

text
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

text
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 load
  • height: 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

text
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

text
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

text
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 stream
  • AFileType: 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

text
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 stream
  • AWidth: the image width in pixels
  • AHeight: the image height in pixels
  • AFormat: a PixelFormat value
  • AHeaderSize: 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

text
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 stream
  • AFileType: 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

text
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 stream
  • AFileType: 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

text
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 stream
  • AFileType: 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

text
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 stream
  • AFileType: the file type: ".ttf", ".otf"
  • AFontSize: the size the glyphs are made at
  • ACodepoints: the codepoints, or nil
  • ACodepointCount: 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

text
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 stream
  • AFileType: 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

text
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 stream
  • AFileType: 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

text
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 stream
  • AFileType: 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

text
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

text
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

text
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

text
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

text
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 files
  • APath: 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

text
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 files
  • APath: 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

text
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

text
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

text
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

text
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 file
  • AEntry: the entry's path in it
  • APassword: 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

text
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

text
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

text
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

text
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

text
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

text
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

text
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 video
  • ASeconds: 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

text
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

text
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

text
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 video
  • ALoop: true to loop

Example: SetVideoLooping(LBackground, true);

See also: IsVideoLooping. Since: 0.2

IsVideoLooping

text
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

text
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 video
  • AVolume: the level, 0 .. 1

Example: SetVideoVolume(LIntro, 0.5);

See also: GetVideoVolume. Since: 0.2

GetVideoVolume

text
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

text
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 video
  • ACallback: the routine; nil for none

Example: SetVideoStatusCallback(LIntro, OnVideo);

See also: VideoStatusCallback. Since: 0.2

GetVideoFrameRate

text
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

text
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

text
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

text
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

text
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

text
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

text
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 video
  • APosX: the left edge, in screen pixels
  • APosY: the top edge, in screen pixels
  • ATint: the colour the frame is multiplied by (WHITE: as decoded)

Example: DrawVideo(LIntro, 0, 0, WHITE);

See also: DrawVideoPro. Since: 0.2

DrawVideoPro

text
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 video
  • ASource: 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 size
  • AOrigin: the rotation centre, relative to ADest's top left
  • ARotation: the rotation, in degrees
  • ATint: 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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
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

text
routine GetFrameBarColor(): Color;

The colour of the bars around the frame.

Returns: the colour

Example: LColor := GetFrameBarColor();

See also: SetFrameBarColor. Since: 0.3

ToggleFrameFullscreen

text
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

text
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 width
  • AWindowHeight: the window's height
  • ABaseWidth: the frame's base width
  • ABaseHeight: 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

text
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 width
  • ABaseHeight: the frame's base height
  • ADpi: 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

text
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 units
  • ALetterbox: the frame's rectangle in the window
  • ABaseWidth: the frame's base width
  • ABaseHeight: 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

text
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

text
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

text
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

text
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

text
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

text
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

text
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 texture
  • ATexture: 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

text
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: an sf::RenderWindow with 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 an sf::InputStream.
  • sfx::Video, sfx::Mixer and sfx::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 and Math's Vector2 / Rect and Console's Rgb.

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

text
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

text
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

text
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, / separated
  • APassword: 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

text
routine LoadSoundZip(const AArchive: string; const AEntry: string; const AMono: bool): ALuint;

LoadSoundZip for an archive with no password.

Parameters

  • AArchive: the zip file
  • AEntry: the entry's path in the archive
  • AMono: 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

text
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

text
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, / separated
  • APassword: 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

text
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 file
  • AEntry: the entry's path in the archive
  • ADb: 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

text
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 clear
  • KeyColour: Color: That colour (Tiled's "transparent colour"); its alpha is ignored
  • TextureHandle: Texture2D: The texture, unloaded by UnloadTiledMap

See also: TiledMap. Since: 0.3

TiledMapTile

text
TiledMapTile = record

Where one global tile id's pixels are.

Members

  • ImageIndex: int32: Its image in TiledMap.Images; -1: the id draws nothing
  • Source: Rectangle: Its pixels in that image
  • OffsetX: float32: Its tileset's tile offset to the right, in pixels
  • OffsetY: float32: Its tileset's tile offset down, in pixels

See also: TiledMap. Since: 0.3

TiledMap

text
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, properties
  • Images: array of TiledMapImage: Every image the map draws from
  • Tiles: 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

text
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 it
  • AMap: 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

text
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, / separated
  • AMap: 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

text
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, / separated
  • APassword: 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

text
routine LoadTiledMapZip(const AArchive: string; const AEntry: string; var AMap: TiledMap): bool;

LoadTiledMapZip for an archive with no password.

Parameters

  • AArchive: the zip file
  • AEntry: the map's path in the archive
  • AMap: filled with the map

Returns: true when the map and every file it names were read

Since: 0.3

UnloadTiledMap

text
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

text
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

text
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 nothing
  • APosX: where the map's left edge goes, in pixels
  • APosY: where the map's top edge goes, in pixels
  • ATint: multiplied into every pixel (WHITE: as it is)

Example: DrawTiledMap(LWorld, 0.0f, 0.0f, WHITE);

See also: DrawTiledLayer. Since: 0.3

DrawTiledLayer

text
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 map
  • ALayer: the layer's index in AMap.Map.getLayers() (GetTiledLayerIndex finds it by name); out of range draws nothing
  • APosX: where the map's left edge goes, in pixels
  • APosY: where the map's top edge goes, in pixels
  • ATint: multiplied into every pixel

Example: DrawTiledLayer(LWorld, GetTiledLayerIndex(LWorld, "ground"), 0.0f, 0.0f, WHITE);

See also: DrawTiledMap. Since: 0.3

GetTiledLayerIndex

text
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 map
  • ALayerName: 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

text
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

text
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

text
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

text
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 loaded
  • Images: array of LdtkImage: Every image the project draws from
  • Tilesets: array of LdtkTileset: Every tileset that has an image, with that image
  • ErrorMessage: 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

text
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 it
  • 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 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

text
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, / separated
  • 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 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

text
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, / separated
  • APassword: 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

text
routine LoadLdtkProjectZip(const AArchive: string; const AEntry: string; var AProject: LdtkProject): bool;

LoadLdtkProjectZip for an archive with no password.

Parameters

  • AArchive: the zip file
  • AEntry: the project's path in the archive
  • AProject: filled with the project

Returns: true when the project and every file it names were read

Since: 0.3

UnloadLdtkProject

text
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

text
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

text
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 project
  • ALevelName: 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

text
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 nil
  • ALayerName: 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

text
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 project
  • ALevelName: the level's identifier; a name the project does not have draws nothing
  • APosX: where the level's left edge goes, in pixels
  • APosY: where the level's top edge goes, in pixels
  • ATint: multiplied into every pixel (WHITE: as it is)

Example: DrawLdtkLevel(LWorld, "Town", 0.0f, 0.0f, WHITE);

See also: DrawLdtkLayer. Since: 0.3

DrawLdtkLayer

text
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 project
  • ALevelName: the level's identifier
  • ALayerName: the layer's identifier; a name the level does not have draws nothing
  • APosX: where the level's left edge goes, in pixels
  • APosY: where the level's top edge goes, in pixels
  • ATint: multiplied into every pixel

Example: DrawLdtkLayer(LWorld, "Town", "Ground", 0.0f, 0.0f, WHITE);

See also: DrawLdtkLevel. Since: 0.3

GetLdtkLevelSize

text
routine GetLdtkLevelSize(const AProject: LdtkProject; const ALevelName: string): ::Vector2;

A level's size in pixels (LDtk's level width and height).

Parameters

  • AProject: the project
  • ALevelName: 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

text
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

text
MirHost0 = routine clink(): int64;

A host routine JIT'd code may import, taking no argument.

See also: MirLoadHost. Since: 0.3

MirHost1

text
MirHost1 = routine clink(AA: int64): int64;

A host routine JIT'd code may import, taking one int64.

See also: MirLoadHost. Since: 0.3

MirHost2

text
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

text
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

text
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

text
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

text
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

text
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

text
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 context
  • AText: 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

text
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 context
  • AName: the name the code imports
  • AHost: the routine

Example: MirLoadHost(LCtx, "tick", Tick);

See also: MirLink. Since: 0.3

text
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 context
  • AName: the name the code imports
  • AHost: the routine

Example: MirLoadHost(LCtx, "square", Square);

See also: MirLoadHost. Since: 0.3

text
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 context
  • AName: the name the code imports
  • AHost: the routine

Example: MirLoadHost(LCtx, "host_mul", HostMul);

See also: MirLoadHost. Since: 0.3

text
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 context
  • AName: the name the code imports
  • AHost: the routine

Example: MirLoadHost(LCtx, "clamp", Clamp);

See also: MirLoadHost. Since: 0.3

MirLoadStdC

text
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

text
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 context
  • AMode: 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

text
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 context
  • AModule: the module
  • AName: the function's name

Returns: the item, or nil when the module has no function AName

See also: MirFuncAddr. Since: 0.3

MirFuncAddr

text
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 context
  • AModule: the module
  • AName: 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

text
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

text
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

text
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 argument
  • AB: the second argument

Returns: its result

See also: MirFuncAddr. Since: 0.3

text
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 argument
  • AB: the second argument
  • AC: the third argument

Returns: its result

See also: MirFuncAddr. Since: 0.3

C2MirCompileString

text
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 context
  • ASource: the C source
  • AName: 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

text
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 context
  • AIO: 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

text
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 context
  • APath: 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

text
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 context
  • AArchive: the zip file
  • AEntry: the C source's entry
  • APassword: 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

text
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 context
  • AIO: 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

text
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 context
  • APath: the file (.bmir by custom)

Returns: true when written

Example: MirWriteFile(LCtx, "$P:demo.bmir");

See also: MirReadFile. Since: 0.3

MirReadIO

text
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 context
  • AIO: 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

text
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 context
  • APath: 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

text
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 context
  • AArchive: the zip file
  • AEntry: the binary form's entry
  • APassword: 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

text
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 context
  • AName: the function's name

Returns: the function's item

Example: LFunc := MirNewFunc(LCtx, "answer");

See also: MirFinishFunc. Since: 0.3

text
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 context
  • AName: the function's name
  • AA: the parameter's name

Returns: the function's item

Example: LFunc := MirNewFunc(LCtx, "sum_to", "n");

See also: MirNewFunc. Since: 0.3

text
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 context
  • AName: the function's name
  • AA: the first parameter's name
  • AB: the second parameter's name

Returns: the function's item

See also: MirNewFunc. Since: 0.3

text
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 context
  • AName: the function's name
  • AA: the first parameter's name
  • AB: the second parameter's name
  • AC: the third parameter's name

Returns: the function's item

See also: MirNewFunc. Since: 0.3

MirEmit

text
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 context
  • AFunc: 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

text
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 context
  • AFunc: the function
  • ACode: the instruction
  • AA: its first operand
  • AB: its second operand

See also: MirEmit. Since: 0.3

text
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 context
  • AFunc: the function
  • ACode: the instruction
  • AA: its first operand
  • AB: its second operand
  • AC: its third operand

See also: MirEmit. Since: 0.3

MirEmitRet

text
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 context
  • AFunc: the function
  • AValue: the value returned

See also: MirEmit. Since: 0.3

MirEmitLabel

text
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 context
  • AFunc: the function
  • ALabel: the label

See also: MirEmit. Since: 0.3

MirFinishFunc

text
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

text
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

text
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 context
  • AModule: the module (nil prints nothing)

See also: MirLoadModuleText. Since: 0.3