
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.