Browse Source

first commit

Eric Streit 7 hours ago
commit
9a83b7ca75

+ 13 - 0
modula2/README.md

@@ -0,0 +1,13 @@
+# A GNU Modula-2 binding of the tigr graphic library
+
+I did this because I needed a graphic library to follow the UI tutorial here :
+
+https://nakst.gitlab.io/tutorial/ui-part-1.html
+
+The tigr library repository is here:
+
+https://github.com/erkkah/tigr/tree/master
+
+I used also the **h2d** utility found in the **XDS** distribution, 
+to check my choices when I tralslated the C headers into Modula-2 ones.
+

BIN
modula2/examples/Essai1/Essai1


+ 67 - 0
modula2/examples/Essai1/Essai1.mod

@@ -0,0 +1,67 @@
+MODULE Essai1;
+
+FROM tigr IMPORT TigrPtr,tigrWindow,tigrFree,tigrClosed, tigrClear, tigrUpdate, TPixelType,
+                tigrLine, TK_ESCAPE, tigrKeyDown, tigrReadChar, tfont, tigrPrint,tigrFill,
+                tigrCircle, tigrRect, tigrFillCircle,  tigrTime, tigrError;
+FROM helper IMPORT tigrRGB, tigrRGBA;
+FROM InOut IMPORT Write, WriteLn, WriteString, WriteCard;
+FROM RealInOut IMPORT WriteShortReal;
+FROM DynamicStrings IMPORT String, InitString;
+FROM Delay IMPORT Delay;
+
+VAR 
+    screen : TigrPtr;
+    redColor, blueColor, greenColor, blueColorHalf : TPixelType;
+    message1, message2, message3 : String;
+
+
+BEGIN
+    message1 := InitString("Hello");
+    message2 := InitString("Bonjour tout le monde!");
+    message3 := InitString("How are you all?");
+    WITH redColor DO 
+        r := 255;
+        g := 0;
+        b := 0;
+        a := 255;
+    END;
+    WITH blueColor DO
+        r := 65;
+        g := 105;
+        b := 225;
+        a := 255;
+    END;
+    WITH blueColorHalf DO
+        r := 65;
+        g := 105;
+        b := 225;
+        a := 128;
+    END;
+    WITH greenColor DO
+        r := 0;
+        g := 128;
+        b := 0;
+        a := 255;
+    END;
+    screen := tigrWindow(1000, 800, message1, 0);
+     WriteShortReal(tigrTime(),8); WriteLn;
+    WHILE (NOT (tigrClosed(screen) > 0)) OR (tigrKeyDown(screen, TK_ESCAPE) > 0) DO 
+        tigrClear(screen, tigrRGB(80H, 90H, 0A0H));
+        tigrLine(screen, 10, 10, 300, 500, redColor );
+        IF (tigrKeyDown(screen, ORD("a")) > 0) THEN
+            tigrLine(screen, 100, 100, 300, 500, blueColor );
+        END;
+        Write ( CHR(tigrReadChar(screen)));
+        tigrPrint(screen, tfont, 10, 10, redColor, message2);
+        tigrPrint(screen, tfont, 150, 150, blueColor, message3);
+        tigrFill(screen,200,200,250,250,blueColorHalf);
+        tigrCircle(screen, 600, 600,50,greenColor);
+        tigrRect(screen, 250,250,250,250,blueColorHalf);
+        tigrFillCircle(screen,500,500, 25,redColor );
+        tigrFillCircle(screen,600,600, 25,blueColorHalf );
+        tigrUpdate(screen);
+    END;
+    WriteShortReal(tigrTime(),8);WriteLn;
+    tigrError(screen, "The window is closed! Messager used to display errors.");
+    tigrFree(screen);
+END Essai1.

+ 10 - 0
modula2/examples/Essai2/Essai2.mod

@@ -0,0 +1,10 @@
+MODULE Essai2;
+
+IMPORT helper, tigr;
+
+VAR
+    a : tigr.TPixelType;
+
+BEGIN
+ a := helper.tigrRGB(80H, 90H, 0A0H)
+END Essai2.

BIN
modula2/examples/clavier/clavier


+ 31 - 0
modula2/examples/clavier/clavier.mod

@@ -0,0 +1,31 @@
+MODULE clavier;
+
+FROM tigr IMPORT TigrPtr,tigrWindow,tigrFree,tigrClosed, tigrClear, tigrUpdate, TPixelType,
+                tigrLine, TK_ESCAPE, tigrKeyDown, tigrReadChar, tfont, tigrPrint,tigrFill,
+                tigrCircle, tigrRect, tigrFillCircle,  tigrTime, tigrError, tigrClip, 
+                tigrFillRect, tigrTextWidth, tigrTextHeight, tigrLoadImage, tigrReadFile,
+                tigrBitmap, TIGR_2X, tigrSetPostFX, tigrMouse,tigrBlit, tigrBlitAlpha,
+                 tigrEncodeUTF8, TK_RIGHT,tigrKeyHeld, TK_SPACE, TK_LEFT;
+
+FROM helper IMPORT tigrRGB, tigrRGBA;
+FROM DynamicStrings IMPORT String, InitString;
+FROM InOut IMPORT Write, WriteLn, WriteCard,WriteString, WriteHex;
+FROM Delay IMPORT Delay;
+
+VAR
+    touche : CARDINAL;
+    ecran : TigrPtr;
+    titre : String;
+
+BEGIN
+    titre := InitString("你好");
+    ecran := tigrWindow(320, 240, titre, 0);
+    WHILE NOT (tigrClosed(ecran ) > 0) DO
+        tigrClear(ecran, tigrRGB(80H, 90H, 0A0H));
+        WriteHex(tigrReadChar(ecran), 7); WriteLn;
+        tigrUpdate(ecran);
+
+        Delay(100);
+    END;
+    tigrFree(ecran);
+END clavier.

BIN
modula2/examples/clip/clip


+ 52 - 0
modula2/examples/clip/clip.mod

