فهرست منبع

Graph2 renamed to Graph, SDL2 removed

Arthur Yefimov 3 سال پیش
والد
کامیت
3ab6e5f16c
15فایلهای تغییر یافته به همراه1292 افزوده شده و 3272 حذف شده
  1. 6 7
      src/FreeOberon.Mod
  2. 2 2
      src/GTest.Mod
  3. 1263 1189
      src/Graph.Mod
  4. 0 1440
      src/Graph2.Mod
  5. 0 525
      src/SDL2.Mod
  6. 0 89
      src/SDL2.h0
  7. 1 1
      src/TermBox.Mod
  8. 2 2
      src/compile_GTest.bat
  9. 2 2
      src/compile_GTest.sh
  10. 2 2
      src/compile_TTest.sh
  11. 2 2
      src/compile_TermSnow.sh
  12. 2 2
      src/compile_Tetragon.sh
  13. 2 1
      src/edit.sh
  14. 4 4
      src/make.bat
  15. 4 4
      src/make.sh

+ 6 - 7
src/FreeOberon.Mod

@@ -571,12 +571,11 @@ PROCEDURE ResetSysModules;
   END Add;
 
 BEGIN sysModules := NIL;
-  Add('SYSTEM');  Add('Texts');    Add('Files');  Add('Strings');
-  Add('In');      Add('Out');      Add('Math');   Add('MathL');
-  Add('Modules'); Add('Platform'); Add('Oberon'); Add('Reals');
-  Add('VT100');   Add('Graph');    Add('SDL2');   Add('Term');
-  Add('Graph2');  Add('Allegro5'); Add('TermBox');
-  Add('Dir');     Add('Int');      Add('Random')
+  Add('SYSTEM');   Add('Texts');    Add('Files');   Add('Strings');
+  Add('In');       Add('Out');      Add('Math');    Add('MathL');
+  Add('Modules');  Add('Platform'); Add('Oberon');  Add('Reals');
+  Add('VT100');    Add('Graph');    Add('TermBox'); Add('Term');
+  Add('Allegro5'); Add('Dir');      Add('Int');     Add('Random')
 END ResetSysModules;
 
 PROCEDURE CompileAll(modules: StrList; graph: BOOLEAN;
@@ -833,7 +832,7 @@ BEGIN res := NIL; ok := TRUE;
 RETURN res END UsedModuleList;
 
 PROCEDURE ImportsGraph(p: StrList): BOOLEAN;
-BEGIN WHILE (p # NIL) & (p.s # 'Graph') & (p.s # 'Graph2') (*!FIXME*) DO p := p.next END ;
+BEGIN WHILE (p # NIL) & (p.s # 'Graph') DO p := p.next END ;
 RETURN p # NIL END ImportsGraph;
 
 (* "Module.Mod" -> "Module" *)

+ 2 - 2
src/GTest.Mod

@@ -1,6 +1,6 @@
-(* Graph2 Test Module *)
+(* Graph Test Module *)
 MODULE GTest;
-IMPORT G := Graph2, Random, Out;
+IMPORT G := Graph, Random, Out;
 VAR main: G.Window;
   dialogs: ARRAY 10 OF G.Window;
   nofdialogs: INTEGER;

+ 1263 - 1189
src/Graph.Mod

@@ -1,1366 +1,1440 @@
 MODULE Graph;
-(* Copyright 2017-2022 Arthur Yefimov
-
-This file is part of Free Oberon.
-
-Free Oberon is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-Free Oberon is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
-*)
-IMPORT SDL := SDL2, SYSTEM, Platform, Out, Utf8, Strings, Texts;
+IMPORT Out, Al := Allegro5, Utf8, Files, Dir, Strings, SYSTEM;
 
 CONST
-  (* Flip Flags *)
-  flipNone* = {};
-  flipH*    = 0;
-  flipV*    = 1;
-  flipHV*   = flipH + flipV;
-
-  (* Draw Mode Flags *)
-  drawSpriteNormal* = 0;
-  drawSpriteLit*    = 1;
-  drawSpriteTrans*  = 2;
-
-  (* Settings, see global varialbe settings *)
-  fullscreen*  = 0;
-  buffered*    = 1;
-  spread*      = 2;
-  sharpPixels* = 3;
-  software*    = 4;
-  initMouse*   = 8;
-  noPng* = 11;
-  noJpg* = 12;
-
-  (* Event Types *)
+  fontPlanes = 4; (*!TODO*)
+
+  (* Settings set members *)
+  manual*      = 0;
+  fullscreen*  = 1;
+  window*      = 2;
+  exact*       = 3;
+  smooth*      = 4;
+  software*    = 5;
+  noMouse*     = 6;
+  center*      = 7;
+  resizable*   = 8;
+  maximized*   = 9;
+  minimized*   = 10;
+  frameless*   = 11;
+  nobuffer*    = 12;
+  topleft*     = 13;
+
+  (* Event.type possible values *)
+  noEvent      = 0;
   quit*        = 1;
-  windowEvent* = 2;
-  keyDown*     = 3;
-  keyUp*       = 4;
-  textInput*   = 5;
-  mouseMove*   = 6;
-  mouseDown*   = 7;
-  mouseUp*     = 8;
-  mouseWheel*  = 9;
-
-  (* Mouse Buttons *)
-  btnLeft*  = 0;
-  btnRight* = 1;
-  btnMid*   = 2;
+  timer*       = 2;
+  windowEvent* = 3;
+  keyDown*     = 4;
+  keyUp*       = 5;
+  char*        = 6;
+  mouseMove*   = 7;
+  mouseDown*   = 8;
+  mouseUp*     = 9;
+  mouseWheel*  = 10;
+  resize*      = 11;
+
+  eventUserResize = 2005;
+
+  (* Window.zoom possible values *)
+  noZoom   = 0; (* The screen is not zoomed *)
+  intZoom  = 1; (* The zoom value is an integer: 2x, 3x etc. *)
+  realZoom = 2; (* The zoom value is not an integer, i.e. 2.5x *)
+
+  (* Flip flags *)
+  flipHor*  = 1;
+  flipVert* = 2;
 
   (* Key Codes *)
-  kA*           = 4;
-  kB*           = 5;
-  kC*           = 6;
-  kD*           = 7;
-  kE*           = 8;
-  kF*           = 9;
-  kG*           = 10;
-  kH*           = 11;
-  kI*           = 12;
-  kJ*           = 13;
-  kK*           = 14;
-  kL*           = 15;
-  kM*           = 16;
-  kN*           = 17;
-  kO*           = 18;
-  kP*           = 19;
-  kQ*           = 20;
-  kR*           = 21;
-  kS*           = 22;
-  kT*           = 23;
-  kU*           = 24;
-  kV*           = 25;
-  kW*           = 26;
-  kX*           = 27;
-  kY*           = 28;
-  kZ*           = 29;
-  k1*           = 30;
-  k2*           = 31;
-  k3*           = 32;
-  k4*           = 33;
-  k5*           = 34;
-  k6*           = 35;
-  k7*           = 36;
-  k8*           = 37;
-  k9*           = 38;
-  k0*           = 39;
-  k1Pad*        = 89;
-  k2Pad*        = 90;
-  k3Pad*        = 91;
-  k4Pad*        = 92;
-  k5Pad*        = 93;
-  k6Pad*        = 94;
-  k7Pad*        = 95;
-  k8Pad*        = 96;
-  k9Pad*        = 97;
-  k0Pad*        = 98;
-  kF1*          = 58;
-  kF2*          = 59;
-  kF3*          = 60;
-  kF4*          = 61;
-  kF5*          = 62;
-  kF6*          = 63;
-  kF7*          = 64;
-  kF8*          = 65;
-  kF9*          = 66;
-  kF10*         = 67;
-  kF11*         = 68;
-  kF12*         = 69;
-  kEsc*         = 41;
-  kTilde*       = 53;
-  kMinus*       = 45;
-  kEquals*      = 46;
-  kBackspace*   = 42;
-  kTab*         = 43;
-  kOpenBrace*   = 47;
-  kCloseBrace*  = 48;
-  kEnter*       = 40;
-  kColon*       = 51;
-  kQuote*       = 52;
-  kBackslash*   = 49;
-  kBackslash2*  = 100;
-  kComma*       = 54;
-  kStop*        = 55;
-  kSlash*       = 56;
-  kSpace*       = 44;
-  kInsert*      = 73;
-  kDel*         = 76;
-  kHome*        = 74;
-  kEnd*         = 77;
-  kPgUp*        = 75;
-  kPgDn*        = 78;
-  kLeft*        = 80;
-  kRight*       = 79;
-  kUp*          = 82;
-  kDown*        = 81;
-  kSlashPad*    = 84;
-  kAsterisk*    = 85;
-  kMinusPad*    = 86;
-  kPlusPad*     = 87;
-  kDelPad*      = 99;
-  kEnterPad*    = 88;
-  kPrtScr*      = 70;
-  kPause*       = 72;
-
-  kModifiers*   = 115;
-
-  kLShift*      = 225;
-  kRShift*      = 229;
-  kLCtrl*       = 224;
-  kRCtrl*       = 228;
-  kAlt*         = 226;
-  kAltGr*       = 230;
-  kLWin*        = 227;
-  kRWin*        = 231;
-  kMenu*        = 123;
-  kScrLock*     = 124;
-  kNumLock*     = 125;
-  kCapsLock*    = 126;
-
-  kMax*         = 127;
+  kA*          = 1;
+  kB*          = 2;
+  kC*          = 3;
+  kD*          = 4;
+  kE*          = 5;
+  kF*          = 6;
+  kG*          = 7;
+  kH*          = 8;
+  kI*          = 9;
+  kJ*          = 10;
+  kK*          = 11;
+  kL*          = 12;
+  kM*          = 13;
+  kN*          = 14;
+  kO*          = 15;
+  kP*          = 16;
+  kQ*          = 17;
+  kR*          = 18;
+  kS*          = 19;
+  kT*          = 20;
+  kU*          = 21;
+  kV*          = 22;
+  kW*          = 23;
+  kX*          = 24;
+  kY*          = 25;
+  kZ*          = 26;
+  k0*          = 27;
+  k1*          = 28;
+  k2*          = 29;
+  k3*          = 30;
+  k4*          = 31;
+  k5*          = 32;
+  k6*          = 33;
+  k7*          = 34;
+  k8*          = 35;
+  k9*          = 36;
+  k0Pad*       = 37;
+  k1Pad*       = 38;
+  k2Pad*       = 39;
+  k3Pad*       = 40;
+  k4Pad*       = 41;
+  k5Pad*       = 42;
+  k6Pad*       = 43;
+  k7Pad*       = 44;
+  k8Pad*       = 45;
+  k9Pad*       = 46;
+  kF1*         = 47;
+  kF2*         = 48;
+  kF3*         = 49;
+  kF4*         = 50;
+  kF5*         = 51;
+  kF6*         = 52;
+  kF7*         = 53;
+  kF8*         = 54;
+  kF9*         = 55;
+  kF10*        = 56;
+  kF11*        = 57;
+  kF12*        = 58;
+  kEsc*        = 59;
+  kTilde*      = 60;
+  kMinus*      = 61;
+  kEquals*     = 62;
+  kBackspace*  = 63;
+  kTab*        = 64;
+  kOpenBrace*  = 65;
+  kCloseBrace* = 66;
+  kEnter*      = 67;
+  kColon*      = 68;
+  kQuote*      = 69;
+  kBackslash*  = 70;
+  kBackslash2* = 71;
+  kComma*      = 72;
+  kStop*       = 73;
+  kSlash*      = 74;
+  kSpace*      = 75;
+  kInsert*     = 76;
+  kDel*        = 77;
+  kHome*       = 78;
+  kEnd*        = 79;
+  kPgUp*       = 80;
+  kPgDn*       = 81;
+  kLeft*       = 82;
+  kRight*      = 83;
+  kUp*         = 84;
+  kDown*       = 85;
+  kSlashPad*   = 86;
+  kAsterisk*   = 87;
+  kMinusPad*   = 88;
+  kPlusPad*    = 89;
+  kDelPad*     = 90;
+  kEnterPad*   = 91;
+  kPrtScr*     = 92;
+  kPause*      = 93;
+  kEqualsPad*  = 103;
+  kBackquote*  = 104;
+  kSemicolon2* = 105;
+  kCommand*    = 106;
+
+  kBack*       = 107;
+  kVolumeUp*   = 108;
+  kVolumeDown* = 109;
+
+  kModifers*   = 215;
+
+  kLShift*     = 215;
+  kRShift*     = 216;
+  kLCtrl*      = 217;
+  kRCtrl*      = 218;
+  kAlt*        = 219;
+  kAltGr*      = 220;
+  kLMeta*      = 221;
+  kRMeta*      = 222;
+  kMenu*       = 223;
+  kScrLock*    = 224;
+  kNumLock*    = 225;
+  kCapsLock*   = 226;
+
+  kMax*        = 226;
 
   (* Modifiers Set *)
-  mLShift*   = 0;
-  mRShift*   = 1;
-  mLCtrl*    = 6;
-  mRCtrl*    = 7;
-  mLAlt*     = 8;
-  mRAlt*     = 9;
-  mLGui*     = 10;
-  mRGui*     = 11;
-  mNum*      = 12;
-  mCaps*     = 13;
-  mMode*     = 14;
-  mReserved* = 15;
-  mCtrl*  = {mLCtrl, mRCtrl};
-  mShift* = {mLShift, mRShift};
-  mAlt*   = {mLAlt, mRAlt};
-  mGui*   = {mLGui, mRGui};
+  mShift*      = 0;
+  mCtrl*       = 1;
+  mAlt*        = 2;
+  mLwin*       = 3;
+  mRwin*       = 4;
+  mMenu*       = 5;
+  mAltGr*      = 6;
+  mCommand*    = 7;
+  mScrolllock* = 8;
+  mNumlock*    = 9;
+  mCapslock*   = 10;
 
 TYPE
   ADRINT = SYSTEM.ADRINT;
-  SET32 = SET;
   REAL = SYSTEM.REAL32;
+  LONGREAL = SYSTEM.REAL64;
+  LONGINT = SYSTEM.INT64;
+  SHORTCHAR = SYSTEM.CHAR8;
 
-  Bitmap* = POINTER TO BitmapDesc;
-  BitmapDesc* = RECORD
-    surface: SDL.Surface;
-    w*, h*: INTEGER
-  END;
-
-  MonoFont* = POINTER TO MonoFontDesc;
-  MonoFontDesc* = RECORD
-    bmp*: Bitmap;
-    charW*, charH*: INTEGER;
-    charRows*, charsInRow*: INTEGER;
-    sprites*: POINTER TO ARRAY OF ARRAY OF SDL.Rect
+  Color* = RECORD
+    r, g, b, a: REAL
   END;
 
-  CharGeo* = RECORD
-    w*, x*, y*: INTEGER
+  Transform* = RECORD
+    m: ARRAY 4, 4 OF REAL
   END;
 
-  Font* = POINTER TO FontDesc;
-  FontDesc* = RECORD
-    bmp*: Bitmap;
-    geo*: ARRAY 512 OF CharGeo;
-    geoCount*: INTEGER;
-    h*: INTEGER
+  Timer* = POINTER TO TimerDesc;
+  TimerDesc* = RECORD
+    tmr: Al.Timer;
+    next: Timer (* See timerList below *)
   END;
 
-  KeyArray = SDL.KeyArray;
-
-  Key* = RECORD
-    code*: INTEGER; (* Physical key code *)
-    sym*: INTEGER; (* Virtual key code *)
-    mod*: SET; (* Key modifiers *)
-    repeat*: BOOLEAN
+  Bitmap* = POINTER TO BitmapDesc;
+  BitmapDesc* = RECORD
+    bmp: Al.Bitmap;
+    w*, h*: INTEGER
   END;
 
-  Region* = RECORD
-    x*, y*, w*, h*: INTEGER
+  Window* = POINTER TO WindowDesc;
+  WindowDesc* = RECORD(BitmapDesc)
+    display: Al.Display;
+    winW, winH: INTEGER; (* Window size in real pixels *)
+    initX, initY: INTEGER; (* Window position upon its creation *)
+    initW, initH: INTEGER; (* Window size upon its creation *)
+    fsW, fsH: INTEGER; (* Window size upon its creation *)
+    wantZoom: REAL; (* Window zoom upon its creation *)
+    lastX, lastY: INTEGER; (* Last mouse position in virtual pixels *)
+    lastW, lastH: INTEGER; (* Last stepped size in virtual pixels *)
+    zoom: INTEGER; (* See constants above; based on this rzoom/izoom is used *)
+    izoom: INTEGER; (* Window.izoom is used if Window.zoom = intZoom  *)
+    rzoom: REAL;    (* Window.rzoom is used if Window.zoom = realZoom *)
+    scaleOn: BOOLEAN; (* If TRUE, scaleX and scaleY are used *)
+    scaleX, scaleY: REAL; (* Deforms pixels on Flip, but zoom is for drawing *)
+    sizeStepX, sizeStepY: INTEGER;
+    flipX, flipY, flipW, flipH: REAL; (* Where to flip the window bitmap to *)
+    iFlipX, iFlipY: INTEGER; (* Same as flipX, flipY, which are always whole *)
+    options: SET;
+    title: ARRAY 256 OF CHAR;
+    resized: BOOLEAN; (* TRUE if fullscreen mode has been toggled for window *)
+    showMouse: BOOLEAN;
+    icons: ARRAY 64 OF Al.Bitmap;
+    noficons: INTEGER;
+    next: Window (* See windowList below *)
   END;
 
   Event* = RECORD
     type*: INTEGER;
-    key*: Key;
-    x*, y*: INTEGER;
-    xRel*, yRel*: INTEGER;
+    time*: REAL;
+    x*, y*, z*, w*, h*: INTEGER;
+    dx*, dy*, dz*, dw*: INTEGER;
     button*: INTEGER;
     buttons*: SET; (* What mouse buttons are pressed *)
     down*: BOOLEAN;
-    s*: ARRAY 32 OF CHAR; (* For Text Input and Text Edit Events (SDL2, !TODO) *)
-    ch*: CHAR
+    count*: LONGINT; (* Timer counter *)
+    key*: INTEGER; (* Physical key code *)
+    ch*: CHAR; (* Typed character for event.type = char *)
+    mod*: SET; (* Key modifiers *)
+    repeat*: BOOLEAN;
+    window*: Window;
+    timer*: Timer;
+    display: Al.Display
   END;
 
-  EventQueue* = RECORD
-    buf: ARRAY 256 OF Event;
-    first, last: INTEGER; (* Index of first and last element *)
-    len: INTEGER (* Amount of elements currently in queue *)
+  FontMessage* = POINTER TO FontMessageDesc;
+  FontMessageDesc* = RECORD
+
   END;
 
-  CloseBtnProc* = PROCEDURE;
+  FontDrawMsg* = POINTER TO FontDrawMsgDesc;
+  FontDrawMsgDesc* = RECORD(FontMessage)
+
+  END;
+
+  Font* = POINTER TO FontDesc;
+  FontDesc* = RECORD
+    fname: ARRAY 256 OF CHAR;
+    handle: PROCEDURE (font: Font; VAR msg: FontMessage);
+    draw: PROCEDURE (font: Font; VAR msg: FontDrawMsg);
+    loaded*: BOOLEAN
+  END;
+
+  MonoFont* = POINTER TO MonoFontDesc;
+  MonoFontDesc* = RECORD(FontDesc)
+    bmp: Bitmap;
+    charW*, charH*: INTEGER;
+    rows, cols: INTEGER
+  END;
 
 VAR
-  window: SDL.Window;
-  renderer: SDL.Renderer;
-  screen: Bitmap;
-  screenTexture: SDL.Texture;
-  events: EventQueue;
-  keyPressed: INTEGER;
-
-  settings, initSettings: SET; (* See constants above *)
-  sizeStepX, sizeStepY: INTEGER;
-  scaleX, scaleY: REAL;
-  scrW, scrH: INTEGER;
-  wantFPS: INTEGER;
-  buffer: Bitmap;
-  lastFlip: INTEGER;
-  frames, framesT: INTEGER;
-  screenAlpha: INTEGER;
-
-  (* Flip Region *)
-  flipRegion: Region;
-
-  (* Mouse *)
-  mouseX, mouseY: INTEGER;
-  mouseFocusX, mouseFocusY: INTEGER;
-  lastBlitMouseOutside: BOOLEAN;
-  lastBlitMouseX, lastBlitMouseY: INTEGER;
-  needRedrawMouse: BOOLEAN; (* True if mouse has moved since last redraw *)
-  showMouse: BOOLEAN; (* Whether to show mouse pointer on screen *)
-  stdMousePointer: Bitmap;
-  mousePointer: Bitmap;
-  underMouse: Bitmap; (* Buffer to copy part of image under the mouse *)
-
-PROCEDURE -AAIncludeSDL2h0 '#include "SDL2.h0"';
-
-(* General *)
-
-PROCEDURE GetError*(OUT s: ARRAY OF CHAR);
-TYPE P = POINTER TO ARRAY 2048 OF SHORTCHAR;
-VAR p: P;
-BEGIN p := SYSTEM.VAL(P, SDL.GetError()); Utf8.Decode(p^, s)
-END GetError;
+  Done*: BOOLEAN;
+
+  settings: SET; (* See list of constants Settings above *)
+  wantW, wantH: INTEGER; (* Assigned in procedure Settings *)
+  wantZoom: REAL; (* Assigned in procedure SetZoom *)
+  wantSizeStepX, wantSizeStepY: INTEGER; (* Assigned in SetSizeStep *)
+  wantScaleX, wantScaleY: REAL; (* Assigned in procedure SetScale *)
+  wantTitle: ARRAY 256 OF CHAR; (* Assigned in procedure SetTitle *)
+  queue: Al.EventQueue;
+  userEventSource: Al.EventSource;
+  windowList: Window;
+  timerList: Timer;
+  screen: Window;
+  target: Bitmap;
+  black: Color;
+
+PROCEDURE Error(s: ARRAY OF CHAR);
+BEGIN Out.String(s); Out.Ln
+END Error;
+
+PROCEDURE GetDesktopResolution*(VAR w, h: INTEGER);
+VAR info: Al.MonitorInfo;
+BEGIN
+  IF Al.get_monitor_info(0, info) THEN
+    w := info.x2 - info.x1;
+    h := info.y2 - info.y1
+  ELSE w := -1; h := -1
+  END
+END GetDesktopResolution;
+
+PROCEDURE GetScreen*(): Window;
+RETURN screen END GetScreen;
+
+PROCEDURE GetScreenSize*(VAR width, height: INTEGER);
+BEGIN
+  IF screen # NIL THEN width := screen.w; height := screen.h
+  ELSE width := 0; height := 0
+  END
+END GetScreenSize;
 
 PROCEDURE Settings*(w, h: INTEGER; flags: SET);
-BEGIN scrW := w; scrH := h;
-  initSettings := flags;
-  showMouse := initMouse IN flags
+BEGIN wantW := w; wantH := h; settings := flags
 END Settings;
 
 PROCEDURE SetSizeStep*(w, h: INTEGER);
-BEGIN sizeStepX := w; sizeStepY := h
+BEGIN wantSizeStepX := w; wantSizeStepY := h
 END SetSizeStep;
 
-PROCEDURE ApplyScale;
+PROCEDURE ApplySizeStep(W: Window; VAR w, h: INTEGER);
 BEGIN
-  SDL.RenderSetLogicalSize(renderer,
-    SHORT(ENTIER(scrW * scaleX)), SHORT(ENTIER(scrH * scaleY)));
-END ApplyScale;
-
-PROCEDURE SetScale*(x, y: REAL);
-BEGIN scaleX := x; scaleY := y;
-  IF renderer # 0 THEN ApplyScale END
-END SetScale;
-
-PROCEDURE SetFPS*(fps: INTEGER);
-BEGIN IF fps <= 0 THEN fps := -1 END;
-  wantFPS := fps
-END SetFPS;
+  IF W.sizeStepX # 1 THEN
+    w := w DIV W.sizeStepX * W.sizeStepX;
+    IF w < W.sizeStepX THEN w := W.sizeStepX END
+  END;
+  IF W.sizeStepY # 1 THEN
+    h := h DIV W.sizeStepY * W.sizeStepY;
+    IF h < W.sizeStepY THEN h := W.sizeStepY END
+  END
+END ApplySizeStep;
 
-PROCEDURE GetDesktopResolution*(VAR w, h: INTEGER);
-VAR mode: SDL.DisplayMode;
-BEGIN SDL.GetDesktopDisplayMode(0, mode);
-  w := mode.w; h := mode.h
-END GetDesktopResolution;
+PROCEDURE GetTarget*(): Bitmap;
+RETURN target END GetTarget;
 
-(* Flip Region *)
-PROCEDURE SetRegion*(x, y, w, h: INTEGER);
+PROCEDURE GetTargetSize*(VAR width, height: INTEGER);
 BEGIN
-  flipRegion.x := x; flipRegion.y := y;
-  flipRegion.w := w; flipRegion.h := h
-END SetRegion;
+  IF target # NIL THEN width := target.w; height := target.h
+  ELSE width := 0; height := 0
+  END
+END GetTargetSize;
+
+PROCEDURE Target*(bitmap: Bitmap);
+VAR T: Al.Transform;
+  W: Window;
+BEGIN target := bitmap;
+  IF bitmap # NIL THEN
+    IF (bitmap IS Window) & (bitmap.bmp = NIL) THEN W := bitmap(Window);
+      Al.set_target_backbuffer(W.display);
+      Al.build_transform(T, W.flipX, W.flipY, W.scaleX, W.scaleY, 0.0);
+      Al.use_transform(T)
+    ELSE Al.set_target_bitmap(SYSTEM.VAL(Al.Bitmap, bitmap.bmp))
+    END
+  END
+END Target;
 
-PROCEDURE UnsetRegion*;
-BEGIN flipRegion.w := -1
-END UnsetRegion;
+PROCEDURE TargetScreen*;
+BEGIN
+  IF screen # NIL THEN Target(screen)
+  ELSIF windowList # NIL THEN Target(windowList)
+  ELSE Target(NIL)
+  END
+END TargetScreen;
 
-PROCEDURE AddRegion*(x, y, w, h: INTEGER);
+PROCEDURE ResetFlipVars(W: Window);
+VAR w, h: INTEGER;
 BEGIN
-  IF flipRegion.w = -1 THEN (* No flip region yet *)
-    SetRegion(x, y, w, h) (* Just set it *)
-  ELSE (* Flip Region exists, add to it *)
-    IF x < flipRegion.x THEN flipRegion.x := x END;
-    IF y < flipRegion.y THEN flipRegion.y := y END;
-    IF x + w > flipRegion.x + flipRegion.w THEN
-      flipRegion.w := w + x - flipRegion.x END;
-    IF y + h > flipRegion.y + flipRegion.h THEN
-      flipRegion.h := h + y - flipRegion.y END
+  IF W.zoom = intZoom THEN
+    w := W.w * W.izoom; h := W.h * W.izoom;
+    IF W.scaleOn THEN
+      W.flipW := FLT(FLOOR(FLT(w) * W.scaleX + 0.9));
+      W.flipH := FLT(FLOOR(FLT(h) * W.scaleY + 0.9));
+      W.iFlipX := (W.winW - FLOOR(W.flipW + 0.1)) DIV 2;
+      W.iFlipY := (W.winH - FLOOR(W.flipH + 0.1)) DIV 2
+    ELSE W.flipW := FLT(w); W.flipH := FLT(h);
+      W.iFlipX := (W.winW - w) DIV 2; W.iFlipY := (W.winH - h) DIV 2
+    END
+  ELSE
+    W.flipW := FLT(FLOOR(W.w * W.rzoom * W.scaleX + 0.9));
+    W.flipH := FLT(FLOOR(W.h * W.rzoom * W.scaleY + 0.9));
+    W.iFlipX := (W.winW - FLOOR(W.flipW + 0.1)) DIV 2;
+    W.iFlipY := (W.winH - FLOOR(W.flipH + 0.1)) DIV 2
+  END;
+  IF topleft IN W.options THEN W.iFlipX := 0; W.iFlipY := 0 END;
+  W.flipX := FLT(W.iFlipX); W.flipY := FLT(W.iFlipY);
+  IF ~(exact IN W.options) & (smooth IN W.options) &
+     ~(topleft IN W.options) & (W.winW - W.flipX - W.flipW < W.rzoom) &
+     (W.winH - W.flipY - W.flipH < W.rzoom) THEN
+    W.iFlipX := 0; W.iFlipY := 0; W.flipX := 0.0; W.flipY := 0.0;
+    W.flipW := FLT(W.winW); W.flipH := FLT(W.winH)
   END
-END AddRegion;
+END ResetFlipVars;
+
+PROCEDURE ResetWindowBitmap(W: Window);
+VAR opt: SET;
+  w, h, bw, bh: INTEGER;
+  fw, fh: REAL;
+  scaled, wasTarget: BOOLEAN;
+BEGIN scaled := FALSE;
+  IF W.bmp = NIL THEN bw := -1
+  ELSE bw := Al.get_bitmap_width(W.bmp); bh := Al.get_bitmap_height(W.bmp)
+  END;
+  IF ~(exact IN W.options) THEN
+    IF W.zoom = noZoom THEN w := W.winW; h := W.winH
+    ELSIF (W.zoom = intZoom) & ~W.scaleOn THEN
+      w := W.winW DIV W.izoom; h := W.winH DIV W.izoom
+    ELSE scaled := TRUE;
+      w := FLOOR(W.winW / W.rzoom / W.scaleX + 0.1);
+      h := FLOOR(W.winH / W.rzoom / W.scaleY + 0.1)
+    END
+  ELSE w := W.w; h := W.h
+  END;
+  IF W.scaleOn & ~scaled THEN
+    w := FLOOR(w / W.scaleX + 0.1); h := FLOOR(h / W.scaleY + 0.1)
+  END;
 
-(* Drawing *)
+  ApplySizeStep(W, w, h);
+  IF (w > bw) OR (h > bh) OR (W.zoom = noZoom) THEN
+    IF W.bmp # NIL THEN
+      wasTarget := Al.get_target_bitmap() = W.bmp;
+      Al.destroy_bitmap(W.bmp)
+    END;
+    IF (W.zoom = noZoom) & (nobuffer IN W.options) THEN
+      W.bmp := NIL;
+      IF wasTarget THEN Target(NIL) END
+    ELSE opt := {Al.convertBitmap};
+      IF smooth IN W.options THEN
+      	opt := opt + {Al.minLinear, Al.magLinear}
+      END;
+      Al.set_new_bitmap_flags(opt);
+      W.bmp := Al.create_bitmap(w, h);
+      IF wasTarget THEN Target(W) END
+    END
+  END;
+  W.w := w; W.h := h;
+  ResetFlipVars(W)
+END ResetWindowBitmap;
+
+PROCEDURE GetWindowOptions*(W: Window): SET;
+RETURN W.options END GetWindowOptions;
+
+PROCEDURE GetWindowZoom*(W: Window): REAL;
+RETURN W.rzoom END GetWindowZoom;
+
+PROCEDURE SetWindowZoomF*(W: Window; zoom: REAL);
+BEGIN W.rzoom := zoom;
+  IF zoom = 1.0 THEN W.zoom := noZoom
+  ELSIF FLOOR(zoom + 0.001) * 100 = FLOOR(zoom * 100 + 0.001) THEN
+    W.zoom := intZoom; W.izoom := FLOOR(zoom + 0.001)
+  ELSE W.zoom := realZoom
+  END;
+  ResetWindowBitmap(W)
+END SetWindowZoomF;
 
-PROCEDURE MakeCol*(r, g, b: INTEGER): INTEGER;
-BEGIN
-  r := SYSTEM.VAL(INTEGER, SYSTEM.VAL(SET32, r) * {0..7});
-  g := SYSTEM.VAL(INTEGER, SYSTEM.VAL(SET32, g) * {0..7});
-  b := SYSTEM.VAL(INTEGER, SYSTEM.VAL(SET32, b) * {0..7}) ;
-RETURN SYSTEM.LSH(SYSTEM.LSH(0FF00H + b, 8) + g, 8) + r END MakeCol;
+PROCEDURE SetWindowZoom*(W: Window; zoom: INTEGER);
+BEGIN W.rzoom := FLT(zoom);
+  IF zoom = 1 THEN W.zoom := noZoom
+  ELSE W.zoom := intZoom; W.izoom := zoom
+  END;
+  ResetWindowBitmap(W)
+END SetWindowZoom;
 
-PROCEDURE ColorToRGB*(color: INTEGER; VAR r, g, b: INTEGER);
-BEGIN
-  r := SYSTEM.VAL(INTEGER, SYSTEM.VAL(SET32, color) * {0..7});
-  g := SYSTEM.VAL(INTEGER, SYSTEM.VAL(SET32, SYSTEM.LSH(color, -8)) * {0..7});
-  b := SYSTEM.VAL(INTEGER, SYSTEM.VAL(SET32, SYSTEM.LSH(color, -16)) * {0..7})
-END ColorToRGB;
+PROCEDURE SetNewWindowZoomF*(zoom: REAL);
+BEGIN wantZoom := zoom
+END SetNewWindowZoomF;
+
+PROCEDURE SetZoomF*(zoom: REAL);
+BEGIN wantZoom := zoom;
+  IF screen # NIL THEN SetWindowZoomF(screen, zoom) END
+END SetZoomF;
 
-PROCEDURE ColorToRGBA*(color: INTEGER; VAR r, g, b, a: INTEGER);
+PROCEDURE SetNewWindowZoom*(zoom: INTEGER);
+BEGIN wantZoom := FLT(zoom)
+END SetNewWindowZoom;
+
+PROCEDURE SetZoom*(zoom: INTEGER);
+BEGIN wantZoom := FLT(zoom);
+  IF screen # NIL THEN SetWindowZoom(screen, zoom) END
+END SetZoom;
+
+PROCEDURE SetWindowFullscreenSize*(win: Window; width, height: INTEGER);
+BEGIN win.fsW := width; win.fsH := height
+END SetWindowFullscreenSize;
+
+PROCEDURE ShowWindowMouse*(W: Window; show: BOOLEAN);
 BEGIN
-  r := SYSTEM.VAL(INTEGER, SYSTEM.VAL(SET32, color) * {0..7});
-  g := SYSTEM.VAL(INTEGER, SYSTEM.VAL(SET32, SYSTEM.LSH(color, -8)) * {0..7});
-  b := SYSTEM.VAL(INTEGER, SYSTEM.VAL(SET32, SYSTEM.LSH(color, -16)) * {0..7});
-  a := SYSTEM.VAL(INTEGER, SYSTEM.VAL(SET32, SYSTEM.LSH(color, -24)) * {0..7})
-END ColorToRGBA;
+  IF show THEN
+    IF Al.show_mouse_cursor(W.display) THEN W.showMouse := TRUE END
+  ELSE
+    IF Al.hide_mouse_cursor(W.display) THEN W.showMouse := FALSE END
+  END
+END ShowWindowMouse;
 
-PROCEDURE BmpCol*(bmp: Bitmap; r, g, b: INTEGER): INTEGER;
-BEGIN RETURN SDL.MapRGB(bmp.surface.format, SHORT(r), SHORT(g), SHORT(b))
-END BmpCol;
+PROCEDURE ShowMouse*(show: BOOLEAN);
+BEGIN IF screen # NIL THEN ShowWindowMouse(screen, show) END
+END ShowMouse;
 
-PROCEDURE ClearToColor*(bmp: Bitmap; color: INTEGER);
-BEGIN SDL.FillRectNil(bmp.surface, color)
-END ClearToColor;
+PROCEDURE ApplyScale*(W: Window);
+VAR t: Al.Transform;
+BEGIN
+  (*Target(W);
+  Al.build_transform(t, 0.0, 0.0, 6.0, 6.0, 0.0);
+  Al.use_transform(t)*)
+END ApplyScale;
 
-PROCEDURE ClearBitmap*(bmp: Bitmap);
-BEGIN ClearToColor(bmp, MakeCol(0, 0, 0))
-END ClearBitmap;
+PROCEDURE SetWindowOption*(W: Window; key: INTEGER; on: BOOLEAN);
+BEGIN IF on THEN INCL(W.options, key) ELSE EXCL(W.options, key) END
+END SetWindowOption;
 
-PROCEDURE ClearScreenToColor*(color: INTEGER);
-BEGIN ClearToColor(screen, color)
-END ClearScreenToColor;
+PROCEDURE SetWindowScale*(W: Window; x, y: REAL);
+BEGIN W.scaleOn := (x # 1.0) OR (y # 1.0);
+  W.scaleX := x; W.scaleY := y; ApplyScale(W)
+END SetWindowScale;
 
-PROCEDURE ClearScreen*;
-BEGIN ClearToColor(screen, MakeCol(0, 0, 0))
-END ClearScreen;
+PROCEDURE SetNewWindowScale*(x, y: REAL);
+BEGIN wantScaleX := x; wantScaleY := y
+END SetNewWindowScale;
 
-PROCEDURE LockBitmap*(bmp: Bitmap);
-BEGIN SDL.LockSurface(bmp.surface)
-END LockBitmap;
+PROCEDURE SetScale*(x, y: REAL);
+BEGIN wantScaleX := x; wantScaleY := y;
+  IF screen # NIL THEN SetWindowScale(screen, x, y) END
+END SetScale;
 
-PROCEDURE UnlockBitmap*(bmp: Bitmap);
-BEGIN SDL.UnlockSurface(bmp.surface)
-END UnlockBitmap;
+PROCEDURE SetWindowTitle*(W: Window; title: ARRAY OF CHAR);
+VAR q: ARRAY 256 OF SHORTCHAR;
+BEGIN Utf8.Encode(title, q); Al.set_window_title(W.display, q)
+END SetWindowTitle;
 
-PROCEDURE PutPixelFast*(bmp: Bitmap; x, y, color: INTEGER);
-VAR n: ADRINT;
-BEGIN n := SYSTEM.VAL(ADRINT, bmp.surface.pixels);
-  INC(n, (y * bmp.w + x) * 4);
-  SYSTEM.PUT(n, color)
-END PutPixelFast;
+PROCEDURE SetNewWindowTitle*(title: ARRAY OF CHAR);
+BEGIN wantTitle := title
+END SetNewWindowTitle;
+
+PROCEDURE SetTitle*(title: ARRAY OF CHAR);
+BEGIN wantTitle := title;
+  IF screen # NIL THEN SetWindowTitle(screen, title) END
+END SetTitle;
+
+(*PROCEDURE ClearBitmap*(bmp: Bitmap);
+PROCEDURE ClearScreenToColor*(color: INTEGER);*)
+
+PROCEDURE LoadBitmap*(fname: ARRAY OF CHAR): Bitmap;
+VAR B: Bitmap;
+  q: ARRAY 2048 OF SHORTCHAR;
+BEGIN Al.set_new_bitmap_flags({Al.convertBitmap});
+  NEW(B); Utf8.Encode(fname, q); B.bmp := Al.load_bitmap(q);
+  IF B.bmp = NIL THEN B := NIL
+  ELSE B.w := Al.get_bitmap_width(B.bmp); B.h := Al.get_bitmap_height(B.bmp)
+  END
+RETURN B END LoadBitmap;
 
-PROCEDURE PutPixel*(bmp: Bitmap; x, y, color: INTEGER);
-VAR n: ADRINT;
+PROCEDURE Flip*;
+VAR tmp: Al.Bitmap;
+  W: Window;
+  T: Al.Transform;
+  x, y, w, h: REAL;
 BEGIN
-  IF (x >= 0) & (x < bmp.w) &
-     (y >= 0) & (y < bmp.h) THEN
-    SDL.LockSurface(bmp.surface);
-    n := SYSTEM.VAL(ADRINT, bmp.surface.pixels);
-    INC(n, (y * bmp.w + x) * 4);
-    SYSTEM.PUT(n, color);
-    SDL.UnlockSurface(bmp.surface)
+  IF ((target = NIL) OR ~(target IS Window)) & (screen # NIL) THEN
+    Target(screen)
+  END;
+  IF (target # NIL) & (target IS Window) THEN
+    W := target(Window);
+    tmp := Al.get_target_bitmap();
+    Al.set_target_backbuffer(W.display);
+    Al.identity_transform(T);
+    Al.use_transform(T);
+    IF target.bmp # NIL THEN
+      Al.clear_to_color(SYSTEM.VAL(Al.Color, black));
+      Al.draw_scaled_bitmap(W.bmp, 0.0, 0.0, FLT(W.w), FLT(W.h),
+        W.flipX, W.flipY, W.flipW, W.flipH, {})
+    ELSE w := FLT(W.winW); h := FLT(W.winH);
+      x := FLT(FLOOR(W.flipX + W.flipW + 0.1));
+      y := FLT(FLOOR(W.flipY + W.flipH + 0.1));
+      Al.draw_filled_rectangle(0.0, 0.0, w, W.flipY,
+        SYSTEM.VAL(Al.Color, black));
+      Al.draw_filled_rectangle(0.0, y, w, h, SYSTEM.VAL(Al.Color, black));
+      Al.draw_filled_rectangle(0.0, W.flipY, W.flipX, y,
+        SYSTEM.VAL(Al.Color, black));
+      Al.draw_filled_rectangle(x, W.flipY, w, y, SYSTEM.VAL(Al.Color, black))
+    END;
+    Al.flip_display();
+    Al.set_target_bitmap(tmp)
   END
+END Flip;
+
+PROCEDURE PutPixel2*(x, y: INTEGER; c: Color);
+BEGIN Al.draw_filled_rectangle(FLT(x), FLT(y), FLT(x + 1), FLT(y + 1),
+  SYSTEM.VAL(Al.Color, c))
+END PutPixel2;
+
+PROCEDURE PutPixel*(x, y: INTEGER; c: Color);
+BEGIN Al.draw_pixel(FLT(x) + 0.5, FLT(y) + 0.5, SYSTEM.VAL(Al.Color, c))
 END PutPixel;
 
-PROCEDURE GetPixelFast*(bmp: Bitmap; x, y: INTEGER): INTEGER;
-VAR color: INTEGER;
-  n: ADRINT;
-BEGIN n := SYSTEM.VAL(ADRINT, bmp.surface.pixels);
-  INC(n, (y * bmp.w + x) * 4);
-  SYSTEM.GET(n, color) ;
-RETURN color END GetPixelFast;
-
-PROCEDURE GetPixel*(bmp: Bitmap; x, y: INTEGER): INTEGER;
-VAR color: INTEGER;
-  n: ADRINT;
-BEGIN
-  IF (x >= 0) & (x < bmp.w) &
-     (y >= 0) & (y < bmp.h) THEN
-    SDL.LockSurface(bmp.surface);
-    n := SYSTEM.VAL(ADRINT, bmp.surface.pixels);
-    INC(n, (y * bmp.w + x) * 4);
-    SYSTEM.GET(n, color);
-    SDL.UnlockSurface(bmp.surface)
-  ELSE color := 0
-  END ;
-RETURN color END GetPixel;
-
-PROCEDURE HLine*(bmp: Bitmap; x1, y, x2, color: INTEGER);
-VAR rect: SDL.Rect; t: INTEGER;
-BEGIN
-  IF x1 > x2 THEN t := x1; x1 := x2; x2 := t END;
-  rect.x := x1; rect.y := y;
-  rect.w := x2 - x1 + 1; rect.h := 1;
-  SDL.FillRect(bmp.surface, rect, color)
-END HLine;
+PROCEDURE MakeCol*(VAR color: Color; r, g, b: INTEGER);
+BEGIN color.r := r / 255; color.g := g / 255;
+  color.b := b / 255; color.a := 1.0
+END MakeCol;
+
+PROCEDURE ColorToRGB*(color: Color; VAR r, g, b: INTEGER);
+BEGIN r := FLOOR(color.r * 255 + 0.1) MOD 256;
+  g := FLOOR(color.g * 255 + 0.1) MOD 256;
+  b := FLOOR(color.b * 255 + 0.1) MOD 256
+END ColorToRGB;
+
+PROCEDURE ColorToRGBA*(color: Color; VAR r, g, b, a: INTEGER);
+BEGIN r := FLOOR(color.r * 255 + 0.1) MOD 256;
+  g := FLOOR(color.g * 255 + 0.1) MOD 256;
+  b := FLOOR(color.b * 255 + 0.1) MOD 256;
+  a := FLOOR(color.a * 255 + 0.1) MOD 256
+END ColorToRGBA;
+
+PROCEDURE ClearToColor*(c: Color);
+BEGIN Al.clear_to_color(SYSTEM.VAL(Al.Color, c))
+END ClearToColor;
+
+PROCEDURE ClearScreen*;
+BEGIN Al.clear_to_color(SYSTEM.VAL(Al.Color, black))
+END ClearScreen;
 
-PROCEDURE VLine*(bmp: Bitmap; x, y1, y2, color: INTEGER);
-VAR rect: SDL.Rect; t: INTEGER;
+PROCEDURE ThickLineF*(x1, y1, x2, y2: REAL; color: Color; thickness: REAL);
+BEGIN Al.draw_line(x1, y1, x2, y2, SYSTEM.VAL(Al.Color, color), thickness)
+END ThickLineF;
+
+PROCEDURE ThickLine*(x1, y1, x2, y2: INTEGER; color: Color;
+    thickness: INTEGER);
 BEGIN
-  IF y1 > y2 THEN t := y1; y1 := y2; y2 := t END;
-  rect.x := x; rect.y := y1;
-  rect.w := 1; rect.h := y2 - y1 + 1;
-  SDL.FillRect(bmp.surface, rect, color)
-END VLine;
+  Al.draw_line(FLT(x1) + 0.5, FLT(y1) + 0.5, FLT(x2) + 0.5, FLT(y2) + 0.5,
+    SYSTEM.VAL(Al.Color, color), FLT(thickness))
+END ThickLine;
 
-PROCEDURE Line*(bmp: Bitmap; x1, y1, x2, y2, color: INTEGER);
-VAR x, y, i, dx, dy, sx, sy, e: INTEGER; vert: BOOLEAN;
+PROCEDURE LineF*(x1, y1, x2, y2: REAL; color: Color);
 BEGIN
-  IF x1 = x2 THEN VLine(bmp, x1, y1, y2, color)
-  ELSIF y1 = y2 THEN HLine(bmp, x1, y1, x2, color)
-  ELSE
-    SDL.LockSurface(bmp.surface);
-    dx := ABS(x1 - x2); dy := ABS(y1 - y2);
-    IF x2 > x1 THEN sx := 1 ELSE sx := -1 END;
-    IF y2 > y1 THEN sy := 1 ELSE sy := -1 END;
-    x := x1; y := y1; vert := dy > dx;
-    IF vert THEN i := dx; dx := dy; dy := i END;
-    e := 2 * dy - dx;
-    FOR i := 0 TO dx DO
-      IF (x >= 0) & (x < bmp.w) &
-         (y >= 0) & (y < bmp.h) THEN
-        PutPixelFast(bmp, x, y, color)
-      END;
-      IF e >= 0 THEN
-        IF vert THEN INC(x, sx) ELSE INC(y, sy) END;
-        DEC(e, 2 * dx)
-      END;
-      IF vert THEN INC(y, sy) ELSE INC(x, sx) END;
-      INC(e, 2 * dy)
-    END;
-    SDL.UnlockSurface(bmp.surface)
-  END
+  IF x1 < x2 THEN x2 := x2 + 1
+  ELSIF x1 > x2 THEN x1 := x1 + 1
+  ELSE x1 := x1 + 0.5; x2 := x2 + 0.5
+  END;
+  IF y1 < y2 THEN y2 := y2 + 1
+  ELSIF y1 > y2 THEN y1 := y1 + 1
+  ELSE y1 := y1 + 0.5; y2 := y2 + 0.5
+  END;
+  Al.draw_line(x1, y1, x2, y2, SYSTEM.VAL(Al.Color, color), 0.0)
+END LineF;
+
+PROCEDURE Line*(x1, y1, x2, y2: INTEGER; color: Color);
+BEGIN LineF(FLT(x1), FLT(y1), FLT(x2), FLT(y2), color)
 END Line;
 
-PROCEDURE FastLine*(bmp: Bitmap; x1, y1, x2, y2, color: INTEGER);
-BEGIN
-  (*Al.FastLine(bmp.bmp, x1, y1, x2, y2, color)*)
-END FastLine;
+PROCEDURE HLine*(x, y1, y2: INTEGER; color: Color);
+BEGIN LineF(FLT(x), FLT(y1), FLT(x), FLT(y2), color)
+END HLine;
 
-PROCEDURE Rect*(bmp: Bitmap; x1, y1, x2, y2, color: INTEGER); (*!FIXME*)
-VAR rect: SDL.Rect;
-BEGIN
-  rect.x := x1; rect.y := y1;
-  rect.w := 1; rect.h := y2 - y1 + 1;
-  SDL.FillRect(bmp.surface, rect, color);
-  rect.x := x2;
-  SDL.FillRect(bmp.surface, rect, color);
-  rect.x := x1; rect.w := x2 - x1 + 1; rect.h := 1;
-  SDL.FillRect(bmp.surface, rect, color);
-  rect.y := y2;
-  SDL.FillRect(bmp.surface, rect, color)
-END Rect;
+PROCEDURE VLine*(x1, y, x2: INTEGER; color: Color);
+BEGIN LineF(FLT(x1), FLT(y), FLT(x2), FLT(y), color)
+END VLine;
 
-PROCEDURE RectFill*(bmp: Bitmap; x1, y1, x2, y2, color: INTEGER);
-VAR rect: SDL.Rect;
-BEGIN
-  rect.x := x1; rect.y := y1;
-  rect.w := x2 - x1 + 1; rect.h := y2 - y1 + 1;
-  SDL.FillRect(bmp.surface, rect, color)
-END RectFill;
-
-PROCEDURE Circle*(b: Bitmap; cx, cy, r, col: INTEGER);
-VAR x, y, d: INTEGER;
-BEGIN x := 0; y := r; d := 3 - 2 * r;
-  WHILE x <= y DO
-    PutPixel(b, cx + x, cy + y, col);
-    PutPixel(b, cx + y, cy + x, col);
-    PutPixel(b, cx + x, cy - y, col);
-    PutPixel(b, cx + y, cy - x, col);
-    PutPixel(b, cx - x, cy + y, col);
-    PutPixel(b, cx - y, cy + x, col);
-    PutPixel(b, cx - x, cy - y, col);
-    PutPixel(b, cx - y, cy - x, col);
-    IF d < 0 THEN d := d + 4 * x + 6
-    ELSE d := d + 4 * (x - y) + 10; DEC(y)
-    END;
-    INC(x)
-  END
-END Circle;
-
-PROCEDURE CircleFill*(b: Bitmap; cx, cy, r, col: INTEGER);
-VAR x, y, d: INTEGER;
-BEGIN x := 0; y := r; d := 3 - 2 * r;
-  WHILE x <= y DO
-    HLine(b, cx - x, cy + y, cx + x, col);
-    HLine(b, cx - y, cy + x, cx + y, col);
-    HLine(b, cx - x, cy - y, cx + x, col);
-    HLine(b, cx - y, cy - x, cx + y, col);
-    IF d < 0 THEN d := d + 4 * x + 6
-    ELSE d := d + 4 * (x - y) + 10; DEC(y)
-    END;
-    INC(x)
-  END
-END CircleFill;
+PROCEDURE FillRectF*(x1, y1, x2, y2: REAL; color: Color);
+BEGIN Al.draw_filled_rectangle(x1, y1, x2, y2, SYSTEM.VAL(Al.Color, color))
+END FillRectF;
 
-PROCEDURE Ellipse*(bmp: Bitmap; x, y, rx, ry, color: INTEGER);
+PROCEDURE FillRect*(x1, y1, x2, y2: INTEGER; color: Color);
 BEGIN
-END Ellipse;
+  Al.draw_filled_rectangle(FLT(x1), FLT(y1),
+    FLT(x2 + 1), FLT(y2 + 1), SYSTEM.VAL(Al.Color, color))
+END FillRect;
 
-PROCEDURE EllipseFill*(bmp: Bitmap; x, y, rx, ry, color: INTEGER);
-BEGIN
-END EllipseFill;
+PROCEDURE ThickRectF*(x1, y1, x2, y2: REAL; color: Color; thickness: REAL);
+BEGIN Al.draw_rectangle(x1, y1, x2, y2, SYSTEM.VAL(Al.Color, color), thickness)
+END ThickRectF;
 
-PROCEDURE FloodFill*(bmp: Bitmap; x, y, color: INTEGER);
+PROCEDURE ThickRect*(x1, y1, x2, y2: INTEGER; color: Color;
+    thickness: INTEGER);
 BEGIN
-END FloodFill;
+  Al.draw_rectangle(FLT(x1) + 0.5, FLT(y1) + 0.5,
+    FLT(x2) + 0.5, FLT(y2) + 0.5, SYSTEM.VAL(Al.Color, color), FLT(thickness))
+END ThickRect;
 
-(* Bitmap *)
+PROCEDURE RectF*(x1, y1, x2, y2: REAL; color: Color);
+BEGIN Al.draw_rectangle(x1, y1, x2, y2, SYSTEM.VAL(Al.Color, color), 1.0)
+END RectF;
 
-PROCEDURE (bmp: Bitmap) Finalize*, NEW;
-BEGIN
-END Finalize;
-
-PROCEDURE CreateBitmap*(w, h: INTEGER): Bitmap;
-VAR bmp: Bitmap;
-  s: ARRAY 2560 OF CHAR;
-BEGIN NEW(bmp);
-  bmp.surface := SDL.CreateRGBSurface(0, w, h, 32,
-    000000FFH, 0000FF00H, 00FF0000H, -1000000H);
-  IF bmp.surface = NIL THEN
-    GetError(s); Out.String(s); Out.Ln
-  END;
-  bmp.w := w; bmp.h := h ;
-RETURN bmp END CreateBitmap;
-
-PROCEDURE DestroyBitmap*(bmp: Bitmap);
-BEGIN SDL.FreeSurface(bmp.surface)
-END DestroyBitmap;
-
-PROCEDURE LoadBitmap*(IN filename: ARRAY OF CHAR): Bitmap;
-VAR bmp: Bitmap;
-  s: ARRAY 2048 OF SHORTCHAR;
-BEGIN NEW(bmp); Utf8.Encode(filename, s); bmp.surface := SDL.ImgLoad(s);
-  IF bmp.surface = NIL THEN bmp := NIL
-  ELSE bmp.w := bmp.surface.w; bmp.h := bmp.surface.h END ;
-RETURN bmp END LoadBitmap;
-
-PROCEDURE SaveBmp*(bmp: Bitmap; IN filename: ARRAY OF CHAR): BOOLEAN;
-VAR s: ARRAY 2048 OF SHORTCHAR;
-BEGIN Utf8.Encode(filename, s) ;
-RETURN SDL.SaveBmpRW(bmp.surface, SDL.RWFromFile(s, 'wb'), 1) = 0 END SaveBmp;
-
-PROCEDURE SavePng*(bmp: Bitmap; IN filename: ARRAY OF CHAR): BOOLEAN;
-VAR s: ARRAY 2048 OF SHORTCHAR;
-BEGIN Utf8.Encode(filename, s) ;
-RETURN SDL.ImgSavePng(bmp.surface, s) = 0 END SavePng;
-
-PROCEDURE SaveJpg*(bmp: Bitmap; IN filename: ARRAY OF CHAR): BOOLEAN;
-VAR s: ARRAY 2048 OF SHORTCHAR;
-BEGIN Utf8.Encode(filename, s) ;
-RETURN SDL.ImgSaveJpg(bmp.surface, s) = 0 END SaveJpg;
-
-PROCEDURE Blit*(src, dest: Bitmap; sx, sy, sw, sh, dx, dy: INTEGER);
-VAR a, b: SDL.Rect;
-BEGIN a.x := sx; a.y := sy; a.w := sw; a.h := sh;
-  b.x := dx; b.y := dy;
-  SDL.BlitSurface(src.surface, a, dest.surface, b)
-END Blit;
-
-(*!FIXME remove FlipBlit *)
-PROCEDURE FlipBlit*(src, dest: Bitmap; sx, sy, sw, sh, dx, dy: INTEGER;
-    hFlip: BOOLEAN);
-VAR x, y, sx0: INTEGER;
-  c1, c2, r1, r2, g1, g2, b1, b2, a1, a2: INTEGER;
+PROCEDURE Rect*(x1, y1, x2, y2: INTEGER; color: Color);
 BEGIN
-  IF ~hFlip THEN Blit(src, dest, sx, sy, sw, sh, dx, dy)
-  ELSE
-    IF sx < 0 THEN DEC(sw, -sx); INC(dx, -sx); sx := 0
-    ELSIF sx + sw - 1 >= src.w THEN DEC(sw, sx + sw - 1 - src.w)
-    ELSIF dx + sw - 1 >= dest.w THEN DEC(sw, dx + sw - 1 - dest.w)
-    END;
-    IF sy < 0 THEN DEC(sh, -sy); INC(dy, -sy); sy := 0
-    ELSIF sy + sh - 1 >= src.h THEN DEC(sh, sy + sh - 1 - src.h)
-    ELSIF dy + sh - 1 >= dest.h THEN DEC(sh, dy + sh - 1 - dest.h)
-    END;
-    LockBitmap(src);
-    LockBitmap(dest);
-    sx0 := sx + sw - 1;
-    FOR y := dy TO dy + sh - 1 DO
-      sx := sx0;
-      FOR x := dx TO dx + sw - 1 DO
-        c1 := GetPixelFast(src, sx, sy);
-        ColorToRGBA(c1, r1, g1, b1, a1);
-        IF a1 # 0 THEN
-          c2 := GetPixelFast(dest, x, y);
-          ColorToRGBA(c2, r2, g2, b2, a2);
-          IF a1 # 255 THEN
-            c1 := MakeCol((r1 * a1 + r2 * (255 - a1)) DIV 256, 
-                (g1 * a1 + g2 * (255 - g1)) DIV 256, 
-                (b1 * a1 + b2 * (255 - b1)) DIV 256)
-          END;
-          PutPixelFast(dest, x, y, c1)
-        END;
-        DEC(sx)
-      END;
-      INC(sy)
-    END;
-    UnlockBitmap(dest);
-    UnlockBitmap(src)
-  END
-END FlipBlit;
+  Al.draw_rectangle(FLT(x1) + 0.5, FLT(y1) + 0.5,
+    FLT(x2) + 0.5, FLT(y2) + 0.5, SYSTEM.VAL(Al.Color, color), 1.0)
+END Rect;
 
-PROCEDURE BlitWhole*(src, dest: Bitmap; x, y: INTEGER);
-VAR b: SDL.Rect;
-BEGIN b.x := x; b.y := y;
-  SDL.BlitSurfaceNil(src.surface, dest.surface, b)
-END BlitWhole;
+PROCEDURE NewBitmap*(w, h: INTEGER): Bitmap;
+VAR b: Bitmap;
+BEGIN NEW(b);
+  Al.set_new_bitmap_flags({Al.convertBitmap});
+  b.bmp := Al.create_bitmap(w, h);
+  IF b.bmp = NIL THEN b := NIL ELSE b.w := w; b.h := h END
+RETURN b END NewBitmap;
 
-PROCEDURE StretchBlit*(src, dest: Bitmap; sx, sy, sw, sh, dx, dy, dw, dh: INTEGER);
-VAR a, b: SDL.Rect;
+PROCEDURE DrawPartFlip*(bmp: Bitmap; sx, sy, sw, sh, dx, dy: INTEGER;
+    flags: SET);
 BEGIN
-  a.x := sx; a.y := sy; a.w := sw; a.h := sh;
-  b.x := dx; b.y := dy; b.w := dw; b.h := dh;
-  SDL.BlitScaled(src.surface, a, dest.surface, b)
-END StretchBlit;
+  Al.draw_bitmap_region(bmp.bmp, FLT(sx), FLT(sy), FLT(sw), FLT(sh),
+    FLT(dx), FLT(dy), flags)
+END DrawPartFlip;
 
-PROCEDURE SetScreenAlpha*(alpha: INTEGER);
-BEGIN screenAlpha := alpha
-END SetScreenAlpha;
+PROCEDURE DrawPart*(bmp: Bitmap; sx, sy, sw, sh, dx, dy: INTEGER);
+BEGIN
+  Al.draw_bitmap_region(bmp.bmp, FLT(sx), FLT(sy), FLT(sw), FLT(sh),
+    FLT(dx), FLT(dy), {})
+END DrawPart;
 
-PROCEDURE SetAlpha*(bmp: Bitmap; alpha: INTEGER);
+PROCEDURE DrawTintedPart*(bmp: Bitmap; color: Color;
+    sx, sy, sw, sh, dx, dy: INTEGER);
 BEGIN
-  IF SDL.SetSurfaceAlphaMod(bmp.surface, SYSTEM.VAL(BYTE, alpha)) = 0 THEN END
-END SetAlpha;
+  IF ~Al.is_compatible_bitmap(bmp.bmp) THEN Out.String('NON-COMPAT'); Out.Ln END;
+  Al.draw_tinted_bitmap_region(bmp.bmp, SYSTEM.VAL(Al.Color, color),
+    FLT(sx), FLT(sy), FLT(sw), FLT(sh), FLT(dx), FLT(dy), {})
+END DrawTintedPart;
 
-PROCEDURE SetClip*(bmp: Bitmap; x, y, w, h: INTEGER);
-VAR r: SDL.Rect;
-BEGIN r.x := x; r.y := y; r.w := w; r.h := h;
-  IF SDL.SetClipRect(bmp.surface, r) = 0 THEN END
-END SetClip;
+PROCEDURE DrawFlip*(bmp: Bitmap; x, y: INTEGER; flags: SET);
+BEGIN Al.draw_bitmap(bmp.bmp, FLT(x), FLT(y), flags)
+END DrawFlip;
 
-PROCEDURE UnsetClip*(bmp: Bitmap);
-BEGIN
-  IF SDL.SetClipRectNil(bmp.surface) = 0 THEN END
-END UnsetClip;
+PROCEDURE Draw*(bmp: Bitmap; x, y: INTEGER);
+BEGIN Al.draw_bitmap(bmp.bmp, FLT(x), FLT(y), {})
+END Draw;
 
-PROCEDURE MaskedBlit*(src, dest: Bitmap; sx, sy, dx, dy, w, h: INTEGER);
+PROCEDURE DrawEx*(bmp: Bitmap; sx, sy, sw, sh, dx, dy, dw, dh: INTEGER;
+    flags: SET);
 BEGIN
-  (*Al.MaskedBlit(src.bmp, dest.bmp, sx, sy, dx, dy, w, h)*)
-END MaskedBlit;
+  Al.draw_scaled_bitmap(bmp.bmp, FLT(sx), FLT(sy), FLT(sw), FLT(sh),
+    FLT(dx), FLT(dy), FLT(dw), FLT(dh), flags)
+END DrawEx;
 
-PROCEDURE DrawSpriteEx*(dest, sprite: Bitmap; x, y, mode: INTEGER; flip: SET);
+PROCEDURE DrawRotated*(bmp: Bitmap; cx, cy, dx, dy: INTEGER;
+    angle: REAL; flags: SET);
 BEGIN
-  (*Al.DrawSpriteEx(dest.bmp, sprite.bmp, x, y, mode, flip)*)
-END DrawSpriteEx;
+  Al.draw_rotated_bitmap(bmp.bmp, FLT(cx), FLT(cy),
+    FLT(dx), FLT(dy), angle, flags)
+END DrawRotated;
 
-PROCEDURE DrawCharacterEx*(dest, sprite: Bitmap; x, y, color, bg: INTEGER);
+PROCEDURE DrawScaledRotated*(bmp: Bitmap; cx, cy, dx, dy: INTEGER;
+    xScale, yScale, angle: REAL; flags: SET);
 BEGIN
-  (*Al.DrawCharacterEx(dest.bmp, sprite.bmp, x, y, color, bg)*)
-END DrawCharacterEx;
+  Al.draw_scaled_rotated_bitmap(bmp.bmp, FLT(cx), FLT(cy),
+    FLT(dx), FLT(dy), xScale, yScale, angle, flags)
+END DrawScaledRotated;
 
-PROCEDURE SetColorKey*(bmp: Bitmap; color: INTEGER);
-BEGIN SDL.SetColorKey(bmp.surface, 1, color)
-END SetColorKey;
+PROCEDURE DelayF*(n: REAL);
+BEGIN Al.rest(n)
+END DelayF;
 
-PROCEDURE SetColorMod*(bmp: Bitmap; r, g, b: INTEGER);
+PROCEDURE Delay*(n: INTEGER);
+BEGIN Al.rest(n / 1000)
+END Delay;
+
+PROCEDURE Pause*;
 BEGIN
-  SDL.SetSurfaceColorMod(bmp.surface, r, g, b)
-END SetColorMod;
 
-(* MonoFont *)
+END Pause;
 
-PROCEDURE LoadMonoFont*(IN filename: ARRAY OF CHAR;
-    charW, charH: INTEGER): MonoFont;
-VAR bmp: Bitmap; font: MonoFont;
-  x, y, sx, sy, tmp: INTEGER;
-BEGIN
-  bmp := LoadBitmap(filename);
-  IF bmp = NIL THEN font := NIL
-  ELSE
-    bmp.surface := SDL.ConvertSurface(bmp.surface,
-      screen.surface.format, 0);
-    SetColorKey(bmp, BmpCol(bmp, 0, 0, 0));
-    NEW(font); font.bmp := bmp;
-    font.charW := charW; font.charH := charH;
-    font.charsInRow := font.bmp.w DIV charW;
-    font.charRows := font.bmp.h DIV charH;
-    (*!FIXME remove sprites from here at all*)
-    NEW(font.sprites, font.charRows, font.charsInRow);
-    sy := 0;
-    FOR y := 0 TO font.charRows - 1 DO
-      sx := 0;
-      FOR x := 0 TO font.charsInRow - 1 DO
-        font.sprites[y, x].x := sx;
-        font.sprites[y, x].y := sy;
-        font.sprites[y, x].w := charW;
-        font.sprites[y, x].h := charH;
-        INC(sx, charW)
-      END;
-      INC(sy, charH)
-    END
-  END ;
-RETURN font END LoadMonoFont;
+PROCEDURE ConvertMemoryBitmaps*;
+BEGIN Al.convert_memory_bitmaps
+END ConvertMemoryBitmaps;
+
+PROCEDURE RecreateDisplay(W: Window; alterSize: BOOLEAN);
+VAR d: Al.Display;
+  q: ARRAY 256 OF SHORTCHAR;
+  opt: SET;
+  n, x, y, w, h, dw, dh, nw, nh, sw, sh: INTEGER;
+  nwf, nhf: REAL;
+  isCurTarget: BOOLEAN;
+BEGIN isCurTarget := target = W;
+  IF W.display # NIL THEN Al.destroy_display(W.display) END;
+
+  W.rzoom := W.wantZoom;
+  IF W.wantZoom = 1.0 THEN W.zoom := noZoom
+  ELSIF FLOOR(W.wantZoom + 0.001) * 100 = FLOOR(W.wantZoom * 100 + 0.001) THEN
+    W.zoom := intZoom; W.izoom := FLOOR(W.wantZoom + 0.001)
+  ELSE W.zoom := realZoom
+  END;
 
-PROCEDURE FindFontChar(c: CHAR; OUT n: INTEGER);
-BEGIN
-  IF c <= 0FFX THEN n := ORD(c)
-  ELSIF (410X(*A*) <= c) & (c <= 43FX(*p*)) THEN n := ORD(c) - (410H - 80H)
-  ELSIF (440X(*r*) <= c) & (c <= 44FX(*ja*)) THEN n := ORD(c) - (440H - 0E0H)
-  ELSIF c = 401X(*JO*) THEN n := 0F0H
-  ELSIF c = 451X(*jo*) THEN n := 0F1H
-  ELSE n := -1
-  END
-END FindFontChar;
+  Utf8.Encode(W.title, q); Al.set_new_window_title(q);
+  IF software IN W.options THEN n := 0 ELSE n := 1 END;
+  Al.set_new_display_option(Al.renderMethod, n, Al.suggest);
+  Al.set_new_display_option(Al.vsync, 2(*off*), Al.suggest);
+  Al.set_new_display_option(Al.singleBuffer, 1, Al.suggest);
+  IF smooth IN W.options THEN n := 1;
+    Al.set_new_display_option(Al.samples, 8, Al.suggest)
+  ELSE n := 0
+  END;
+  (* Al.set_new_display_option(Al.sampleBuffers, n, Al.suggest); *)
+  GetDesktopResolution(dw, dh);
+  dw := FLOOR(FLT(dw) / wantScaleX + 0.1);
+  dh := FLOOR(FLT(dh) / wantScaleY + 0.1);
 
-PROCEDURE DrawCharacter*(dest: Bitmap; font: MonoFont;
-    x, y: INTEGER; ch: CHAR; fg: INTEGER);
-VAR n, fx, fy, r, g, b: INTEGER; dstRect: SDL.Rect;
-BEGIN dstRect.x := x; dstRect.y := y;
-  FindFontChar(ch, n);
-  IF n < 0 THEN n := 1 (* "Bad" character *) END;
-  fx := n MOD font.charsInRow;
-  fy := n DIV font.charsInRow;
-  ColorToRGB(fg, r, g, b);
-  SDL.SetSurfaceColorMod(font.bmp.surface, r, g, b);
-  IF (fy < LEN(font.sprites)) & (fx < LEN(font.sprites[0])) THEN
-    SDL.BlitSurface(font.bmp.surface, font.sprites[fy, fx],
-      screen.surface, dstRect)
-  END
-END DrawCharacter;
-
-PROCEDURE DrawString*(dest: Bitmap; font: MonoFont;
-    x, y: INTEGER; IN s: ARRAY OF CHAR; fg: INTEGER);
-VAR i, cx: INTEGER;
-BEGIN i := 0; cx := x;
-  WHILE (s[i] # 0X) & (cx < dest.w) DO
-    DrawCharacter(dest, font, cx, y, s[i], fg);
-    INC(i); INC(cx, font.charW)
-  END
-END DrawString;
+  W.scaleOn := (wantScaleX # 1.0) OR (wantScaleY # 1.0);
+  W.scaleX := wantScaleX; W.scaleY := wantScaleY;
 
-(* Font *)
+  IF fullscreen IN W.options THEN w := W.fsW; h := W.fsH
+  ELSE w := W.initW; h := W.initH
+  END;
 
-PROCEDURE LoadFont*(IN fname: ARRAY OF CHAR): Font;
-VAR T: Texts.Text;
-  S: Texts.Scanner;
-  i: INTEGER;
-  s: ARRAY 512 OF CHAR;
-  f: Font;
-BEGIN NEW(f);
-  s := fname$; Strings.Append('.png', s);
-  f.bmp := LoadBitmap(s);
-  IF f.bmp = NIL THEN f := NIL
-  ELSE s := fname$; Strings.Append('.dat', s);
-    NEW(T); Texts.Open(T, s);
-    Texts.OpenScanner(S, T, 0);
-    Texts.Scan(S);
-    IF S.class = Texts.Int THEN f.h := S.i ELSE f.h := 0 END;
-    Texts.Scan(S); i := 0;
-    WHILE ~S.eot & (S.class = Texts.Int) DO
-      f.geo[i].w := S.i; Texts.Scan(S);
-      f.geo[i].x := S.i; Texts.Scan(S);
-      f.geo[i].y := S.i; Texts.Scan(S);
-      INC(i)
+  IF (w < 0) OR (h < 0) THEN
+    IF fullscreen IN W.options THEN
+      w := FLOOR(dw / W.wantZoom + 0.1); h := FLOOR(dh / W.wantZoom + 0.1);
+      ApplySizeStep(W, w, h);
+      sw := FLOOR(w * W.wantZoom + 0.1); sh := FLOOR(h * W.wantZoom + 0.1)
+    ELSE w := 640; h := 400; W.zoom := noZoom;
+      ApplySizeStep(W, w, h); sw := w; sh := h
+    END
+  ELSIF fullscreen IN W.options THEN
+    IF smooth IN W.options THEN nwf := dw / w; nhf := dh / h;
+      IF nhf < nwf THEN nwf := nhf END;
+      W.zoom := realZoom; W.rzoom := nwf;
+      IF exact IN W.options THEN
+        sw := FLOOR(w * nwf + 0.1); sh := FLOOR(h * nwf + 0.1)
+      ELSE sw := dw; sh := dh
+      END
+    ELSE nw := dw DIV w; nh := dh DIV h;
+      IF nh < nw THEN nw := nh END;
+      W.zoom := intZoom; W.izoom := nw; W.rzoom := FLT(nw);
+      IF exact IN W.options THEN sw := w * nw; sh := h * nw
+      ELSE sw := dw DIV nw * nw; sh := dh DIV nw * nw
+      END
     END;
-    f.geoCount := i
+
+    IF W.zoom = realZoom THEN
+      w := FLOOR(sw / W.rzoom + 0.1); h := FLOOR(sh / W.rzoom + 0.1)
+    ELSIF W.zoom = intZoom THEN w := sw DIV W.izoom; h := sh DIV W.izoom
+    ELSE w := sw; h := sh
+    END;
+    ApplySizeStep(W, w, h); sw := w; sh := h;
+    IF alterSize THEN W.initW := w; W.initH := h END
+  ELSE ApplySizeStep(W, w, h);
+    sw := FLOOR(w * W.wantZoom * W.scaleX + 0.999);
+    sh := FLOOR(h * W.wantZoom * W.scaleY + 0.999)
   END;
-RETURN f END LoadFont;
 
-PROCEDURE GetCharGeometry*(font: Font; ch: INTEGER; VAR fx, fy, w: INTEGER);
-VAR i: INTEGER;
-BEGIN
-  IF (32 <= ch) & (ch <= 127) THEN i := ch - 32
-  ELSIF (1040 <= ch) & (ch <= 1103) THEN i := ch - 1040 + 95
-  ELSIF ch = 1025 THEN i := 64 + 95
-  ELSIF ch = 1105 THEN i := 65 + 95;
-  ELSE i := font.geoCount
+  W.lastW := 0; W.lastH := 0;
+
+  IF center IN W.options THEN GetDesktopResolution(dw, dh);
+    x := (dw - sw) DIV 2; y := (dh - sh) DIV 2;
+    IF x < 0 THEN x := 0 END; IF y < 0 THEN y := 0 END
+  ELSIF (W.initX < 0) OR (W.initY < 0) THEN x := Al.intMax; y := Al.intMax
+  ELSE x := W.initX; y := W.initY
   END;
-  IF i >= font.geoCount THEN i := 31 (*'?'*) END;
-  w  := font.geo[i].w;
-  fx := font.geo[i].x;
-  fy := font.geo[i].y
-END GetCharGeometry;
-
-PROCEDURE GetTextWidth*(font: Font; IN s: ARRAY OF CHAR): INTEGER;
-VAR i, w, tw, maxTw, fx, fy: INTEGER;
-  c1, c2: CHAR;
-  ch: INTEGER;
-BEGIN
-  maxTw := 0; tw := 0; i := 0;
-  IF font # NIL THEN
-    WHILE (i < LEN(s) - 1) & (s[i] # 0X) DO
-      c1 := s[i]; c2 := s[i + 1];
-      IF c1 < 80X THEN ch := ORD(c1); INC(i)
-      ELSE ch := ORD(c1) MOD 32 * 64 + ORD(c2) MOD 64; INC(i, 2)
-      END;
-      IF ch = 0AH THEN
-        IF tw > maxTw THEN maxTw := tw END;
-        tw := 0
-      ELSE
-        GetCharGeometry(font, ch, fx, fy, w);
-        INC(tw, w)
-      END
+  Al.set_new_window_position(x, y);
+
+  opt := {};
+  IF fullscreen IN W.options THEN INCL(opt, Al.fullscreenWindow)
+  ELSE INCL(opt, Al.windowed)
+  END;
+  IF resizable IN W.options THEN INCL(opt, Al.resizable) END;
+  IF maximized IN W.options THEN INCL(opt, Al.maximized) END;
+  IF minimized IN W.options THEN INCL(opt, Al.minimized) END;
+  IF frameless IN W.options THEN INCL(opt, Al.frameless) END;
+  Al.set_new_display_flags(opt);
+
+  IF W.bmp # NIL THEN Al.destroy_bitmap(W.bmp); W.bmp := NIL END;
+  W.display := Al.create_display(sw, sh);
+  IF W.display # NIL THEN
+    (*IF isCurTarget OR (windowList = NIL) OR (windowList.next = NIL) THEN
+      Al.set_target_backbuffer(W.display);
+      ConvertMemoryBitmaps;
+    END;*)
+    W.winW := Al.get_display_width(W.display);
+    W.winH := Al.get_display_height(W.display);
+    W.w := w; W.h := h;
+    ResetWindowBitmap(W);
+    Al.register_event_source(queue, Al.get_display_event_source(W.display));
+    IF isCurTarget THEN Target(W) END;
+    IF ~W.showMouse THEN ShowWindowMouse(W, FALSE) END;
+    IF W.noficons > 0 THEN
+      Al.set_display_icons(W.display, W.noficons, W.icons)
     END
+  END
+END RecreateDisplay;
+
+PROCEDURE NewWindow*(x, y, w, h: INTEGER; title: ARRAY OF CHAR;
+    options: SET): Window;
+VAR W: Window;
+  d: Al.Display;
+  q: ARRAY 256 OF SHORTCHAR;
+  opt: SET;
+  i, n, dw, dh, nw, nh, sw, sh: INTEGER;
+  nwf, nhf: REAL;
+BEGIN NEW(W); W.lastX := -1; W.lastY := -1; W.resized := FALSE;
+  W.sizeStepX := wantSizeStepX; W.sizeStepY := wantSizeStepY;
+  IF {fullscreen, window} * options = {} THEN INCL(options, window)
+  ELSIF window IN options THEN EXCL(options, fullscreen)
   END;
-  IF tw > maxTw THEN maxTw := tw END;
-RETURN maxTw END GetTextWidth;
-
-PROCEDURE DrawChar*(dest: Bitmap; font: Font; x, y, ch, color: INTEGER;
-    VAR w: INTEGER);
-VAR r, g, b, fx, fy: INTEGER; (* Font X, Y *)
+  W.options := options;
+  W.title := title;
+  W.wantZoom := wantZoom;
+  W.scaleOn := (wantScaleX # 1.0) OR (wantScaleY # 1.0);
+  W.scaleX := wantScaleX; W.scaleY := wantScaleY;
+  W.initX := x; W.initY := y; W.initW := w; W.initH := h;
+  W.fsW := w; W.fsH := h;
+  W.showMouse := TRUE;
+  FOR i := 0 TO LEN(W.icons) - 1 DO W.icons[i] := NIL END;
+  W.noficons := 0;
+
+  W.display := NIL; RecreateDisplay(W, TRUE);
+  IF W.display # NIL THEN W.next := windowList; windowList := W
+  ELSE Error('Could not create dispaly.'); W := NIL
+  END;
+  IF (screen = NIL) & (W # NIL) THEN screen := W; Target(screen) END
+RETURN W END NewWindow;
+
+PROCEDURE CloseWindow*(W: Window);
+BEGIN Al.destroy_display(W.display)
+END CloseWindow;
+
+PROCEDURE NewTimer*(speed: REAL): Timer;
+VAR T: Timer;
+BEGIN NEW(T); T.tmr := Al.create_timer(speed);
+  IF T.tmr # NIL THEN
+    Al.register_event_source(queue, Al.get_timer_event_source(T.tmr));
+    T.next := timerList; timerList := T
+  ELSE T := NIL
+  END;
+RETURN T END NewTimer;
+
+PROCEDURE GetWindow(d: Al.Display): Window;
+VAR W: Window;
+BEGIN W := windowList;
+  WHILE (W # NIL) & (W.display # d) DO W := W.next END
+RETURN W END GetWindow;
+
+PROCEDURE GetTimer(a: Al.Timer): Timer;
+VAR t: Timer;
+BEGIN t := timerList;
+  WHILE (t # NIL) & (t.tmr # a) DO t := t.next END
+RETURN t END GetTimer;
+
+PROCEDURE EmitResizeEvent(W: Window);
+VAR E: Al.UserEvent;
 BEGIN
-  IF font # NIL THEN
-    GetCharGeometry(font, ch, fx, fy, w);
-    IF ch # 32 (*space*) THEN
-      ColorToRGB(color, r, g, b);
-      SetColorMod(font.bmp, r, g, b);
-      Blit(font.bmp, dest, fx, fy, w, font.h, x, y)
-    END
+  E.type := eventUserResize;
+  E.data4 := SYSTEM.VAL(ADRINT, W.display);
+  IF Al.emit_user_event(userEventSource, SYSTEM.VAL(Al.Event, E), 0) THEN END
+END EmitResizeEvent;
+
+PROCEDURE ToggleFS*(win: Window);
+VAR fs: BOOLEAN;
+  w, h: REAL;
+BEGIN
+  IF (win = NIL) & (screen # NIL) THEN win := screen END;
+  IF (win # NIL) & (win.display # NIL) THEN
+    fs := ~(Al.windowed IN Al.get_display_flags(win.display));
+    IF fs THEN EXCL(win.options, fullscreen); INCL(win.options, window)
+    ELSE INCL(win.options, fullscreen); EXCL(win.options, window);
+      w := Al.get_display_width(win.display) / win.rzoom;
+      h := Al.get_display_height(win.display) / win.rzoom;
+      IF win.scaleOn THEN w := w / win.scaleX; h := h / win.scaleY END;
+      win.initW := FLOOR(w + 0.1); win.initH := FLOOR(h + 0.1);
+      EXCL(win.options, center);
+      Al.get_window_position(win.display, win.initX, win.initY);
+      ApplySizeStep(win, win.initW, win.initH)
+    END;
+    win.scaleX := wantScaleX;
+    win.scaleY := wantScaleY;
+    RecreateDisplay(win, FALSE);
+    EmitResizeEvent(win)
   END
-END DrawChar;
-
-PROCEDURE DrawText*(dest: Bitmap; font: Font; x, y: INTEGER;
-    IN s: ARRAY OF CHAR; color: INTEGER);
-VAR x0, i, w: INTEGER;
-  c1, c2: CHAR;
-  ch: INTEGER;
+END ToggleFS;
+
+PROCEDURE SwitchToWindow*(win: Window);
+BEGIN IF ~(window IN GetWindowOptions(screen)) THEN ToggleFS(win) END
+END SwitchToWindow;
+
+PROCEDURE SwitchToFS*(win: Window);
+BEGIN IF window IN GetWindowOptions(screen) THEN ToggleFS(win) END
+END SwitchToFS;
+
+PROCEDURE ParseEvent(E: Al.Event; VAR event: Event);
+VAR DE: Al.PDisplayEvent;
+  TE: Al.PTimerEvent;
+  KE: Al.PKeyboardEvent;
+  ME: Al.PMouseEvent;
+  UE: Al.PUserEvent;
+  W: Window;
+  d: Al.Display;
+  x, y, w, h: INTEGER;
+  fw, fh: REAL;
 BEGIN
-  IF font # NIL THEN
-    x0 := x; i := 0;
-    WHILE (i < LEN(s) - 1) & (s[i] # 0X) DO
-      c1 := s[i]; c2 := s[i + 1];
-      IF c1 < 80X THEN ch := ORD(c1); INC(i)
-      ELSE ch := ORD(c1) MOD 32 * 64 + ORD(c2) MOD 64; INC(i, 2)
+  event.time := E.timestamp;
+  IF E.type = Al.eventMouseAxes THEN
+    ME := SYSTEM.VAL(Al.PMouseEvent, SYSTEM.ADR(E));
+    W := GetWindow(ME.display);
+    IF W.zoom = noZoom THEN x := ME.x - W.iFlipX; y := ME.y - W.iFlipY
+    ELSIF W.zoom = intZoom THEN
+      x := (ME.x - W.iFlipX) DIV W.izoom; y := (ME.y - W.iFlipY) DIV W.izoom
+    ELSE x := FLOOR((ME.x - W.flipX) / W.rzoom + 0.1);
+      y := FLOOR((ME.y - W.flipY) / W.rzoom + 0.1)
+    END;
+    IF W.scaleOn THEN
+      x := FLOOR(x / W.scaleX + 0.1); y := FLOOR(y / W.scaleY + 0.1)
+    END;
+    IF (x # W.lastX) OR (y # W.lastY) OR (ME.dz # 0) OR (ME.dw # 0) THEN
+      IF (ME.dz # 0) OR (ME.dw # 0) THEN event.type := mouseWheel;
+        event.dz := ME.dz; event.dw := ME.dw;
+        event.x := W.lastX; event.y := W.lastY;
+        event.z := ME.z; event.w := ME.w;
+        event.dx := 0; event.dy := 0
+      ELSE event.type := mouseMove;
+        IF x = -1 THEN event.dx := 0; event.dy := 0
+        ELSE event.dx := x - W.lastX; event.dy := y - W.lastY
+        END;
+        event.x := x; event.y := y;
+        W.lastX := event.x; W.lastY := event.y
       END;
-      IF ch = 0AH THEN INC(y, font.h); x := x0
-      ELSE DrawChar(dest, font, x, y, ch, color, w); INC(x, w)
-      END
+      event.button := ME.button;
+      event.mod := {};
+      event.display := ME.display; event.window := W
+    ELSE event.type := noEvent
     END
+  ELSIF E.type = Al.eventMouseButtonDown THEN
+    event.type := mouseDown;
+    ME := SYSTEM.VAL(Al.PMouseEvent, SYSTEM.ADR(E));
+    W := GetWindow(ME.display); event.window := W;
+    IF W.zoom = noZoom THEN x := ME.x - W.iFlipX; y := ME.y - W.iFlipY
+    ELSIF W.zoom = intZoom THEN
+      x := (ME.x - W.iFlipX) DIV W.izoom; y := (ME.y - W.iFlipY) DIV W.izoom
+    ELSE x := FLOOR((ME.x - W.flipX) / W.rzoom + 0.1);
+      y := FLOOR((ME.y - W.flipY) / W.rzoom + 0.1)
+    END;
+    IF W.scaleOn THEN
+      x := FLOOR(x / W.scaleX + 0.1); y := FLOOR(y / W.scaleY + 0.1)
+    END;
+    event.x := x; event.y := y;
+    event.z := ME.z; event.w := ME.w;
+    event.button := ME.button;
+    event.mod := {};
+    event.display := ME.display
+  ELSIF E.type = Al.eventMouseButtonUp THEN
+    event.type := mouseUp;
+    ME := SYSTEM.VAL(Al.PMouseEvent, SYSTEM.ADR(E));
+    W := GetWindow(ME.display); event.window := W;
+    IF W.zoom = noZoom THEN x := ME.x - W.iFlipX; y := ME.y - W.iFlipY
+    ELSIF W.zoom = intZoom THEN
+      x := (ME.x - W.iFlipX) DIV W.izoom; y := (ME.y - W.iFlipY) DIV W.izoom
+    ELSE x := FLOOR((ME.x - W.flipX) / W.rzoom + 0.1);
+      y := FLOOR((ME.y - W.flipY) / W.rzoom + 0.1)
+    END;
+    IF W.scaleOn THEN
+      x := FLOOR(x / W.scaleX + 0.1); y := FLOOR(y / W.scaleY + 0.1)
+    END;
+    event.x := x; event.y := y;
+    event.z := ME.z; event.w := ME.w;
+    event.button := ME.button;
+    event.mod := {};
+    event.display := ME.display
+  ELSIF E.type = Al.eventTimer THEN
+    event.type := timer;
+    TE := SYSTEM.VAL(Al.PTimerEvent, SYSTEM.ADR(E));
+    event.count := TE.count;
+    event.timer := GetTimer(SYSTEM.VAL(Al.Timer, TE.source))
+  ELSIF E.type = Al.eventKeyDown THEN
+    event.type := keyDown;
+    KE := SYSTEM.VAL(Al.PKeyboardEvent, SYSTEM.ADR(E));
+    event.key := KE.keycode;
+    event.mod := {};
+    event.display := KE.display;
+    event.window := GetWindow(event.display)
+  ELSIF E.type = Al.eventKeyUp THEN
+    event.type := keyUp;
+    KE := SYSTEM.VAL(Al.PKeyboardEvent, SYSTEM.ADR(E));
+    event.key := KE.keycode;
+    event.mod := {};
+    event.display := KE.display;
+    event.window := GetWindow(event.display)
+  ELSIF E.type = Al.eventKeyChar THEN
+    KE := SYSTEM.VAL(Al.PKeyboardEvent, SYSTEM.ADR(E));
+    event.type := char;
+    event.key := KE.keycode;
+    event.ch := CHR(KE.unichar);
+    event.mod := KE.modifiers;
+    event.repeat := KE.repeat;
+    event.display := KE.display;
+    event.window := GetWindow(event.display)
+  ELSIF (E.type = Al.eventDisplayResize) OR (E.type = eventUserResize) THEN
+    IF E.type = Al.eventDisplayResize THEN
+      DE := SYSTEM.VAL(Al.PDisplayEvent, SYSTEM.ADR(E));
+      d := DE.source; W := GetWindow(d);
+      W.winW := DE.width; W.winH := DE.height
+    ELSE UE := SYSTEM.VAL(Al.PUserEvent, SYSTEM.ADR(E));
+      d := SYSTEM.VAL(Al.Display, UE.data4); W := GetWindow(d);
+      W.winW := Al.get_display_width(d); W.winH := Al.get_display_height(d)
+    END;
+    fw := W.winW / W.rzoom; fh := W.winH / W.rzoom;
+    IF W.scaleOn THEN fw := fw / W.scaleX; fh := fh / W.scaleY END;
+    w := FLOOR(fw + 0.1); h := FLOOR(fh + 0.1);
+    IF E.type = Al.eventDisplayResize THEN
+      Al.acknowledge_resize(d);
+      ApplySizeStep(W, w, h)
+    END;
+    IF (w # W.lastW) OR (h # W.lastH) THEN
+      W.lastW := w; W.lastH := h;
+      event.type := resize; event.window := W; event.display := d;
+      event.w := w; event.h := h;
+      IF E.type = Al.eventDisplayResize THEN event.x := DE.x; event.y := DE.y
+      ELSE Al.get_window_position(d, event.x, event.y)
+      END;
+      ResetWindowBitmap(W)
+    ELSE ResetFlipVars(W); Flip; event.type := noEvent
+    END
+  ELSIF E.type = Al.eventDisplayClose THEN
+    event.type := quit;
+    event.display := SYSTEM.VAL(Al.Display, E.source);
+    event.window := GetWindow(event.display)
+  ELSE event.type := noEvent
   END
-END DrawText;
-
-(* Events *)
-
-PROCEDURE StartTextInput*;
-BEGIN SDL.StartTextInput
-END StartTextInput;
+END ParseEvent;
 
-PROCEDURE StopTextInput*;
-BEGIN SDL.StopTextInput
-END StopTextInput;
-
-PROCEDURE QueueEvent;
-BEGIN INC(events.len); INC(events.last);
-  IF events.last = LEN(events.buf) THEN events.last := 0 END
-END QueueEvent;
-
-PROCEDURE PumpKeyDown(VAR event: SDL.Event);
-VAR e: SDL.KeyboardEvent;
-  n: INTEGER; mod: SET;
+PROCEDURE WaitAndParseEvent(VAR event: Event);
+VAR E: Al.Event;
 BEGIN
-  IF events.len < LEN(events.buf) THEN
-    e := SYSTEM.VAL(SDL.KeyboardEvent, SYSTEM.ADR(event));
-    n := e.keysym.mod; mod := SYSTEM.VAL(SET32, n);
-    QueueEvent;
-    events.buf[events.last].type := keyDown;
-    events.buf[events.last].key.code := e.keysym.scancode;
-    events.buf[events.last].key.sym := e.keysym.sym;
-    events.buf[events.last].key.mod := mod;
-    events.buf[events.last].key.repeat := e.repeat # 0;
-    INC(keyPressed)
-  END
-END PumpKeyDown;
+  Al.wait_for_event(queue, E);
+  ParseEvent(E, event)
+END WaitAndParseEvent;
 
-PROCEDURE PumpTextEvent(event: SDL.Event);
-VAR sym: INTEGER;
-  e: SDL.TextInputEvent;
+PROCEDURE PeekAndParseEvent(VAR event: Event): BOOLEAN;
+VAR E: Al.Event;
+  got: BOOLEAN;
 BEGIN
-  IF events.len < LEN(events.buf) THEN
-    e := SYSTEM.VAL(SDL.TextInputEvent, SYSTEM.ADR(event));
-    QueueEvent;
-    events.buf[events.last].type := textInput;
-    Utf8.Decode(e.text, events.buf[events.last].s);
-    events.buf[events.last].ch := events.buf[events.last].s[0]
-  END
-END PumpTextEvent;
+  got := Al.peek_next_event(queue, E);
+  IF got THEN ParseEvent(E, event) END
+RETURN got END PeekAndParseEvent;
 
-PROCEDURE UpdateMousePos(event: SDL.Event);
-VAR e: SDL.MouseMotionEvent; newX, newY: INTEGER;
+PROCEDURE WaitEvent*(VAR event: Event);
+BEGIN REPEAT WaitAndParseEvent(event) UNTIL event.type # noEvent
+END WaitEvent;
+
+PROCEDURE PeekEvent*(VAR event: Event): BOOLEAN;
+VAR got: BOOLEAN;
 BEGIN
-  e := SYSTEM.VAL(SDL.MouseMotionEvent, SYSTEM.ADR(event));
-  newX := e.x; newY := e.y;
-  IF newX < 0 THEN newX := 0
-  ELSIF newX >= screen.w THEN newX := screen.w - 1 END;
-  IF newY < 0 THEN newY := 0
-  ELSIF newY >= screen.h THEN newY := screen.h - 1 END;
-  IF (newX # mouseX) OR (newY # mouseY) THEN
-    mouseX := newX;  mouseY := newY;
-    needRedrawMouse := TRUE
+  got := PeekAndParseEvent(event);
+  WHILE got & (event.type = noEvent) DO
+    IF Al.drop_next_event(queue) THEN END;
+    got := PeekAndParseEvent(event)
   END
-END UpdateMousePos;
+RETURN got END PeekEvent;
 
-(* Keyboard *)
+PROCEDURE HasEvents*(): BOOLEAN;
+VAR e: Event;
+RETURN PeekEvent(e) END HasEvents;
 
-PROCEDURE GetKeyArray(): KeyArray; BEGIN
-RETURN SYSTEM.VAL(KeyArray, SDL.GetKeyboardStateNil()) END GetKeyArray;
+PROCEDURE DropNextEvent*;
+VAR e: Event;
+BEGIN (*WaitEvent(e)*)
+  IF Al.drop_next_event(queue) THEN END
+END DropNextEvent;
 
-PROCEDURE KeyDown*(key: INTEGER): BOOLEAN;
-VAR keys: KeyArray;
-BEGIN keys := GetKeyArray() ;
-RETURN keys[key] END KeyDown;
+PROCEDURE StartTimer*(timer: Timer);
+BEGIN Al.start_timer(timer.tmr)
+END StartTimer;
 
-PROCEDURE AltPressed*(): BOOLEAN;
-VAR keys: KeyArray;
-BEGIN keys := GetKeyArray() ;
-RETURN keys[kAlt] OR keys[kAltGr] END AltPressed;
+PROCEDURE StopTimer*(timer: Timer);
+BEGIN Al.stop_timer(timer.tmr)
+END StopTimer;
 
-PROCEDURE ShiftPressed*(): BOOLEAN;
-VAR keys: KeyArray;
-BEGIN keys := GetKeyArray() ;
-RETURN keys[kLShift] OR keys[kRShift] END ShiftPressed;
+PROCEDURE ResumeTimer*(timer: Timer);
+BEGIN Al.resume_timer(timer.tmr)
+END ResumeTimer;
 
-PROCEDURE CtrlPressed*(): BOOLEAN;
-VAR keys: KeyArray;
-BEGIN keys := GetKeyArray() ;
-RETURN keys[kLCtrl] OR keys[kRCtrl] END CtrlPressed;
+(* Font *)
 
-(* Mouse *)
+PROCEDURE GetMonoFontSize*(font: Font; VAR charW, charH: INTEGER);
+BEGIN charW := font(MonoFont).charW; charH := font(MonoFont).charH
+END GetMonoFontSize;
+
+PROCEDURE FindFontChar(font: Font; c: CHAR; VAR bmp: Bitmap;
+    VAR x, y, w, h: INTEGER);
+VAR n: INTEGER;
+  m: MonoFont;
+BEGIN m := font(MonoFont);
+  IF c < 200X THEN n := ORD(c)
+  ELSIF (400X <= c) & (c < 500X) THEN n := ORD(c) + (300H - 400H)
+  ELSIF (2500X <= c) & (c < 2600X) THEN n := ORD(c) + (200H - 2500H)
+  ELSE n := -1
+  END;
+  IF n < 0 THEN n := 1 (* "Bad" character *) END;
+  bmp := m.bmp;
+  x := n MOD m.cols * m.charW; y := n DIV m.cols * m.charH;
+  w := m.charW; h := m.charH
+END FindFontChar;
 
-PROCEDURE MouseOnScreen*(): BOOLEAN;
-VAR flags: SET;
-BEGIN flags := SDL.GetWindowFlags(window);
-RETURN SDL.windowMouseFocus IN flags END MouseOnScreen;
+PROCEDURE DrawCharEx*(ch: CHAR; x, y: INTEGER; font: Font; color: Color;
+    VAR w: INTEGER);
+VAR sx, sy, h: INTEGER;
+  bmp: Bitmap;
+BEGIN FindFontChar(font, ch, bmp, sx, sy, w, h);
+  DrawTintedPart(bmp, color, sx, sy, w, h, x, y)
+END DrawCharEx;
+
+PROCEDURE DrawChar*(ch: CHAR; x, y: INTEGER; font: Font; color: Color);
+VAR w: INTEGER;
+BEGIN DrawCharEx(ch, x, y, font, color, w)
+END DrawChar;
 
-PROCEDURE ShowMouse*(show: BOOLEAN);
-BEGIN showMouse := show
-END ShowMouse;
+PROCEDURE DrawString*(s: ARRAY OF CHAR; x, y: INTEGER;
+    font: Font; color: Color);
+VAR i, cx, cy, charW, destW, destH: INTEGER;
+  m: MonoFont;
+BEGIN m := font(MonoFont); i := 0; cx := x; cy := y;
+  GetTargetSize(destW, destH);
+  WHILE (s[i] # 0X) & (cx < destW) & (cy < destH) DO
+    IF s[i] = 0AX THEN cx := x; INC(cy, m.charH)
+    ELSE DrawCharEx(s[i], cx, cy, font, color, charW);
+      INC(i); INC(cx, charW)
+    END
+  END
+END DrawString;
 
-PROCEDURE GetRealMousePos*(VAR x, y: INTEGER);
-BEGIN IF SDL.GetMouseState(x, y) = 0 THEN END
-END GetRealMousePos;
+PROCEDURE MonoFontDraw(f: Font; VAR msg: FontDrawMsg);
+VAR m: MonoFont;
+BEGIN m := f(MonoFont);
+  (*!TODO*)
+END MonoFontDraw;
 
-PROCEDURE GetMousePos*(VAR x, y: INTEGER);
-BEGIN x := mouseX; y := mouseY
-END GetMousePos;
+PROCEDURE MonoFontHandle(f: Font; VAR msg: FontMessage);
+VAR m: MonoFont;
+BEGIN m := f(MonoFont)
+  (*!TODO*)
+END MonoFontHandle;
 
-PROCEDURE GetMouseButtons*(): SET;
-VAR x, y: INTEGER;
-BEGIN
-RETURN SYSTEM.VAL(SET32, SDL.GetMouseState(x, y)) END GetMouseButtons;
-
-PROCEDURE CreateStdMousePointer*;
-VAR b: Bitmap; fg, bg: INTEGER;
-BEGIN b := CreateBitmap(12, 19);
-  bg := MakeCol(255, 0, 255); fg := MakeCol(0, 0, 0);
-  ClearToColor(b, bg); SetColorKey(b, bg);
-  Line(b, 0, 0, 10, 10, fg); Line(b, 0, 0, 0, 14, fg);
-  Line(b, 0, 14, 3, 11, fg); Line(b, 10, 10, 6, 10, fg);
-  Line(b, 4, 12, 6, 17, fg); Line(b, 6, 11, 9, 17, fg);
-  Line(b, 7, 18, 8, 18, fg); bg := MakeCol(255, 255, 255);
-  VLine(b, 1, 2, 12, bg); VLine(b, 2, 3, 11, bg);
-  VLine(b, 3, 4, 10, bg); VLine(b, 4, 5, 11, bg);
-  VLine(b, 5, 6, 13, bg); VLine(b, 6, 7, 9, bg);
-  VLine(b, 7, 8, 9, bg); VLine(b, 8, 9, 9, bg);
-  VLine(b, 6, 12, 15, bg); VLine(b, 7, 14, 17, bg);
-  VLine(b, 8, 16, 17, bg);
-  stdMousePointer := b
-END CreateStdMousePointer;
-
-PROCEDURE SetMouseFocus*(x, y: INTEGER);
+PROCEDURE ReadWord(VAR r: Files.Rider; VAR s: ARRAY OF CHAR);
+VAR ch: CHAR;
+  i: INTEGER;
 BEGIN
-  mouseFocusX := x; mouseFocusY := y;
-  needRedrawMouse := TRUE
-END SetMouseFocus;
+  Files.ReadChar(r, ch);
+  WHILE ~r.eof & (ch <= ' ') DO Files.ReadChar(r, ch) END;
 
-PROCEDURE SetMousePointer*(bmp: Bitmap; x, y: INTEGER);
-BEGIN
-  IF bmp = NIL THEN
-    mousePointer := stdMousePointer;
-    x := 0; y := 0
-  ELSE mousePointer := bmp
+  i := 0;
+  WHILE ~r.eof & (ch > ' ') DO
+    IF (i # LEN(s) - 1) THEN s[i] := ch; INC(i) END;
+    Files.ReadChar(r, ch)
   END;
-  SetMouseFocus(x, y);
-  underMouse := CreateBitmap(mousePointer.w, mousePointer.h);
-  needRedrawMouse := TRUE
-END SetMousePointer;
-
-PROCEDURE GetMousePointer*(): Bitmap; BEGIN
-RETURN mousePointer END GetMousePointer;
-
-PROCEDURE SetStdMousePointer*;
-BEGIN SetMousePointer(stdMousePointer, 0, 0)
-END SetStdMousePointer;
-
-PROCEDURE InitMouseData;
-BEGIN CreateStdMousePointer; SetStdMousePointer
-END InitMouseData;
-
-(* Misc *)
-PROCEDURE SetWindowTitle*(IN title: ARRAY OF CHAR);
-VAR s: ARRAY 2048 OF SHORTCHAR;
-BEGIN Utf8.Encode(title, s); SDL.SetWindowTitle(window, s)
-END SetWindowTitle;
+  s[i] := 0X
+END ReadWord;
 
-PROCEDURE SwitchToWindowed*;
+PROCEDURE ReadInt(VAR r: Files.Rider; VAR n: INTEGER);
+VAR ch: CHAR;
+  i: INTEGER;
 BEGIN
-  IF fullscreen IN settings THEN
-    SDL.SetWindowSize(window, screen.w, screen.h);
-    IF SDL.SetWindowFullscreen(window, {}) = 0 THEN
-      EXCL(settings, fullscreen)
-    END
-  END
-END SwitchToWindowed;
+  Files.ReadChar(r, ch);
+  WHILE ~r.eof & (ch <= ' ') DO Files.ReadChar(r, ch) END;
 
-PROCEDURE SwitchToFullscreen*;
-BEGIN
-  IF ~(fullscreen IN settings) THEN
-    IF SDL.SetWindowFullscreen(window, SDL.windowFullscreenDesktop) = 0 THEN
-      INCL(settings, fullscreen)
+  n := 0;
+  WHILE ~r.eof & ('0' <= ch) & (ch <= '9') DO
+    n := n * 10 + ORD(ch) - ORD('0');
+    Files.ReadChar(r, ch)
+  END
+END ReadInt;
+
+PROCEDURE ReadFontInfo(VAR r: Files.Rider): Font;
+VAR f: Font;
+  mf: MonoFont;
+  s: ARRAY 4096 OF CHAR;
+BEGIN f := NIL;
+  ReadWord(r, s);
+  IF s = 'mono' THEN
+    NEW(mf); mf.bmp := NIL;
+    ReadInt(r, mf.charW); ReadInt(r, mf.charH);
+    IF (mf.charW > 0) & (mf.charH > 0) THEN
+      mf.cols := 16; mf.rows := 16 * fontPlanes
+    ELSE mf := NIL
+    END;
+    f := mf
+  END
+RETURN f END ReadFontInfo;
+
+PROCEDURE LoadFontInfo*(fname: ARRAY OF CHAR): Font;
+VAR f: Font;
+  F: Files.File;
+  r: Files.Rider;
+  s: ARRAY 4096 OF CHAR;
+BEGIN f := NIL;
+  s := fname; Strings.Append('.ofi', s);
+  F := Files.Old(s);
+  IF F # NIL THEN
+    s := fname; Strings.Append('.png', s);
+    IF Dir.FileExists(s) THEN
+      Files.Set(r, F, 0);
+      f := ReadFontInfo(r);
+      IF f # NIL THEN
+        f.loaded := FALSE;
+        f.fname := fname;
+        f.draw := MonoFontDraw;
+        f.handle := MonoFontHandle
+      END
     END
   END
-END SwitchToFullscreen;
+RETURN f END LoadFontInfo;
 
-PROCEDURE ToggleFullscreen*;
+PROCEDURE LoadFontBitmap*(f: Font);
+VAR s: ARRAY 4096 OF CHAR;
 BEGIN
-  IF fullscreen IN settings THEN SwitchToWindowed ELSE SwitchToFullscreen END
-END ToggleFullscreen;
+  s := ''; Strings.Append(f.fname, s); Strings.Append('.png', s);
+  f(MonoFont).bmp := LoadBitmap(s);
+  IF f(MonoFont).bmp # NIL THEN f.loaded := TRUE END
+END LoadFontBitmap;
+
+PROCEDURE LoadFont*(fname: ARRAY OF CHAR): Font;
+VAR f: Font;
+BEGIN f := LoadFontInfo(fname);
+  IF f # NIL THEN LoadFontBitmap(f) END
+RETURN f END LoadFont;
 
-PROCEDURE Delay*(n: INTEGER);
-BEGIN SDL.Delay(n)
-END Delay;
+(* Clipboard *)
 
-PROCEDURE PumpQuit;
+PROCEDURE GetClipboardText*(win: Window; VAR s: ARRAY OF CHAR);
+TYPE P = POINTER [1] TO ARRAY 5000 OF SHORTCHAR;
+VAR a: Al.ADRINT;
+  p: P;
+  q: ARRAY 20 OF SHORTCHAR;
 BEGIN
-  IF events.len < LEN(events.buf) THEN
-    QueueEvent;
-    events.buf[events.last].type := quit
+  a := Al.get_clipboard_text(win.display);
+  (*IF a = 0 THEN a := Al.get_clipboard_text(win.display) END; (*Allegro bug*)*)
+  Out.String('PASTE DEBUG. a = ');Out.Int(a, 0);Out.Ln;
+  IF a # 0 THEN p := SYSTEM.VAL(P, a); Utf8.Decode(p^, s);
+    Al.free_with_context(a, 27, 'Graph.Mod', 'GetClipboardText')
+    (*;Utf8.Encode('Привет', q);
+    ;IF Al.set_clipboard_text(win.display, SYSTEM.VAL(Al.ADRINT, SYSTEM.ADR(q))) THEN END*)
+  ELSE s[0] := 0X
   END
-END PumpQuit;
+END GetClipboardText;
 
-PROCEDURE PumpMouseMove(VAR event: SDL.Event);
-VAR e: SDL.MouseMotionEvent;
-  newX, newY: INTEGER;
-BEGIN
-  e := SYSTEM.VAL(SDL.MouseMotionEvent, SYSTEM.ADR(event));
-  newX := e.x; newY := e.y;
-  IF newX < 0 THEN newX := 0
-  ELSIF newX >= screen.w THEN newX := screen.w - 1
-  END;
-  IF newY < 0 THEN newY := 0
-  ELSIF newY >= screen.h THEN newY := screen.h - 1
-  END;
-  IF (newX # mouseX) OR (newY # mouseY) THEN
-    mouseX := newX; mouseY := newY;
-    needRedrawMouse := TRUE;
-    IF events.len < LEN(events.buf) THEN
-      QueueEvent;
-      events.buf[events.last].type := mouseMove;
-      events.buf[events.last].x := SHORT(ENTIER(newX / scaleX));
-      events.buf[events.last].y := SHORT(ENTIER(newY / scaleY));
-      events.buf[events.last].xRel := e.xRel;
-      events.buf[events.last].yRel := e.yRel;
-      events.buf[events.last].buttons := SYSTEM.VAL(SET32, e.state)
-    END
-  END
-END PumpMouseMove;
+PROCEDURE Time*(): REAL;
+RETURN Al.get_time() END Time;
 
-PROCEDURE PumpMouseButton(VAR event: SDL.Event; type: INTEGER);
-VAR e: SDL.MouseButtonEvent;
-BEGIN
-  e := SYSTEM.VAL(SDL.MouseButtonEvent, SYSTEM.ADR(event));
-  IF events.len < LEN(events.buf) THEN
-    QueueEvent;
-    events.buf[events.last].type := type;
-    events.buf[events.last].button := e.button - 1;
-    events.buf[events.last].down := e.state # 0;
-    IF e.x < 0 THEN e.x := 0
-    ELSIF e.x >= screen.w THEN e.x := screen.w - 1
-    END;
-    IF e.y < 0 THEN e.y := 0
-    ELSIF e.y >= screen.h THEN e.y := screen.h - 1
-    END;
-    events.buf[events.last].x := SHORT(ENTIER(e.x / scaleX));
-    events.buf[events.last].y := SHORT(ENTIER(e.y / scaleY))
-  END
-END PumpMouseButton;
+(* Window Icons *)
 
-PROCEDURE RepeatFlip*;
+PROCEDURE SetWindowIconsEx*(win: Window; icons: ARRAY OF Bitmap;
+    from, len: INTEGER);
+VAR m: ARRAY 64 OF Al.Bitmap;
+  i: INTEGER;
 BEGIN
-  IF screenTexture # 0 THEN
-    SDL.SetRenderDrawColor(renderer, 0, 0, 0, 255);
-    SDL.RenderClear(renderer);
-    SDL.RenderCopyNil(renderer, screenTexture);
-    SDL.RenderPresent(renderer)
-  END
-END RepeatFlip;
+  FOR i := 0 TO len - 1 DO m[i] := icons[from + i].bmp END;
+  FOR i := 0 TO len - 1 DO win.icons[i] := m[i] END;
+  win.noficons := len;
+  Al.set_display_icons(win.display, len, m)
+END SetWindowIconsEx;
 
-PROCEDURE WaitEvents*(timeout: INTEGER);
-VAR event: SDL.Event; n: INTEGER;
-BEGIN
-  n := SDL.PollEvent(event);
-  IF (n # 0) OR (events.len = 0) THEN
-    IF n = 0 THEN
-      IF timeout > 0 THEN n := SDL.WaitEventTimeout(event, timeout)
-      ELSIF timeout < 0 THEN n := SDL.WaitEvent(event)
-      END
-    END;
-    IF n # 0 THEN
-      REPEAT
-        IF event.type = SDL.mouseMotion THEN
-          PumpMouseMove(event)
-        ELSIF event.type = SDL.mouseButtonDown THEN
-          PumpMouseButton(event, mouseDown)
-        ELSIF event.type = SDL.mouseButtonUp THEN
-          PumpMouseButton(event, mouseUp)
-        ELSIF event.type = SDL.keyDown THEN
-          PumpKeyDown(event)
-        ELSIF event.type = SDL.textInput THEN
-          PumpTextEvent(event)
-        ELSIF event.type = SDL.quit THEN
-          PumpQuit
-        END
-      UNTIL SDL.PollEvent(event) = 0
-    END
-  END
-END WaitEvents;
+PROCEDURE SetWindowIcons*(win: Window; icons: ARRAY OF Bitmap);
+BEGIN SetWindowIconsEx(win, icons, 0, LEN(icons))
+END SetWindowIcons;
 
-PROCEDURE PollEvent*(VAR event: Event): BOOLEAN;
-VAR hasEvent: BOOLEAN;
+PROCEDURE SetWindowIcon*(win: Window; icon: Bitmap);
+VAR i: INTEGER;
 BEGIN
-  IF events.len > 0 THEN
-    event := events.buf[events.first];
-    IF event.type = keyDown THEN DEC(keyPressed) END;
-    DEC(events.len); INC(events.first);
-    IF events.first = LEN(events.buf) THEN events.first := 0 END;
-    hasEvent := TRUE
-  ELSE hasEvent := FALSE
-  END ;
-RETURN hasEvent END PollEvent;
-
-PROCEDURE KeyPressed*(): BOOLEAN;
-BEGIN WaitEvents(0) ;
-RETURN keyPressed > 0 END KeyPressed;
-
-PROCEDURE ReadKey*(): CHAR;
-VAR event: Event; done: BOOLEAN; ch: CHAR;
-BEGIN done := FALSE;
-  REPEAT
-    WaitEvents(-1);
-    WHILE PollEvent(event) DO
-      CASE event.type OF
-        keyDown: ch := CHR(event.key.sym); done := TRUE
-      | quit: ch := 0X; done := TRUE
-      ELSE
-      END
-    END
-  UNTIL done ;
-RETURN ch END ReadKey;
+  FOR i := 1 TO LEN(win.icons) - 1 DO win.icons[i] := NIL END;
+  win.icons[0] := icon.bmp; win.noficons := 1;
+  Al.set_display_icon(win.display, icon.bmp)
+END SetWindowIcon;
 
-PROCEDURE Pause*;
-BEGIN IF ReadKey() = 0X THEN END
-END Pause;
-
-PROCEDURE WindowShown*(): BOOLEAN;
-VAR flags: SET;
-BEGIN flags := SDL.GetWindowFlags(window) ;
-RETURN SDL.windowShown IN flags END WindowShown;
-
-PROCEDURE GetTicks*(): INTEGER; BEGIN
-RETURN SDL.GetTicks() END GetTicks;
+(* Init *)
 
-PROCEDURE Flip*;
-VAR mx, my: INTEGER; (* Mouse bitmap X Y *)
-    blitMouse: BOOLEAN;
-    dt: INTEGER; (* Delta time *)
-
-  PROCEDURE PrepareMouse;
-  BEGIN
-    mx := mouseX - mouseFocusX;
-    my := mouseY - mouseFocusY;
-    (* Save image under mouse from buffer *)
-    Blit(screen, underMouse, mx, my,
-      underMouse.w, underMouse.h, 0, 0);
-    (* Blit mouse pointer onto buffer *)
-    IF mouseX # -1 THEN
-      Blit(mousePointer, screen, 0, 0,
-        mousePointer.w, mousePointer.h, mx, my)
+PROCEDURE InitScreen(): BOOLEAN;
+VAR opt: SET;
+BEGIN
+  opt := settings;
+  IF {fullscreen, window} * opt = {} THEN INCL(opt, fullscreen)
+  ELSIF fullscreen IN opt THEN EXCL(opt, window)
+  END;
+  IF (wantW <= 0) OR (wantH <= 0) THEN
+    IF fullscreen IN opt THEN wantW := -1; wantH := -1
+    ELSE wantW := 640; wantH := 400
     END
-  END PrepareMouse;
-
-  PROCEDURE CleanMouse;
-  BEGIN
-    IF mouseX # -1 THEN (* Restore image under mouse in buffer *)
-      Blit(underMouse, screen, 0, 0, underMouse.w, underMouse.h, mx, my)
+  END
+RETURN NewWindow(-1, -1, wantW, wantH, wantTitle, opt) # NIL END InitScreen;
+
+PROCEDURE Init*;
+VAR ok: BOOLEAN;
+BEGIN ok := TRUE;
+  IF Al.install_system(Al.get_allegro_version(), 0) THEN
+    IF ~Al.install_keyboard() THEN
+      Error('Could not install keyboard.'); ok := FALSE
     END;
-    needRedrawMouse := FALSE
-  END CleanMouse;
 
-BEGIN
-  IF wantFPS # -1 THEN
-    IF lastFlip # -1 THEN
-      dt := 1000 DIV wantFPS - (GetTicks() - lastFlip);
-      IF (dt > 0) & (dt < 1000) THEN Delay(dt) END
-    END;
-    lastFlip := GetTicks()
-  END;
-  IF WindowShown() THEN
-    mx := 0; my := 0;
-    blitMouse := showMouse & MouseOnScreen();
-    IF blitMouse THEN PrepareMouse END;
-
-    (* Blit buffer on screen *)
-    SDL.SetRenderDrawColor(renderer, 0, 0, 0, 255);
-    SDL.RenderClear(renderer);
-    IF screenTexture # 0 THEN
-      SDL.DestroyTexture(screenTexture);
-      screenTexture := 0
+    IF ~(noMouse IN settings) & ~Al.install_mouse() THEN
+      Error('Could not install mouse.'); ok := FALSE
     END;
-    screenTexture := SDL.CreateTextureFromSurface(renderer, screen.surface);
-    SDL.SetTextureAlphaMod(screenTexture, screenAlpha);
-    SDL.RenderCopyNil(renderer, screenTexture);
-    SDL.RenderPresent(renderer);
 
-    IF blitMouse THEN CleanMouse END
-  END
-END Flip;
+    IF ~Al.init_primitives_addon() THEN
+      Error('Could not init primitives addon.'); ok := FALSE
+    END;
 
+    IF ~Al.init_image_addon() THEN
+      Error('Could not init image addon.'); ok := FALSE
+    END;
 
-(* Init *)
+    queue := Al.create_event_queue();
+    IF queue = NIL THEN
+      Error('Could not create queue.'); ok := FALSE
+    END;
 
-PROCEDURE Init*(): Bitmap;
-VAR flags: SET; success: BOOLEAN; w, h, nw, nh: INTEGER;
-  s: ARRAY 2000 OF CHAR;
-BEGIN screen := NIL; settings := initSettings;
-  IF SDL.Init({SDL.initVideo}) = 0 THEN
-    flags := {};
-    IF fullscreen IN settings THEN
-      flags := flags + SDL.windowFullscreenDesktop;
-      IF (scrW <= 0) OR (scrH <= 0) THEN
-        GetDesktopResolution(scrW, scrH);
-        scrW := SHORT(ENTIER(scrW / scaleX));
-        scrH := SHORT(ENTIER(scrH / scaleY))
-      ELSIF spread IN settings THEN
-        GetDesktopResolution(w, h);
-        w := SHORT(ENTIER(w / scaleX)); h := SHORT(ENTIER(h / scaleY));
-        IF sharpPixels IN settings THEN
-          nw := w DIV scrW; nh := h DIV scrH;
-          IF nw < nh THEN scrW := w DIV nw; scrH := h DIV nw
-          ELSE scrW := w DIV nh; scrH := h DIV nh
-          END
-        END;
-        IF w / h > scrW / scrH THEN scrW := w * scrH DIV h
-        ELSE scrH := h * scrW DIV w
-        END
+    IF ok THEN
+      Al.init_user_event_source(userEventSource);
+      Al.register_event_source(queue,
+        SYSTEM.VAL(Al.PEventSource, SYSTEM.ADR(userEventSource)));
+      Al.register_event_source(queue, Al.get_keyboard_event_source());
+      IF ~(noMouse IN settings) THEN
+        Al.register_event_source(queue, Al.get_mouse_event_source())
       END
-    ELSIF (scrW <= 0) OR (scrH <= 0) THEN scrW := 640; scrH := 400
     END;
-    IF sizeStepX # 1 THEN scrW := scrW DIV sizeStepX * sizeStepX END;
-    IF sizeStepY # 1 THEN scrH := scrH DIV sizeStepY * sizeStepY END;
-    window := SDL.CreateWindow('',
-      SDL.windowPosUndefined, SDL.windowPosUndefined,
-      scrW, scrH, flags);
-    IF window # 0 THEN
-      IF software IN settings THEN flags := {SDL.rendererSoftware}
-      ELSE flags := {SDL.rendererAccelerated}
-      END;
-      INCL(flags, SDL.rendererPresentVsync);
-      renderer := SDL.CreateRenderer(window, -1, flags);
-      IF sharpPixels IN settings THEN
-        SDL.SetHint(SDL.hintRenderScaleQuality, '0')
-      ELSE SDL.SetHint(SDL.hintRenderScaleQuality, '1')
-      END;
-      ApplyScale;
-      screen := CreateBitmap(scrW, scrH);
-      screenTexture := 0;
-      UnsetRegion;
-      SDL.ShowCursor(0);
-      IF initMouse IN settings THEN InitMouseData END;
-      IF {noPng, noJpg} - settings # {} THEN flags := {};
-        IF ~(noPng IN settings) THEN INCL(flags, SDL.imgInitPng) END;
-        IF ~(noJpg IN settings) THEN INCL(flags, SDL.imgInitJpg) END;
-        IF flags - SDL.ImgInit(flags) # {} THEN
-          Out.String('Could not initialize image format support.'); Out.Ln;
-          GetError(s); Out.String(s); Out.Ln
-        END
-      END;
-      keyPressed := 0;
-      lastFlip := -1;
-      screenAlpha := 255
+
+    IF ~(manual IN settings) THEN
+      IF ~InitScreen() THEN ok := FALSE END
     END
-  END ;
-RETURN screen END Init;
+  ELSE Error('Could not init Allegro.'); ok := FALSE
+  END;
+  Done := ok
+END Init;
+
+PROCEDURE ResetDefaults;
+BEGIN
+  wantW := 640; wantH := 400; wantSizeStepX := 1; wantSizeStepY := 1;
+  wantScaleX := 1.0; wantScaleY := 1.0; wantZoom := 1.0;
+  settings := {};
+  wantTitle := 'Oberon';
+  (* Reset global variables *)
+  queue := NIL; windowList := NIL; timerList := NIL;
+  screen := NIL; target := NIL
+END ResetDefaults;
 
 PROCEDURE Close*;
 BEGIN
-  IF screenTexture # 0 THEN
-    SDL.DestroyTexture(screenTexture);
-    screenTexture := 0
-  END;
-  IF renderer # 0 THEN
-    SDL.DestroyRenderer(renderer);
-    renderer := 0
-  END;
-  SDL.Quit
+  Al.uninstall_system;
+  ResetDefaults
 END Close;
 
-BEGIN
-  scrW := 640; scrH := 400;
-  sizeStepX := 1; sizeStepY := 1;
-  initSettings := {fullscreen, spread, sharpPixels};
-  renderer := 0; buffer := NIL; wantFPS := 60;
-  mousePointer := NIL; lastBlitMouseOutside := FALSE;
-  mouseFocusX := 0; mouseFocusY := 0;
-  scaleX := 1; scaleY := 1;
-  events.first := 0; events.last := -1; events.len := 0;
-  keyPressed := 0
+BEGIN Done := FALSE;
+  MakeCol(black, 0, 0, 0);
+  ResetDefaults
 END Graph.

+ 0 - 1440
src/Graph2.Mod

@@ -1,1440 +0,0 @@
-MODULE Graph2;
-IMPORT Out, Al := Allegro5, Utf8, Files, Dir, Strings, SYSTEM;
-
-CONST
-  fontPlanes = 4; (*!TODO*)
-
-  (* Settings set members *)
-  manual*      = 0;
-  fullscreen*  = 1;
-  window*      = 2;
-  exact*       = 3;
-  smooth*      = 4;
-  software*    = 5;
-  noMouse*     = 6;
-  center*      = 7;
-  resizable*   = 8;
-  maximized*   = 9;
-  minimized*   = 10;
-  frameless*   = 11;
-  nobuffer*    = 12;
-  topleft*     = 13;
-
-  (* Event.type possible values *)
-  noEvent      = 0;
-  quit*        = 1;
-  timer*       = 2;
-  windowEvent* = 3;
-  keyDown*     = 4;
-  keyUp*       = 5;
-  char*        = 6;
-  mouseMove*   = 7;
-  mouseDown*   = 8;
-  mouseUp*     = 9;
-  mouseWheel*  = 10;
-  resize*      = 11;
-
-  eventUserResize = 2005;
-
-  (* Window.zoom possible values *)
-  noZoom   = 0; (* The screen is not zoomed *)
-  intZoom  = 1; (* The zoom value is an integer: 2x, 3x etc. *)
-  realZoom = 2; (* The zoom value is not an integer, i.e. 2.5x *)
-
-  (* Flip flags *)
-  flipHor*  = 1;
-  flipVert* = 2;
-
-  (* Key Codes *)
-  kA*          = 1;
-  kB*          = 2;
-  kC*          = 3;
-  kD*          = 4;
-  kE*          = 5;
-  kF*          = 6;
-  kG*          = 7;
-  kH*          = 8;
-  kI*          = 9;
-  kJ*          = 10;
-  kK*          = 11;
-  kL*          = 12;
-  kM*          = 13;
-  kN*          = 14;
-  kO*          = 15;
-  kP*          = 16;
-  kQ*          = 17;
-  kR*          = 18;
-  kS*          = 19;
-  kT*          = 20;
-  kU*          = 21;
-  kV*          = 22;
-  kW*          = 23;
-  kX*          = 24;
-  kY*          = 25;
-  kZ*          = 26;
-  k0*          = 27;
-  k1*          = 28;
-  k2*          = 29;
-  k3*          = 30;
-  k4*          = 31;
-  k5*          = 32;
-  k6*          = 33;
-  k7*          = 34;
-  k8*          = 35;
-  k9*          = 36;
-  k0Pad*       = 37;
-  k1Pad*       = 38;
-  k2Pad*       = 39;
-  k3Pad*       = 40;
-  k4Pad*       = 41;
-  k5Pad*       = 42;
-  k6Pad*       = 43;
-  k7Pad*       = 44;
-  k8Pad*       = 45;
-  k9Pad*       = 46;
-  kF1*         = 47;
-  kF2*         = 48;
-  kF3*         = 49;
-  kF4*         = 50;
-  kF5*         = 51;
-  kF6*         = 52;
-  kF7*         = 53;
-  kF8*         = 54;
-  kF9*         = 55;
-  kF10*        = 56;
-  kF11*        = 57;
-  kF12*        = 58;
-  kEsc*        = 59;
-  kTilde*      = 60;
-  kMinus*      = 61;
-  kEquals*     = 62;
-  kBackspace*  = 63;
-  kTab*        = 64;
-  kOpenBrace*  = 65;
-  kCloseBrace* = 66;
-  kEnter*      = 67;
-  kColon*      = 68;
-  kQuote*      = 69;
-  kBackslash*  = 70;
-  kBackslash2* = 71;
-  kComma*      = 72;
-  kStop*       = 73;
-  kSlash*      = 74;
-  kSpace*      = 75;
-  kInsert*     = 76;
-  kDel*        = 77;
-  kHome*       = 78;
-  kEnd*        = 79;
-  kPgUp*       = 80;
-  kPgDn*       = 81;
-  kLeft*       = 82;
-  kRight*      = 83;
-  kUp*         = 84;
-  kDown*       = 85;
-  kSlashPad*   = 86;
-  kAsterisk*   = 87;
-  kMinusPad*   = 88;
-  kPlusPad*    = 89;
-  kDelPad*     = 90;
-  kEnterPad*   = 91;
-  kPrtScr*     = 92;
-  kPause*      = 93;
-  kEqualsPad*  = 103;
-  kBackquote*  = 104;
-  kSemicolon2* = 105;
-  kCommand*    = 106;
-
-  kBack*       = 107;
-  kVolumeUp*   = 108;
-  kVolumeDown* = 109;
-
-  kModifers*   = 215;
-
-  kLShift*     = 215;
-  kRShift*     = 216;
-  kLCtrl*      = 217;
-  kRCtrl*      = 218;
-  kAlt*        = 219;
-  kAltGr*      = 220;
-  kLMeta*      = 221;
-  kRMeta*      = 222;
-  kMenu*       = 223;
-  kScrLock*    = 224;
-  kNumLock*    = 225;
-  kCapsLock*   = 226;
-
-  kMax*        = 226;
-
-  (* Modifiers Set *)
-  mShift*      = 0;
-  mCtrl*       = 1;
-  mAlt*        = 2;
-  mLwin*       = 3;
-  mRwin*       = 4;
-  mMenu*       = 5;
-  mAltGr*      = 6;
-  mCommand*    = 7;
-  mScrolllock* = 8;
-  mNumlock*    = 9;
-  mCapslock*   = 10;
-
-TYPE
-  ADRINT = SYSTEM.ADRINT;
-  REAL = SYSTEM.REAL32;
-  LONGREAL = SYSTEM.REAL64;
-  LONGINT = SYSTEM.INT64;
-  SHORTCHAR = SYSTEM.CHAR8;
-
-  Color* = RECORD
-    r, g, b, a: REAL
-  END;
-
-  Transform* = RECORD
-    m: ARRAY 4, 4 OF REAL
-  END;
-
-  Timer* = POINTER TO TimerDesc;
-  TimerDesc* = RECORD
-    tmr: Al.Timer;
-    next: Timer (* See timerList below *)
-  END;
-
-  Bitmap* = POINTER TO BitmapDesc;
-  BitmapDesc* = RECORD
-    bmp: Al.Bitmap;
-    w*, h*: INTEGER
-  END;
-
-  Window* = POINTER TO WindowDesc;
-  WindowDesc* = RECORD(BitmapDesc)
-    display: Al.Display;
-    winW, winH: INTEGER; (* Window size in real pixels *)
-    initX, initY: INTEGER; (* Window position upon its creation *)
-    initW, initH: INTEGER; (* Window size upon its creation *)
-    fsW, fsH: INTEGER; (* Window size upon its creation *)
-    wantZoom: REAL; (* Window zoom upon its creation *)
-    lastX, lastY: INTEGER; (* Last mouse position in virtual pixels *)
-    lastW, lastH: INTEGER; (* Last stepped size in virtual pixels *)
-    zoom: INTEGER; (* See constants above; based on this rzoom/izoom is used *)
-    izoom: INTEGER; (* Window.izoom is used if Window.zoom = intZoom  *)
-    rzoom: REAL;    (* Window.rzoom is used if Window.zoom = realZoom *)
-    scaleOn: BOOLEAN; (* If TRUE, scaleX and scaleY are used *)
-    scaleX, scaleY: REAL; (* Deforms pixels on Flip, but zoom is for drawing *)
-    sizeStepX, sizeStepY: INTEGER;
-    flipX, flipY, flipW, flipH: REAL; (* Where to flip the window bitmap to *)
-    iFlipX, iFlipY: INTEGER; (* Same as flipX, flipY, which are always whole *)
-    options: SET;
-    title: ARRAY 256 OF CHAR;
-    resized: BOOLEAN; (* TRUE if fullscreen mode has been toggled for window *)
-    showMouse: BOOLEAN;
-    icons: ARRAY 64 OF Al.Bitmap;
-    noficons: INTEGER;
-    next: Window (* See windowList below *)
-  END;
-
-  Event* = RECORD
-    type*: INTEGER;
-    time*: REAL;
-    x*, y*, z*, w*, h*: INTEGER;
-    dx*, dy*, dz*, dw*: INTEGER;
-    button*: INTEGER;
-    buttons*: SET; (* What mouse buttons are pressed *)
-    down*: BOOLEAN;
-    count*: LONGINT; (* Timer counter *)
-    key*: INTEGER; (* Physical key code *)
-    ch*: CHAR; (* Typed character for event.type = char *)
-    mod*: SET; (* Key modifiers *)
-    repeat*: BOOLEAN;
-    window*: Window;
-    timer*: Timer;
-    display: Al.Display
-  END;
-
-  FontMessage* = POINTER TO FontMessageDesc;
-  FontMessageDesc* = RECORD
-
-  END;
-
-  FontDrawMsg* = POINTER TO FontDrawMsgDesc;
-  FontDrawMsgDesc* = RECORD(FontMessage)
-
-  END;
-
-  Font* = POINTER TO FontDesc;
-  FontDesc* = RECORD
-    fname: ARRAY 256 OF CHAR;
-    handle: PROCEDURE (font: Font; VAR msg: FontMessage);
-    draw: PROCEDURE (font: Font; VAR msg: FontDrawMsg);
-    loaded*: BOOLEAN
-  END;
-
-  MonoFont* = POINTER TO MonoFontDesc;
-  MonoFontDesc* = RECORD(FontDesc)
-    bmp: Bitmap;
-    charW*, charH*: INTEGER;
-    rows, cols: INTEGER
-  END;
-
-VAR
-  Done*: BOOLEAN;
-
-  settings: SET; (* See list of constants Settings above *)
-  wantW, wantH: INTEGER; (* Assigned in procedure Settings *)
-  wantZoom: REAL; (* Assigned in procedure SetZoom *)
-  wantSizeStepX, wantSizeStepY: INTEGER; (* Assigned in SetSizeStep *)
-  wantScaleX, wantScaleY: REAL; (* Assigned in procedure SetScale *)
-  wantTitle: ARRAY 256 OF CHAR; (* Assigned in procedure SetTitle *)
-  queue: Al.EventQueue;
-  userEventSource: Al.EventSource;
-  windowList: Window;
-  timerList: Timer;
-  screen: Window;
-  target: Bitmap;
-  black: Color;
-
-PROCEDURE Error(s: ARRAY OF CHAR);
-BEGIN Out.String(s); Out.Ln
-END Error;
-
-PROCEDURE GetDesktopResolution*(VAR w, h: INTEGER);
-VAR info: Al.MonitorInfo;
-BEGIN
-  IF Al.get_monitor_info(0, info) THEN
-    w := info.x2 - info.x1;
-    h := info.y2 - info.y1
-  ELSE w := -1; h := -1
-  END
-END GetDesktopResolution;
-
-PROCEDURE GetScreen*(): Window;
-RETURN screen END GetScreen;
-
-PROCEDURE GetScreenSize*(VAR width, height: INTEGER);
-BEGIN
-  IF screen # NIL THEN width := screen.w; height := screen.h
-  ELSE width := 0; height := 0
-  END
-END GetScreenSize;
-
-PROCEDURE Settings*(w, h: INTEGER; flags: SET);
-BEGIN wantW := w; wantH := h; settings := flags
-END Settings;
-
-PROCEDURE SetSizeStep*(w, h: INTEGER);
-BEGIN wantSizeStepX := w; wantSizeStepY := h
-END SetSizeStep;
-
-PROCEDURE ApplySizeStep(W: Window; VAR w, h: INTEGER);
-BEGIN
-  IF W.sizeStepX # 1 THEN
-    w := w DIV W.sizeStepX * W.sizeStepX;
-    IF w < W.sizeStepX THEN w := W.sizeStepX END
-  END;
-  IF W.sizeStepY # 1 THEN
-    h := h DIV W.sizeStepY * W.sizeStepY;
-    IF h < W.sizeStepY THEN h := W.sizeStepY END
-  END
-END ApplySizeStep;
-
-PROCEDURE GetTarget*(): Bitmap;
-RETURN target END GetTarget;
-
-PROCEDURE GetTargetSize*(VAR width, height: INTEGER);
-BEGIN
-  IF target # NIL THEN width := target.w; height := target.h
-  ELSE width := 0; height := 0
-  END
-END GetTargetSize;
-
-PROCEDURE Target*(bitmap: Bitmap);
-VAR T: Al.Transform;
-  W: Window;
-BEGIN target := bitmap;
-  IF bitmap # NIL THEN
-    IF (bitmap IS Window) & (bitmap.bmp = NIL) THEN W := bitmap(Window);
-      Al.set_target_backbuffer(W.display);
-      Al.build_transform(T, W.flipX, W.flipY, W.scaleX, W.scaleY, 0.0);
-      Al.use_transform(T)
-    ELSE Al.set_target_bitmap(SYSTEM.VAL(Al.Bitmap, bitmap.bmp))
-    END
-  END
-END Target;
-
-PROCEDURE TargetScreen*;
-BEGIN
-  IF screen # NIL THEN Target(screen)
-  ELSIF windowList # NIL THEN Target(windowList)
-  ELSE Target(NIL)
-  END
-END TargetScreen;
-
-PROCEDURE ResetFlipVars(W: Window);
-VAR w, h: INTEGER;
-BEGIN
-  IF W.zoom = intZoom THEN
-    w := W.w * W.izoom; h := W.h * W.izoom;
-    IF W.scaleOn THEN
-      W.flipW := FLT(FLOOR(FLT(w) * W.scaleX + 0.9));
-      W.flipH := FLT(FLOOR(FLT(h) * W.scaleY + 0.9));
-      W.iFlipX := (W.winW - FLOOR(W.flipW + 0.1)) DIV 2;
-      W.iFlipY := (W.winH - FLOOR(W.flipH + 0.1)) DIV 2
-    ELSE W.flipW := FLT(w); W.flipH := FLT(h);
-      W.iFlipX := (W.winW - w) DIV 2; W.iFlipY := (W.winH - h) DIV 2
-    END
-  ELSE
-    W.flipW := FLT(FLOOR(W.w * W.rzoom * W.scaleX + 0.9));
-    W.flipH := FLT(FLOOR(W.h * W.rzoom * W.scaleY + 0.9));
-    W.iFlipX := (W.winW - FLOOR(W.flipW + 0.1)) DIV 2;
-    W.iFlipY := (W.winH - FLOOR(W.flipH + 0.1)) DIV 2
-  END;
-  IF topleft IN W.options THEN W.iFlipX := 0; W.iFlipY := 0 END;
-  W.flipX := FLT(W.iFlipX); W.flipY := FLT(W.iFlipY);
-  IF ~(exact IN W.options) & (smooth IN W.options) &
-     ~(topleft IN W.options) & (W.winW - W.flipX - W.flipW < W.rzoom) &
-     (W.winH - W.flipY - W.flipH < W.rzoom) THEN
-    W.iFlipX := 0; W.iFlipY := 0; W.flipX := 0.0; W.flipY := 0.0;
-    W.flipW := FLT(W.winW); W.flipH := FLT(W.winH)
-  END
-END ResetFlipVars;
-
-PROCEDURE ResetWindowBitmap(W: Window);
-VAR opt: SET;
-  w, h, bw, bh: INTEGER;
-  fw, fh: REAL;
-  scaled, wasTarget: BOOLEAN;
-BEGIN scaled := FALSE;
-  IF W.bmp = NIL THEN bw := -1
-  ELSE bw := Al.get_bitmap_width(W.bmp); bh := Al.get_bitmap_height(W.bmp)
-  END;
-  IF ~(exact IN W.options) THEN
-    IF W.zoom = noZoom THEN w := W.winW; h := W.winH
-    ELSIF (W.zoom = intZoom) & ~W.scaleOn THEN
-      w := W.winW DIV W.izoom; h := W.winH DIV W.izoom
-    ELSE scaled := TRUE;
-      w := FLOOR(W.winW / W.rzoom / W.scaleX + 0.1);
-      h := FLOOR(W.winH / W.rzoom / W.scaleY + 0.1)
-    END
-  ELSE w := W.w; h := W.h
-  END;
-  IF W.scaleOn & ~scaled THEN
-    w := FLOOR(w / W.scaleX + 0.1); h := FLOOR(h / W.scaleY + 0.1)
-  END;
-
-  ApplySizeStep(W, w, h);
-  IF (w > bw) OR (h > bh) OR (W.zoom = noZoom) THEN
-    IF W.bmp # NIL THEN
-      wasTarget := Al.get_target_bitmap() = W.bmp;
-      Al.destroy_bitmap(W.bmp)
-    END;
-    IF (W.zoom = noZoom) & (nobuffer IN W.options) THEN
-      W.bmp := NIL;
-      IF wasTarget THEN Target(NIL) END
-    ELSE opt := {Al.convertBitmap};
-      IF smooth IN W.options THEN
-      	opt := opt + {Al.minLinear, Al.magLinear}
-      END;
-      Al.set_new_bitmap_flags(opt);
-      W.bmp := Al.create_bitmap(w, h);
-      IF wasTarget THEN Target(W) END
-    END
-  END;
-  W.w := w; W.h := h;
-  ResetFlipVars(W)
-END ResetWindowBitmap;
-
-PROCEDURE GetWindowOptions*(W: Window): SET;
-RETURN W.options END GetWindowOptions;
-
-PROCEDURE GetWindowZoom*(W: Window): REAL;
-RETURN W.rzoom END GetWindowZoom;
-
-PROCEDURE SetWindowZoomF*(W: Window; zoom: REAL);
-BEGIN W.rzoom := zoom;
-  IF zoom = 1.0 THEN W.zoom := noZoom
-  ELSIF FLOOR(zoom + 0.001) * 100 = FLOOR(zoom * 100 + 0.001) THEN
-    W.zoom := intZoom; W.izoom := FLOOR(zoom + 0.001)
-  ELSE W.zoom := realZoom
-  END;
-  ResetWindowBitmap(W)
-END SetWindowZoomF;
-
-PROCEDURE SetWindowZoom*(W: Window; zoom: INTEGER);
-BEGIN W.rzoom := FLT(zoom);
-  IF zoom = 1 THEN W.zoom := noZoom
-  ELSE W.zoom := intZoom; W.izoom := zoom
-  END;
-  ResetWindowBitmap(W)
-END SetWindowZoom;
-
-PROCEDURE SetNewWindowZoomF*(zoom: REAL);
-BEGIN wantZoom := zoom
-END SetNewWindowZoomF;
-
-PROCEDURE SetZoomF*(zoom: REAL);
-BEGIN wantZoom := zoom;
-  IF screen # NIL THEN SetWindowZoomF(screen, zoom) END
-END SetZoomF;
-
-PROCEDURE SetNewWindowZoom*(zoom: INTEGER);
-BEGIN wantZoom := FLT(zoom)
-END SetNewWindowZoom;
-
-PROCEDURE SetZoom*(zoom: INTEGER);
-BEGIN wantZoom := FLT(zoom);
-  IF screen # NIL THEN SetWindowZoom(screen, zoom) END
-END SetZoom;
-
-PROCEDURE SetWindowFullscreenSize*(win: Window; width, height: INTEGER);
-BEGIN win.fsW := width; win.fsH := height
-END SetWindowFullscreenSize;
-
-PROCEDURE ShowWindowMouse*(W: Window; show: BOOLEAN);
-BEGIN
-  IF show THEN
-    IF Al.show_mouse_cursor(W.display) THEN W.showMouse := TRUE END
-  ELSE
-    IF Al.hide_mouse_cursor(W.display) THEN W.showMouse := FALSE END
-  END
-END ShowWindowMouse;
-
-PROCEDURE ShowMouse*(show: BOOLEAN);
-BEGIN IF screen # NIL THEN ShowWindowMouse(screen, show) END
-END ShowMouse;
-
-PROCEDURE ApplyScale*(W: Window);
-VAR t: Al.Transform;
-BEGIN
-  (*Target(W);
-  Al.build_transform(t, 0.0, 0.0, 6.0, 6.0, 0.0);
-  Al.use_transform(t)*)
-END ApplyScale;
-
-PROCEDURE SetWindowOption*(W: Window; key: INTEGER; on: BOOLEAN);
-BEGIN IF on THEN INCL(W.options, key) ELSE EXCL(W.options, key) END
-END SetWindowOption;
-
-PROCEDURE SetWindowScale*(W: Window; x, y: REAL);
-BEGIN W.scaleOn := (x # 1.0) OR (y # 1.0);
-  W.scaleX := x; W.scaleY := y; ApplyScale(W)
-END SetWindowScale;
-
-PROCEDURE SetNewWindowScale*(x, y: REAL);
-BEGIN wantScaleX := x; wantScaleY := y
-END SetNewWindowScale;
-
-PROCEDURE SetScale*(x, y: REAL);
-BEGIN wantScaleX := x; wantScaleY := y;
-  IF screen # NIL THEN SetWindowScale(screen, x, y) END
-END SetScale;
-
-PROCEDURE SetWindowTitle*(W: Window; title: ARRAY OF CHAR);
-VAR q: ARRAY 256 OF SHORTCHAR;
-BEGIN Utf8.Encode(title, q); Al.set_window_title(W.display, q)
-END SetWindowTitle;
-
-PROCEDURE SetNewWindowTitle*(title: ARRAY OF CHAR);
-BEGIN wantTitle := title
-END SetNewWindowTitle;
-
-PROCEDURE SetTitle*(title: ARRAY OF CHAR);
-BEGIN wantTitle := title;
-  IF screen # NIL THEN SetWindowTitle(screen, title) END
-END SetTitle;
-
-(*PROCEDURE ClearBitmap*(bmp: Bitmap);
-PROCEDURE ClearScreenToColor*(color: INTEGER);*)
-
-PROCEDURE LoadBitmap*(fname: ARRAY OF CHAR): Bitmap;
-VAR B: Bitmap;
-  q: ARRAY 2048 OF SHORTCHAR;
-BEGIN Al.set_new_bitmap_flags({Al.convertBitmap});
-  NEW(B); Utf8.Encode(fname, q); B.bmp := Al.load_bitmap(q);
-  IF B.bmp = NIL THEN B := NIL
-  ELSE B.w := Al.get_bitmap_width(B.bmp); B.h := Al.get_bitmap_height(B.bmp)
-  END
-RETURN B END LoadBitmap;
-
-PROCEDURE Flip*;
-VAR tmp: Al.Bitmap;
-  W: Window;
-  T: Al.Transform;
-  x, y, w, h: REAL;
-BEGIN
-  IF ((target = NIL) OR ~(target IS Window)) & (screen # NIL) THEN
-    Target(screen)
-  END;
-  IF (target # NIL) & (target IS Window) THEN
-    W := target(Window);
-    tmp := Al.get_target_bitmap();
-    Al.set_target_backbuffer(W.display);
-    Al.identity_transform(T);
-    Al.use_transform(T);
-    IF target.bmp # NIL THEN
-      Al.clear_to_color(SYSTEM.VAL(Al.Color, black));
-      Al.draw_scaled_bitmap(W.bmp, 0.0, 0.0, FLT(W.w), FLT(W.h),
-        W.flipX, W.flipY, W.flipW, W.flipH, {})
-    ELSE w := FLT(W.winW); h := FLT(W.winH);
-      x := FLT(FLOOR(W.flipX + W.flipW + 0.1));
-      y := FLT(FLOOR(W.flipY + W.flipH + 0.1));
-      Al.draw_filled_rectangle(0.0, 0.0, w, W.flipY,
-        SYSTEM.VAL(Al.Color, black));
-      Al.draw_filled_rectangle(0.0, y, w, h, SYSTEM.VAL(Al.Color, black));
-      Al.draw_filled_rectangle(0.0, W.flipY, W.flipX, y,
-        SYSTEM.VAL(Al.Color, black));
-      Al.draw_filled_rectangle(x, W.flipY, w, y, SYSTEM.VAL(Al.Color, black))
-    END;
-    Al.flip_display();
-    Al.set_target_bitmap(tmp)
-  END
-END Flip;
-
-PROCEDURE PutPixel2*(x, y: INTEGER; c: Color);
-BEGIN Al.draw_filled_rectangle(FLT(x), FLT(y), FLT(x + 1), FLT(y + 1),
-  SYSTEM.VAL(Al.Color, c))
-END PutPixel2;
-
-PROCEDURE PutPixel*(x, y: INTEGER; c: Color);
-BEGIN Al.draw_pixel(FLT(x) + 0.5, FLT(y) + 0.5, SYSTEM.VAL(Al.Color, c))
-END PutPixel;
-
-PROCEDURE MakeCol*(VAR color: Color; r, g, b: INTEGER);
-BEGIN color.r := r / 255; color.g := g / 255;
-  color.b := b / 255; color.a := 1.0
-END MakeCol;
-
-PROCEDURE ColorToRGB*(color: Color; VAR r, g, b: INTEGER);
-BEGIN r := FLOOR(color.r * 255 + 0.1) MOD 256;
-  g := FLOOR(color.g * 255 + 0.1) MOD 256;
-  b := FLOOR(color.b * 255 + 0.1) MOD 256
-END ColorToRGB;
-
-PROCEDURE ColorToRGBA*(color: Color; VAR r, g, b, a: INTEGER);
-BEGIN r := FLOOR(color.r * 255 + 0.1) MOD 256;
-  g := FLOOR(color.g * 255 + 0.1) MOD 256;
-  b := FLOOR(color.b * 255 + 0.1) MOD 256;
-  a := FLOOR(color.a * 255 + 0.1) MOD 256
-END ColorToRGBA;
-
-PROCEDURE ClearToColor*(c: Color);
-BEGIN Al.clear_to_color(SYSTEM.VAL(Al.Color, c))
-END ClearToColor;
-
-PROCEDURE ClearScreen*;
-BEGIN Al.clear_to_color(SYSTEM.VAL(Al.Color, black))
-END ClearScreen;
-
-PROCEDURE ThickLineF*(x1, y1, x2, y2: REAL; color: Color; thickness: REAL);
-BEGIN Al.draw_line(x1, y1, x2, y2, SYSTEM.VAL(Al.Color, color), thickness)
-END ThickLineF;
-
-PROCEDURE ThickLine*(x1, y1, x2, y2: INTEGER; color: Color;
-    thickness: INTEGER);
-BEGIN
-  Al.draw_line(FLT(x1) + 0.5, FLT(y1) + 0.5, FLT(x2) + 0.5, FLT(y2) + 0.5,
-    SYSTEM.VAL(Al.Color, color), FLT(thickness))
-END ThickLine;
-
-PROCEDURE LineF*(x1, y1, x2, y2: REAL; color: Color);
-BEGIN
-  IF x1 < x2 THEN x2 := x2 + 1
-  ELSIF x1 > x2 THEN x1 := x1 + 1
-  ELSE x1 := x1 + 0.5; x2 := x2 + 0.5
-  END;
-  IF y1 < y2 THEN y2 := y2 + 1
-  ELSIF y1 > y2 THEN y1 := y1 + 1
-  ELSE y1 := y1 + 0.5; y2 := y2 + 0.5
-  END;
-  Al.draw_line(x1, y1, x2, y2, SYSTEM.VAL(Al.Color, color), 0.0)
-END LineF;
-
-PROCEDURE Line*(x1, y1, x2, y2: INTEGER; color: Color);
-BEGIN LineF(FLT(x1), FLT(y1), FLT(x2), FLT(y2), color)
-END Line;
-
-PROCEDURE HLine*(x, y1, y2: INTEGER; color: Color);
-BEGIN LineF(FLT(x), FLT(y1), FLT(x), FLT(y2), color)
-END HLine;
-
-PROCEDURE VLine*(x1, y, x2: INTEGER; color: Color);
-BEGIN LineF(FLT(x1), FLT(y), FLT(x2), FLT(y), color)
-END VLine;
-
-PROCEDURE FillRectF*(x1, y1, x2, y2: REAL; color: Color);
-BEGIN Al.draw_filled_rectangle(x1, y1, x2, y2, SYSTEM.VAL(Al.Color, color))
-END FillRectF;
-
-PROCEDURE FillRect*(x1, y1, x2, y2: INTEGER; color: Color);
-BEGIN
-  Al.draw_filled_rectangle(FLT(x1), FLT(y1),
-    FLT(x2 + 1), FLT(y2 + 1), SYSTEM.VAL(Al.Color, color))
-END FillRect;
-
-PROCEDURE ThickRectF*(x1, y1, x2, y2: REAL; color: Color; thickness: REAL);
-BEGIN Al.draw_rectangle(x1, y1, x2, y2, SYSTEM.VAL(Al.Color, color), thickness)
-END ThickRectF;
-
-PROCEDURE ThickRect*(x1, y1, x2, y2: INTEGER; color: Color;
-    thickness: INTEGER);
-BEGIN
-  Al.draw_rectangle(FLT(x1) + 0.5, FLT(y1) + 0.5,
-    FLT(x2) + 0.5, FLT(y2) + 0.5, SYSTEM.VAL(Al.Color, color), FLT(thickness))
-END ThickRect;
-
-PROCEDURE RectF*(x1, y1, x2, y2: REAL; color: Color);
-BEGIN Al.draw_rectangle(x1, y1, x2, y2, SYSTEM.VAL(Al.Color, color), 1.0)
-END RectF;
-
-PROCEDURE Rect*(x1, y1, x2, y2: INTEGER; color: Color);
-BEGIN
-  Al.draw_rectangle(FLT(x1) + 0.5, FLT(y1) + 0.5,
-    FLT(x2) + 0.5, FLT(y2) + 0.5, SYSTEM.VAL(Al.Color, color), 1.0)
-END Rect;
-
-PROCEDURE NewBitmap*(w, h: INTEGER): Bitmap;
-VAR b: Bitmap;
-BEGIN NEW(b);
-  Al.set_new_bitmap_flags({Al.convertBitmap});
-  b.bmp := Al.create_bitmap(w, h);
-  IF b.bmp = NIL THEN b := NIL ELSE b.w := w; b.h := h END
-RETURN b END NewBitmap;
-
-PROCEDURE DrawPartFlip*(bmp: Bitmap; sx, sy, sw, sh, dx, dy: INTEGER;
-    flags: SET);
-BEGIN
-  Al.draw_bitmap_region(bmp.bmp, FLT(sx), FLT(sy), FLT(sw), FLT(sh),
-    FLT(dx), FLT(dy), flags)
-END DrawPartFlip;
-
-PROCEDURE DrawPart*(bmp: Bitmap; sx, sy, sw, sh, dx, dy: INTEGER);
-BEGIN
-  Al.draw_bitmap_region(bmp.bmp, FLT(sx), FLT(sy), FLT(sw), FLT(sh),
-    FLT(dx), FLT(dy), {})
-END DrawPart;
-
-PROCEDURE DrawTintedPart*(bmp: Bitmap; color: Color;
-    sx, sy, sw, sh, dx, dy: INTEGER);
-BEGIN
-  IF ~Al.is_compatible_bitmap(bmp.bmp) THEN Out.String('NON-COMPAT'); Out.Ln END;
-  Al.draw_tinted_bitmap_region(bmp.bmp, SYSTEM.VAL(Al.Color, color),
-    FLT(sx), FLT(sy), FLT(sw), FLT(sh), FLT(dx), FLT(dy), {})
-END DrawTintedPart;
-
-PROCEDURE DrawFlip*(bmp: Bitmap; x, y: INTEGER; flags: SET);
-BEGIN Al.draw_bitmap(bmp.bmp, FLT(x), FLT(y), flags)
-END DrawFlip;
-
-PROCEDURE Draw*(bmp: Bitmap; x, y: INTEGER);
-BEGIN Al.draw_bitmap(bmp.bmp, FLT(x), FLT(y), {})
-END Draw;
-
-PROCEDURE DrawEx*(bmp: Bitmap; sx, sy, sw, sh, dx, dy, dw, dh: INTEGER;
-    flags: SET);
-BEGIN
-  Al.draw_scaled_bitmap(bmp.bmp, FLT(sx), FLT(sy), FLT(sw), FLT(sh),
-    FLT(dx), FLT(dy), FLT(dw), FLT(dh), flags)
-END DrawEx;
-
-PROCEDURE DrawRotated*(bmp: Bitmap; cx, cy, dx, dy: INTEGER;
-    angle: REAL; flags: SET);
-BEGIN
-  Al.draw_rotated_bitmap(bmp.bmp, FLT(cx), FLT(cy),
-    FLT(dx), FLT(dy), angle, flags)
-END DrawRotated;
-
-PROCEDURE DrawScaledRotated*(bmp: Bitmap; cx, cy, dx, dy: INTEGER;
-    xScale, yScale, angle: REAL; flags: SET);
-BEGIN
-  Al.draw_scaled_rotated_bitmap(bmp.bmp, FLT(cx), FLT(cy),
-    FLT(dx), FLT(dy), xScale, yScale, angle, flags)
-END DrawScaledRotated;
-
-PROCEDURE DelayF*(n: REAL);
-BEGIN Al.rest(n)
-END DelayF;
-
-PROCEDURE Delay*(n: INTEGER);
-BEGIN Al.rest(n / 1000)
-END Delay;
-
-PROCEDURE Pause*;
-BEGIN
-
-END Pause;
-
-PROCEDURE ConvertMemoryBitmaps*;
-BEGIN Al.convert_memory_bitmaps
-END ConvertMemoryBitmaps;
-
-PROCEDURE RecreateDisplay(W: Window; alterSize: BOOLEAN);
-VAR d: Al.Display;
-  q: ARRAY 256 OF SHORTCHAR;
-  opt: SET;
-  n, x, y, w, h, dw, dh, nw, nh, sw, sh: INTEGER;
-  nwf, nhf: REAL;
-  isCurTarget: BOOLEAN;
-BEGIN isCurTarget := target = W;
-  IF W.display # NIL THEN Al.destroy_display(W.display) END;
-
-  W.rzoom := W.wantZoom;
-  IF W.wantZoom = 1.0 THEN W.zoom := noZoom
-  ELSIF FLOOR(W.wantZoom + 0.001) * 100 = FLOOR(W.wantZoom * 100 + 0.001) THEN
-    W.zoom := intZoom; W.izoom := FLOOR(W.wantZoom + 0.001)
-  ELSE W.zoom := realZoom
-  END;
-
-  Utf8.Encode(W.title, q); Al.set_new_window_title(q);
-  IF software IN W.options THEN n := 0 ELSE n := 1 END;
-  Al.set_new_display_option(Al.renderMethod, n, Al.suggest);
-  Al.set_new_display_option(Al.vsync, 2(*off*), Al.suggest);
-  Al.set_new_display_option(Al.singleBuffer, 1, Al.suggest);
-  IF smooth IN W.options THEN n := 1;
-    Al.set_new_display_option(Al.samples, 8, Al.suggest)
-  ELSE n := 0
-  END;
-  (* Al.set_new_display_option(Al.sampleBuffers, n, Al.suggest); *)
-  GetDesktopResolution(dw, dh);
-  dw := FLOOR(FLT(dw) / wantScaleX + 0.1);
-  dh := FLOOR(FLT(dh) / wantScaleY + 0.1);
-
-  W.scaleOn := (wantScaleX # 1.0) OR (wantScaleY # 1.0);
-  W.scaleX := wantScaleX; W.scaleY := wantScaleY;
-
-  IF fullscreen IN W.options THEN w := W.fsW; h := W.fsH
-  ELSE w := W.initW; h := W.initH
-  END;
-
-  IF (w < 0) OR (h < 0) THEN
-    IF fullscreen IN W.options THEN
-      w := FLOOR(dw / W.wantZoom + 0.1); h := FLOOR(dh / W.wantZoom + 0.1);
-      ApplySizeStep(W, w, h);
-      sw := FLOOR(w * W.wantZoom + 0.1); sh := FLOOR(h * W.wantZoom + 0.1)
-    ELSE w := 640; h := 400; W.zoom := noZoom;
-      ApplySizeStep(W, w, h); sw := w; sh := h
-    END
-  ELSIF fullscreen IN W.options THEN
-    IF smooth IN W.options THEN nwf := dw / w; nhf := dh / h;
-      IF nhf < nwf THEN nwf := nhf END;
-      W.zoom := realZoom; W.rzoom := nwf;
-      IF exact IN W.options THEN
-        sw := FLOOR(w * nwf + 0.1); sh := FLOOR(h * nwf + 0.1)
-      ELSE sw := dw; sh := dh
-      END
-    ELSE nw := dw DIV w; nh := dh DIV h;
-      IF nh < nw THEN nw := nh END;
-      W.zoom := intZoom; W.izoom := nw; W.rzoom := FLT(nw);
-      IF exact IN W.options THEN sw := w * nw; sh := h * nw
-      ELSE sw := dw DIV nw * nw; sh := dh DIV nw * nw
-      END
-    END;
-
-    IF W.zoom = realZoom THEN
-      w := FLOOR(sw / W.rzoom + 0.1); h := FLOOR(sh / W.rzoom + 0.1)
-    ELSIF W.zoom = intZoom THEN w := sw DIV W.izoom; h := sh DIV W.izoom
-    ELSE w := sw; h := sh
-    END;
-    ApplySizeStep(W, w, h); sw := w; sh := h;
-    IF alterSize THEN W.initW := w; W.initH := h END
-  ELSE ApplySizeStep(W, w, h);
-    sw := FLOOR(w * W.wantZoom * W.scaleX + 0.999);
-    sh := FLOOR(h * W.wantZoom * W.scaleY + 0.999)
-  END;
-
-  W.lastW := 0; W.lastH := 0;
-
-  IF center IN W.options THEN GetDesktopResolution(dw, dh);
-    x := (dw - sw) DIV 2; y := (dh - sh) DIV 2;
-    IF x < 0 THEN x := 0 END; IF y < 0 THEN y := 0 END
-  ELSIF (W.initX < 0) OR (W.initY < 0) THEN x := Al.intMax; y := Al.intMax
-  ELSE x := W.initX; y := W.initY
-  END;
-  Al.set_new_window_position(x, y);
-
-  opt := {};
-  IF fullscreen IN W.options THEN INCL(opt, Al.fullscreenWindow)
-  ELSE INCL(opt, Al.windowed)
-  END;
-  IF resizable IN W.options THEN INCL(opt, Al.resizable) END;
-  IF maximized IN W.options THEN INCL(opt, Al.maximized) END;
-  IF minimized IN W.options THEN INCL(opt, Al.minimized) END;
-  IF frameless IN W.options THEN INCL(opt, Al.frameless) END;
-  Al.set_new_display_flags(opt);
-
-  IF W.bmp # NIL THEN Al.destroy_bitmap(W.bmp); W.bmp := NIL END;
-  W.display := Al.create_display(sw, sh);
-  IF W.display # NIL THEN
-    (*IF isCurTarget OR (windowList = NIL) OR (windowList.next = NIL) THEN
-      Al.set_target_backbuffer(W.display);
-      ConvertMemoryBitmaps;
-    END;*)
-    W.winW := Al.get_display_width(W.display);
-    W.winH := Al.get_display_height(W.display);
-    W.w := w; W.h := h;
-    ResetWindowBitmap(W);
-    Al.register_event_source(queue, Al.get_display_event_source(W.display));
-    IF isCurTarget THEN Target(W) END;
-    IF ~W.showMouse THEN ShowWindowMouse(W, FALSE) END;
-    IF W.noficons > 0 THEN
-      Al.set_display_icons(W.display, W.noficons, W.icons)
-    END
-  END
-END RecreateDisplay;
-
-PROCEDURE NewWindow*(x, y, w, h: INTEGER; title: ARRAY OF CHAR;
-    options: SET): Window;
-VAR W: Window;
-  d: Al.Display;
-  q: ARRAY 256 OF SHORTCHAR;
-  opt: SET;
-  i, n, dw, dh, nw, nh, sw, sh: INTEGER;
-  nwf, nhf: REAL;
-BEGIN NEW(W); W.lastX := -1; W.lastY := -1; W.resized := FALSE;
-  W.sizeStepX := wantSizeStepX; W.sizeStepY := wantSizeStepY;
-  IF {fullscreen, window} * options = {} THEN INCL(options, window)
-  ELSIF window IN options THEN EXCL(options, fullscreen)
-  END;
-  W.options := options;
-  W.title := title;
-  W.wantZoom := wantZoom;
-  W.scaleOn := (wantScaleX # 1.0) OR (wantScaleY # 1.0);
-  W.scaleX := wantScaleX; W.scaleY := wantScaleY;
-  W.initX := x; W.initY := y; W.initW := w; W.initH := h;
-  W.fsW := w; W.fsH := h;
-  W.showMouse := TRUE;
-  FOR i := 0 TO LEN(W.icons) - 1 DO W.icons[i] := NIL END;
-  W.noficons := 0;
-
-  W.display := NIL; RecreateDisplay(W, TRUE);
-  IF W.display # NIL THEN W.next := windowList; windowList := W
-  ELSE Error('Could not create dispaly.'); W := NIL
-  END;
-  IF (screen = NIL) & (W # NIL) THEN screen := W; Target(screen) END
-RETURN W END NewWindow;
-
-PROCEDURE CloseWindow*(W: Window);
-BEGIN Al.destroy_display(W.display)
-END CloseWindow;
-
-PROCEDURE NewTimer*(speed: REAL): Timer;
-VAR T: Timer;
-BEGIN NEW(T); T.tmr := Al.create_timer(speed);
-  IF T.tmr # NIL THEN
-    Al.register_event_source(queue, Al.get_timer_event_source(T.tmr));
-    T.next := timerList; timerList := T
-  ELSE T := NIL
-  END;
-RETURN T END NewTimer;
-
-PROCEDURE GetWindow(d: Al.Display): Window;
-VAR W: Window;
-BEGIN W := windowList;
-  WHILE (W # NIL) & (W.display # d) DO W := W.next END
-RETURN W END GetWindow;
-
-PROCEDURE GetTimer(a: Al.Timer): Timer;
-VAR t: Timer;
-BEGIN t := timerList;
-  WHILE (t # NIL) & (t.tmr # a) DO t := t.next END
-RETURN t END GetTimer;
-
-PROCEDURE EmitResizeEvent(W: Window);
-VAR E: Al.UserEvent;
-BEGIN
-  E.type := eventUserResize;
-  E.data4 := SYSTEM.VAL(ADRINT, W.display);
-  IF Al.emit_user_event(userEventSource, SYSTEM.VAL(Al.Event, E), 0) THEN END
-END EmitResizeEvent;
-
-PROCEDURE ToggleFS*(win: Window);
-VAR fs: BOOLEAN;
-  w, h: REAL;
-BEGIN
-  IF (win = NIL) & (screen # NIL) THEN win := screen END;
-  IF (win # NIL) & (win.display # NIL) THEN
-    fs := ~(Al.windowed IN Al.get_display_flags(win.display));
-    IF fs THEN EXCL(win.options, fullscreen); INCL(win.options, window)
-    ELSE INCL(win.options, fullscreen); EXCL(win.options, window);
-      w := Al.get_display_width(win.display) / win.rzoom;
-      h := Al.get_display_height(win.display) / win.rzoom;
-      IF win.scaleOn THEN w := w / win.scaleX; h := h / win.scaleY END;
-      win.initW := FLOOR(w + 0.1); win.initH := FLOOR(h + 0.1);
-      EXCL(win.options, center);
-      Al.get_window_position(win.display, win.initX, win.initY);
-      ApplySizeStep(win, win.initW, win.initH)
-    END;
-    win.scaleX := wantScaleX;
-    win.scaleY := wantScaleY;
-    RecreateDisplay(win, FALSE);
-    EmitResizeEvent(win)
-  END
-END ToggleFS;
-
-PROCEDURE SwitchToWindow*(win: Window);
-BEGIN IF ~(window IN GetWindowOptions(screen)) THEN ToggleFS(win) END
-END SwitchToWindow;
-
-PROCEDURE SwitchToFS*(win: Window);
-BEGIN IF window IN GetWindowOptions(screen) THEN ToggleFS(win) END
-END SwitchToFS;
-
-PROCEDURE ParseEvent(E: Al.Event; VAR event: Event);
-VAR DE: Al.PDisplayEvent;
-  TE: Al.PTimerEvent;
-  KE: Al.PKeyboardEvent;
-  ME: Al.PMouseEvent;
-  UE: Al.PUserEvent;
-  W: Window;
-  d: Al.Display;
-  x, y, w, h: INTEGER;
-  fw, fh: REAL;
-BEGIN
-  event.time := E.timestamp;
-  IF E.type = Al.eventMouseAxes THEN
-    ME := SYSTEM.VAL(Al.PMouseEvent, SYSTEM.ADR(E));
-    W := GetWindow(ME.display);
-    IF W.zoom = noZoom THEN x := ME.x - W.iFlipX; y := ME.y - W.iFlipY
-    ELSIF W.zoom = intZoom THEN
-      x := (ME.x - W.iFlipX) DIV W.izoom; y := (ME.y - W.iFlipY) DIV W.izoom
-    ELSE x := FLOOR((ME.x - W.flipX) / W.rzoom + 0.1);
-      y := FLOOR((ME.y - W.flipY) / W.rzoom + 0.1)
-    END;
-    IF W.scaleOn THEN
-      x := FLOOR(x / W.scaleX + 0.1); y := FLOOR(y / W.scaleY + 0.1)
-    END;
-    IF (x # W.lastX) OR (y # W.lastY) OR (ME.dz # 0) OR (ME.dw # 0) THEN
-      IF (ME.dz # 0) OR (ME.dw # 0) THEN event.type := mouseWheel;
-        event.dz := ME.dz; event.dw := ME.dw;
-        event.x := W.lastX; event.y := W.lastY;
-        event.z := ME.z; event.w := ME.w;
-        event.dx := 0; event.dy := 0
-      ELSE event.type := mouseMove;
-        IF x = -1 THEN event.dx := 0; event.dy := 0
-        ELSE event.dx := x - W.lastX; event.dy := y - W.lastY
-        END;
-        event.x := x; event.y := y;
-        W.lastX := event.x; W.lastY := event.y
-      END;
-      event.button := ME.button;
-      event.mod := {};
-      event.display := ME.display; event.window := W
-    ELSE event.type := noEvent
-    END
-  ELSIF E.type = Al.eventMouseButtonDown THEN
-    event.type := mouseDown;
-    ME := SYSTEM.VAL(Al.PMouseEvent, SYSTEM.ADR(E));
-    W := GetWindow(ME.display); event.window := W;
-    IF W.zoom = noZoom THEN x := ME.x - W.iFlipX; y := ME.y - W.iFlipY
-    ELSIF W.zoom = intZoom THEN
-      x := (ME.x - W.iFlipX) DIV W.izoom; y := (ME.y - W.iFlipY) DIV W.izoom
-    ELSE x := FLOOR((ME.x - W.flipX) / W.rzoom + 0.1);
-      y := FLOOR((ME.y - W.flipY) / W.rzoom + 0.1)
-    END;
-    IF W.scaleOn THEN
-      x := FLOOR(x / W.scaleX + 0.1); y := FLOOR(y / W.scaleY + 0.1)
-    END;
-    event.x := x; event.y := y;
-    event.z := ME.z; event.w := ME.w;
-    event.button := ME.button;
-    event.mod := {};
-    event.display := ME.display
-  ELSIF E.type = Al.eventMouseButtonUp THEN
-    event.type := mouseUp;
-    ME := SYSTEM.VAL(Al.PMouseEvent, SYSTEM.ADR(E));
-    W := GetWindow(ME.display); event.window := W;
-    IF W.zoom = noZoom THEN x := ME.x - W.iFlipX; y := ME.y - W.iFlipY
-    ELSIF W.zoom = intZoom THEN
-      x := (ME.x - W.iFlipX) DIV W.izoom; y := (ME.y - W.iFlipY) DIV W.izoom
-    ELSE x := FLOOR((ME.x - W.flipX) / W.rzoom + 0.1);
-      y := FLOOR((ME.y - W.flipY) / W.rzoom + 0.1)
-    END;
-    IF W.scaleOn THEN
-      x := FLOOR(x / W.scaleX + 0.1); y := FLOOR(y / W.scaleY + 0.1)
-    END;
-    event.x := x; event.y := y;
-    event.z := ME.z; event.w := ME.w;
-    event.button := ME.button;
-    event.mod := {};
-    event.display := ME.display
-  ELSIF E.type = Al.eventTimer THEN
-    event.type := timer;
-    TE := SYSTEM.VAL(Al.PTimerEvent, SYSTEM.ADR(E));
-    event.count := TE.count;
-    event.timer := GetTimer(SYSTEM.VAL(Al.Timer, TE.source))
-  ELSIF E.type = Al.eventKeyDown THEN
-    event.type := keyDown;
-    KE := SYSTEM.VAL(Al.PKeyboardEvent, SYSTEM.ADR(E));
-    event.key := KE.keycode;
-    event.mod := {};
-    event.display := KE.display;
-    event.window := GetWindow(event.display)
-  ELSIF E.type = Al.eventKeyUp THEN
-    event.type := keyUp;
-    KE := SYSTEM.VAL(Al.PKeyboardEvent, SYSTEM.ADR(E));
-    event.key := KE.keycode;
-    event.mod := {};
-    event.display := KE.display;
-    event.window := GetWindow(event.display)
-  ELSIF E.type = Al.eventKeyChar THEN
-    KE := SYSTEM.VAL(Al.PKeyboardEvent, SYSTEM.ADR(E));
-    event.type := char;
-    event.key := KE.keycode;
-    event.ch := CHR(KE.unichar);
-    event.mod := KE.modifiers;
-    event.repeat := KE.repeat;
-    event.display := KE.display;
-    event.window := GetWindow(event.display)
-  ELSIF (E.type = Al.eventDisplayResize) OR (E.type = eventUserResize) THEN
-    IF E.type = Al.eventDisplayResize THEN
-      DE := SYSTEM.VAL(Al.PDisplayEvent, SYSTEM.ADR(E));
-      d := DE.source; W := GetWindow(d);
-      W.winW := DE.width; W.winH := DE.height
-    ELSE UE := SYSTEM.VAL(Al.PUserEvent, SYSTEM.ADR(E));
-      d := SYSTEM.VAL(Al.Display, UE.data4); W := GetWindow(d);
-      W.winW := Al.get_display_width(d); W.winH := Al.get_display_height(d)
-    END;
-    fw := W.winW / W.rzoom; fh := W.winH / W.rzoom;
-    IF W.scaleOn THEN fw := fw / W.scaleX; fh := fh / W.scaleY END;
-    w := FLOOR(fw + 0.1); h := FLOOR(fh + 0.1);
-    IF E.type = Al.eventDisplayResize THEN
-      Al.acknowledge_resize(d);
-      ApplySizeStep(W, w, h)
-    END;
-    IF (w # W.lastW) OR (h # W.lastH) THEN
-      W.lastW := w; W.lastH := h;
-      event.type := resize; event.window := W; event.display := d;
-      event.w := w; event.h := h;
-      IF E.type = Al.eventDisplayResize THEN event.x := DE.x; event.y := DE.y
-      ELSE Al.get_window_position(d, event.x, event.y)
-      END;
-      ResetWindowBitmap(W)
-    ELSE ResetFlipVars(W); Flip; event.type := noEvent
-    END
-  ELSIF E.type = Al.eventDisplayClose THEN
-    event.type := quit;
-    event.display := SYSTEM.VAL(Al.Display, E.source);
-    event.window := GetWindow(event.display)
-  ELSE event.type := noEvent
-  END
-END ParseEvent;
-
-PROCEDURE WaitAndParseEvent(VAR event: Event);
-VAR E: Al.Event;
-BEGIN
-  Al.wait_for_event(queue, E);
-  ParseEvent(E, event)
-END WaitAndParseEvent;
-
-PROCEDURE PeekAndParseEvent(VAR event: Event): BOOLEAN;
-VAR E: Al.Event;
-  got: BOOLEAN;
-BEGIN
-  got := Al.peek_next_event(queue, E);
-  IF got THEN ParseEvent(E, event) END
-RETURN got END PeekAndParseEvent;
-
-PROCEDURE WaitEvent*(VAR event: Event);
-BEGIN REPEAT WaitAndParseEvent(event) UNTIL event.type # noEvent
-END WaitEvent;
-
-PROCEDURE PeekEvent*(VAR event: Event): BOOLEAN;
-VAR got: BOOLEAN;
-BEGIN
-  got := PeekAndParseEvent(event);
-  WHILE got & (event.type = noEvent) DO
-    IF Al.drop_next_event(queue) THEN END;
-    got := PeekAndParseEvent(event)
-  END
-RETURN got END PeekEvent;
-
-PROCEDURE HasEvents*(): BOOLEAN;
-VAR e: Event;
-RETURN PeekEvent(e) END HasEvents;
-
-PROCEDURE DropNextEvent*;
-VAR e: Event;
-BEGIN (*WaitEvent(e)*)
-  IF Al.drop_next_event(queue) THEN END
-END DropNextEvent;
-
-PROCEDURE StartTimer*(timer: Timer);
-BEGIN Al.start_timer(timer.tmr)
-END StartTimer;
-
-PROCEDURE StopTimer*(timer: Timer);
-BEGIN Al.stop_timer(timer.tmr)
-END StopTimer;
-
-PROCEDURE ResumeTimer*(timer: Timer);
-BEGIN Al.resume_timer(timer.tmr)
-END ResumeTimer;
-
-(* Font *)
-
-PROCEDURE GetMonoFontSize*(font: Font; VAR charW, charH: INTEGER);
-BEGIN charW := font(MonoFont).charW; charH := font(MonoFont).charH
-END GetMonoFontSize;
-
-PROCEDURE FindFontChar(font: Font; c: CHAR; VAR bmp: Bitmap;
-    VAR x, y, w, h: INTEGER);
-VAR n: INTEGER;
-  m: MonoFont;
-BEGIN m := font(MonoFont);
-  IF c < 200X THEN n := ORD(c)
-  ELSIF (400X <= c) & (c < 500X) THEN n := ORD(c) + (300H - 400H)
-  ELSIF (2500X <= c) & (c < 2600X) THEN n := ORD(c) + (200H - 2500H)
-  ELSE n := -1
-  END;
-  IF n < 0 THEN n := 1 (* "Bad" character *) END;
-  bmp := m.bmp;
-  x := n MOD m.cols * m.charW; y := n DIV m.cols * m.charH;
-  w := m.charW; h := m.charH
-END FindFontChar;
-
-PROCEDURE DrawCharEx*(ch: CHAR; x, y: INTEGER; font: Font; color: Color;
-    VAR w: INTEGER);
-VAR sx, sy, h: INTEGER;
-  bmp: Bitmap;
-BEGIN FindFontChar(font, ch, bmp, sx, sy, w, h);
-  DrawTintedPart(bmp, color, sx, sy, w, h, x, y)
-END DrawCharEx;
-
-PROCEDURE DrawChar*(ch: CHAR; x, y: INTEGER; font: Font; color: Color);
-VAR w: INTEGER;
-BEGIN DrawCharEx(ch, x, y, font, color, w)
-END DrawChar;
-
-PROCEDURE DrawString*(s: ARRAY OF CHAR; x, y: INTEGER;
-    font: Font; color: Color);
-VAR i, cx, cy, charW, destW, destH: INTEGER;
-  m: MonoFont;
-BEGIN m := font(MonoFont); i := 0; cx := x; cy := y;
-  GetTargetSize(destW, destH);
-  WHILE (s[i] # 0X) & (cx < destW) & (cy < destH) DO
-    IF s[i] = 0AX THEN cx := x; INC(cy, m.charH)
-    ELSE DrawCharEx(s[i], cx, cy, font, color, charW);
-      INC(i); INC(cx, charW)
-    END
-  END
-END DrawString;
-
-PROCEDURE MonoFontDraw(f: Font; VAR msg: FontDrawMsg);
-VAR m: MonoFont;
-BEGIN m := f(MonoFont);
-  (*!TODO*)
-END MonoFontDraw;
-
-PROCEDURE MonoFontHandle(f: Font; VAR msg: FontMessage);
-VAR m: MonoFont;
-BEGIN m := f(MonoFont)
-  (*!TODO*)
-END MonoFontHandle;
-
-PROCEDURE ReadWord(VAR r: Files.Rider; VAR s: ARRAY OF CHAR);
-VAR ch: CHAR;
-  i: INTEGER;
-BEGIN
-  Files.ReadChar(r, ch);
-  WHILE ~r.eof & (ch <= ' ') DO Files.ReadChar(r, ch) END;
-
-  i := 0;
-  WHILE ~r.eof & (ch > ' ') DO
-    IF (i # LEN(s) - 1) THEN s[i] := ch; INC(i) END;
-    Files.ReadChar(r, ch)
-  END;
-  s[i] := 0X
-END ReadWord;
-
-PROCEDURE ReadInt(VAR r: Files.Rider; VAR n: INTEGER);
-VAR ch: CHAR;
-  i: INTEGER;
-BEGIN
-  Files.ReadChar(r, ch);
-  WHILE ~r.eof & (ch <= ' ') DO Files.ReadChar(r, ch) END;
-
-  n := 0;
-  WHILE ~r.eof & ('0' <= ch) & (ch <= '9') DO
-    n := n * 10 + ORD(ch) - ORD('0');
-    Files.ReadChar(r, ch)
-  END
-END ReadInt;
-
-PROCEDURE ReadFontInfo(VAR r: Files.Rider): Font;
-VAR f: Font;
-  mf: MonoFont;
-  s: ARRAY 4096 OF CHAR;
-BEGIN f := NIL;
-  ReadWord(r, s);
-  IF s = 'mono' THEN
-    NEW(mf); mf.bmp := NIL;
-    ReadInt(r, mf.charW); ReadInt(r, mf.charH);
-    IF (mf.charW > 0) & (mf.charH > 0) THEN
-      mf.cols := 16; mf.rows := 16 * fontPlanes
-    ELSE mf := NIL
-    END;
-    f := mf
-  END
-RETURN f END ReadFontInfo;
-
-PROCEDURE LoadFontInfo*(fname: ARRAY OF CHAR): Font;
-VAR f: Font;
-  F: Files.File;
-  r: Files.Rider;
-  s: ARRAY 4096 OF CHAR;
-BEGIN f := NIL;
-  s := fname; Strings.Append('.ofi', s);
-  F := Files.Old(s);
-  IF F # NIL THEN
-    s := fname; Strings.Append('.png', s);
-    IF Dir.FileExists(s) THEN
-      Files.Set(r, F, 0);
-      f := ReadFontInfo(r);
-      IF f # NIL THEN
-        f.loaded := FALSE;
-        f.fname := fname;
-        f.draw := MonoFontDraw;
-        f.handle := MonoFontHandle
-      END
-    END
-  END
-RETURN f END LoadFontInfo;
-
-PROCEDURE LoadFontBitmap*(f: Font);
-VAR s: ARRAY 4096 OF CHAR;
-BEGIN
-  s := ''; Strings.Append(f.fname, s); Strings.Append('.png', s);
-  f(MonoFont).bmp := LoadBitmap(s);
-  IF f(MonoFont).bmp # NIL THEN f.loaded := TRUE END
-END LoadFontBitmap;
-
-PROCEDURE LoadFont*(fname: ARRAY OF CHAR): Font;
-VAR f: Font;
-BEGIN f := LoadFontInfo(fname);
-  IF f # NIL THEN LoadFontBitmap(f) END
-RETURN f END LoadFont;
-
-(* Clipboard *)
-
-PROCEDURE GetClipboardText*(win: Window; VAR s: ARRAY OF CHAR);
-TYPE P = POINTER [1] TO ARRAY 5000 OF SHORTCHAR;
-VAR a: Al.ADRINT;
-  p: P;
-  q: ARRAY 20 OF SHORTCHAR;
-BEGIN
-  a := Al.get_clipboard_text(win.display);
-  (*IF a = 0 THEN a := Al.get_clipboard_text(win.display) END; (*Allegro bug*)*)
-  Out.String('PASTE DEBUG. a = ');Out.Int(a, 0);Out.Ln;
-  IF a # 0 THEN p := SYSTEM.VAL(P, a); Utf8.Decode(p^, s);
-    Al.free_with_context(a, 27, 'Graph2.Mod', 'GetClipboardText')
-    (*;Utf8.Encode('Привет', q);
-    ;IF Al.set_clipboard_text(win.display, SYSTEM.VAL(Al.ADRINT, SYSTEM.ADR(q))) THEN END*)
-  ELSE s[0] := 0X
-  END
-END GetClipboardText;
-
-PROCEDURE Time*(): REAL;
-RETURN Al.get_time() END Time;
-
-(* Window Icons *)
-
-PROCEDURE SetWindowIconsEx*(win: Window; icons: ARRAY OF Bitmap;
-    from, len: INTEGER);
-VAR m: ARRAY 64 OF Al.Bitmap;
-  i: INTEGER;
-BEGIN
-  FOR i := 0 TO len - 1 DO m[i] := icons[from + i].bmp END;
-  FOR i := 0 TO len - 1 DO win.icons[i] := m[i] END;
-  win.noficons := len;
-  Al.set_display_icons(win.display, len, m)
-END SetWindowIconsEx;
-
-PROCEDURE SetWindowIcons*(win: Window; icons: ARRAY OF Bitmap);
-BEGIN SetWindowIconsEx(win, icons, 0, LEN(icons))
-END SetWindowIcons;
-
-PROCEDURE SetWindowIcon*(win: Window; icon: Bitmap);
-VAR i: INTEGER;
-BEGIN
-  FOR i := 1 TO LEN(win.icons) - 1 DO win.icons[i] := NIL END;
-  win.icons[0] := icon.bmp; win.noficons := 1;
-  Al.set_display_icon(win.display, icon.bmp)
-END SetWindowIcon;
-
-(* Init *)
-
-PROCEDURE InitScreen(): BOOLEAN;
-VAR opt: SET;
-BEGIN
-  opt := settings;
-  IF {fullscreen, window} * opt = {} THEN INCL(opt, fullscreen)
-  ELSIF fullscreen IN opt THEN EXCL(opt, window)
-  END;
-  IF (wantW <= 0) OR (wantH <= 0) THEN
-    IF fullscreen IN opt THEN wantW := -1; wantH := -1
-    ELSE wantW := 640; wantH := 400
-    END
-  END
-RETURN NewWindow(-1, -1, wantW, wantH, wantTitle, opt) # NIL END InitScreen;
-
-PROCEDURE Init*;
-VAR ok: BOOLEAN;
-BEGIN ok := TRUE;
-  IF Al.install_system(Al.get_allegro_version(), 0) THEN
-    IF ~Al.install_keyboard() THEN
-      Error('Could not install keyboard.'); ok := FALSE
-    END;
-
-    IF ~(noMouse IN settings) & ~Al.install_mouse() THEN
-      Error('Could not install mouse.'); ok := FALSE
-    END;
-
-    IF ~Al.init_primitives_addon() THEN
-      Error('Could not init primitives addon.'); ok := FALSE
-    END;
-
-    IF ~Al.init_image_addon() THEN
-      Error('Could not init image addon.'); ok := FALSE
-    END;
-
-    queue := Al.create_event_queue();
-    IF queue = NIL THEN
-      Error('Could not create queue.'); ok := FALSE
-    END;
-
-    IF ok THEN
-      Al.init_user_event_source(userEventSource);
-      Al.register_event_source(queue,
-        SYSTEM.VAL(Al.PEventSource, SYSTEM.ADR(userEventSource)));
-      Al.register_event_source(queue, Al.get_keyboard_event_source());
-      IF ~(noMouse IN settings) THEN
-        Al.register_event_source(queue, Al.get_mouse_event_source())
-      END
-    END;
-
-    IF ~(manual IN settings) THEN
-      IF ~InitScreen() THEN ok := FALSE END
-    END
-  ELSE Error('Could not init Allegro.'); ok := FALSE
-  END;
-  Done := ok
-END Init;
-
-PROCEDURE ResetDefaults;
-BEGIN
-  wantW := 640; wantH := 400; wantSizeStepX := 1; wantSizeStepY := 1;
-  wantScaleX := 1.0; wantScaleY := 1.0; wantZoom := 1.0;
-  settings := {};
-  wantTitle := 'Oberon';
-  (* Reset global variables *)
-  queue := NIL; windowList := NIL; timerList := NIL;
-  screen := NIL; target := NIL
-END ResetDefaults;
-
-PROCEDURE Close*;
-BEGIN
-  Al.uninstall_system;
-  ResetDefaults
-END Close;
-
-BEGIN Done := FALSE;
-  MakeCol(black, 0, 0, 0);
-  ResetDefaults
-END Graph2.

+ 0 - 525
src/SDL2.Mod

@@ -1,525 +0,0 @@
-MODULE SDL2;
-(* Copyright 2017-2022 Arthur Yefimov
-
-This file is part of Free Oberon.
-
-Free Oberon is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-Free Oberon is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
-*)
-IMPORT SYSTEM;
-CONST
-  (* SDL_Init Flags *)
-  initTimer*          = 0;
-  initAudio*          = 4;
-  initVideo*          = 5;
-  initJoystick*       = 9;
-  initHaptic*         = 12;
-  initGameController* = 13;
-  initEvents*         = 14;
-  initEverything*     = {initTimer, initAudio, initVideo, initJoystick,
-                        initHaptic, initGameController, initEvents};
-
-  (* SDL_CreateWindow Flags *)
-  windowFullscreen*        = 0;
-  windowOpenGL*            = 1;
-  windowShown*             = 2;
-  windowHidden*            = 3;
-  windowBorderless*        = 4;
-  windowResizable*         = 5;
-  windowMinimized*         = 6;
-  windowMaximized*         = 7;
-  windowInputGrabbed*      = 8;
-  windowInputFocus*        = 9;
-  windowMouseFocus*        = 10;
-  windowFullscreenDesktop* = {windowFullscreen, 12};
-  windowForeign*           = 11;
-  windowAllowHighDPI*      = 13;
-
-  (* Window Position *)
-  windowPosUndefined* = 1FFF0000H;
-
-  (* Event Types *)
-  firstEvent*      = 0;
-  quit*            = 100H;
-  windowEvent*     = 200H;
-  keyDown*         = 300H;
-  keyUp*           = 301H;
-  textEditing*     = 302H;
-  textInput*       = 303H;
-  mouseMotion*     = 400H;
-  mouseButtonDown* = 401H;
-  mouseButtonUp*   = 402H;
-  mouseWheel*      = 403H;
-  userEvent*       = 8000H;
-  lastEvent*       = 0FFFFH;
-
-  (* Key Mods *)
-  kmodLShift*   = 0;
-  kmodRShift*   = 1;
-  kmodLCtrl*    = 6;
-  kmodRCtrl*    = 7;
-  kmodLAlt*     = 8;
-  kmodRAlt*     = 9;
-  kmodLGui*     = 10;
-  kmodRGui*     = 11;
-  kmodNum*      = 12;
-  kmodCaps*     = 13;
-  kmodMode*     = 14;
-  kmodReserved* = 15;
-  kmodCtrl*     = {kmodLCtrl, kmodRCtrl};
-  kmodShift*    = {kmodLShift, kmodRShift};
-  kmodAlt*      = {kmodLAlt, kmodRAlt};
-  kmodGui*      = {kmodLGui, kmodRGui};
-
-  (* Hints (for SDL_Hint) *)
-  hintFramebufferAcceleration*             = 'SDL_FRAMEBUFFER_ACCELERATION';
-  hintRenderDriver*                        = 'SDL_RENDER_DRIVER';
-  hintRenderOpenglShaders*                 = 'SDL_RENDER_OPENGL_SHADERS';
-  hintRenderDirect3dThreadsafe*            = 'SDL_RENDER_DIRECT3D_THREADSAFE';
-  hintRenderDirect3d11Debug*               = 'SDL_RENDER_DIRECT3D11_DEBUG';
-  hintRenderLogicalSizeMode*               = 'SDL_RENDER_LOGICAL_SIZE_MODE';
-  hintRenderScaleQuality*                  = 'SDL_RENDER_SCALE_QUALITY';
-  hintRenderVsync*                         = 'SDL_RENDER_VSYNC';
-  hintVideoAllowScreensaver*               = 'SDL_VIDEO_ALLOW_SCREENSAVER';
-  hintVideoX11Xvidmode*                    = 'SDL_VIDEO_X11_XVIDMODE';
-  hintVideoX11Xinerama*                    = 'SDL_VIDEO_X11_XINERAMA';
-  hintVideoX11Xrandr*                      = 'SDL_VIDEO_X11_XRANDR';
-  hintVideoX11NetWmPing*                   = 'SDL_VIDEO_X11_NET_WM_PING';
-  hintVideoX11NetWmBypassCompositor*       = 'SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR';
-  hintWindowFrameUsableWhileCursorHidden*  = 'SDL_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN';
-  hintWindowsIntresourceIcon*              = 'SDL_WINDOWS_INTRESOURCE_ICON';
-  hintWindowsIntresourceIconSmall*         = 'SDL_WINDOWS_INTRESOURCE_ICON_SMALL';
-  hintWindowsEnableMessageloop*            = 'SDL_WINDOWS_ENABLE_MESSAGELOOP';
-  hintGrabKeyboard*                        = 'SDL_GRAB_KEYBOARD';
-  hintMouseDoubleClickTime*                = 'SDL_MOUSE_DOUBLE_CLICK_TIME';
-  hintMouseDoubleClickRadius*              = 'SDL_MOUSE_DOUBLE_CLICK_RADIUS';
-  hintMouseNormalSpeedScale*               = 'SDL_MOUSE_NORMAL_SPEED_SCALE';
-  hintMouseRelativeSpeedScale*             = 'SDL_MOUSE_RELATIVE_SPEED_SCALE';
-  hintMouseRelativeModeWarp*               = 'SDL_MOUSE_RELATIVE_MODE_WARP';
-  hintMouseFocusClickthrough*              = 'SDL_MOUSE_FOCUS_CLICKTHROUGH';
-  hintTouchMouseEvents*                    = 'SDL_TOUCH_MOUSE_EVENTS';
-  hintMouseTouchEvents*                    = 'SDL_MOUSE_TOUCH_EVENTS';
-  hintVideoMinimizeOnFocusLoss*            = 'SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS';
-  hintIdleTimerDisabled*                   = 'SDL_IOS_IDLE_TIMER_DISABLED';
-  hintOrientations*                        = 'SDL_IOS_ORIENTATIONS';
-  hintAppleTvControllerUiEvents*           = 'SDL_APPLE_TV_CONTROLLER_UI_EVENTS';
-  hintAppleTvRemoteAllowRotation*          = 'SDL_APPLE_TV_REMOTE_ALLOW_ROTATION';
-  hintIosHideHomeIndicator*                = 'SDL_IOS_HIDE_HOME_INDICATOR';
-  hintAccelerometerAsJoystick*             = 'SDL_ACCELEROMETER_AS_JOYSTICK';
-  hintTvRemoteAsJoystick*                  = 'SDL_TV_REMOTE_AS_JOYSTICK';
-  hintXinputEnabled*                       = 'SDL_XINPUT_ENABLED';
-  hintXinputUseOldJoystickMapping*         = 'SDL_XINPUT_USE_OLD_JOYSTICK_MAPPING';
-  hintGamecontrollerconfig*                = 'SDL_GAMECONTROLLERCONFIG';
-  hintGamecontrollerconfigFile*            = 'SDL_GAMECONTROLLERCONFIG_FILE';
-  hintGamecontrollerIgnoreDevices*         = 'SDL_GAMECONTROLLER_IGNORE_DEVICES';
-  hintGamecontrollerIgnoreDevicesExcept*   = 'SDL_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT';
-  hintJoystickAllowBackgroundEvents*       = 'SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS';
-  hintJoystickHidapi*                      = 'SDL_JOYSTICK_HIDAPI';
-  hintJoystickHidapiPs4*                   = 'SDL_JOYSTICK_HIDAPI_PS4';
-  hintJoystickHidapiPs4Rumble*             = 'SDL_JOYSTICK_HIDAPI_PS4_RUMBLE';
-  hintJoystickHidapiSteam*                 = 'SDL_JOYSTICK_HIDAPI_STEAM';
-  hintJoystickHidapiSwitch*                = 'SDL_JOYSTICK_HIDAPI_SWITCH';
-  hintJoystickHidapiXbox*                  = 'SDL_JOYSTICK_HIDAPI_XBOX';
-  hintEnableSteamControllers*              = 'SDL_ENABLE_STEAM_CONTROLLERS';
-  hintAllowTopmost*                        = 'SDL_ALLOW_TOPMOST';
-  hintTimerResolution*                     = 'SDL_TIMER_RESOLUTION';
-  hintQtwaylandContentOrientation*         = 'SDL_QTWAYLAND_CONTENT_ORIENTATION';
-  hintQtwaylandWindowFlags*                = 'SDL_QTWAYLAND_WINDOW_FLAGS';
-  hintThreadStackSize*                     = 'SDL_THREAD_STACK_SIZE';
-  hintVideoHighdpiDisabled*                = 'SDL_VIDEO_HIGHDPI_DISABLED';
-  hintMacCtrlClickEmulateRightClick*       = 'SDL_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK';
-  hintVideoWinD3dcompiler*                 = 'SDL_VIDEO_WIN_D3DCOMPILER';
-  hintVideoWindowSharePixelFormat*         = 'SDL_VIDEO_WINDOW_SHARE_PIXEL_FORMAT';
-  hintWinrtPrivacyPolicyUrl*               = 'SDL_WINRT_PRIVACY_POLICY_URL';
-  hintWinrtPrivacyPolicyLabel*             = 'SDL_WINRT_PRIVACY_POLICY_LABEL';
-  hintWinrtHandleBackButton*               = 'SDL_WINRT_HANDLE_BACK_BUTTON';
-  hintVideoMacFullscreenSpaces*            = 'SDL_VIDEO_MAC_FULLSCREEN_SPACES';
-  hintMacBackgroundApp*                    = 'SDL_MAC_BACKGROUND_APP';
-  hintAndroidApkExpansionMainFileVersion*  = 'SDL_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION';
-  hintAndroidApkExpansionPatchFileVersion* = 'SDL_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION';
-  hintImeInternalEditing*                  = 'SDL_IME_INTERNAL_EDITING';
-  hintAndroidTrapBackButton*               = 'SDL_ANDROID_TRAP_BACK_BUTTON';
-  hintAndroidBlockOnPause*                 = 'SDL_ANDROID_BLOCK_ON_PAUSE';
-  hintReturnKeyHidesIme*                   = 'SDL_RETURN_KEY_HIDES_IME';
-  hintEmscriptenKeyboardElement*           = 'SDL_EMSCRIPTEN_KEYBOARD_ELEMENT';
-  hintNoSignalHandlers*                    = 'SDL_NO_SIGNAL_HANDLERS';
-  hintWindowsNoCloseOnAltF4*               = 'SDL_WINDOWS_NO_CLOSE_ON_ALT_F4';
-  hintBmpSaveLegacyFormat*                 = 'SDL_BMP_SAVE_LEGACY_FORMAT';
-  hintWindowsDisableThreadNaming*          = 'SDL_WINDOWS_DISABLE_THREAD_NAMING';
-  hintRpiVideoLayer*                       = 'SDL_RPI_VIDEO_LAYER';
-  hintVideoDoubleBuffer*                   = 'SDL_VIDEO_DOUBLE_BUFFER';
-  hintOpenglEsDriver*                      = 'SDL_OPENGL_ES_DRIVER';
-  hintAudioResamplingMode*                 = 'SDL_AUDIO_RESAMPLING_MODE';
-  hintAudioCategory*                       = 'SDL_AUDIO_CATEGORY';
-  hintRenderBatching*                      = 'SDL_RENDER_BATCHING';
-  hintEventLogging*                        = 'SDL_EVENT_LOGGING';
-  hintWaveRiffChunkSize*                   = 'SDL_WAVE_RIFF_CHUNK_SIZE';
-  hintWaveTruncation*                      = 'SDL_WAVE_TRUNCATION';
-  hintWaveFactChunk*                       = 'SDL_WAVE_FACT_CHUNK';
-
-  (* Renderer Flags *)
-  rendererSoftware*      = 0;
-  rendererAccelerated*   = 1;
-  rendererPresentVsync*  = 2;
-  rendererTargetTexture* = 3;
-
-  (* Flip Flags*)
-  flipHorizontal* = 0;
-  flipVertical*   = 1;
-
-  (* ImgInit Flags *)
-  imgInitJpg*  = 0;
-  imgInitPng*  = 1;
-  imgInitTif*  = 2;
-  imgInitWebp* = 3;
-
-  (* Blend Modes *)
-  blendModeBlend* = 0;
-  blendModeAdd*   = 1;
-  blendModeMod*   = 2;
-
-  (* Mouse Buttons *)
-  buttonLeft*      = 1;
-  buttonMiddle*    = 2;
-  buttonRight*     = 3;
-  buttonWheelUp*   = 4;
-  buttonWheelDown* = 5;
-  buttonX1*        = 6;
-  buttonX2*        = 7;
-
-  (* Text Editing and Input *)
-  textEditingEventTextSize* = 32;
-  textInputEventTextSize*   = 32;
-
-  (* PeepEvents actions *)
-  addEvent*  = 0;
-  peekEvent* = 1;
-  getEvent*  = 2;
-
-TYPE
-  ADRINT = SYSTEM.ADRINT;
-  CHAR = SHORTCHAR;
-  INT8* = SYSTEM.INT8;
-  INT16* = SYSTEM.INT16;
-
-  Window* = ADRINT;
-
-  Renderer* = ADRINT;
-
-  WindowEvent* = POINTER [1] TO WindowEventDesc;
-  WindowEventDesc* = RECORD
-    type*: INTEGER;
-    timestamp*: INTEGER;
-    windowID*: INTEGER;
-    event*: INT16;
-    data1*: INTEGER;
-    data2*: INTEGER
-  END;
-
-  Keysym* = RECORD
-    scancode*: INTEGER;
-    sym*: INTEGER;
-    mod*: INT16
-  END;
-
-  KeyboardEvent* = POINTER [1] TO KeyboardEventDesc;
-  KeyboardEventDesc = RECORD
-    type*: INTEGER;
-    timestamp*: INTEGER;
-    windowID*: INTEGER;
-    state*: INT16;
-    repeat*: INT16;
-    keysym*: Keysym
-  END;
-
-  MouseMotionEvent* = POINTER [1] TO MouseMotionEventDesc;
-  MouseMotionEventDesc* = RECORD
-    type*: INTEGER;
-    timestamp*: INTEGER;
-    windowID*: INTEGER;
-    which*: INTEGER;
-    state*: INTEGER;
-    x*: INTEGER;
-    y*: INTEGER;
-    xRel*: INTEGER;
-    yRel*: INTEGER
-  END;
-
-  MouseButtonEvent* = POINTER [1] TO MouseButtonEventDesc;
-  MouseButtonEventDesc* = RECORD
-    type*: INTEGER;
-    timestamp*: INTEGER;
-    windowID*: INTEGER;
-    which*: INTEGER;
-    button*: INT8;
-    state*: INT8;
-    clicks*: INT8;
-    padding: INT8;
-    x*: INTEGER;
-    y*: INTEGER
-  END;
-
-  MouseWheelEvent* = POINTER [1] TO MouseWheelEventDesc;
-  MouseWheelEventDesc* = RECORD
-    type*: INTEGER;
-    timestamp*: INTEGER;
-    windowID*: INTEGER;
-    which*: INTEGER;
-    x*: INTEGER;
-    y*: INTEGER;
-    direction*: INTEGER
-  END;
-
-  TextEditingEvent* = POINTER [1] TO TextEditingEventDesc;
-  TextEditingEventDesc* = RECORD
-    type*: INTEGER;
-    timestamp*: INTEGER;
-    windowID*: INTEGER;
-    text*: ARRAY textEditingEventTextSize OF CHAR;
-    start*: INTEGER;
-    length*: INTEGER
-  END;
-
-  TextInputEvent* = POINTER [1] TO TextInputEventDesc;
-  TextInputEventDesc* = RECORD
-    type*: INTEGER;
-    timestamp*: INTEGER;
-    windowID*: INTEGER;
-    text*: ARRAY textInputEventTextSize OF CHAR
-  END;
-
-  Event* = RECORD
-    type*: INTEGER;
-    padding: ARRAY 124 OF CHAR
-  END;
-
-  Rect* = RECORD
-    x*, y*, w*, h*: INTEGER
-  END;
-
-  Palette* = POINTER [1] TO PaletteDesc;
-  PaletteDesc* = RECORD
-    nColors: INTEGER;
-    colors: ADRINT;
-    version: INTEGER;
-    refCount: INTEGER
-  END;
-
-  DisplayMode* = RECORD
-    format*: INTEGER;
-    w*, h*: INTEGER;
-    refreshRate*: INTEGER;
-    driverData: ADRINT
-  END;
-
-  PixelFormat* = POINTER [1] TO PixelFormatDesc;
-  PixelFormatDesc* = RECORD
-    format*: INTEGER;
-    palette*: Palette;
-    bitsPerPixel*: INT16;
-    bytesPerPixel*: INT16;
-    rMask*: INTEGER;
-    gMask*: INTEGER;
-    aMask*: INTEGER;
-    padding: ARRAY 17 OF CHAR
-  END;
-
-  Surface* = POINTER [1] TO SurfaceDesc;
-  SurfaceDesc* = RECORD
-    flags: INTEGER;
-    format*: PixelFormat;
-    w*, h*, pitch*: INTEGER;
-    pixels*: ADRINT;
-    userData*: ADRINT;
-    locked: INTEGER;
-    lockData: ADRINT;
-    clipRect*: Rect;
-    map: ADRINT;
-    refCount*: INTEGER
-  END;
-
-  Texture* = ADRINT;
-
-  KeyArray* = POINTER [1] TO ARRAY 1024 OF BOOLEAN;
-
-PROCEDURE -AAIncludeSDL2h0 '#include "SDL2.h0"';
-
-PROCEDURE -Init*(flags: SET): SHORTINT "SDL_Init(flags)";
-PROCEDURE -Quit* "SDL_Quit()";
-
-PROCEDURE -CreateWindow*(title: ARRAY OF CHAR; x, y, w, h: INTEGER;
-    flags: SET): Window
-    "(SYSTEM_ADRINT)SDL_CreateWindow(title, x, y, w, h, flags)";
-PROCEDURE -GetWindowSize*(window: Window; VAR w, h: INTEGER)
-    "SDL_GetWindowSize((void *)window, w, h)";
-PROCEDURE -SetWindowSize*(window: Window; w, h: INTEGER)
-    "SDL_SetWindowSize((void *)window, w, h)";
-PROCEDURE -DestroyWindow(window: ADRINT) "SDL_DestroyWindow((void *)window)";
-
-PROCEDURE -PollEvent*(VAR e: Event): INTEGER "SDL_PollEvent(e)";
-PROCEDURE -WaitEvent*(VAR e: Event): INTEGER "SDL_WaitEvent(e)";
-PROCEDURE -WaitEventTimeout*(VAR e: Event; timeout: INTEGER): INTEGER
-    "SDL_WaitEventTimeout(e, timeout)";
-
-PROCEDURE -PumpEvents* "SDL_PumpEvents()";
-PROCEDURE -PeepEvents*(events: ARRAY OF Event; numevents, action,
-    minType, maxType: INTEGER): INTEGER
-    "SDL_PeepEvents(events, numevents, action, minType, maxType)";
-
-PROCEDURE -HasEvent*(type: INTEGER): INTEGER "SDL_HasEvent(type)";
-PROCEDURE -HasEvents*(minType, maxType: INTEGER): INTEGER
-    "SDL_HasEvents(minType, maxType)";
-
-PROCEDURE -StartTextInput* "SDL_StartTextInput()";
-PROCEDURE -StopTextInput* "SDL_StopTextInput()";
-
-PROCEDURE -SetColorKey*(surface: Surface; flag: INTEGER; key: INTEGER)
-    "SDL_SetColorKey(surface, flag, key)";
-
-PROCEDURE -MapRGB*(format: PixelFormat; r, g, b: SHORTINT): INTEGER
-    "SDL_MapRGB(format, r, g, b)";
-
-PROCEDURE -RWFromFile*(fname, mode: ARRAY OF CHAR): ADRINT
-    "SDL_RWFromFile(fname, mode)";
-PROCEDURE -LoadBmpRW*(src: ADRINT; freeSrc: INTEGER): Surface
-    "(void *)SDL_LoadBMP_RW(src, freeSrc)";
-PROCEDURE -SaveBmpRW*(surface: Surface; src: ADRINT;
-    freeSrc: INTEGER): INTEGER
-    "(int)SDL_SaveBMP_RW(surface, src, freeSrc)";
-
-(* SDL Image Addon *)
-
-PROCEDURE -ImgInit*(flags: SET): SET "IMG_Init(flags)";
-PROCEDURE -ImgQuit* "IMG_Quit()";
-PROCEDURE -ImgLoad*(file: ARRAY OF CHAR): Surface
-    "(void *)IMG_Load(file)";
-PROCEDURE -ImgSavePng*(surface: Surface; file: ARRAY OF CHAR): INTEGER
-    "(int)IMG_SavePNG(surface, file)";
-PROCEDURE -ImgSaveJpg*(surface: Surface; file: ARRAY OF CHAR): INTEGER
-    "(int)IMG_SaveJPG(surface, file)";
-
-(* Renderer *)
-
-PROCEDURE -CreateRenderer*(window: Window; index: INTEGER;
-    flags: SET): Renderer
-    "(SYSTEM_ADRINT)SDL_CreateRenderer((void *)window, index, flags)";
-PROCEDURE -SetRenderDrawColor*(renderer: Renderer; r, g, b, a: SHORTINT)
-    "SDL_SetRenderDrawColor((void *)renderer, r, g, b, a)";
-PROCEDURE -RenderClear*(renderer: Renderer)
-    "SDL_RenderClear((void *)renderer)";
-PROCEDURE -RenderPresent*(renderer: Renderer)
-    "SDL_RenderPresent((void *)renderer)";
-PROCEDURE -RenderDrawLine*(renderer: Renderer; x1, y1, x2, y2: INTEGER)
-    "SDL_RenderDrawLine((void *)renderer, x1, y1, x2, y2)";
-PROCEDURE -RenderDrawPoint*(renderer: Renderer; x, y: INTEGER)
-    "SDL_RenderDrawPoint((void *)renderer, x, y)";
-PROCEDURE -RenderDrawRect*(renderer: Renderer; VAR rect: Rect)
-    "SDL_RenderDrawRect((void *)renderer, rect)";
-PROCEDURE -RenderFillRect*(renderer: Renderer; VAR rect: Rect)
-    "SDL_RenderFillRect((void *)renderer, rect)";
-PROCEDURE -RenderSetLogicalSize*(renderer: Renderer; w, h: INTEGER)
-    "SDL_RenderSetLogicalSize((void *)renderer, w, h)";
-PROCEDURE -RenderCopy*(renderer: Renderer; texture: Texture;
-    VAR srcRect, dstRect: Rect)
-    "SDL_RenderCopy((void *)renderer, (void *)texture, srcRect, dstRect)";
-PROCEDURE -RenderCopyNil*(renderer: Renderer; texture: Texture)
-    "SDL_RenderCopy((void *)renderer, (void *)texture, (void *)0, (void *)0)";
-(*PROCEDURE -RenderCopyEx*(renderer: Renderer; texture: Texture;
-    VAR srcRect, dstRect: Rect; angle: REAL; center: Point; flip: SET)
-    "SDL_RenderCopyEx((void * )renderer, (void * )texture, srcRect, dstRect, angle, center, flip)";*)
-PROCEDURE -SetRenderDrawBlendMode*(renderer: Renderer; blendMode: SET)
-    "SDL_SetRenderDrawBlendMode(void *)renderer, blendMode)";
-PROCEDURE -RenderSetScale*(renderer: Renderer; scaleX, scaleY: REAL)
-    "SDL_RenderSetScale((void *)renderer, scaleX, scaleY)";
-PROCEDURE -DestroyRenderer*(renderer: ADRINT)
-    "SDL_DestroyRenderer((void *)renderer)";
-
-(* Misc *)
-
-PROCEDURE -Delay*(ms: INTEGER) "SDL_Delay(ms)";
-PROCEDURE -SetHint*(name: ARRAY OF CHAR; value: ARRAY OF CHAR)
-    "SDL_SetHint(name, value)";
-PROCEDURE -ShowCursor*(toggle: SHORTINT) "SDL_ShowCursor(toggle)";
-PROCEDURE -GetError*(): ADRINT "SDL_GetError()";
-PROCEDURE -SDLGetKeyboardState(VAR numKeys: INTEGER): ADRINT
-    "(void *)SDL_GetKeyboardState(numKeys)";
-
-PROCEDURE -GetDesktopDisplayMode*(displayIndex: INTEGER; VAR mode: DisplayMode)
-    "SDL_GetDesktopDisplayMode(displayIndex, mode)";
-
-PROCEDURE -FillRect*(dst: Surface; VAR rect: Rect; color: INTEGER)
-    "SDL_FillRect(dst, rect, color)";
-
-PROCEDURE -FillRectNil*(dst: Surface; color: INTEGER)
-    "SDL_FillRect(dst, (void *)0, color)";
-
-PROCEDURE -LockSurface*(surface: Surface) "SDL_LockSurface(surface)";
-PROCEDURE -UnlockSurface*(surface: Surface) "SDL_UnlockSurface(surface)";
-PROCEDURE -FreeSurface*(surface: Surface) "SDL_FreeSurface(surface)";
-
-PROCEDURE -CreateRGBSurface*(flags, w, h, depth: INTEGER;
-    rMask, gMask, bMask, aMask: LONGINT): Surface
-    "(void *)SDL_CreateRGBSurface(flags, w, h, depth, rMask, gMask, bMask, aMask)";
-
-PROCEDURE -BlitSurface*(src: Surface; VAR srcRect: Rect;
-    dst: Surface; VAR dstRect: Rect) "SDL_UpperBlit(src, srcRect, dst, dstRect)";
-PROCEDURE -BlitSurfaceNil*(src: Surface;
-    dst: Surface; VAR dstRect: Rect) "SDL_UpperBlit(src, (void *)0, dst, dstRect)";
-PROCEDURE -BlitScaled*(src: Surface; VAR srcRect: Rect;
-    dst: Surface; VAR dstRect: Rect) "SDL_UpperBlitScaled(src, srcRect, dst, dstRect)";
-
-PROCEDURE -ConvertSurface*(src: Surface; fmt: PixelFormat;
-    flags: INTEGER): Surface "(void *)SDL_ConvertSurface(src, fmt, flags)";
-
-PROCEDURE -SetSurfaceColorMod*(surface: Surface; r, g, b: INTEGER)
-    "SDL_SetSurfaceColorMod((void *)surface, r, g, b)";
-
-PROCEDURE -SetTextureColorMod*(texture: Texture; r, g, b: INTEGER)
-    "SDL_SetTextureColorMod((void *)texture, r, g, b)";
-
-PROCEDURE -SetTextureAlphaMod*(texture: Texture; alpha: INTEGER)
-    "SDL_SetTextureAlphaMod((void *)texture, alpha)";
-
-PROCEDURE -GetKeyboardState*(VAR numKeys: INTEGER): KeyArray
-    "SDL_GetKeyboardState(numKeys)";
-
-PROCEDURE -GetKeyboardStateNil*(): KeyArray "(void *)SDL_GetKeyboardState((void *)0)";
-
-PROCEDURE -GetMouseState*(VAR x, y: INTEGER): INTEGER "SDL_GetMouseState(x, y)";
-
-PROCEDURE -GetWindowFlags*(window: Window): SET "SDL_GetWindowFlags((void *)window)";
-
-PROCEDURE -SetWindowTitle*(window: Window; title: ARRAY OF CHAR)
-    "SDL_SetWindowTitle((void *)window, title)";
-
-PROCEDURE -CreateTextureFromSurface*(renderer: Renderer; surface: Surface): Texture
-    "(SYSTEM_ADRINT)SDL_CreateTextureFromSurface((void *)renderer, surface)";
-
-PROCEDURE -DestroyTexture*(texture: Texture)
-    "SDL_DestroyTexture((void *)texture)";
-
-PROCEDURE -GetTicks*(): INTEGER "SDL_GetTicks()";
-
-PROCEDURE -SetWindowFullscreen*(window: Window; flags: SET): INTEGER
-    "SDL_SetWindowFullscreen((void *)window, flags)";
-
-PROCEDURE -SetSurfaceAlphaMod*(surface: Surface; alpha: BYTE): INTEGER
-    "SDL_SetSurfaceAlphaMod(surface, alpha)";
-
-PROCEDURE -SetClipRect*(surface: Surface; VAR rect: Rect): INTEGER
-    "SDL_SetClipRect(surface, rect)";
-
-PROCEDURE -SetClipRectNil*(surface: Surface): INTEGER
-    "SDL_SetClipRect(surface, (void *)0)";
-
-END SDL2.

+ 0 - 89
src/SDL2.h0

@@ -1,89 +0,0 @@
-#ifndef SDL2__h0
-#define SDL2__h0
-
-typedef unsigned char UINT8;
-typedef unsigned short UINT16;
-typedef unsigned int UINT32;
-
-typedef enum {
-  SDL_FALSE = 0,
-  SDL_TRUE  = 1
-} SDL_bool;
-
-typedef enum {
-    SDL_BLENDMODE_NONE = 0x00000000,
-    SDL_BLENDMODE_BLEND = 0x00000001,
-    SDL_BLENDMODE_ADD = 0x00000002,
-    SDL_BLENDMODE_MOD = 0x00000004
-} SDL_BlendMode;
-
-extern int SDL_UpperBlitScaled(void *, void *, void *, void *);
-extern int SDL_UpperBlit(void *, void *, void *, void *);
-extern void *SDL_ConvertSurface(void *, void *, UINT32);
-extern void *SDL_CreateRGBSurface(UINT32, int, int, int, UINT32, UINT32, UINT32, UINT32);
-extern void *SDL_CreateRenderer(void *, int, UINT32);
-extern void *SDL_CreateTextureFromSurface(void *, void *);
-extern void *SDL_CreateWindow(void *, int, int, int, int, UINT32);
-extern void SDL_Delay(UINT32);
-extern void SDL_DestroyTexture(void *);
-extern int SDL_FillRect(void *, void *, UINT32);
-extern void SDL_FreeSurface(void *);
-extern int SDL_GetDesktopDisplayMode(int, void *);
-extern void *SDL_GetError(void);
-extern int SDL_GetModState();
-extern void *SDL_GetKeyboardState(void *);
-extern UINT32 SDL_GetMouseState(void *, void *);
-extern UINT32 SDL_GetTicks(void);
-extern UINT32 SDL_GetWindowFlags(void *);
-extern void SDL_GetWindowSize(void *, void *, void *);
-extern int IMG_Init(int);
-extern void *IMG_Load(void *);
-extern void IMG_Quit(void);
-extern int IMG_SavePNG(void *, void *);
-extern int IMG_SaveJPG(void *, void *);
-extern int SDL_Init(UINT32);
-extern int SDL_InitSubSystem(UINT32);
-extern void *SDL_LoadBMP_RW(void *, int);
-extern int SDL_SaveBMP_RW(void *, void *, int);
-extern int SDL_LockSurface(void *);
-extern UINT32 SDL_MapRGB(void *, UINT8, UINT8, UINT8);
-extern int SDL_PollEvent(void *);
-extern int SDL_WaitEvent(void *);
-extern int SDL_WaitEventTimeout(void *, int timeout);
-extern void SDL_Quit(void);
-extern void SDL_QuitSubSystem(UINT32);
-extern void *SDL_RWFromFile(void *, void *);
-extern int SDL_RenderClear(void *);
-extern int SDL_RenderCopy(void *, void *, void *, void *);
-extern int SDL_RenderDrawLine(void *, int, int, int, int);
-extern int SDL_RenderDrawPoint(void *, int, int);
-extern int SDL_RenderDrawRect(void *, void *);
-extern int SDL_RenderFillRect(void *, void *);
-extern void SDL_RenderPresent(void *);
-extern int SDL_RenderSetLogicalSize(void *, int, int);
-extern int SDL_SetColorKey(void *, int, UINT32);
-extern SDL_bool SDL_SetHint(void *, void *);
-extern int SDL_SetRenderDrawBlendMode(void *, SDL_BlendMode);
-
-extern int SDL_RenderSetScale(void *renderer, float scaleX, float scaleY);
-extern void SDL_DestroyRenderer(void *renderer);
-
-extern int SDL_SetRenderDrawColor(void *, UINT8, UINT8, UINT8, UINT8);
-extern int SDL_SetSurfaceColorMod(void *, UINT8, UINT8, UINT8);
-extern int SDL_SetWindowFullscreen(void *, UINT32);
-extern void SDL_SetWindowSize(void *, int, int);
-extern void SDL_SetWindowTitle(void *, void *);
-extern void SDL_SetWindowIcon(void *, void *);
-extern int SDL_ShowCursor(int);
-extern void SDL_UnlockSurface(void *);
-extern void SDL_StartTextInput(void);
-extern void SDL_StopTextInput(void);
-extern int SDL_HasEvent(int);
-extern int SDL_HasEvents(int, int);
-extern int SDL_PeepEvents(void *, int, int, int, int);
-extern int SDL_SetSurfaceAlphaMod(void *, UINT8);
-extern int SDL_SetTextureColorMod(void *, UINT8, UINT8, UINT8);
-extern int SDL_SetTextureAlphaMod(void *, UINT8);
-extern SDL_bool SDL_SetClipRect(void *, void *);
-
-#endif

+ 1 - 1
src/TermBox.Mod

@@ -1,5 +1,5 @@
 MODULE TermBox;
-IMPORT G := Graph2, Strings, Int, Out, Platform, Kernel;
+IMPORT G := Graph, Strings, Int, Out, Platform, Kernel;
 
 CONST
   partW = 512;

+ 2 - 2
src/compile_GTest.bat

@@ -14,13 +14,13 @@ SET CCFULL=%CC% -g3 -O0 -fno-exceptions -I %OFRDIR%\..\..\Mod\Lib -I %OFRDIR%\Li
 ECHO ON
 %OFR% -7w Allegro5.Mod
 @IF ERRORLEVEL 1 GOTO ERR
-%OFR% -7w Graph2.Mod
+%OFR% -7w Graph.Mod
 @IF ERRORLEVEL 1 GOTO ERR
 %OFR% -7wm GTest.Mod
 @IF ERRORLEVEL 1 GOTO ERR
 
 %CCFULL% -o ..\%PROG%.exe resources.o ^
-  Graph2.c ^
+  Graph.c ^
   %PROG%.c ^
   ..\Data\bin\FreeOberon.a ^
   %OFRDIR%\Lib\Ofront.a ^

+ 2 - 2
src/compile_GTest.sh

@@ -5,12 +5,12 @@ export OBERON=.:$OFRDIR/Lib/Sym
 OFR="ofront+ -s88"
 
 $OFR -7w Allegro5.Mod && \
-$OFR -7w Graph2.Mod && \
+$OFR -7w Graph.Mod && \
 $OFR -7wm $PROG.Mod && \
 gcc -o $PROG -g3 -O0 -fno-exceptions \
   -I $OFRDIR/../../Mod/Lib \
   -I $OFRDIR/Lib/Obj \
-  Graph2.c $PROG.c \
+  Graph.c $PROG.c \
   ../Data/bin/libFreeOberon.a \
   $OFRDIR/Lib/libOfront.a \
   $(pkg-config \

+ 2 - 2
src/compile_TTest.sh

@@ -5,14 +5,14 @@ export OBERON=.:$OFRDIR/Lib/Sym
 OFR="ofront+ -s88"
 
 $OFR -7w Allegro5.Mod && \
-$OFR -7w Graph2.Mod && \
+$OFR -7w Graph.Mod && \
 $OFR -7w TermBox.Mod && \
 $OFR -7w TermSnow.Mod && \
 $OFR -7wm $PROG.Mod && \
 gcc -o $PROG -g3 -O0 -fno-exceptions \
   -I $OFRDIR/../../Mod/Lib \
   -I $OFRDIR/Lib/Obj \
-  Graph2.c TermBox.c $PROG.c \
+  Graph.c TermBox.c $PROG.c \
   ../Data/bin/libFreeOberon.a \
   $OFRDIR/Lib/libOfront.a \
   $(pkg-config \

+ 2 - 2
src/compile_TermSnow.sh

@@ -5,14 +5,14 @@ export OBERON=.:$OFRDIR/Lib/Sym
 OFR="ofront+ -s88"
 
 $OFR -7w Allegro5.Mod && \
-$OFR -7w Graph2.Mod && \
+$OFR -7w Graph.Mod && \
 $OFR -7w TermBox.Mod && \
 $OFR -7w TermSnow.Mod && \
 $OFR -7wm $PROG.Mod && \
 gcc -o $PROG -g3 -O0 -fno-exceptions \
   -I $OFRDIR/../../Mod/Lib \
   -I $OFRDIR/Lib/Obj \
-  Graph2.c TermBox.c $PROG.c \
+  Graph.c TermBox.c $PROG.c \
   ../Data/bin/libFreeOberon.a \
   $OFRDIR/Lib/libOfront.a \
   $(pkg-config \

+ 2 - 2
src/compile_Tetragon.sh

@@ -3,13 +3,13 @@ PATH="$OFRDIR:$PATH"
 export OBERON=.:$OFRDIR/Lib/Sym
 
 ofront+ -887ws Allegro5.Mod && \
-ofront+ -887ws Graph2.Mod && \
+ofront+ -887ws Graph.Mod && \
 ofront+ -887ws TermBox.Mod && \
 ofront+ -887wm Tetragon.Mod && \
 gcc -o Tetragon -g3 -O0 -fno-exceptions \
   -I ../Data/bin/OfrontPlus/Target/Linux_amd64/../../Mod/Lib \
   -I ../Data/bin/OfrontPlus/Target/Linux_amd64/Lib/Obj \
-  Graph2.c TermBox.c Tetragon.c \
+  Graph.c TermBox.c Tetragon.c \
   ../Data/bin/libFreeOberon.a \
   ../Data/bin/OfrontPlus/Target/Linux_amd64/Lib/libOfront.a \
   $(pkg-config \

+ 2 - 1
src/edit.sh

@@ -1,2 +1,3 @@
 #!/bin/bash
-vim -p Texts.Mod Files.Mod FreeOberon.Mod FoStrings.Mod ../Data/Texts/ru.dat Texts.Mod OV.Mod
+vim -p FreeOberon.Mod Graph.Mod Allegro5.Mod ../Data/bin/*.sh
+#vim -p Texts.Mod Files.Mod FreeOberon.Mod FoStrings.Mod ../Data/Texts/ru.dat Texts.Mod OV.Mod

+ 4 - 4
src/make.bat

@@ -41,7 +41,7 @@ ECHO ON
 @IF ERRORLEVEL 1 GOTO ERR
 %OFR% -7w Allegro5.Mod
 @IF ERRORLEVEL 1 GOTO ERR
-%OFR% -7w Graph2.Mod
+%OFR% -7w Graph.Mod
 @IF ERRORLEVEL 1 GOTO ERR
 %OFR% -7w TermBox.Mod
 @IF ERRORLEVEL 1 GOTO ERR
@@ -84,18 +84,18 @@ windres resources.rc resources.o
 @IF ERRORLEVEL 1 GOTO ERR
 %CCFULL% -c Dir.c -I..\Data\bin\mingw32\include
 @IF ERRORLEVEL 1 GOTO ERR
-%CCFULL% -c Graph2.c
+%CCFULL% -c Graph.c
 @IF ERRORLEVEL 1 GOTO ERR
 %CCFULL% -c TermBox.c
 @IF ERRORLEVEL 1 GOTO ERR
 
 %AR% -crs ..\Data\bin\FreeOberon.a ^
   Utf8.o Strings.o Reals.o Int.o In.o Out.o Args.o Files.o Texts.o Random.o ^
-  StrList.o Dir.o Graph2.o TermBox.o
+  StrList.o Dir.o Graph.o TermBox.o
 @IF ERRORLEVEL 1 GOTO ERR
 
 %CCFULL% -o ..\%PROG%.exe resources.o ^
-  Graph2.c TermBox.c ^
+  Graph.c TermBox.c ^
   Config.c term\term_win32.c ^
   Term.c OV.c FoStrings.c EditorText.c Editor.c ^
   %PROG%.c ^

+ 4 - 4
src/make.sh

@@ -40,7 +40,7 @@ $OFR -7w Dir.Mod &&
 
 $OFR -7w Allegro5.Mod &&
 
-$OFR -7w Graph2.Mod &&
+$OFR -7w Graph.Mod &&
 
 $OFR -7w TermBox.Mod &&
 
@@ -70,15 +70,15 @@ $CCFULL -c Texts.c &&
 $CCFULL -c Random.c &&
 $CCFULL -c StrList.c &&
 $CCFULL -c Dir.c &&
-$CCFULL -c Graph2.c &&
+$CCFULL -c Graph.c &&
 $CCFULL -c TermBox.c &&
 
 $AR -crs ../Data/bin/libFreeOberon.a \
   Utf8.o Strings.o Reals.o Int.o In.o Out.o Args.o Files.o Texts.o Random.o \
-  StrList.o Dir.o Graph2.o TermBox.o &&
+  StrList.o Dir.o Graph.o TermBox.o &&
 
 $CCFULL -o ../$PROG \
-  Graph2.c TermBox.c \
+  Graph.c TermBox.c \
   Config.c term/term_linux.c \
   Term.c OV.c FoStrings.c EditorText.c Editor.c \
   $PROG.c \