home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / XLIBP202.ZIP / XLIB2.PAS < prev    next >
Pascal/Delphi Source File  |  1994-10-04  |  42KB  |  899 lines

  1. Unit Xlib2;
  2.  
  3. {#F
  4. ╔═══════════════════════════════════════════════════════════════════════════╗
  5. ║                                                                           ║
  6. ║                 XLIB v2.0 - Graphics Library for Borland/Turbo Pascal 7.0          ║
  7. ║                                                                           ║
  8. ║               Tristan Tarrant - tristant@cogs.susx.ac.uk                  ║
  9. ║                                                                           ║
  10. ╠═══════════════════════════════════════════════════════════════════════════╣
  11. ║                                                                           ║
  12. ║                                 Credits                                   ║
  13. ║                                                                           ║
  14. ║                             Themie Gouthas                                ║
  15. ║                                                                           ║
  16. ║                            Matthew MacKenzie                              ║
  17. ║                                                                           ║
  18. ║                             Tore Bastiansen                               ║
  19. ║                                                                           ║
  20. ║                                 Andy Tam                                  ║
  21. ║                                                                           ║
  22. ║                               Douglas Webb                                ║
  23. ║                                                                           ║
  24. ║                              John  Schlagel                               ║
  25. ║                                                                           ║
  26. ╠═══════════════════════════════════════════════════════════════════════════╣
  27. ║                                                                           ║
  28. ║           I informally reserve all rights to the code in XLIB             ║
  29. ║       Rights to contributed code is also assumed to be reserved by        ║
  30. ║                          the original authors.                            ║
  31. ║                                                                           ║
  32. ╚═══════════════════════════════════════════════════════════════════════════╝
  33.  
  34.     XLibPas v2.0 is a set of libraries and utilities that allow you to use some
  35.     extended features of the standard VGA adapter which are not exploited in
  36.     mode 13h. The most important features are :
  37.         - Use of all of the 256k of standard VGA memory
  38.         - Several tweaked resolutions, all in 256 colours
  39.         - Multiple pages, double- and triple-buffering, page flipping
  40.                 and panning
  41.         - Split screen
  42.         - Planar, Video and Compiled bitmaps
  43.         - Drawing procedures (line,circle,pixel,boxes,filling,polygons)
  44.         - Text handling supporting user fonts
  45.         - Archiving and compression
  46.         - GIF/BMP encoding and decoding
  47.         - Bitmap scaling
  48.         - Virtual VSync handler
  49.         - Mouse routines
  50.         - Palette handling
  51.         - ...and (at long last) Protected Mode (experimental)}
  52. {#F}
  53.  
  54. {$A+,B-,E-,G+,N-,O-,P-,Q-,S-,T-,X+}
  55.  
  56. {$IFDEF DPMI}
  57. {$C FIXED PRELOAD PERMANENT}
  58. {$ENDIF}
  59.  
  60. Interface
  61.  
  62. Type
  63.     Vertex = record
  64.         x, y : word;
  65.     end;
  66.     AlignmentHeader = record
  67.         size, ImageWidth, ImageHeight : word;
  68.         alignments : array[0..3] of
  69.         record
  70.              ImagePtr, MaskPtr : word;
  71.         end;
  72.     end; { Data structure for VBMs. See #XBm2# }
  73.     LBMHeader = record
  74.         width, height : byte;
  75.     end;
  76.     PAlignmentHeader = ^AlignmentHeader;
  77. Const
  78.     XMode320x200  = 0;       {320x200x256 colors - 4.0+ pages}
  79.     XMode320x240  = 1;       {320x240x256 colors - 3.4+ pages - Square Pixels}
  80.     XMode360x200  = 2;       {360x200x256 colors - 3.6+ pages}
  81.     XMode360x240  = 3;       {360x240x256 colors - 3.0+ pages}
  82.     XMode376x282  = 4;       {376x282x256 colors - 2.4+ pages - Square Pixels}
  83.     XMode320x400  = 5;       {320x400x256 colors - 2.0+ pages}
  84.     XMode320x480  = 6;       {320x480x256 colors - 1.7+ pages}
  85.     XMode360x400  = 7;       {360x400x256 colors - 1.8+ pages}
  86.     XMode360x480  = 8;       {360x480x256 colors - 1.5+ pages}
  87.     XMode360x360  = 9;       {360x360x256 colors - 2.0+ pages}
  88.     XMode376x308  = 10;      {376x308x256 colors - 2.2+ pages}
  89.     XMode376x564  = 11;      {376x564x256 colors - 1.2+ pages}
  90.     XMode256x200  = 12;      {256x200x256 colors - 5.1+ pages}
  91.     XMode256x240  = 13;      {256x240x256 colors - 4.2+ pages}
  92.     XMode256x224  = 14;      {256x224x256 colors - 4.5+ pages}
  93.     XMode256x256  = 15;      {256x256x256 colors - 4.0  pages}
  94.     XMode360x270  = 16;      {360x270x256 colors - 2.6+ pages - Square Pixels}
  95.     XMode400x300  = 17;      {400x300x256 colors - 2.1+ pages - Square Pixels}
  96.  
  97.     LastMode      = 17;      {Number of modes available}
  98.  
  99.     RBackward     = 0;       {Rotate palette bacwards}
  100.     RForward      = 1;       {Rotate palette forwards}
  101.     InvalidXMode  = -1;      {Selected mode is invalid i.e. it does not exist}
  102.     Error         = 1;
  103. { An error has occured while executing an XLib procedure or function }
  104.     LeftPressed   = 1;       {Left Mouse button is pressed}
  105.     RightPressed  = 2;       {Right Mouse button is pressed}
  106.     {#Z+}
  107.     AlignData     = 6;
  108.     ColumnMask : array[0..3] of byte =
  109.         ( $11, $22, $44, $88 );
  110.     InitMouseDef : array[0..13] of byte =
  111.         (1,3,7,15,31,63,127,255,31,27,48,48,96,96);
  112.     {#Z-}
  113.  
  114. Var
  115.     InGraphics, {1 if in a graphics mode, 0 otherwise}
  116.     ErrorValue, {Set by every routine to indicate success or failure}
  117.     FontDriverActive, {Set after a call to xtextinit}
  118.     CharHeight, {Height of the current character set}
  119.     CharWidth, {Width of the current character set}
  120.     FirstChar, {First character in character set}
  121.     UserChHeight, {Height of the User Font}
  122.     UserChWidth, {Width of the User Font}
  123.     UserFirstCh, {First character in User's font}
  124.     DoubleScanFlag : Byte; {1 if mode is double-scanned, 0 otherwise}
  125.     CurrXMode, {Contains value of current graphics mode}
  126.     ScrnPhysicalByteWidth, {Physical width of the screen in bytes ( ie : group of 4 pixels )}
  127.     ScrnPhysicalPixelWidth, {Physical width of the screen in pixels}
  128.     ScrnPhysicalHeight, {Physical height of the screen in pixels}
  129.     SplitScrnOffs, {Offset in VRAM of Split Screen}
  130.     SplitScrnScanLine, {Screen Line where Split Screen is displayed}
  131.     SplitScrnVisibleHeight, {Height of the visible part of the split screen}
  132.     SplitScrnActive, {Contains 1 if SplitScreen is visible,0 otherwise}
  133.     Page0Offs, {Offset in VRAM of 1st page}
  134.     Page1Offs, {Offset in VRAM of 2nd page ( #XSetDoubleBuffer# )}
  135.     Page2Offs, {Offset in VRAM of 3rd page ( #XSetTripleBuffer# )}
  136.     ScrnLogicalByteWidth, {Width in bytes ( groups of 4 pixels ) of a page}
  137.     ScrnLogicalPixelWidth, {Width in pixels of a page}
  138.     ScrnLogicalHeight, {Height in pixels of a page}
  139.     MaxScrollX, {Maximum value for left edge of screen}
  140.     MaxScrollY, {Maximum value for top edge of screen}
  141.     DoubleBufferActive, {Set by #XSetDoubleBuffer#}
  142.     TripleBufferActive, {Set by #XSetTripleBuffer#}
  143.     VisiblePageIdx, {Number of the Visible Page}
  144.     HiddenPageOffs, {Offset of the Hidden page}
  145.     VisiblePageOffs, {Offset of the Visible page}
  146.     WaitingPageOffs, {Offset of the Waiting page}
  147.     NonVisualOffs, {Offset of start of unused VRAM}
  148.     TopClip, {Top clipping edge}
  149.     BottomClip,{Bottom clipping edge}
  150.     LeftClip, {Left clipping edge}
  151.     RightClip, {Right clipping edge}
  152.     PhysicalStartPixelX, {X coordinate of top left pixel}
  153.     PhysicalStartByteX, {X coordinate of top left pixel /4}
  154.     PhysicalStartY, {Y coordinate of top left pixel}
  155.     VsyncHandlerActive, {set to 1 if the VSync handler has been installed}
  156.     MouseRefreshFlag, {set to 1 if the mouse pointer needs refreshing}
  157.     StartAddressFlag, {if set to 0 then it's possible to #xpageflip#}
  158.     MouseInstalled, {set to 1 if the Mouse handler has been installed}
  159.     MouseHidden, {set to 1 if after a call to #XHideMouse#}
  160.     MouseButtonStatus, {information on the button presses}
  161.     MouseButtonCount, {the number of buttons on the mouse}
  162.     MouseX, {X coordinate of mouse pointer}
  163.     MouseY, {Y coordinate of mouse pointer}
  164.     ScreenSeg : word; {Segment/Selector of VRAM}
  165.     MouseFrozen, {set to 1 if you want to update the mouse manually}
  166.     MouseColor : byte;  {color of the mouse pointer}
  167.  
  168. Function  XSetMode( Mode, WidthInPixels : Word ) : Word;
  169. { Mode            - The required mode
  170.     WidthInPixels   - The width of the logical screen
  171.  
  172.     This function initialises the graphics system, setting the apropriate
  173.     screen resolution and allocating a virtual screen. The virtual screen
  174.     allocated may not necessarily be of the same size as specified in the
  175.     WidthInPixels parameter as it is rounded down to the nearest
  176.     multiple of 4.
  177.  
  178.     The function returns the actual width of the allocated virtual screen
  179.     in pixels if a valid mode was selected otherwise returns
  180.     XMODEINVALID.}
  181. Procedure XSelectDefaultPlane( Plane : Byte );
  182. { Enables default Read/Write access to a specified plane}
  183. Procedure XSetSplitscreen( Line : Word );
  184. {   line - The starting scan line of the required split screen.
  185.  
  186.     This function activates Mode X split screen and sets starting scan line
  187.     The split screen resides on the bottom half of the screen and has a
  188.     starting address of A000:0000 in video RAM.
  189.  
  190.     It also Updates Page0Offs to reflect the existence of the split screen
  191.     region ie MainScrnOffset is set to the offset of the first pixel
  192.     beyond the split screen region. Other variables set are #Page1Offs# which
  193.     is set to the same value as #Page0Offs# (see graphics call sequence below),
  194.     #ScrnLogicalHeight#,#ScrnPhysicalHeight#, #SplitScrnScanLine# and
  195.     #MaxScrollY#.
  196.  
  197.     This function cannot be called after double buffering has been activated,
  198.     it will return an error. To configure your graphics environment the
  199.     sequence of graphics calls is as follows although either or both steps b
  200.     and c may be omitted:
  201.         a) #XSetMode#
  202.         b) #XSetSplitScreen#
  203.         c) #XSetDoubleBuffer#
  204.     Thus when you call this function successfully, double buffering is not
  205.     active so #Page1Offs# is set to the same address as #Page0Offs#.
  206.  
  207.     WARNING: If you use one of the high resolution modes (376x564 as an
  208.     extreme example) you may not have enough video ram for split screen
  209.     and double buffering options since VGA video RAM is restricted to 64K.}
  210. Procedure XSetStartAddr( X, Y : Word );
  211. { X,Y - coordinates of top left corner of physical screen within current
  212.     virtual screen.
  213.  
  214.     Set Mode X non split screen physical start address within current virtual
  215.     page.
  216.  
  217.     X must not exceed (Logical screen width - Physical screen width)
  218.     ie #MaxScrollX# and Y must not exceed (Logical screen height -
  219.     Physical screen height) ie #MaxScrollY#}
  220. Procedure XHideSplitscreen;
  221. { This function hides an existing split screen by setting its starting
  222.     scan line to the last physical screen scan line.
  223.     ScreenPhysicalHeight is adjusted but the SplitScreenScanLine is not
  224.     altered as it is required for restoring the split screen at a later stage.
  225.  
  226.     WARNING: Only to be used if #XSetSplitScreen# has been previously called
  227.          The memory for  the initial split screen is reserved and the size
  228.          limitations of certain modes means any change in the split screen scan
  229.          line will encroach on the split screen ram.}
  230. Procedure XShowSplitscreen;
  231. { Restores split screen start scan line to the initial split screen
  232.     starting scan line as set by #XSetSplitScreen#.
  233.     #ScreenPhysicalHeight# is adjusted.
  234.  
  235.     WARNING: Only to be used if #XSetSplitScrnLine# has been previously called
  236.          The memory for the initial split screen is reserved and the size
  237.          limitations of certain modes means any change in the split screen scan
  238.          line will encroach on the split screen ram.}
  239. Procedure XAdjustSplitscreen( Line : Word );
  240. { line - The scan line at which the split screen is to start.
  241.  
  242.     Sets the split screen start scan line to a new scan line. Valid scan lines
  243.     are between the initial split screen starting scan line and the last
  244.     physical screen scan line. ScreenPhysicalHeight is also adjusted.
  245.  
  246.     WARNING: Only to be used if #XSetSplitScreen# has been previously called
  247.          The memory for the initial split screen is reserved and the size
  248.          limitations of certain modes means any change in the split screen scan
  249.          line will encroach on the split screen ram.}
  250. Procedure XSetDoubleBuffer( PageHeight : Word );
  251. {   PageHeight    - The height of the two double buffering virtual screens.
  252.         Returns       - The closest possible height to the specified.
  253.  
  254.     This function sets up two double buffering virtual pages. ErrorValue
  255.     is set according to the success or failure of this command.
  256.  
  257.     Other variables set are:
  258.  
  259.         #Page1Offs#            -  Offset of second virtual page
  260.         #NonVisualOffs#        -  Offset of first non visible video ram byte
  261.         #DoubleBufferActive#   -  Flag
  262.         #ScrnLogicalHeight#    -  Logical height of the double buffering pages
  263.         #MaxScrollY#           -  Max vertical start address of physical screen
  264.                                                         within the virtual screen
  265.  
  266.     WARNING: If you use one of the high resolution modes (376x564 as an
  267.          extreme example) you may not have enough video ram for split screen
  268.          and double buffering options since VGA video RAM for is restricted to
  269.          256K.}
  270. Procedure XSetTripleBuffer( PageHeight : word );
  271. { This procedure behaves like #XDoubleBuffer#, but when used with
  272.     #XInstallVSyncHandler# you can draw immediately after a page flip.
  273.     When #XPageFlip# is called, #VisiblePageOffs# is set to the page that
  274.     will be display next vsync. Until then, #WaitingPageOffs# will be displayed.
  275.     You can draw to #HiddenPageOffs#.}
  276. Procedure XPageFlip( X, Y : Word );
  277. { X,Y - coordinates of top left corner of physical screen within the
  278.     the hidden virtual screen if double buffering is active, or
  279.     the current virtual screen otherwise.
  280.  
  281.     Sets the physical screen start address within currently hidden virtual
  282.     page and then flips pages. If double buffering is not active then this
  283.     function is functionally equivalent to #XSetStartAddr#.
  284.  
  285.     X must not exceed (Logical screen width - Physical screen width)
  286.     ie #MaxScrollX# and Y must not exceed (Logical screen height -
  287.     Physical screen height) ie #MaxScrollY#}
  288. Procedure XSetClipRect( Left, Top, Right, Bottom : Word );
  289. {  Defines the clipping rectangle for clipping versions of planar and video
  290.     bitmap puts.
  291.  
  292.     NOTE: Compiled bitmaps cannot be clipped.}
  293. Procedure XTextMode;
  294. { Disables graphics mode.}
  295. Procedure XWaitVsync;
  296. { Waits for a vsync to occur : i.e. when the electron beam that's refreshing
  297.     the video image has reached the bottom of the screen.}
  298. Procedure XLine( x1, y1, x2, y2, Color, PgOffs : word );
  299. { Draw a line with the specified end points in the page starting at
  300.     offset PgOffs.
  301.  
  302.     No Clipping is performed.}
  303. Procedure XPutPix( X,Y,PgOfs,Color:word );
  304. { Draw a point of specified colour at coordinates X,Y within the virtual page
  305.     starting at offset PgOfs.}
  306. Function  XGetPix( x,y,PageBase:word ) : word;
  307. { Read a point of at coordinates X,Y within the virtual page starting
  308.     at offset PageBase.}
  309. Procedure XRectFill( StartX,StartY,EndX,EndY,PageBase,Color:word );
  310. {   StartX,StartY - Coordinates of upper left hand corner of rectangle
  311.         EndX,EndY     - Coordinates of lower right hand corner of rectangle
  312.         PageBase      - Offset of virtual screen
  313.         Color         - Color of the box.
  314.  
  315.  
  316.     Mode X rectangle fill routine. This procedure draw a rectangle with
  317.     upper left coordinates (StartX,StartY) and lower right coordinates
  318.     (EndX, Endy) at offset PageBase in color Color}
  319. Procedure XRectPattern( StartX,StartY,EndX,EndY,PageBase:word; var Pattern);
  320. {   StartX,StartY - Coordinates of upper left hand corner of rectangle
  321.         EndX,EndY     - Coordinates of lower right hand corner of rectangle
  322.         PageBase      - Offset of virtual screen
  323.         Pattern       - Untyped variable for the user defined pattern (16 bytes)
  324.  
  325.  
  326.     Mode X rectangle 4x4 pattern fill routine.
  327.  
  328.     Upper left corner of pattern is always aligned to a multiple-of-4
  329.     row and column. Works on all VGAs. Uses approach of copying the
  330.     pattern to off-screen display memory, then loading the latches with
  331.     the pattern for each scan line and filling each scan line four
  332.     pixels at a time. Fills up to but not including the column at EndX
  333.     and the row at EndY. No clipping is performed.
  334.  
  335.     Warning the VGA memory locations PATTERNBUFFER (A000:FFFc) to
  336.     A000:FFFF are reserved for the pattern buffer}
  337. Procedure XCpVidPage( SourceOffs, DestOffs : word );
  338. {   SourceOffs    - Offset of source video page
  339.         DestOffs      - Offset of destination page
  340.  
  341.     Copies the contents of page SourceOffs to DestOffs. Twice as fast as a
  342.     #XCpVidRect# would be (because it uses less parameters, so less stack work is
  343.     required).}
  344. Procedure XCpVidRect( SrcStartX,SrcStartY,SrcEndX,SrcEndY,DestStartX,
  345.                     DestStartY,SrcPageBase,DestPageBase,SrcBitmapW,
  346.                     DestBitmapW:word );
  347. {   StartX,StartY - Coordinates of upper left hand corner of source rectangle
  348.         EndX,EndY     - Coordinates of lower right hand corner of source rectangle
  349.         DestStartX,DestStartY - Coordinates of rectangle destination
  350.         SourcePageBase        - source rectangle page offset
  351.         DestPageBase          - destination rectangles page offset
  352.         SourceBitmapWidth     - width of bitmap within the source virtual screen
  353.                     containing the source rectangle
  354.         DestBitmapWidth       - width of bitmap within the dest. virtual screen
  355.                     containing the destination rectangle
  356.  
  357.     Mode X display memory to display memory copy
  358.     routine. Left edge of source rectangle modulo 4 must equal left edge
  359.     of destination rectangle modulo 4. Works on all VGAs. Uses approach
  360.     of reading 4 pixels at a time from the source into the latches, then
  361.     writing the latches to the destination. Copies up to but not
  362.     including the column at SrcEndX and the row at SrcEndY. No
  363.     clipping is performed. Results are not guaranteed if the source and
  364.     destination overlap.
  365.     If you want to copy an entire page to another use #XCpVidPage# instead}
  366. Procedure XShiftRect( SrcLeft,SrcTop,SrcRight,SrcBottom,DestLeft,DestTop,
  367.                     ScreenOffs:word );
  368. {   SrcLeft, SrcTop - Coordinates of upper left hand corner of rectangle
  369.         SrcRight, SrcBottom - Coordinates of lower right hand corner of rectangle
  370.         DestLeft, DestTop - Coordinates of upper left corner of destination
  371.         ScreenOffs    - Offset of virtual screen
  372.  
  373.     This function copies a rectangle of VRAM onto another area of VRAM,
  374.     even if the destination overlaps with the source.  It is designed
  375.     for scrolling text up and down, and for moving large areas of screens
  376.     around in tiling systems.  It rounds all horizontal coordinates to
  377.     the nearest byte (4-column chunk) for the sake of speed.  This means
  378.     that it can NOT perform smooth horizontal scrolling.  For that,
  379.     either scroll the whole screen (minus the split screen), or copy
  380.     smaller areas through system memory using the functions in the
  381.     #XBM2# module.
  382.  
  383.     SrcRight is rounded up, and the left edges are rounded down, to
  384.     ensure that the pixels pointed to by the arguments are inside the
  385.     the rectangle.  That is, SrcRight is treated as (SrcRight+3) >> 2,
  386.     and SrcLeft as SrcLeft >> 2.
  387.  
  388.     The width of the rectangle in bytes (width in pixels / 4)
  389.     cannot exceed 255.}
  390. Procedure XCircle( Left, Top, Diameter, Color, ScreenOffs:word );
  391. { Draws a circle with the given upper-left-hand corner and diameter,
  392.     which are given in pixels.}
  393. Procedure XFilledCircle( Left, Top, Diameter, Color, ScreenOffs:word );
  394. { Draws a filled circle with the given upper-left-hand corner and
  395.     diameter.}
  396. Procedure XGetPalStruc( var PalBuff; NumColors,StartColor:word );
  397. {    Read DAC palette into annotated type buffer with interrupts disabled
  398.     ie byte colours to skip, byte colours to set, r1,g1,b1,r1,g2,b2...rn,gn,bn
  399.  
  400.     WARNING: memory for the palette buffers must all be pre-allocated}
  401. Procedure XGetPalRaw( Var PalBuff; NumColors,StartColor:word );
  402. {    Read DAC palette into raw buffer with interrupts disabled
  403.     ie byte r1,g1,b1,r1,g2,b2...rn,gn,bn
  404.  
  405.     WARNING: Memory for the palette buffers must all be pre-allocated.}
  406. Procedure XPutPalStruc( Var CompPalBuff );
  407. {    Write DAC palette from annotated type buffer with interrupts disabled
  408.     ie byte colours to skip, byte colours to set, r1,g1,b1,r1,g2,b2...rn,gn,bn}
  409. Procedure XTransposePalStruc( Var CompPalBuff; StartColor:word );
  410. {    Write DAC palette from annotated type buffer with interrupts disabled
  411.     starting at a new palette index.}
  412. Procedure XPutPalRaw( Var PalBuff; NumColors,StartColor:word );
  413. {    Write DAC palette from raw buffer with interrupts disabled
  414.     ie byte r1,g1,b1,r1,g2,b2...rn,gn,bn}
  415. Procedure XSetRGB( ColorIndex,R,G,B:byte );
  416. {    Set the RGB components of a vga color}
  417. Procedure XRotPalStruc( Var PalBuff; Direction:word );
  418. {    Rotate annotated palette buffer entries. Direction 0 = backward,
  419.     1 = forward.}
  420. Procedure XRotPalRaw( Var PalBuff; Direction, NumColors:word );
  421. {    Rotate a raw palette buffer. Direction 0 = backward,
  422.     1 = forward.}
  423. Function  XCpContrastPalStruc( Var PalSrcBuff,PalDestBuff; Intensity:byte ) : word;
  424. {    Copy one annotated palette buffer to another making the intensity
  425.     adjustment. Used in fading in and out fast and smoothly.}
  426. Procedure XPutContrastPalStruc( Var CompPalBuff; Intensity:byte );
  427. {    Write DAC palette from annotated type buffer with specified intensity
  428.     adjustment (ie palette entries are decremented where possible by
  429.     intensity units).
  430.  
  431.     Designed for fading in or out a palette without using an intermediate
  432.     working palette buffer ! (Slow but memory efficient ... OK for small
  433.     pal strucs)}
  434. Function  XCharPut( Chr:char; X, Y, ScrnOffs, Color:word ) : byte;
  435. {    Draw a text character at the specified location with the specified
  436.     color.
  437.  
  438.         ch       -  char to draw
  439.         x,y      -  screen coords at which to draw ch
  440.         ScrnOffs -  Starting offset of page on whih to draw
  441.         Color    -  Color of the text
  442.  
  443.     WARNING: xtextinit must be called before using this function}
  444. Procedure XSetFont( FontID : word );
  445. {    Procedure xsetfont(FontId : word);
  446.  
  447.     Select the working font where 0 = VGA ROM 8x8, 1 = VGA ROM 8x14
  448.     2 = User defined bitmapped font.
  449.  
  450.     WARNING: A user font must be registered before setting FontID 2 by
  451.                      using procedure #XRegisterUserFont#}
  452. Procedure XTextInit;
  453. {    Initializes the Mode X text driver and sets the default font (VGA ROM 8x8)}
  454. Procedure XRegisterUserFont( var FontToRegister );
  455. {    Register a user font for later selection. Only one user font can be
  456.     registered at any given time. Registering a user font deregisters the
  457.     previous user font. User fonts may be at most 8 pixels wide.
  458.  
  459.     USER FONT STRUCTURE
  460.  
  461.     Word:  ascii code of first char in font
  462.     Byte:  Height of chars in font
  463.     Byte:  Width of chars in font
  464.     n*h*Byte: the font data where n = number of chars and h = height
  465.         of chars
  466.  
  467.     WARNING: The onus is on the program to ensure that all characters
  468.          drawn whilst this font is active, are within the range of
  469.          characters defined.}
  470. Function  XGetCharWidth( ch : char ) : byte;
  471. {    Returns the width in pixels of character ch in the currently selected font.}
  472. Function  XPrintf( x, y, ScrnOffs, Color : word; s : string ) : integer;
  473. {        x,y      -  screen coords at which to draw s
  474.         ScrnOffs -  Starting offset of page on whih to draw
  475.         Color    -  Color of the text
  476.         s        -  The string to be displayed
  477.  
  478.     Displays the string s at coordinates x,y on page ScrnOffs in Color.
  479.     Returns the width of the string in pixels.}
  480. Function  XBgPrintf( x, y, ScrnOffs, fgcolor, bgcolor : word; s : string ) : integer;
  481. {        x,y      -  screen coords at which to draw s
  482.         ScrnOffs -  Starting offset of page on whih to draw
  483.         fgcolor  -  Color of the text foreground
  484.         bgcolor  -  Color of the text background
  485.         s        -  The string to be displayed
  486.  
  487.     Same as #XPrintf# but erases the background of the string with color bgcolor.}
  488. Function  XCentre( x, y, ScrnOffs, color : word; s : string ) : integer;
  489. {        x,y      -  screen coords at which to draw s
  490.         ScrnOffs -  Starting offset of page on whih to draw
  491.         color    -  Color of the text foreground
  492.         s        -  The string to be displayed
  493.  
  494.     Same as #XPrintf# but centres the string with respect to x}
  495. Function  XBgCentre( x, y, ScrnOffs, fgcolor, bgcolor : word; s : string ) : integer;
  496. {        x,y      -  screen coords at which to draw s
  497.         ScrnOffs -  Starting offset of page on whih to draw
  498.         fgcolor  -  Color of the text foreground
  499.         bgcolor  -  Color of the text background
  500.         s        -  The string to be displayed
  501.  
  502.     Same as #XCentre# but erases the background of the string with color bgcolor}
  503.  
  504. function  XStrWidth( s : string ) : integer;
  505. { Returns the width in pixels of the string s}
  506. Procedure XTriangle( X0, Y0, X1, Y1, X2, Y2, Color, PageOffset:word );
  507. { This function draws a filled triangle which is clipped to the current
  508.     clipping window defined by #TopClip#,#BottomClip#,#LeftClip#,#RightClip#.
  509.     Remember: the X clipping variable are in byteS not PIXELS so you can only
  510.     clip to 4 pixel byte boundaries.}
  511. Procedure XPolygon( var vertices; numvertices, Color, PageOffset:word );
  512. { This function is similar to the triangle function but draws
  513.     convex polygons. The vertices are supplied as an array of vertices.
  514.  
  515.     NOTE: a convex polygon is one such that if you draw a line from
  516.     any two vertices, every point on that line will be within the
  517.     polygon.
  518.  
  519.     This function works by splitting up a polygon into its component
  520.     triangles and calling the triangle routine above to draw each one.
  521.     Performance is respectable but a custom polygon routine might be
  522.     faster.}
  523. Procedure XPutCursor( X, Y, TopClip, BottomClip, ScrnOffs : word );
  524. { Display the mouse pointer at coordinated X,Y on page ScrnOffs}
  525. Procedure XDefineMouseCursor( var MouseDef; MouseColor:byte );
  526. {      MouseDef - a buffer of 14 characters containing a bitmask for all the
  527.              cursor's rows.
  528.         MouseColor - The colour to use when drawing the mouse cursor.
  529.  
  530.     Define a mouse cursor shape for use in subsequent cursor redraws. XLib
  531.     has a hardwired mouse cursor size of 8 pixels across by 14 pixels down.
  532.  
  533.     WARNING: This function assumes MouseDef points to 14 bytes.
  534.  
  535.     Note: Bit order is in reverse. ie bit 7 represents pixel 0 ..
  536.         bit 0 represents pixel 7 in each MouseDef byte.}
  537. function XMouseInit:integer;
  538. {    Initialize the mouse driver functions and install the mouse event handler
  539.     function. This is the first function you must call before using any of the
  540.     mouse functions. This mouse code uses the fastest possible techniques to
  541.     save and restore mouse backgrounds and to draw the mouse cursor.
  542.  
  543.     WARNING: This function uses and updates NonVisualOffset to allocate
  544.          video ram for the saved mouse background.
  545.  
  546.     LIMITATIONS: No clipping is supported horizontally for the mouse cursor
  547.                  No validity checking is performed for NonVisualOffs
  548.  
  549.     **WARNING** You must Hide or at least Freeze the mouse cursor while drawing
  550.     using any of the other XLIB procedures since the mouse handler may
  551.     modify vga register settings at any time. VGA register settings
  552.     are not preserved which will result in unpredictable drawing behavior.
  553.     If you know the drawing will occur away from the mouse cursor set
  554.     #MouseFrozen# to 1, do your drawing  then set it to 0.
  555.     Alternatively call #XHideMouse#, perform your drawing and then call
  556.     #XShowMouse#. Another alternative is to disable interrupts while drawing
  557.     but usually drawing takes up alot of time and having interrupts
  558.     disabled for too long is not a good idea.
  559.     If you are using the Virtual VSync Handler and just updating the palette
  560.     you don't need to freeze the mouse.}
  561. Procedure XMouseWindow( x0, y0, x1, y1:word );
  562. {    Defines a mouse window. The mouse can't move outside the boundaries
  563.     specified.}
  564. procedure XShowMouse;
  565. {    Makes the cursor visible if it was previously hidden.
  566.     See also : #XHideMouse#}
  567. Procedure XHideMouse;
  568. {    Makes the cursor hidden if it was previously visible.
  569.     See also : #XShowMouse#}
  570. Procedure XMouseRemove;
  571. { Stop mouse event handling and remove the mouse handler.
  572.  
  573.     NOTE: This function MUST be called before quitting the program if
  574.     a mouse handler has been installed}
  575. Procedure XPositionMouse( X, Y : word );
  576. {    Positions the mouse at a specified location}
  577. Procedure XUpdateMouse;
  578. {    Forces the mouse position to be updated and cursor to be redrawn.
  579.     Note: this function is useful when you have set #MouseFrozen# to true.
  580.     Allows the cursor position to be updated manually rather than
  581.     automatically by the installed handler.}
  582. Function  XFloodFill( X, Y, PgOfs, Color:word ) : word;
  583. {    This function performs the familiar flood filling used by many
  584.     paint programs and of course the Borland BGI's flood fill function.
  585.     The pixel at x,y and all adjacent pixels of the same color are filled
  586.     to the new color. Filling stops when there are no more adjacent pixels
  587.     of the original pixel's color. The function returns the number of
  588.     pixels that have been filled.}
  589. Function  XBoundaryFill( X, Y, PgOfs, BoundaryColor, Color : word ) : word;
  590. {    This function is a variant of the flood fill described above. This
  591.     function, unlike the above function, can fill across color boundaries.
  592.     Filling stops when the area being filled is fully enclosed by pixels
  593.     of the color boundary. Again, this function returns the number of
  594.     pixels filled.}
  595. Procedure XInstallVSyncHandler( VrtsToSkip : word );
  596. {    This function installs the vsync handler using timer 0. It's called
  597.     about 100 microseconds before every vertical retrace.
  598.  
  599.     The VrtsToSkip value (>=1) defines the delay in VRT's between consecutive
  600.     physical screen start address changes, thus allowing you to limit the
  601.     maximum frame rate for page flips in animation systems. The frame rate
  602.     is calculated as Vertical refresh rate / VrtsToSkip, eg for
  603.     320x240 mode which refreshes at 60Hz a VrtsToSkip value of 3 will result
  604.     in a maximum page flipping rate of 20Hz (frames per second)
  605.  
  606.     WARNING:  Be sure to remove it before exiting.
  607.     When used with a debugger, the system clock may speed up.
  608. }
  609. Procedure XRemoveVSyncHandler;
  610. {    This routine MUST be called before exiting (or aborting) the program,
  611.     or your system will crash.}
  612. Procedure XSetUserVSyncHandler( handler : pointer );
  613. {    Installs a user routine to be called once each vertical retrace. The user
  614.     handler has its own stack of 256 bytes.
  615.     WARNING: This installs an interrupt driven handler, beware of the following:
  616.          Only 8086 registers are preserved. If you're using 386 code, save
  617.          all the 386 regs.
  618.          Don't do any drawing.
  619.          Don't call any DOS functions.
  620.  
  621.     So why use it?
  622.     Well, you can update global variables if you're careful. And it's nice for
  623.     palette animation. You can even do fades while loading from disk. You
  624.     should use this instead of installing your own int08h routine and chain
  625.     to the original.}
  626.  
  627. Implementation
  628.  
  629. type
  630.     VBMInfoStruc = record
  631.          Size, ImageWidth, ImageHeight : word;
  632.     end;
  633.     VBMAlignmentStruc = record
  634.          ImagePtr, MaskPtr : word;
  635.     end;
  636.  
  637. const
  638.     X320Y200 : array[0..4] of word =
  639.         ( $0200, $0014, $E317, 320, 200 );
  640.   X320Y240 : array[0..12] of word =
  641.     ( $0AE3, $0D06, $3E07, $4109, $EA10, $AC11, $DF12, $0014, $E715, $0616,
  642.       $E317, 320, 240 );
  643.   X360Y200 : array[0..10] of word =
  644.     ( $08E7, $6B00, $5901, $5A02, $8E03, $5E04, $8A05, $0014, $E317, 360,
  645.       200 );
  646.     X360Y240 : array[0..19] of word =
  647.     ( $11E7, $6b00, $5901, $5A02, $8E03, $5E04, $8A05, $0D06, $3E07, $4109,
  648.       $EA10, $AC11, $DF12, $2D13, $0014, $E715, $0616, $E317, 360, 240 );
  649.   X376Y282 : array[0..20] of word =
  650.     ( $12E7, $6e00, $5d01, $5e02, $9103, $6204, $8f05, $6206, $f007, $6109,
  651.       $310f, $3710, $8911, $3312, $2f13, $0014, $3C15, $5C16, $e317, 376,
  652.       282 );
  653.   X256Y400 : array[0..11] of word  =
  654.     ( $08E3, $5f00, $3f01, $4202, $9f03, $4c04, $0005, $4009, $0014, $E317,
  655.             256, 400 );
  656.   X256Y480 : array[0..18] of word =
  657.     ( $10e3, $5f00, $3f01, $4202, $9f03, $4c04, $0005, $0d06, $3e07, $4009,
  658.       $ea10, $ac11, $df12, $0014, $e715, $0616, $e317, 256, 480 );
  659.   X320Y400 : array[0..5] of word =
  660.     ( $03e3, $4009, $0014, $e317, 320, 400 );
  661.   X320Y480 : array[0..12] of word =
  662.     ( $0AE3, $0D06, $3E07, $4009, $EA10, $AC11, $DF12, $0014, $E715, $0616,
  663.       $E317, 320, 480 );
  664.   X360Y400 : array[0..11] of word =
  665.     ( $09E7, $6B00, $5901, $5A02, $8E03, $5E04, $8A05, $4009, $0014, $E317,
  666.       360, 400 );
  667.     X360Y480 : array[0..19] of word =
  668.     ( $11E7, $6B00, $5901, $5A02, $8E03, $5E04, $8A05, $0D06, $3E07, $4009,
  669.       $EA10, $AC11, $DF12, $2D13, $0014, $E715, $0616, $E317, 360, 480 );
  670.   X360Y360 : array[0..17] of word =
  671.     ( $0FE7, $6b00, $5901, $5A02, $8E03, $5E04, $8A05, $4009, $8810, $8511,
  672.       $6712, $2D13, $0014, $6D15, $BA16, $E317, 360, 360 );
  673.   X376Y308 : array[0..20] of word =
  674.     ( $12E7, $6E00, $5D01, $5E02, $9103, $6204, $8F05, $6206, $0F07, $4009,
  675.       $310F, $3710, $8911, $3312, $2F13, $0014, $3C15, $5C16, $E317, 376,
  676.             308 );
  677.   X376Y564 : array[0..20] of word =
  678.     ( $12E7, $6E00, $5D01, $5E02, $9103, $06204, $8F05, $6206, $F007, $6109,
  679.       $310F, $3710, $8911, $3312, $2F13, $0014, $3C15, $5C16, $E317, 376,
  680.       564 );
  681.   X256Y200 : array[0..10] of word =
  682.     ( $08e3, $5f00, $3f01, $4202, $9f03, $4c04, $0005, $0014, $e317, 256,
  683.       200 );
  684.   X256Y240 : array[0..18] of word =
  685.     ( $10e3, $5f00, $3f01, $4202, $9f03, $4c04, $0005, $0d06, $3e07, $4109,
  686.       $ea10, $ac11, $df12, $0014, $e715, $0616, $e317, 256, 240 );
  687.   X256Y224 : array[0..20] of word =
  688.     ( $12e3, $5f00, $3f01, $4202, $8203, $4a04, $9a05, $0b06, $3e07, $0008,
  689.       $4109, $da10, $9c11, $bf12, $2013, $0014, $c715, $0416, $e317, 256,
  690.       224 );
  691.   X256Y256 : array[0..20] of word =
  692.     ( $12e3, $5f00, $3f01, $4002, $8203, $4a04, $9a05, $2306, $b207, $0008,
  693.       $6109, $0a10, $ac11, $ff12, $2013, $0014, $0715, $1a16, $e317, 256,
  694.       256 );
  695.   X360Y270 : array[0..20] of word =
  696.     ( $12e7, $6b00, $5901, $5a02, $8e03, $5e04, $8a05, $3006, $f007, $0008,
  697.             $6109, $2010, $a911, $1b12, $2d13, $0014, $1f15, $2f16, $e317, 360,
  698.       270 );
  699.   X400Y300 : array[0..20] of word =
  700.     ( $12a7, $7100, $6301, $6402, $9203, $6504, $8205, $4606, $1f07, $0008,
  701.       $4009, $3110, $8011, $2b12, $3213, $0014, $2f15, $4416, $e317, 400,
  702.       300 );
  703.   ModeTable : array[0..17] of word =
  704.     ( Ofs(X320Y200[0]), Ofs(X320Y240[0]), Ofs(X360Y200[0]), Ofs(X360Y240[0]),
  705.       Ofs(X376Y282[0]), Ofs(X320Y400[0]), Ofs(X320Y480[0]), Ofs(X360Y400[0]),
  706.       Ofs(X360Y480[0]), Ofs(X360Y360[0]), Ofs(X376Y308[0]), Ofs(X376Y564[0]),
  707.       Ofs(X256Y200[0]), Ofs(X256Y240[0]), Ofs(X256Y224[0]), Ofs(X256Y256[0]),
  708.       Ofs(X360Y270[0]), Ofs(X400Y300[0]) );
  709.  
  710.   MirrorTable : array[0..255] of byte =
  711.         ( 0,128, 64,192, 32,160, 96,224, 16,144, 80,208, 48,176,112,240,
  712.             8,136, 72,200, 40,168,104,232, 24,152, 88,216, 56,184,120,248,
  713.             4,132, 68,196, 36,164,100,228, 20,148, 84,212, 52,180,116,244,
  714.          12,140, 76,204, 44,172,108,236, 28,156, 92,220, 60,188,124,252,
  715.             2,130, 66,194, 34,162, 98,226, 18,146, 82,210, 50,178,114,242,
  716.          10,138, 74,202, 42,170,106,234, 26,154, 90,218, 58,186,122,250,
  717.             6,134, 70,198, 38,166,102,230, 22,150, 86,214, 54,182,118,246,
  718.          14,142, 78,206, 46,174,110,238, 30,158, 94,222, 62,190,126,254,
  719.             1,129, 65,193, 33,161, 97,225, 17,145, 81,209, 49,177,113,241,
  720.             9,137, 73,201, 41,169,105,233, 25,153, 89,217, 57,185,121,249,
  721.             5,133, 69,197, 37,165,101,229, 21,149, 85,213, 53,181,117,245,
  722.          13,141, 77,205, 45,173,109,237, 29,157, 93,221, 61,189,125,253,
  723.             3,131, 67,195, 35,163, 99,227, 19,147, 83,211, 51,179,115,243,
  724.          11,139, 75,203, 43,171,107,235, 27,155, 91,219, 59,187,123,251,
  725.             7,135, 71,199, 39,167,103,231, 23,151, 87,215, 55,183,119,247,
  726.          15,143, 79,207, 47,175,111,239, 31,159, 95,223, 63,191,127,255 );
  727.     PelPanMask : array[0..3] of byte =
  728.         ( 0, 2, 4, 6 );
  729.     LeftClipPlaneMask  : array[0..3] of byte =
  730.         ( $0F, $0E, $0C, $08 );
  731.     RightClipPlaneMask : array[0..3] of byte =
  732.         ( $0F, $01, $03, $07 );
  733.     LeftMaskTable : array[0..8] of byte =
  734.         ( 0, $ff, $ee, 0, $cc, 0, 0, 0, $88 );
  735.     RightMaskTable: array[0..8] of byte =
  736.         ( 0, $11, $33, 0, $77, 0, 0, 0, $ff );
  737.     LeftDelay : array[0..3] of byte =
  738.         ( 0, 1, 2, 4 );
  739.     RightDelay : array[0..3] of byte =
  740.         ( 0, 4, 2, 1 );
  741.     PS2Cards : array[0..12] of byte = ( 0,1,2,2,4,3,2,5,6,2,8,7,8 );
  742.  
  743.     WhenToDraw : array[0..31] of byte = ( 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3,
  744.             2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5 );
  745.  
  746. var
  747.     FontPtr,
  748.     UserFontPtr,
  749.     F8x8Ptr,
  750.     F8x14Ptr, 
  751.     OldTimerIntVar : pointer;
  752.     MouseMask : array[0..167] of byte;
  753.     VSyncPaletteBuffer : array[0..767] of byte;
  754.     WaitingStartLow,
  755.     WaitingStartHigh,
  756.     WaitingPelPan,
  757.     VsyncPaletteStart,
  758.     VsyncPaletteCount,
  759.     MirrorTableOffs,
  760.     BGSaveOffs,
  761.     TopBound,
  762.     BottomBound,
  763.     LeftBound,
  764.     RightBound,
  765.     MouseVersion,
  766.     Seg0000,
  767.     SelectorInc : word;
  768.     MouseType,
  769.     MouseIRQ,
  770.     inhandler : byte;
  771.  
  772.  
  773. {$IFDEF DPMI}
  774. {$L XLIB2.OBP}
  775. procedure __a000h; far; external 'KERNEL' index $00AE;
  776. procedure __c000h; far; external 'KERNEL' index $00C3;
  777. procedure __AHIncr; far;        external 'KERNEL' index $0072;
  778. procedure __0000h; far; external 'KERNEL' index $00B7;
  779. {$ELSE}
  780. {$L XLIB2.OBJ}
  781. {$ENDIF}
  782.  
  783. Function  XSetMode( Mode, WidthInPixels : Word ) : Word; external;
  784. Procedure XSelectDefaultPlane( Plane : Byte ); external;
  785. Procedure XSetSplitscreen( Line : Word ); external;
  786. Procedure XSetStartAddr( X, Y : Word ); external;
  787. Procedure XHideSplitscreen; external;
  788. Procedure XShowSplitscreen; external;
  789. Procedure XAdjustSplitscreen( Line : Word ); external;
  790. Procedure XSetDoubleBuffer( PageHeight : Word ); external;
  791. Procedure XSetTripleBuffer( PageHeight : word ); external;
  792. Procedure XPageFlip( X, Y : Word ); external;
  793. Procedure XSetClipRect( Left, Top, Right, Bottom : Word ); external;
  794. Procedure XTextMode; external;
  795. Procedure XWaitVsync; external;
  796. Procedure XLine( x1, y1, x2, y2, Color, PgOffs : word ); external;
  797. Procedure XPutPix( X,Y,PgOfs,Color:word ); external;
  798. Function  XGetPix( x,y,PageBase:word ) : word; external;
  799. Procedure XRectFill( StartX,StartY,EndX,EndY,PageBase,Color:word ); external;
  800. Procedure XRectPattern( StartX,StartY,EndX,EndY,PageBase:word; var Pattern); external;
  801. Procedure XCpVidPage( SourceOffs, DestOffs : word ); external;
  802. Procedure XCpVidRect( SrcStartX,SrcStartY,SrcEndX,SrcEndY,DestStartX,
  803.                                             DestStartY,SrcPageBase,DestPageBase,SrcBitmapW,
  804.                                             DestBitmapW:word ); external;
  805. Procedure XShiftRect( SrcLeft,SrcTop,SrcRight,SrcBottom,DestLeft,DestTop,
  806.                                             ScreenOffs:word ); external;
  807. Procedure XCircle( Left, Top, Diameter, Color, ScreenOffs:word ); external;
  808. Procedure XFilledCircle( Left, Top, Diameter, Color, ScreenOffs:word ); external;
  809. Procedure XGetPalStruc( var PalBuff; NumColors,StartColor:word ); external;
  810. Procedure XGetPalRaw( Var PalBuff; NumColors,StartColor:word ); external;
  811. Procedure XPutPalStruc( Var CompPalBuff ); external;
  812. Procedure XTransposePalStruc( Var CompPalBuff; StartColor:word ); external;
  813. Procedure XPutPalRaw( Var PalBuff; NumColors,StartColor:word ); external;
  814. Procedure XSetRGB( ColorIndex,R,G,B:byte ); external;
  815. Procedure XRotPalStruc( Var PalBuff; Direction:word ); external;
  816. Procedure XRotPalRaw( Var PalBuff; Direction, NumColors:word ); external;
  817. Function  XCpContrastPalStruc( Var PalSrcBuff,PalDestBuff; Intensity:byte ) : word; external;
  818. Procedure XPutContrastPalStruc( Var CompPalBuff; Intensity:byte ); external;
  819. Function  XCharPut( Chr:char; X, Y, ScrnOffs, Color:word ) : byte; external;
  820. Procedure XSetFont( FontID : word ); external;
  821. Procedure XTextInit; external;
  822. Procedure XRegisterUserFont( var FontToRegister ); external;
  823. Function  XGetCharWidth( ch : char ) : byte; external;
  824. Procedure XTriangle( X0, Y0, X1, Y1, X2, Y2, Color, PageOffset:word ); external;
  825. Procedure XPolygon( var vertices; numvertices, Color, PageOffset:word ); external;
  826. Procedure XPutCursor( X, Y, TopClip, BottomClip, ScrnOffs : word ); external;
  827. Procedure XDefineMouseCursor( var MouseDef; MouseColor:byte ); external;
  828. function XMouseInit:integer; external;
  829. Procedure XMouseWindow( x0, y0, x1, y1:word ); external;
  830. procedure XShowMouse; external;
  831. Procedure XHideMouse; external;
  832. Procedure XMouseRemove; external;
  833. Procedure XPositionMouse( X, Y : word ); external;
  834. Procedure XUpdateMouse; external;
  835. Function  XFloodFill( X, Y, PgOfs, Color:word ) : word; external;
  836. Function  XBoundaryFill( X, Y, PgOfs, BoundaryColor, Color : word ) : word; external;
  837. Procedure XInstallVSyncHandler( VrtsToSkip:word ); external;
  838. Procedure XRemoveVSyncHandler; external;
  839. Procedure XSetUserVSyncHandler; external;
  840.  
  841. function XPrintf( x, y, ScrnOffs, Color : word; s : string ) : integer;
  842. var
  843.     w, i : integer;
  844. begin
  845.     w := x;
  846.     for i := 1 to length(s) do
  847.         x:=x+XCharPut( s[i], x, y, ScrnOffs, color );
  848.     XPrintf := x-w+1;
  849. end;
  850.  
  851. function XStrWidth( s : string ) : integer;
  852. var
  853.     w, i : integer;
  854. begin
  855.     w := 0;
  856.     for i := 1 to length(s) do
  857.         w:=w+XGetCharWidth( s[i] );
  858.     XStrWidth := w;
  859. end;
  860.  
  861. function XBgPrintf( x, y, ScrnOffs, fgcolor, bgcolor : word; s : string ) : integer;
  862. var
  863.     i : integer;
  864. begin
  865.     for i := 1 to length(s) do
  866.     begin
  867.         XRectFill( x, y, x+XGetCharWidth(s[i]),y+CharHeight,ScrnOffs,bgcolor);
  868.         x := x + XCharPut( s[i], x, y, ScrnOffs, fgcolor);
  869.     end;
  870.     XBgPrintf := x;
  871. end;
  872.  
  873. Function XCentre( x, y, ScrnOffs, color : word; s : string ) : integer;
  874. var
  875.     w, i : integer;
  876. begin
  877.     w := 0;
  878.     for i := 1 to length(s) do
  879.         w:=w+XGetCharWidth( s[i] );
  880.     x := x-w div 2;
  881.     xprintf( x, y, ScrnOffs, color, s );
  882.     xcentre := x;
  883. end;
  884.  
  885. Function XBgCentre( x, y, ScrnOffs, fgcolor, bgcolor : word; s : string ) : integer;
  886. var
  887.     w, i : integer;
  888. begin
  889.     w := 0;
  890.     for i := 1 to length(s) do
  891.         w:=w+XGetCharWidth( s[i] );
  892.     x := x-w div 2;
  893.     xbgprintf( x, y, ScrnOffs, fgcolor, bgcolor, s );
  894.     xbgcentre := x;
  895. end;
  896.  
  897. End.
  898.  
  899.