@@ -0,0 +1,52 @@
+MODULE clip;
+
+FROM tigr IMPORT TigrPtr,tigrWindow,tigrFree,tigrClosed, tigrClear, tigrUpdate, TPixelType,
+                tigrLine, TK_ESCAPE, tigrKeyDown, tigrReadChar, tfont, tigrPrint,tigrFill,
+                tigrCircle, tigrRect, tigrFillCircle,  tigrTime, tigrError, tigrClip, 
+                tigrFillRect, tigrTextWidth, tigrTextHeight;
+FROM helper IMPORT tigrRGB, tigrRGBA;
+FROM InOut IMPORT Write, WriteLn;
+FROM RealInOut IMPORT WriteShortReal;
+
+CONST 
+    w = 100;
+    d = 50;
+    message = "Half a thought is also a thought";
+
+VAR 
+    cx, cy : CARDINAL;
+    c0, c1, c2, c3 : TPixelType;
+    screen :  TigrPtr;
+    tw, th : CARDINAL;
+
+BEGIN 
+    screen := tigrWindow(320, 240, "Clip", 0);
+
+    c0 := tigrRGB(55, 55, 55);
+    c1 := tigrRGB(255, 255, 255);
+    c2 := tigrRGB(100, 200, 100);
+    c3 := tigrRGBA(100, 100, 200, 150);
+
+    WHILE (NOT (tigrClosed(screen) > 0)) OR (tigrKeyDown(screen, TK_ESCAPE) > 0) DO 
+        tigrClear(screen, c0);
+
+        cx := screen^.w / 2;
+        cy := screen^.h / 2;
+
+        tigrClip(screen, cx - d, cy - d, w, w);
+        tigrFill(screen, cx - d, cy - d, w, w, c1);
+
+        tigrRect(screen, cx - w, cy - w, w, w, c2);
+        tigrFillRect(screen, cx - w, cy - w, w, w, c3);
+
+        tigrCircle(screen, cx + d, cy - d, d, c2);
+        tigrFillCircle(screen, cx + d, cy - d, d, c3);
+
+        tw := tigrTextWidth(tfont, message);
+        th := tigrTextHeight(tfont, message);
+        tigrPrint(screen, tfont, cx - tw / 2, cy + d - th / 2, c2, message);
+
+        tigrUpdate(screen);
+    END;
+    tigrFree(screen);
+END clip.

BIN
modula2/examples/demo/demo


BIN
modula2/examples/demo/demo.gif


+ 160 - 0
modula2/examples/demo/demo.mod

@@ -0,0 +1,160 @@
+MODULE demo;
+
+FROM tigr IMPORT TigrPtr,tigrWindow,tigrFree,tigrClosed, tigrClear, tigrUpdate, TPixelType,
+                tigrLine, TK_ESCAPE, tigrKeyDown, tigrReadChar, tfont, tigrPrint,tigrFill,
+                tigrCircle, tigrRect, tigrFillCircle,  tigrTime, tigrError, tigrClip, 
+                tigrFillRect, tigrTextWidth, tigrTextHeight, tigrLoadImage, tigrReadFile,
+                tigrBitmap, TIGR_2X, tigrSetPostFX, tigrMouse,tigrBlit, tigrBlitAlpha,
+                 tigrEncodeUTF8, TK_RIGHT,tigrKeyHeld, TK_SPACE, TK_LEFT;
+
+FROM helper IMPORT tigrRGB, tigrRGBA;
+FROM DynamicStrings IMPORT String, InitString;
+FROM InOut IMPORT Write, WriteLn, WriteCard,WriteString;
+FROM Delay IMPORT Delay;
+
+
+    
+
+
+VAR
+    standing            : BOOLEAN;
+    remaining           : SHORTREAL;
+    backdrop, screen    : TigrPtr;    
+    squinkle            : TigrPtr; 
+    greeting            : String;
+    prevx, prevy, prev  : CARDINAL;
+    chars               : ARRAY[0..16] OF CHAR;
+    tempString          : String;
+    n                   : CARDINAL;
+    dt                  : SHORTREAL;
+    x, y ,b             : CARDINAL;
+    message, message1   : String;
+    c                   : CARDINAL;
+    playerx, playery,
+    playerxs, playerys  : INTEGER;
+
+    PROCEDURE update (dt : SHORTREAL);
+
+    VAR
+        oldx, oldy : INTEGER;
+
+    BEGIN
+        IF (remaining > 0.0) THEN 
+            remaining := remaining - dt;
+        END;
+         (* Read the keyboard and move the player. *)
+        WriteString("Position départ ->"); 
+        WriteCard(playerxs, 6); WriteString("**");WriteCard(playerys, 6); WriteLn;
+        IF (standing OR (tigrKeyDown(screen, TK_SPACE) >0)) THEN
+            playerys := playerys - 200;
+        END;
+         IF ((tigrKeyHeld(screen, TK_LEFT) > 0) OR (tigrKeyHeld(screen, ORD('a')) > 0)) THEN
+            WriteString("Touche gauche"); WriteLn;
+            playerxs := playerxs - 10;
+        END;
+        IF ((tigrKeyHeld(screen, TK_RIGHT) > 0) OR (tigrKeyHeld(screen, ORD('d')) > 0)) THEN
+        WriteString("Toiuche droite"); WriteLn;
+            playerxs := playerxs + 10;
+        END;
+        WriteString("Nouvelle Position ->");
+        WriteCard(playerxs, 6); WriteString("**");WriteCard(playerys, 6); WriteLn;
+        Delay(1000);
+
+        
+    END update;
+
+BEGIN
+    standing    := TRUE;
+    remaining   := 0.0;
+    playerx     := 160;
+    playery     := 200;
+    playerxs    := 0;
+    playerys    := 0;
+
+    squinkle := tigrLoadImage("squinkle.png");
+    IF ( squinkle = NIL) THEN
+        tigrError(0, "Cannot load squinkle.png");
+    END;
+    
+    (* Load some UTF-8 text. *)
+    greeting := tigrReadFile("greeting.txt", 0);
+    IF (greeting = NIL) THEN
+        tigrError(0, "Cannot load greeting.txt");
+    END;
+    (* Make a window and an off-screen backdrop. *)
+    screen := tigrWindow(320, 240, greeting, TIGR_2X);
+    backdrop := tigrBitmap(screen^.w, screen^.h);
+
+    (*  Fill in the background. *)
+    tigrClear(backdrop, tigrRGB(80, 180, 255));
+    tigrFill(backdrop, 0, 200, 320, 40, tigrRGB(60, 120, 60));
+    tigrFill(backdrop, 0, 200, 320, 3, tigrRGB(0, 0, 0));
+    tigrLine(backdrop, 0, 201, 320, 201, tigrRGB(255, 255, 255));
+
+    (* Enable post fx *)
+    tigrSetPostFX(screen, 1.0, 1.0, 1.0, 2.0);
+
+    prevx := 0;
+    prevy := 0;
+    prev  := 0;
+
+    (* Maintain a list of characters entered. *)
+    FOR n := 0 TO 16 BY 1 DO
+        chars[n] := "_";
+    END;
+
+    WHILE (NOT (tigrClosed(screen) > 0)) OR (tigrKeyDown(screen, TK_ESCAPE) > 0) DO 
+        (* Update the game. *)
+        dt := tigrTime();
+        update(dt);
+
+        (* Read the mouse and draw lines when pressed. *)
+        
+        tigrMouse(screen, x, y, b );
+        IF (b = 1) THEN
+            IF (prev > 0) THEN
+                tigrLine(backdrop, prevx, prevy, x, y, tigrRGB(0, 0, 0));
+            END;
+            prevx := x;
+            prevy := y;
+            prev  := 1;
+        ELSE 
+            prev := 0;
+        END;
+
+        (* Composite the backdrop and sprite onto the screen. *)
+        tigrBlit(screen, backdrop, 0, 0, 0, 0, backdrop^.w, backdrop^.h);
+        tigrBlitAlpha(screen, squinkle, playerx - INTEGER(squinkle^.w / 2), playery - INTEGER(squinkle^.h), 0, 0, 
+                    squinkle^.w, squinkle^.h, 1.0);
+
+        message := InitString("A D + SPACE");
+        tigrPrint(screen, tfont, 10, 10,  tigrRGBA(0C0H, 0D0H, 0FFH, 0C0H), greeting);
+        tigrPrint(screen, tfont, 10, 222, tigrRGBA(0FFH, 0FFH, 0FFH, 0FFH), message);
+
+        (* Grab any chars and add them to our buffer. *)
+        LOOP
+            c := tigrReadChar(screen);
+            IF (c = 0) THEN
+                EXIT;
+            END;
+            FOR n := 1 TO  16 DO
+                chars[n - 1] := chars[n];
+        END;
+            chars[15] := CHR(c);
+        END;
+        Write(CHR(c));
+        tigrUpdate(screen);
+    END;
+
+        (* (* Print out the character buffer too. *)
+        FOR n := 0 TO 15 DO 
+            tempString := tigrEncodeUTF8(p, chars[n]);
+        END;
+        *p = 0;
+        
+        tigrPrint(screen, tfont, 160, 222, tigrRGB(255, 255, 255), "Chars: %s", tmp); *)
+
+    tigrFree(squinkle);
+    tigrFree(backdrop);
+    tigrFree(screen);
+END demo.

+ 2 - 0
modula2/examples/demo/greeting.txt

@@ -0,0 +1,2 @@
+¡Hola! Välkommen!
+You can draw in here with the mouse.

BIN
modula2/examples/demo/squinkle.png


BIN
modula2/examples/unicode/unicode-test


+ 9 - 0
modula2/examples/unicode/unicode-test.c

@@ -0,0 +1,9 @@
+#include <stdio.h>
+#include <unicode/ustring.h>
+
+int main() {
+    UChar unicodeString[20];
+    u_uastrcpy(unicodeString, "Hello, ICU!");
+    printf("Unicode string: %S\n", unicodeString);
+    return 0;
+}

+ 9 - 0
modula2/examples/unicode/update.mod

@@ -0,0 +1,9 @@
+MODULE update;
+
+VAR
+    x,y,posx, posy  CARDINAL;
+    c : CARDINAL;
+
+BEGIN
+
+END update.

+ 13 - 0
modula2/helper.def

@@ -0,0 +1,13 @@
+DEFINITION MODULE helper;
+
+IMPORT tigr;
+FROM tigr IMPORT TPixelType;
+FROM SYSTEM IMPORT BYTE;
+
+ (* Helper for making colors. *)
+PROCEDURE tigrRGB(r, g, b: BYTE): TPixelType;
+
+ (* Helper for making colors. *)
+PROCEDURE tigrRGBA(r, g, b, a: BYTE): TPixelType;
+
+END helper.

+ 33 - 0
modula2/helper.mod

@@ -0,0 +1,33 @@
+IMPLEMENTATION MODULE helper;
+
+ (* Helper for making colors. *)
+PROCEDURE tigrRGB(r, g, b: BYTE): TPixelType;
+
+VAR 
+    p : TPixelType;
+
+BEGIN
+    p.r := r; 
+    p.g := g; 
+    p.b := b; 
+    p.a := 255; 
+    RETURN p;
+END tigrRGB;
+
+ (* Helper for making colors. *)
+PROCEDURE tigrRGBA(r, g, b, a: BYTE): TPixelType;
+
+VAR 
+    p : TPixelType;
+
+BEGIN
+    p.r := r; 
+    p.g := g; 
+    p.b := b; 
+    p.a := a; 
+    RETURN p;
+END tigrRGBA;
+
+BEGIN
+
+END helper.

+ 412 - 0
modula2/tigr.def

@@ -0,0 +1,412 @@
+
+DEFINITION MODULE FOR "C" tigr;
+
+FROM SYSTEM IMPORT ADDRESS,BYTE;
+FROM DynamicStrings IMPORT String;
+
+EXPORT UNQUALIFIED tigrWindow, TigrPtr, tigrFree, tigrClosed, 
+            tigrClear,tigrUpdate,TPixelPtr,TPixelType,tigrLine, TK_ESCAPE, tigrKeyDown, 
+            tigrReadChar, tfont, tigrPrint,tigrFill,tigrCircle, tigrRect, tigrFillCircle,
+            tigrTime, tigrError, tigrClip, tigrFillRect, tigrTextWidth, tigrTextHeight,
+            tigrLoadImage,tigrReadFile, tigrBitmap, TIGR_2X ,tigrSetPostFX, tigrMouse,
+            tigrBlit, tigrBlitAlpha ,tigrEncodeUTF8, TK_RIGHT,tigrKeyHeld, TK_SPACE, TK_LEFT;
+
+CONST
+    TIGR_FIXED      =   0;    (* window's bitmap is a fixed size (default) *)
+    TIGR_AUTO       =   1;   (* window's bitmap is scaled with the window *)
+    TIGR_2X         =   2;    (* always enforce (at least) 2X pixel scale *)
+    TIGR_3X         =   4;    (* always enforce (at least) 3X pixel scale *)
+    TIGR_4X         =   8;    (* always enforce (at least) 4X pixel scale *)
+    TIGR_RETINA     =   16;   (* enable retina support on OS X *)
+    TIGR_NOCURSOR   =   32;   (* hide cursor *)
+    TIGR_FULLSCREEN =   64;
+
+TYPE
+        TPixelPtr   =   POINTER TO TPixelType;
+        TPixelType  =   RECORD
+                            r, g, b, a : BYTE;
+                        END;
+        TigrPtr     =   POINTER TO TigrType;
+        TigrType    =   RECORD
+                            w,h : CARDINAL;
+                            cx, cy, cw, ch : CARDINAL;
+                            pix : TPixelPtr;
+                            handle : ADDRESS;
+                            blitMode : CARDINAL;
+                        END;
+        intPtr      =   POINTER TO INTEGER;
+    shortRealPtr    =   POINTER TO SHORTREAL;
+
+
+VAR Tigr : TigrType;  
+
+ (* Creates a new empty window with a given bitmap size.
+
+ Title is UTF-8.
+
+ In TIGR_FIXED mode, the window is made as large as possible to contain an integer-scaled
+ version of the bitmap while still fitting on the screen. Resizing the window will adapt
+ the scale in integer steps to fit the bitmap.
+
+ In TIGR_AUTO mode, the initial window size is set to the bitmap size times the pixel
+ scale. Resizing the window will resize the bitmap using the specified scale.
+ For example, in forced 2X mode, the window will be twice as wide (and high) as the bitmap.
+
+ Turning on TIGR_RETINA mode will request full backing resolution on OSX, meaning that
+ the effective window size might be integer scaled to a larger size. In TIGR_AUTO mode,
+ this means that the Tigr bitmap will change size if the window is moved between
+ retina and non-retina screens. *)
+
+PROCEDURE tigrWindow( w, h: CARDINAL; title : String; flags : INTEGER): TigrPtr;
+
+(* Creates an empty off-screen bitmap. *)
+PROCEDURE tigrBitmap(w,h : CARDINAL): TigrPtr;
+
+ (* Deletes a window/bitmap. *)
+PROCEDURE tigrFree(bmp: TigrPtr);
+
+ (* Returns non-zero if the user requested to close a window. *)
+PROCEDURE tigrClosed(bmp: TigrPtr): INTEGER;
+
+(* Displays a window's contents on-screen and updates input. *)
+PROCEDURE tigrUpdate(bmp: TigrPtr);
+
+ (* Called before doing direct OpenGL calls and before tigrUpdate.
+ Returns non-zero if OpenGL is available. *)
+PROCEDURE tigrBeginOpenGL(bmp: TigrPtr): INTEGER;
+
+(* Sets post shader for a window.
+ This replaces the built-in post-FX shader. *)
+PROCEDURE tigrSetPostShader(bmp: TigrPtr; code: ARRAY OF CHAR; size: CARDINAL);
+
+ (* Sets post-FX properties for a window.
+
+ The built-in post-FX shader uses the following parameters:
+ p1: hblur - use bilinear filtering along the x-axis (pixels)
+ p2: vblur - use bilinear filtering along the y-axis (pixels)
+ p3: scanlines - CRT scanlines effect (0-1)
+ p4: contrast - contrast boost (1 = no change, 2 = 2X contrast, etc) *)
+PROCEDURE tigrSetPostFX(bmp: TigrPtr; p1, p2, p3, p4 : SHORTREAL);
+
+
+ (* Drawing ---------------------------------------------------------------- *)
+
+ (* Helper for reading pixels.
+ For high performance, just access bmp->pix directly. *)
+PROCEDURE  tigrGet(bmp: TigrPtr; x, y: CARDINAL): TPixelType;
+
+ (* Plots a pixel.
+ Clips and blends.
+ For high performance, just access bmp->pix directly. *)
+PROCEDURE tigrPlot(bmp: TigrPtr; x, y: CARDINAL; pix: TPixelType);
+
+ (* Clears a bitmap to a color.
+ No blending, no clipping. *)
+PROCEDURE tigrClear(bmp: TigrPtr; color: TPixelType);
+
+ (* Fills a rectangular area.
+ No blending, no clipping. *)
+PROCEDURE tigrFill(bmp: TigrPtr; x, y, w, h: CARDINAL; color: TPixelType);
+
+ (* Draws a line.
+ Start pixel is drawn, end pixel is not.
+ Clips and blends. *)
+PROCEDURE tigrLine(bmp: TigrPtr; x0, y0, x1, y1: CARDINAL; color: TPixelType);
+
+ (* Draws an empty rectangle.
+ Drawing a 1x1 rectangle yields the same result as calling tigrPlot.
+ Clips and blends. *)
+PROCEDURE tigrRect(bmp: TigrPtr; x, y, w, h: CARDINAL; color: TPixelType);
+
+ (* Fills a rectangle.
+ Fills the inside of the specified rectangular area.
+ Calling tigrRect followed by tigrFillRect using the same arguments
+ causes no overdrawing.
+ Clips and blends. *)
+PROCEDURE tigrFillRect(bmp: TigrPtr; x, y, w, h: CARDINAL; color: TPixelType);
+
+ (* Draws a circle.
+ Drawing a zero radius circle yields the same result as calling tigrPlot.
+ Drawing a circle with radius one draws a circle three pixels wide.
+ Clips and blends. *)
+PROCEDURE tigrCircle(bmp: TigrPtr; x, y, r: CARDINAL; color: TPixelType);
+
+ (* Fills a circle.
+ Fills the inside of the specified circle.
+ Calling tigrCircle followed by tigrFillCircle using the same arguments
+ causes no overdrawing.
+ Filling a circle with zero radius has no effect.
+ Clips and blends. *)
+PROCEDURE tigrFillCircle(bmp: TigrPtr; x,y,r: CARDINAL; color: TPixelType );
+
+ (* Sets clip rect.
+ Set to (0, 0, -1, -1) to reset clipping to full bitmap. *)
+PROCEDURE tigrClip(bmp : TigrPtr; cx,cy,cw,ch: CARDINAL);
+
+(* Heper procedures in a separate file*)
+
+(* Copies bitmap data.
+ dx/dy = dest co-ordinates
+ sx/sy = source co-ordinates
+ w/h   = width/height
+
+ RGBAdest = RGBAsrc
+ Clips, does not blend. *)
+PROCEDURE tigrBlit(dest: TigrPtr; src: TigrPtr; dx, dy, sx, sy, w, h: CARDINAL);
+
+ (* 
+ Same as tigrBlit, but alpha blends the source bitmap with the
+ target using per pixel alpha and the specified global alpha. 
+
+ Ablend = Asrc * alpha
+ RGBdest = RGBsrc * Ablend + RGBdest * (1 - Ablend)
+
+ Blit mode == TIGR_KEEP_ALPHA:
+ Adest = Adest
+ 
+ Blit mode == TIGR_BLEND_ALPHA:
+ Adest = Asrc * Ablend + Adest * (1 - Ablend)
+ Clips and blends. 
+ *)
+PROCEDURE tigrBlitAlpha(dest, src: TigrPtr; dx, dy, sx, sy, w, h: CARDINAL; alpha: SHORTREAL);
+
+ (* Same as tigrBlit, but tints the source bitmap with a color
+ and alpha blends the resulting source with the destination.
+
+ Rblend = Rsrc * Rtint
+ Gblend = Gsrc * Gtint
+ Bblend = Bsrc * Btint
+ Ablend = Asrc * Atint
+
+ RGBdest = RGBblend * Ablend + RGBdest * (1 - Ablend)
+
+ Blit mode == TIGR_KEEP_ALPHA:
+ Adest = Adest
+
+ Blit mode == TIGR_BLEND_ALPHA:
+ Adest = Ablend * Ablend + Adest * (1 - Ablend)
+ Clips and blends. *)
+PROCEDURE tigrBlitTint(dest, src: TigrPtr; dx, dy, sx, sy, w, h: CARDINAL; tint: TPixelType);
+
+ (*TIGR_KEEP_ALPHA Keep destination alpha value*)
+ (*TIGR_BLEND_ALPHA Blend destination alpha (default) *)
+CONST
+    TIGR_KEEP_ALPHA     =   0;
+    TIGR_BLEND_ALPHA    =   -1;  
+
+ (* Set destination bitmap blend mode for blit operations. *)
+PROCEDURE tigrBlitMode(dest : TigrPtr; mode: CARDINAL);
+
+
+ (* Font printing ---------------------------------------------------------- *)
+
+TYPE 
+    TigrGlyphType   =   RECORD
+                      code: INTEGER;
+                      x, y, w, h: CARDINAL;
+                    END;  
+    TigrFontTypePtr =   POINTER TO TigrFontType;              
+    TigrFontType    =   RECORD
+                            bitmap: TigrPtr;
+                            numGlyphs: CARDINAL;
+                            glyphs: POINTER TO TigrGlyphType;
+                        END;
+    
+    TCodepageType   =   (TCP_ASCII, TCP_1252, TCP_UTF32);
+                        
+
+VAR
+    TigrGlyph:  TigrGlyphType;
+    TigrFont:   TigrFontType;
+    TCodepage:  TCodepageType;
+
+
+ (* Loads a font from a bitmap font sheet.
+ The loaded font takes ownership of the provided bitmap.
+
+ Codepages:
+
+  TCP_ASCII   - Regular 7-bit ASCII
+  TCP_1252    - Windows 1252
+  TCP_UTF32   - Unicode subset
+
+ For ASCII and 1252, the font bitmap should contain all characters
+ for the given codepage, excluding the first 32 control codes.
+
+ For UTF32 - the font bitmap contains a subset of Unicode characters
+ and must be in the format generated by tigrFont for UTF32. *)
+
+PROCEDURE tigrLoadFont(bitmap: TigrPtr; codepage: CARDINAL): TigrFontTypePtr;
+
+ (* Frees a font and associated font sheet. *)
+PROCEDURE tigrFreeFont(font: TigrFontTypePtr);
+
+ (* Prints UTF-8 text onto a bitmap.
+ NOTE:
+  This uses the target bitmap blit mode.
+  See tigrBlitTint for details. *)
+PROCEDURE tigrPrint(dest: TigrPtr; font: TigrFontTypePtr; x, y: CARDINAL; color: TPixelType; text : String; ...);
+
+ (* Returns the width/height of a string. *)
+PROCEDURE tigrTextWidth(font: TigrFontTypePtr; text: ARRAY OF CHAR): INTEGER;
+PROCEDURE tigrTextHeight(font: TigrFontTypePtr; text: ARRAY OF CHAR): INTEGER;
+
+ (* The built-in font. *)
+VAR tfont: TigrFontTypePtr;
+
+
+(*  User Input -------------------------------------------------------------
+
+ Key scancodes. For letters/numbers, use ASCII ('A'-'Z' and '0'-'9'). *)
+
+
+
+CONST 
+    TK_PAD0 = 128;
+    TK_PAD1 = 129;
+    TK_PAD2 = 130;
+    TK_PAD3 = 131;
+    TK_PAD4 = 132;
+    TK_PAD5 = 133;
+    TK_PAD6 = 134;
+    TK_PAD7 = 135;
+    TK_PAD8 = 136;
+    TK_PAD9 = 137;
+    TK_PADMUL = 138;
+    TK_PADADD = 139;
+    TK_PADENTER = 140;
+    TK_PADSUB = 141;
+    TK_PADDOT = 142;
+    TK_PADDIV = 143;
+    TK_F1 = 144;
+    TK_F2 = 145;
+    TK_F3 = 146;
+    TK_F4 = 147;
+    TK_F5 = 148;
+    TK_F6 = 149;
+    TK_F7 = 150;
+    TK_F8 = 151;
+    TK_F9 = 152;
+    TK_F10 = 153;
+    TK_F11 = 154;
+    TK_F12 = 155;
+    TK_BACKSPACE = 156;
+    TK_TAB = 157;
+    TK_RETURN = 158;
+    TK_SHIFT = 159;
+    TK_CONTROL = 160;
+    TK_ALT = 161;
+    TK_PAUSE = 162;
+    TK_CAPSLOCK = 163;
+    TK_ESCAPE = 164;
+    TK_SPACE = 165;
+    TK_PAGEUP = 166;
+    TK_PAGEDN = 167;
+    TK_END = 168;
+    TK_HOME = 169;
+    TK_LEFT = 170;
+    TK_UP = 171;
+    TK_RIGHT = 172;
+    TK_DOWN = 173;
+    TK_INSERT = 174;
+    TK_DELETE = 175;
+    TK_LWIN = 176;
+    TK_RWIN = 177;
+    TK_NUMLOCK = 178;
+    TK_SCROLL = 179;
+    TK_LSHIFT = 180;
+    TK_RSHIFT = 181;
+    TK_LCONTROL = 182;
+    TK_RCONTROL = 183;
+    TK_LALT = 184;
+    TK_RALT = 185;
+    TK_SEMICOLON = 186;
+    TK_EQUALS = 187;
+    TK_COMMA = 188;
+    TK_MINUS = 189;
+    TK_DOT = 190;
+    TK_SLASH = 191;
+    TK_BACKTICK = 192;
+    TK_LSQUARE = 193;
+    TK_BACKSLASH = 194;
+    TK_RSQUARE = 195;
+    TK_TICK = 196;
+
+ (* Returns mouse input for a window.
+ The value set to "buttons" is a bit set where bits 0, 1 and 2
+ corresponds to the left, right and middle buttons.
+ A set bit indicates that a button is held. *)
+PROCEDURE tigrMouse(bmp: TigrPtr; VAR x,y,buttons: CARDINAL);
+
+TYPE 
+    TigrTouchPoint  =   RECORD
+                            x,y : INTEGER;
+                        END;
+    TigrTouchPointPtr = POINTER TO TigrTouchPoint;
+
+ (* Reads touch input for a window.
+ Returns number of touch points read. *)
+PROCEDURE tigrTouch(bmp: TigrPtr; points: TigrTouchPointPtr; maxPoints: CARDINAL): INTEGER;
+
+ (* Reads the delta of the scroll "wheel" in somewhat platform neutral
+ units where 1.0 corresponds to a "notch". The actual correlation between
+ physical movement and this number varies between platforms, input methods
+ and settings. *)
+PROCEDURE tigrScrollWheel(bmp: TigrPtr; x, y: shortRealPtr);
+
+
+ (* Reads the keyboard for a window.
+ Returns non-zero if a key is pressed/held.
+ tigrKeyDown tests for the initial press, tigrKeyHeld repeats each frame. *)
+PROCEDURE tigrKeyDown(bmp: TigrPtr; key: CARDINAL): CARDINAL;
+PROCEDURE tigrKeyHeld(bmp: TigrPtr; key: CARDINAL): CARDINAL;
+
+ (* Reads character input for a window.
+ Returns the Unicode value of the last key pressed, or 0 if none. *)
+PROCEDURE tigrReadChar(bmp: TigrPtr): CARDINAL;
+
+ (* Show / hide virtual keyboard.
+ (Only available on iOS / Android) *)
+PROCEDURE tigrShowKeyboard(show: CARDINAL);
+
+
+ (* Bitmap I/O ------------------------------------------------------------- *)
+
+ (* Loads a PNG, from either a file or memory. (fileName is UTF-8)
+ On error, returns NULL and sets errno. *)
+PROCEDURE tigrLoadImage(fileName: ARRAY OF CHAR): TigrPtr;
+PROCEDURE tigrLoadImageMem(data: ADDRESS; length: CARDINAL): TigrPtr;
+
+ (* Saves a PNG to a file. (fileName is UTF-8)
+ On error, returns zero and sets errno. *)
+PROCEDURE tigrSaveImage(fileName: ARRAY OF CHAR; bmp: TigrPtr): INTEGER;
+
+
+ (* Helpers ---------------------------------------------------------------- *)
+
+ (* Returns the amount of time elapsed since tigrTime was last called,
+ or zero on the first call. *)
+PROCEDURE tigrTime(): SHORTREAL;
+
+(*  Displays an error message and quits. (UTF-8)
+ 'bmp' can be NULL. *)
+PROCEDURE tigrError(bmp: TigrPtr; message: ARRAY OF CHAR; ...);
+
+ (* Reads an entire file into memory. (fileName is UTF-8)
+ Free it yourself after with 'free'.
+ On error, returns NULL and sets errno.
+ TIGR will automatically append a NUL terminator byte
+ to the end (not included in the length) *)
+PROCEDURE tigrReadFile(fileName: ARRAY OF CHAR; length: intPtr): String;
+
+ (* Decompresses DEFLATEd zip/zlib data into a buffer.
+ Returns non-zero on success. *)
+PROCEDURE tigrInflate(out: ADDRESS; outlen: CARDINAL; in: ADDRESS; inlen: CARDINAL);
+
+ (* Decodes a single UTF8 codepoint and returns the next pointer. *)
+PROCEDURE tigrDecodeUTF8(text: String; cp: intPtr): String;
+
+ (* Encodes a single UTF8 codepoint and returns the next pointer. *)
+PROCEDURE tigrEncodeUTF8(text: String; cp: INTEGER): String;
+
+END tigr.

+ 366 - 0
modula2/tigr.h

@@ -0,0 +1,366 @@
+// TIGR - TIny GRaphics Library - v3.2
+//        ^^   ^^
+//
+// rawr.
+
+/*
+This is free and unencumbered software released into the public domain.
+
+Our intent is that anyone is free to copy and use this software,
+for any purpose, in any form, and by any means.
+
+The authors dedicate any and all copyright interest in the software
+to the public domain, at their own expense for the betterment of mankind.
+
+The software is provided "as is", without any kind of warranty, including
+any implied warranty. If it breaks, you get to keep both pieces.
+*/
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Compiler configuration.
+#ifdef _MSC_VER
+#define TIGR_INLINE static __forceinline
+#else
+#define TIGR_INLINE static inline
+#endif
+
+// Bitmaps ----------------------------------------------------------------
+
+// This struct contains one pixel.
+typedef struct {
+    unsigned char r, g, b, a;
+} TPixel;
+
+// Window flags.
+#define TIGR_FIXED      0   // window's bitmap is a fixed size (default)
+#define TIGR_AUTO       1   // window's bitmap is scaled with the window
+#define TIGR_2X         2   // always enforce (at least) 2X pixel scale
+#define TIGR_3X         4   // always enforce (at least) 3X pixel scale
+#define TIGR_4X         8   // always enforce (at least) 4X pixel scale
+#define TIGR_RETINA     16  // enable retina support on OS X
+#define TIGR_NOCURSOR   32  // hide cursor
+#define TIGR_FULLSCREEN 64  // start in full-screen mode
+
+// A Tigr bitmap.
+typedef struct Tigr {
+    int w, h;           // width/height (unscaled)
+    int cx, cy, cw, ch; // clip rect
+    TPixel *pix;        // pixel data
+    void *handle;       // OS window handle, NULL for off-screen bitmaps.
+    int blitMode;       // Target bitmap blit mode
+} Tigr;
+
+// Creates a new empty window with a given bitmap size.
+//
+// Title is UTF-8.
+//
+// In TIGR_FIXED mode, the window is made as large as possible to contain an integer-scaled
+// version of the bitmap while still fitting on the screen. Resizing the window will adapt
+// the scale in integer steps to fit the bitmap.
+//
+// In TIGR_AUTO mode, the initial window size is set to the bitmap size times the pixel
+// scale. Resizing the window will resize the bitmap using the specified scale.
+// For example, in forced 2X mode, the window will be twice as wide (and high) as the bitmap.
+//
+// Turning on TIGR_RETINA mode will request full backing resolution on OSX, meaning that
+// the effective window size might be integer scaled to a larger size. In TIGR_AUTO mode,
+// this means that the Tigr bitmap will change size if the window is moved between
+// retina and non-retina screens.
+//
+Tigr *tigrWindow(int w, int h, const char *title, int flags);
+
+// Creates an empty off-screen bitmap.
+Tigr *tigrBitmap(int w, int h);
+
+// Deletes a window/bitmap.
+void tigrFree(Tigr *bmp);
+
+// Returns non-zero if the user requested to close a window.
+int tigrClosed(Tigr *bmp);
+
+// Displays a window's contents on-screen and updates input.
+void tigrUpdate(Tigr *bmp);
+
+// Called before doing direct OpenGL calls and before tigrUpdate.
+// Returns non-zero if OpenGL is available.
+int tigrBeginOpenGL(Tigr *bmp);
+
+// Sets post shader for a window.
+// This replaces the built-in post-FX shader.
+void tigrSetPostShader(Tigr *bmp, const char* code, int size);
+
+// Sets post-FX properties for a window.
+//
+// The built-in post-FX shader uses the following parameters:
+// p1: hblur - use bilinear filtering along the x-axis (pixels)
+// p2: vblur - use bilinear filtering along the y-axis (pixels)
+// p3: scanlines - CRT scanlines effect (0-1)
+// p4: contrast - contrast boost (1 = no change, 2 = 2X contrast, etc)
+void tigrSetPostFX(Tigr *bmp, float p1, float p2, float p3, float p4);
+
+
+// Drawing ----------------------------------------------------------------
+
+// Helper for reading pixels.
+// For high performance, just access bmp->pix directly.
+TPixel tigrGet(Tigr *bmp, int x, int y);
+
+// Plots a pixel.
+// Clips and blends.
+// For high performance, just access bmp->pix directly.
+void tigrPlot(Tigr *bmp, int x, int y, TPixel pix);
+
+// Clears a bitmap to a color.
+// No blending, no clipping.
+void tigrClear(Tigr *bmp, TPixel color);
+
+// Fills a rectangular area.
+// No blending, no clipping.
+void tigrFill(Tigr *bmp, int x, int y, int w, int h, TPixel color);
+
+// Draws a line.
+// Start pixel is drawn, end pixel is not.
+// Clips and blends.
+void tigrLine(Tigr *bmp, int x0, int y0, int x1, int y1, TPixel color);
+
+// Draws an empty rectangle.
+// Drawing a 1x1 rectangle yields the same result as calling tigrPlot.
+// Clips and blends.
+void tigrRect(Tigr *bmp, int x, int y, int w, int h, TPixel color);
+
+// Fills a rectangle.
+// Fills the inside of the specified rectangular area.
+// Calling tigrRect followed by tigrFillRect using the same arguments
+// causes no overdrawing.
+// Clips and blends.
+void tigrFillRect(Tigr *bmp, int x, int y, int w, int h, TPixel color);
+
+// Draws a circle.
+// Drawing a zero radius circle yields the same result as calling tigrPlot.
+// Drawing a circle with radius one draws a circle three pixels wide.
+// Clips and blends.
+void tigrCircle(Tigr *bmp, int x, int y, int r, TPixel color);
+
+// Fills a circle.
+// Fills the inside of the specified circle.
+// Calling tigrCircle followed by tigrFillCircle using the same arguments
+// causes no overdrawing.
+// Filling a circle with zero radius has no effect.
+// Clips and blends.
+void tigrFillCircle(Tigr *bmp, int x, int y, int r, TPixel color);
+
+// Sets clip rect.
+// Set to (0, 0, -1, -1) to reset clipping to full bitmap.
+void tigrClip(Tigr *bmp, int cx, int cy, int cw, int ch);
+
+// Copies bitmap data.
+// dx/dy = dest co-ordinates
+// sx/sy = source co-ordinates
+// w/h   = width/height
+//
+// RGBAdest = RGBAsrc
+// Clips, does not blend.
+void tigrBlit(Tigr *dest, Tigr *src, int dx, int dy, int sx, int sy, int w, int h);
+
+// Same as tigrBlit, but alpha blends the source bitmap with the
+// target using per pixel alpha and the specified global alpha.
+//
+// Ablend = Asrc * alpha
+// RGBdest = RGBsrc * Ablend + RGBdest * (1 - Ablend)
+//
+// Blit mode == TIGR_KEEP_ALPHA:
+// Adest = Adest
+//
+// Blit mode == TIGR_BLEND_ALPHA:
+// Adest = Asrc * Ablend + Adest * (1 - Ablend)
+// Clips and blends.
+void tigrBlitAlpha(Tigr *dest, Tigr *src, int dx, int dy, int sx, int sy, int w, int h, float alpha);
+
+// Same as tigrBlit, but tints the source bitmap with a color
+// and alpha blends the resulting source with the destination.
+//
+// Rblend = Rsrc * Rtint
+// Gblend = Gsrc * Gtint
+// Bblend = Bsrc * Btint
+// Ablend = Asrc * Atint
+//
+// RGBdest = RGBblend * Ablend + RGBdest * (1 - Ablend)
+//
+// Blit mode == TIGR_KEEP_ALPHA:
+// Adest = Adest
+//
+// Blit mode == TIGR_BLEND_ALPHA:
+// Adest = Ablend * Ablend + Adest * (1 - Ablend)
+// Clips and blends.
+void tigrBlitTint(Tigr *dest, Tigr *src, int dx, int dy, int sx, int sy, int w, int h, TPixel tint);
+
+enum TIGRBlitMode {
+    TIGR_KEEP_ALPHA = 0,    // Keep destination alpha value
+    TIGR_BLEND_ALPHA = 1,   // Blend destination alpha (default)
+};
+
+// Set destination bitmap blend mode for blit operations.
+void tigrBlitMode(Tigr *dest, int mode);
+
+// Helper for making colors.
+TIGR_INLINE TPixel tigrRGB(unsigned char r, unsigned char g, unsigned char b)
+{
+    TPixel p; p.r = r; p.g = g; p.b = b; p.a = 0xff; return p;
+}
+
+// Helper for making colors.
+TIGR_INLINE TPixel tigrRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
+{
+    TPixel p; p.r = r; p.g = g; p.b = b; p.a = a; return p;
+}
+
+
+// Font printing ----------------------------------------------------------
+
+typedef struct {
+    int code, x, y, w, h;
+} TigrGlyph;
+
+typedef struct {
+    Tigr *bitmap;
+    int numGlyphs;
+    TigrGlyph *glyphs;
+} TigrFont;
+
+typedef enum {
+    TCP_ASCII = 0,
+    TCP_1252 = 1252,
+    TCP_UTF32 = 12001
+} TCodepage;
+
+// Loads a font from a bitmap font sheet.
+// The loaded font takes ownership of the provided bitmap.
+//
+// Codepages:
+//
+//  TCP_ASCII   - Regular 7-bit ASCII
+//  TCP_1252    - Windows 1252
+//  TCP_UTF32   - Unicode subset
+//
+// For ASCII and 1252, the font bitmap should contain all characters
+// for the given codepage, excluding the first 32 control codes.
+//
+// For UTF32 - the font bitmap contains a subset of Unicode characters
+// and must be in the format generated by tigrFont for UTF32.
+//
+TigrFont *tigrLoadFont(Tigr *bitmap, int codepage);
+
+// Frees a font and associated font sheet.
+void tigrFreeFont(TigrFont *font);
+
+// Prints UTF-8 text onto a bitmap.
+// NOTE:
+//  This uses the target bitmap blit mode.
+//  See tigrBlitTint for details.
+void tigrPrint(Tigr *dest, TigrFont *font, int x, int y, TPixel color, const char *text, ...);
+
+// Returns the width/height of a string.
+int tigrTextWidth(TigrFont *font, const char *text);
+int tigrTextHeight(TigrFont *font, const char *text);
+
+// The built-in font.
+extern TigrFont *tfont;
+
+
+// User Input -------------------------------------------------------------
+
+// Key scancodes. For letters/numbers, use ASCII ('A'-'Z' and '0'-'9').
+typedef enum {
+    TK_PAD0=128,TK_PAD1,TK_PAD2,TK_PAD3,TK_PAD4,TK_PAD5,TK_PAD6,TK_PAD7,TK_PAD8,TK_PAD9,
+    TK_PADMUL,TK_PADADD,TK_PADENTER,TK_PADSUB,TK_PADDOT,TK_PADDIV,
+    TK_F1,TK_F2,TK_F3,TK_F4,TK_F5,TK_F6,TK_F7,TK_F8,TK_F9,TK_F10,TK_F11,TK_F12,
+    TK_BACKSPACE,TK_TAB,TK_RETURN,TK_SHIFT,TK_CONTROL,TK_ALT,TK_PAUSE,TK_CAPSLOCK,
+    TK_ESCAPE,TK_SPACE,TK_PAGEUP,TK_PAGEDN,TK_END,TK_HOME,TK_LEFT,TK_UP,TK_RIGHT,TK_DOWN,
+    TK_INSERT,TK_DELETE,TK_LWIN,TK_RWIN,TK_NUMLOCK,TK_SCROLL,TK_LSHIFT,TK_RSHIFT,
+    TK_LCONTROL,TK_RCONTROL,TK_LALT,TK_RALT,TK_SEMICOLON,TK_EQUALS,TK_COMMA,TK_MINUS,
+    TK_DOT,TK_SLASH,TK_BACKTICK,TK_LSQUARE,TK_BACKSLASH,TK_RSQUARE,TK_TICK
+} TKey;
+
+// Returns mouse input for a window.
+// The value set to "buttons" is a bit set where bits 0, 1 and 2
+// corresponds to the left, right and middle buttons.
+// A set bit indicates that a button is held.
+void tigrMouse(Tigr *bmp, int *x, int *y, int *buttons);
+
+typedef struct {
+    int x;
+    int y;
+} TigrTouchPoint;
+
+// Reads touch input for a window.
+// Returns number of touch points read.
+int tigrTouch(Tigr *bmp, TigrTouchPoint* points, int maxPoints);
+
+// Reads the delta of the scroll "wheel" in somewhat platform neutral
+// units where 1.0 corresponds to a "notch". The actual correlation between
+// physical movement and this number varies between platforms, input methods
+// and settings.
+void tigrScrollWheel(Tigr* bmp, float* x, float *y);
+
+// Reads the keyboard for a window.
+// Returns non-zero if a key is pressed/held.
+// tigrKeyDown tests for the initial press, tigrKeyHeld repeats each frame.
+int tigrKeyDown(Tigr *bmp, int key);
+int tigrKeyHeld(Tigr *bmp, int key);
+
+// Reads character input for a window.
+// Returns the Unicode value of the last key pressed, or 0 if none.
+int tigrReadChar(Tigr *bmp);
+
+// Show / hide virtual keyboard.
+// (Only available on iOS / Android)
+void tigrShowKeyboard(int show);
+
+
+// Bitmap I/O -------------------------------------------------------------
+
+// Loads a PNG, from either a file or memory. (fileName is UTF-8)
+// On error, returns NULL and sets errno.
+Tigr *tigrLoadImage(const char *fileName);
+Tigr *tigrLoadImageMem(const void *data, int length);
+
+// Saves a PNG to a file. (fileName is UTF-8)
+// On error, returns zero and sets errno.
+int tigrSaveImage(const char *fileName, Tigr *bmp);
+
+
+// Helpers ----------------------------------------------------------------
+
+// Returns the amount of time elapsed since tigrTime was last called,
+// or zero on the first call.
+float tigrTime(void);
+
+// Displays an error message and quits. (UTF-8)
+// 'bmp' can be NULL.
+void tigrError(Tigr *bmp, const char *message, ...);
+
+// Reads an entire file into memory. (fileName is UTF-8)
+// Free it yourself after with 'free'.
+// On error, returns NULL and sets errno.
+// TIGR will automatically append a NUL terminator byte
+// to the end (not included in the length)
+void *tigrReadFile(const char *fileName, int *length);
+
+// Decompresses DEFLATEd zip/zlib data into a buffer.
+// Returns non-zero on success.
+int tigrInflate(void *out, unsigned outlen, const void *in, unsigned inlen);
+
+// Decodes a single UTF8 codepoint and returns the next pointer.
+const char *tigrDecodeUTF8(const char *text, int *cp);
+
+// Encodes a single UTF8 codepoint and returns the next pointer.
+char *tigrEncodeUTF8(char *text, int cp);
+
+#ifdef __cplusplus
+}
+#endif

BIN
modula2/tigr.o


BIN
tigr-master.zip