<:#1430,9360>"Do not trust this excuse for a manual when in doubt go to the code." Those words were written by Themie Gouthas in each manual accompanying an XLIB release. I have undertaken this project to provide you the end user with a high-quality,
<+#>accurate<-#> manual to use. I have gone to the code, checked and cross-checked everything and consulted the authors to ensure everything is correct. Just the same I'm only human, so if you spot any errors please let me know.
<:s><:#286,9360>
<:#1430,9360>Throughout this manual function names are in bold italics, variables are in regular italics. This only holds true for those of you who are reading the non-ASCII version of this document. If your favorite word processor isn't included in this release of th
e manual let me know and I will make very effort to support it. I also plan on making a printed, 3-ring bound versions available for a small fee (Enough to cover the cost of materials and postage) if enough people are interested.
<:s><:#286,9360>
<:s><:#286,9360>
<:#286,9360><+!><:X11,-32768;TOC 2 "CONTACTING THE AUTHORS">CONTACTING THE AUTHORS<-!><+!>:<-!>
<:s><:#286,9360> Themie Gouthas - Internet: egg@dstos3.dsto.goc.au or teg@bart.dsto.gov.au
<:s><:#286,9360> Matthew MacKenzie - Internet: matm@eng.umd.edu
<:s><:#865,9360><+!>This library is distributed AS IS.<-!> The authors specifically disclaim any responsibility for any loss of profit or any incidental, consequential or other damages. The authors reserve ALL rights to the code contained in XLIB.
<:s><:#865,9360>XLIB is a "user supported freeware" graphics library specifically designed with game programming in mind. It has been released to the public for the benefit of all and is the result of
<+!>MANY<-!> hours of or work.
<:s><:#286,9360>
<:s><:#293,9360>All users <+!>must <-!>comply with the following guidelines:
@Number List@<:s><:#286,9360>Leave the code in the public domain.
@Number List@<:s><:#286,9360>Do not distribute any modified or incomplete versions of this library.
<:s><:#286,9360>
<:s><:#286,9360>New contributions and comments are welcome. There will be more releases as the code evolves.
<+B><:#333,9360><:f280,2Times New Roman,0,0,0><+!>MODULE XMAIN<:X11,-32768;TOC 1 "MODULE XMAIN"><-!><:f>
<:s><:#286,9360>
<:s><:#286,9360>
<:s><:#572,9360>The Xmain module is the base module of the XLIB library. It contains the essential functions that initialize and customize the graphic environment.
<:s><:#293,9360><+">ScrnPhysicalByteWidth<-"> WORD - Physical screen width in bytes. Set by function
<+!><+">x_set_mode<-"><-!>
<:s><:#286,9360>
<:s><:#293,9360><+">ScrnPhysicalPixelWidth<-"> WORD - Physical screen width in pixels. Set by function
<+!><+">x_set_mode<-"><-!>
<:s><:#286,9360><+!>
<:s><:#293,9360><+">ScrnPhysicalHeight<-"> WORD - Physical screen height in pixels. Set by function
<+!><+">x_set_mode<-"><-!>.
<:s><:#286,9360>
<:s><:#293,9360><+">ScrnLogicalByteWidth<-"> WORD - Virtual screen width in bytes. Set by function
<+!><+">x_set_mode<-"><-!>.
<:s><:#286,9360>
<:s><:#293,9360><+">ScrnLogicalPixelWidth<-"> WORD - Virtual screen width in pixels. Set by function
<+!><+">x_set_mode<-"><-!>.
<:s><:#286,9360>
<:s><:#586,9360><+">ScrnLogicalHeight<-"> WORD - Virtual screen height in pixels. Set initially by function
<+!><+">x_set_mode<-"><-!> but is updated by functions <+!><+">x_set_splitscrn<-"><-!> and
<+!><+">x_set_doublebuffer<-"><-!>.
<:s><:#286,9360>
<:s><:#586,9360><+">MaxScrollX<-"> WORD - Max. X pixel position of physical screen within virtual screen. Set by function
<+!><+">x_set_mode<-"><-!>.
<:s><:#586,9360><+">MaxScrollY<-"> WORD - Max. Y pixel position of physical screen within virtual screen. Set initially by function
<+!><+">x_set_mode<-"><-!> but is updated by functions <+!><+">x_set_splitscrn<-"><-!> and
<+!><+">x_set_doublebuffer<-"><-!>.
<:s><:#293,9360><+">
<:s><:#865,9360><+">ErrorValue<-"> WORD - Contains error value. General use variable to communicate the error status from several functions. The value in this variable usually is only valid for the last function called that sets it.
<:s><:#286,9360>
<:s><:#586,9360><+">SplitScrnOffs<-"> WORD - Offset in video ram of split screen. Set by function
<+!><+">x_set_splitscrn<-"><-!>. The value is only valid if a split screen is active. See also: global variable
<+">SplitScrnActive<-">.
<:s><:#286,9360>
<:s><:#879,9360><+">SplitScrnScanLine<-"> WORD - Screen Scan Line the Split Screen starts at initially when set by function<+!><+"> x_set_splitscrn<-"><-!>.
<+#>The value is only valid if a split screen is active<-#>. See also: global variable<+"> SplitScrnActive<-">. This variable is not updated by
<+!><+">x_hide_splitscrn<-"><-!> or <+!><+">x_adjust_splitscrn<-"><-!>.
<:s><:#286,9360>
<:s><:#586,9360><+">SplitScrnVisibleHeight<-"> WORD - The number of rows of the initial split screen which are currently displayed. Modified by
<+!><+">x_hide_splitscrn<-"><-!>, <+!><+">x_adjust_splitscrn<-"><-!> and
<+!><+">x_show_splitscrn<-"><-!>.
<:s><:#286,9360>
<:s><:#586,9360><+">Page0_Offs<-"> WORD - Offset in video ram of main virtual screen. Initially set by function
<+!><+">x_set_mode<-"><-!> but is updated by functions <+!><+">x_set_splitscrn<-"><-!> and
<+!><+">x_set_doublebuffer<-"><-!>.
<:s><:#286,9360>
<:s><:#586,9360><+">Page1_Offs<-"> WORD - Offset in video ram of second virtual screen. Set by and only is valid after a call to
<+!><+">x_set_doublebuffer <-"><-!> or <+!><+">x_triple_buffer.<-"><-!>
<:s><:#286,9360>
<:s><:#586,9360><+">Page2_Offs<-"> WORD - Offset in video ram of the third virtual screen. Set by and is only valid after a call to
<+!><+">x_triple_buffer.<-"><-!>
<:s><:#286,9360><+!><+">
<:s><:#872,9360><+">WaitingPageOffs<-"> WORD - Offset in video ram of the page waiting to be invisible. Initially set by
<+!><+">x_triple_buffer <-!><-">but is updated by <+!><+">x_page_flip<-!><-">. This variable is only used while triple buffering is active.<-"><-">
<:s><:#286,9360>
<:s><:#586,9360><+">HiddenPageOffs<-"> WORD - Offset of hidden page. Initially set by function
<+!><+">x_set_doublebuffer<-"><-!> but is updated by <+!><+">x_page_flip<-"><-!>.
<+#>This variable is only used while double (or triple ) buffering is on<-#>.
<:s><:#286,9360>
<:s><:#586,9360><+">VisiblePageOffs<-"> WORD - Offset of visible page. Initially set by function
<+!><+">x_set_doublebuffer<-"><-!> but is updated by <+!><+">x_page_flip<-"><-!>.
<+#>This variable is only used while double (or triple) buffering is on<-#>.
<:s><:#286,9360>
<:s><:#879,9360><+">NonVisual_Offs<-"> WORD - Offset of first byte of non-visual ram, the ram that is available for bitmap storage etc. Set initially by function
<+!><+">x_set_mode<-"><-!> but is updated by functions <+!><+">x_set_splitscrn<-"><-!> and
<+!><+">x_set_doublebuffer<-"><-!>.
<:s><:#286,9360>
<:s><:#872,9360><+">VisiblePageIdx<-"> WORD - Index number of current visible page. Initially set by function
<+!><+">x_set_doublebuffer<-"><-!> but is updated by <+!><+">x_page_flip<-"><-!>.
<+#>This variable is only used while double( or triple) buffering is on<-#>.
<:s><:#286,9360>
<:s><:#586,9360><+">DoubleBufferActive<-"> WORD - Indicates whether double-buffering is on. Set by function
<+!><+">x_set_doublebuffer<-"><-!>.
<:s><:#286,9360>
<:s><:#579,9360><+">TripleBufferActive<-"> WORD - Indicates whether triple-buffering is active. Set by function
<+!><+">x_triple_buffer.<-"><-!>
<:s><:#286,9360><+!><+">
<:s><:#586,9360><+">TopClip, BottomClip, LeftClip RightClip<-"> WORD - Defines the clipping rectangle for linear and Video clipped bitmap put functions. Set either manually or by
<+!><+">x_set_cliprect. <-"><-!>
<:s><:#293,9360><+!>Note:<-!> <+#>X coordinates are in bytes as all clip functions clip to byte boundaries<-#>.
<:s><:#286,9360>
<:s><:#579,9360><+">PhysicalStartPixelX<-"> WORD - X pixel Offset of physical (visible) screen relative to the upper left hand corner (0,0) of the virtual screen.
<:s><:#286,9360>
<:s><:#579,9360><+">PhysicalStartByteX<-"> WORD - X byte Offset of physical (visible) screen relative to the upper left hand corner (0,0) of the virtual screen.
<:s><:#286,9360>
<:s><:#579,9360><+">PhysicalStartY<-"> WORD - Y pixel Offset of physical (visible) screen relative to the upper left hand corner (0,0) of the virtual screen.
<:s><:#286,9360>
<:s><:#579,9360><+">StartAddressFlag<-"> WORD - This flag is set if there is a new start address waiting to be set by the vsync handler.
<:s><:#286,9360>
<:s><:#586,9360><+">WaitingStartLow, WaitingStartHigh, WaitingPelPan<-"> WORD - These are used by the vsync handler
<+#>only<-#>. <+!>Do not modify!
<:s><:#286,9360><+!>
<:s><:#579,9360><+">VsyncPaletteCount <-">WORD - The start index of the video DAC register to be updated during the next vsync. Set by the palette functions.
<:s><:#286,9360>
<:#579,9360><+">VsyncPaletteCount<-"> WORD - The number of palette entries to be outed during the next vsync. Set by the palette functions.
<:s><:#286,9360>
<:s><+">VsyncPaletteBuffer <-">BYTE<[>768] - A buffer containing values for the next update of the DAC.<:p<* >>
<+@><:#286,9360><:f240, Times New Roman,0,0,0><+!>EXPORTED FUNCTIONS<:X11,-32768;TOC 2 "EXPORTED FUNCTIONS"><-!><:f>
<+B><:s><:#333,9360><+!><:f280,2Times New Roman,0,0,0>
<+B><:s><:#333,9360><+!><:f280,2Times New Roman,0,0,0>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+">x_set_mode<:X11,-32768;TOC 3 "x_set_mode"><-"><-!><:f>
<:s><:#293,9360><+!>C Prototype:<-!> extern WORD x_set_mode(WORD mode, WORD WidthInPixels);
<:s><:#286,9360>
<:s><:#579,9360><+">mode <-">- The required mode as defined by the "Available X Mode resolutions" set of defines in the xlib.h header file.
<:s><:#286,9360>
<:s><:#293,9360><+">WidthInPixels<-"> - The required virtual screen width.
<:s><:#286,9360>
<:s><:#293,9360><+!>Returns:<-!> The actual width in pixels of the allocated virtual screen
<:s><:#286,9360>
<:s><:#865,9360>This function initializes the graphics system, setting the appropriate screen resolution and allocating a virtual screen. The virtual screen allocated may not necessarily be of the same size as specified in the
<+">WidthInPixels<-"> parameter as it is rounded down to the nearest multiple of 4.
<:s><:#286,9360>
<:s><:#572,9360>The function returns the actual width of the allocated virtual screen in pixels if a valid mode was selected otherwise returns X_MODE_INVALID.
<:s><:#286,9360>
<:s><:#1172,9360>Saves virtual screen pixel width in <+">ScrnLogicalPixelWidth<-">. Saves virtual screen byte width in
<+">ScrnLogicalByteWidth<-">. Physical screen dimensions are set in
<+">ScrnPhysicalPixelWidth<-">. <+">ScrnPhysicalByteWidth<-"> and
<+">ScrnPhysicalHeight<-">. Other global variables set are <+">CurrXMode<-">,
<+">MaxScrollX<-">, <+">MaxScrollY<-">, <+">InGraphics<-">. The variable
<+">SplitScrnScanLine<-"> is also initialized to zero.
<:s><:#286,9360>
<:s><:#293,9360><+!>See also:<-!> "Available X Mode resolutions." and "What is Mode X?"
<:s><:#286,9360>
<:s><:#286,9360>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+">x_select_default_plane<:X11,-32768;TOC 3 "x_select_default_plane"><-"><-!><:f>
<:s><:#293,9360><+">line<-"> - The starting scan line of the required split screen.
<:s><:#286,9360>
<:s><:#572,9360>This function activates Mode X split screen and sets starting scan line. The split screen resides on the bottom half of the screen and has a starting address of A000:0000 in video RAM.
<:s><:#286,9360>
<:s><:#1172,9360>It also updates <+">Page0_Offs<-"> to reflect the existence of the split screen region
<+">MainScrnOffset<-"> is set to the offset of the first pixel beyond the split screen region. Other variable set are
<+">Page1_Offs<-"> which is set to the same value as <+">Page0_Offs<-"> (See call sequence below),
<+">ScrnLogicalHeight<-">, <+">ScrnPhysicalHeight<-">, <+">SplitScrnScanLine<-"> and
<+">MaxScrollY<-">.
<:s><:#286,9360>
<:s><:#858,9360>This function cannot be called after double buffering has been activated, it will return an error. To configure your graphics environment the sequence of graphics calls is as follows although either or both steps b and c may be omitted:
<:s><:#293,9360> a) <+!><+">x_set_mode <-"><-!>
<:s><:#293,9360> b) <+!><+">x_set_splitscreen <-"><-!>
<:s><:#293,9360> c) <+!><+">x_set_doublebuffer <-"><-!>
<:s><:#586,9360>Thus when you call this function successfully, double buffering is not active so
<+">Page1_Offs<-"> is set to the same address as <+">Page0_Offs<-">.
<:s><:#286,9360>
<:s><:#865,9360><+!>WARNING:<-!> If you use one of the high resolution modes (376x564 as an extreme example) you may not have enough video ram for split screen and double buffering options since VGA video RAM is restricted to 64K.
<:s><:#286,9360>
<:s><+!>See Also:<-!> "What is a Split Screen?" and "What is double buffering?"<:p<* >>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+">x_set_doublebuffer<:X11,-32768;TOC 3 "x_set_doublebuffer"><-"><-!><:f>
<:s><:#293,9360><+!>C Prototype:<-!> extern WORD x_set_doublebuffer(WORD PageHeight);
<:s><:#286,9360>
<:s><:#293,9360><+">PageHeight<-"> - The height of the two double buffering virtual screens.
<:s><:#286,9360>
<:s><:#293,9360><-!><+!>Returns:<-!> The closest possible height to the requested page height.
<:s><:#286,9360>
<:s><:#579,9360>This function sets up two double buffering virtual pages. <+">ErrorValue<-"> is set according to the success or failure of this command.
<:s><:#286,9360>
<:s><:#286,9360>Other variables set are:
<:s><:#293,9360> <+">Page1_Offs<-"> - Offset of second virtual page
<:s><:#286,9360>
<:s><:#293,9360> <+">NonVisual_Offs<-"> - Offset of first non visible video ram byte
<:s><:#286,9360>
<:s><:#293,9360> <+">DoubleBufferActive<-"> - Flag
<:s><:#286,9360>
<:s><:#293,9360> <+">PageAddrTable<-"> - Table of Double buffering pages start offsets
<:s><:#286,9360>
<:s><:#293,9360> <+">ScrnLogicalHeight<-"><+"> <-">- Logical height of the double buffering pages
<:s><:#286,9360>
<:s><:#293,9360> <+">MaxScrollY<-"> - Max. vertical start address of physical screen within the virtual screen
<:s><:#286,9360>
<:s><:#865,9360><+!>WARNING<-!>: If you use one of the high resolution modes (376x564 as an extreme example) you may not have enough video ram for split screen and double buffering options since VGA video RAM is restricted to 64K.
<:s><:#286,9360>
<:s><:#293,9360><+!>See Also:<-!> "What is double buffering?"
<:s><:#286,9360>
<:s><:#286,9360>
<:s><:#326,9360><:f280, Times New Roman,0,0,0><+!><+">x_triple_buffer
<:s><:#293,9360><+!>C Prototype: <-!>void x_triple_buffer( WORD PageHeight );
<:s><:#286,9360>
<:s><:#293,9360><+">PageHeight<-"> - The desired height of the virtual screen.
<:s><:#286,9360>
<:#1172,9360>This function behaves like <+!><+">x_double_buffer<-!><-"> but when used with
<+!><+">x_install_vsync_handler<-!><-"> you can draw immediately after a page flip. When
<+!><+">x_page_flip<-!><-"> is called, <+">VisiblePageOffs<-"> is set to the page that will be displayed during the next vysnc. Until then,
<+">WaitingPageOffs <-">will be displayed. You can draw to <+">HiddenPageOffs<-">.<-">
<:s><:#286,9360>
<:s><:#293,9360><+!>See also: <-!>"What is triple buffering?"
<:s><:#286,9360>
<:s><+!><+"><:p<* >>
<:#326,9360><-"><-"><+!><+"><:f280, Times New Roman,0,0,0><:X11,-32768;TOC 3 "x_hide_splitscreen">x_hide_splitscreen<-"><-!><:f>
<:s><:#865,9360>This function hides an existing split screen by setting its starting scan line to the last physical screen scan line.
<+">ScreenPhysicalHeight<-"> is adjusted but the <+">SplitScreenScanLine<-"> is not altered as it is required for restoring the split screen at a later stage.
<:s><:#286,9360>
<:s><:#293,9360><+!>WARNING<-!>: <+#>Only to be used if SplitScrnLine has been previously called<-#>
<:s><:#286,9360>
<:s><:#858,9360>Disabled for modes 5-11 (320x400-376x564). The memory for the initial split screen is reserved and the size limitations of these modes means any change in the split screen scan line will encroach on the split screen ram
<:s><:#286,9360>
<:s><+!>See Also:<-!> "What is a split screen?"<:p<* >>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+">x_show_splitscreen<:X11,-32768;TOC 3 "x_show_splitscreen"><-"><-!><:f>
<:s><:#579,9360>Restores split screen start scan line to the initial split screen starting scan line as set by
<+">SplitScrnScanLine<-">. <+">ScreenPhysicalHeight<-"> is adjusted.
<:s><:#286,9360>
<:s><:#293,9360><+!>WARNING: <-!><+#> Only to be used if SplitScrnLine has been previously called.<-#>
<:s><:#286,9360>
<:s><:#858,9360>Disabled for modes 5-11 (320x400-376x564). The memory for the initial split screen is reserved and the size limitations of these modes means any change in the split screen scan line will encroach on the split screen ram
<:s><:#286,9360>
<:s><:#286,9360>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+"><:X11,-32768;TOC 3 "x_adjust_splitscreen">x_adjust_splitscreen<-"><-!><:f>
<:s><:#293,9360><+">line <-">- The scan line at which the split screen is to start.
<:s><:#286,9360>
<:s><:#865,9360>Sets the split screen start scan line to a new scan line. Valid scan lines are between the initial split screen starting scan line and the last physical screen scan line.
<+">ScreenPhysicalHeight<-"> is also adjusted.
<:s><:#286,9360>
<:s><:#293,9360><+!>WARNING:<-!> <+#>Only to be used if SplitScrnLine has been previously called.<-#>
<:s><:#286,9360>
<:s><:#858,9360>Disabled for modes 5-11 (320x400-376x564). The memory for the initial split screen is reserved and the size limitations of these modes means any change in the split screen scan line will encroach on the split screen ram
<:s><:#286,9360>
<:s><:#286,9360>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+">x_set_start_addr<:X11,-32768;TOC 3 "x_set_start_addr"><-"><-!><:f>
<:#579,9360><+">X,Y <-">- coordinates of top left corner of physical screen within the hidden virtual screen if double buffering is active, or the current virtual screen otherwise.
<:s><:#286,9360>
<:s><:#579,9360>Sets the physical screen start address within currently hidden virtual page and then flips pages. If double buffering is not active then this function is functionally equivalent to
<+!><+">x_set_start_addr<-"><-!>.
<:s><:#286,9360>
<:#586,9360><+!>WARNING: <-!><+">X<-"> must not exceed (Logical screen width - Physical screen width) i.e.
<+">MaxScrollX<-">, and <+">Y<-"> must not exceed (Logical screen height - Physical screen height) i.e.
<+">MaxScrollY<-">.
<:s><:#286,9360>
<:s><:#286,9360>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+">x_text_mode<:X11,-32768;TOC 3 "x_text_mode"><-"><-!><:f>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+"><:X11,-32768;TOC 3 "x_rect_pattern">x_rect_pattern<-"><-!><:f>
<:s><:#293,9360><+!>C Prototype:<-!> extern void x_rect_pattern(WORD StartX, WORD StartY, WORD EndX,
<:s><:#286,9360> WORD EndY, WORD PageBase,BYTE far *Pattern);
<:s><:#286,9360>
<:s><:#293,9360><+">StartX, StartY<-"> - Coordinates of upper left hand corner of the rectangle.
<:s><:#286,9360>
<:s><:#293,9360><+">EndX, EndY<-"> - Coordinates of lower right hand corner of the rectangle.
<:s><:#286,9360>
<:s><:#293,9360><+">PageBase<-"> - Offset of the virtual screen.
<:s><:#286,9360>
<:#293,9360><+">Pattern<-"> - Pointer to the user defined pattern (16 bytes).
<:s><:#286,9360>
<:s><:#286,9360>Mode X rectangle 4x4 pattern fill routine.
<:s><:#286,9360>
<:s><:#1151,9360>Upper left corner of pattern is always aligned to a multiple of 4 row and column. Works on all VGAs. Uses approach of copying the pattern to off-screen display memory, then loading the latches with the pattern for each scan line and filling each scan line f
our pixels at a time. Fills up to but not including the column at
<+">EndX<-"> and the row at <+">EndY<-">. <+#>No clipping is performed<-#>.
<:s><:#286,9360>
<:s><:#579,9360><+!>WARNING:<-!> The VGA memory locations PATTERN_BUFFER (A000:FFFc) to A000:FFFF are reserved for the pattern buffer
<:#326,9360><:f280, Times New Roman,0,0,0><+"><+!><:X11,-32768;TOC 3 "x_rect_pattern_clipped">x_rect_pattern_clipped<-!><-"><:f>
<:s><:#293,9360><-"><-!><+!>C Prototype:<-!> extern void x_rect_pattern_clipped(WORD StartX, WORD StartY, WORD EndX,
<:s><:#286,9360> WORD EndY, WORD PageBase,
<:s><:#286,9360> BYTE far *Pattern);
<:s><:#286,9360>
<:s><:#293,9360><+">StartX, StartY<-"> - Coordinates of upper left hand corner of the rectangle.
<:s><:#286,9360>
<:s><:#293,9360><+">EndX, EndY<-"> - Coordinates of lower right hand corner of the rectangle.
<:s><:#286,9360>
<:s><:#293,9360><+">PageBase<-"> - Offset of the virtual screen.
<:s><:#286,9360>
<:#293,9360><+">Pattern<-"> - Pointer to the user defined pattern (16 bytes).
<:s><:#286,9360>
<:s><:#286,9360>Mode X rectangle 4x4 pattern fill routine.
<:s><:#286,9360>
<:s><:#1151,9360>Upper left corner of pattern is always aligned to a multiple of 4 row and column. Works on all VGAs. Uses approach of copying the pattern to off-screen display memory, then loading the latches with the pattern for each scan line and filling each scan line f
our pixels at a time. Fills up to but not including the column at
<+">EndX<-"> and the row at <+">EndY<-">. <+#>Clipping is performed<-#>.
<:s><:#286,9360>
<:s><:#579,9360><+!>WARNING:<-!> The VGA memory locations PATTERN_BUFFER (A000:FFFc) to A000:FFFF are reserved for the pattern buffer
<:s><:#579,9360><+">SourceBitmapWidth<-"> - The width of bitmap within the source virtual screen containing the source rectangle
<:s><:#286,9360>
<:s><:#579,9360><+">DestBitmapWidth<-"> - The width of bitmap within the dest. virtual screen containing the destination rectangle
<:s><:#286,9360>
<:s><:#1151,9360>Mode X display memory to display memory copy routine. Left edge of source rectangle modulo 4 must equal left edge of destination rectangle modulo 4. Works on all VGAs. Uses approach of reading 4 pixels at a time from the source into the latches, then writin
g the latches to the destination. Copies up to but not including the column at
<+">SrcEndX<-"> and the row at <+">SrcEndY<-">.
<:s><:#293,9360><+#>No clipping is performed<-#>. <+!>Results are not guaranteed if the source and destination overlap<-!>.
<:s><:#286,9360>
<:#286,9360>Based on code originally published in DDJ Magazine by M. Abrash
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+">x_shift_rect<:X11,-32768;TOC 3 "x_shift_rect"><-"><-!><:f>
<:s><:#293,9360><+!>C Prototype:<-!> extern void x_shift_rect (WORD SrcLeft, WORD SrcTop, WORD SrcRight,
<:s><:#286,9360> WORD SrcBottom, WORD DestLeft, WORD DestTop,
<:s><:#286,9360> WORD ScreenOffs);
<:s><:#286,9360>
<:s><:#293,9360><+">SrcLeft, SrcTop<-"> - Coordinates of the upper left hand corner of the rectangle.
<:s><:#286,9360>
<:s><:#293,9360><+">SrcRight, SrcBottom <-">- Coordinates of the lower right hand corner of the rectangle.
<:s><:#286,9360>
<:s><:#293,9360><+">DestLeft, DestTop<-"> - Coordinates of the upper left corner of the destination.
<:s><:#286,9360>
<:s><:#293,9360><+">ScreenOffs<-"> - Offset of the virtual screen.
<:s><:#286,9360>
<:s><:#1716,9360>This function copies a rectangle of VRAM onto another area of VRAM, even if the destination overlaps with the source. It is designed for scrolling text up and down, and for moving large areas of screens around in tiling systems. It rounds all horizontal
coordinates to the nearest byte (4-column chunk) for the sake of speed. This means that
<+#>it can NOT perform smooth horizontal scrolling<-#>. For that, either scroll the whole screen (minus the split screen), or copy smaller areas through system memory using the functions in the XPBITMAP module.
<:s><:#286,9360>
<:#879,9360><+">SrcRight<-"> is rounded up, and the left edges are rounded down, to ensure that the pixels pointed to by the arguments are inside the rectangle. That is,
<+">SrcRight<-"> is treated as (<+">SrcRight<-">+3) <;><;> 2, and
<+">SrcLeft<-"> as <+">SrcLeft <-"><;><;> 2.
<:s><:#286,9360>
<:s><+!>NOTE:<-!> The width of the rectangle in bytes (width in pixels / 4) cannot exceed 255.<:p<* >>
<+B><:#333,9360><:f280,2Times New Roman,0,0,0><+!>MODULE XPAL<:X11,-32768;TOC 1 "MODULE XPAL"><-!><:f>
<:s><:#286,9360>
<:s><:#286,9360>Palette functions for VGA 256 color modes.
<:s><:#286,9360>
<:#572,9360>All the functions in this module operate on two variations of the palette buffer, the raw and annotated buffers.
<:s><:#286,9360>
<:s><:#865,9360>All those functions ending in "raw" operate on the following palette structure:
<+">BYTE:r0,g0,b0,r1,g1,b1,...rn,gn,bn<-"> No reference to the starting color index or number of colors stored is contained in the structure.
<:s><:#286,9360>
<:s><:#286,9360>All those functions ending in "struc" operate on the following palette structure:
<:s><:#579,9360><+">BYTE:c,BYTE:n,BYTE:r0,g0,b0,r1,g1,b1,...rn,gn,bn<-"> where<+"> c<-"> is the starting color and<+"> n<-"> is the number of colors stored
<:s><:#286,9360>
<:s><:#579,9360><+!>WARNING:<-!> <+#>There is no validity checking in these functions<-#>. The onus is on the user to supply valid parameters to the functions.
<:#333,9360><:f280, Times New Roman,0,0,0><+!><+"><:X11,-32768;TOC 3 "x_get_pal_raw">x_get_pal_raw<-"><-!>
<:f>
<:s><:#293,9360><+!>C Prototype:<-!> extern void x_get_pal_raw(BYTE far * pal,WORD num_clrs, WORD index);
<:s><:#286,9360>
<:#293,9360><+">pal<-"> - Pointer to a buffer to receive the raw palette.
<:s><:#286,9360>
<:s><:#293,9360><+">num_clrs<-"> - The number of colors to get.
<:s><:#286,9360>
<:s><:#293,9360><+">index <-">- Starting color number to get.
<:s><:#286,9360>
<:#286,9360>Read DAC palette into raw buffer with interrupts disabled i.e. BYTE r1,g1,b1,r1,g2,b2...rn,gn,bn
<:s><:#286,9360>
<:s><:#293,9360><+!>WARNING:<-!> Memory for the palette buffers must all be pre-allocated.
<:s><:#286,9360><+!><+">
<:s><:#286,9360><+!><+">
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+">x_get_pal_struc<:X11,-32768;TOC 3 "x_get_pal_struc"><-"><-!><:f>
<:s><:#293,9360><+!>C Prototype:<-!> extern void x_get_pal_struc(BYTE far *pal, WORD num_clrs, WORD index);
<:s><:#286,9360>
<:#293,9360><+">pal<-"> - Pointer to a buffer to receive the palette structure.
<:s><:#286,9360>
<:s><:#293,9360><+">num_clrs <-">- The number of colors to get.
<:s><:#286,9360>
<:s><:#293,9360><+">index <-">- The starting color number to get.
<:s><:#286,9360>
<:#572,9360>Read DAC palette into annotated type buffer with interrupts disabled i.e. BYTE colors to skip, BYTE colors to set, r1,g1,b1,r1,g2,b2...rn,gn,bn
<:s><:#286,9360>
<:s><:#293,9360><+!>WARNING:<-!> Memory for the palette buffers must all be pre-allocated.
<:s><:#286,9360>
<:s><:#286,9360>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+"><:X11,-32768;TOC 3 "x_put_pal_raw">x_put_pal_raw<-"><-!><:f>
<:s><:#293,9360><+!>C Prototype:<-!> extern void x_put_pal_raw(BYTE far *pal, WORD num_clrs, WORD index);
<:s><:#293,9360><+">
<:#293,9360><+">pal<-"> - Pointer to a buffer containing the raw palette.
<:s><:#286,9360>
<:s><:#293,9360><+">num_clrs<-"> - The number of colors to put.
<:s><:#286,9360>
<:s><:#293,9360><+">index <-">- Starting color number to put.
<:s><:#286,9360>
<:#572,9360>Write DAC palette from raw buffer with interrupts disabled i.e. BYTE r1,g1,b1,r1,g2,b2...rn,gn,bn
<:s><:#286,9360>
<:s><:p<* >>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+">x_put_pal_struc<:X11,-32768;TOC 3 "x_put_pal_struc"><-"><-!><:f>
<:s><:#293,9360><+!>C Prototype:<-!> extern void x_put_pal_struc(BYTE far * pal);
<:s><:#293,9360><+">
<:#293,9360><+">pal<-"> - Pointer to a buffer containing the palette structure.
<:s><:#286,9360>
<:#572,9360>Write DAC palette from annotated type buffer with interrupts disabled i.e. BYTE colors to skip, BYTE colors to set, r1,g1,b1,r1,g2,b2...rn,gn,bn
<:s><:#286,9360>
<:s><:#286,9360>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+"><:X11,-32768;TOC 3 "x_set_rgb">x_set_rgb
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+"><:X11,-32768;TOC 3 "x_rot_pal_raw">x_rot_pal_raw<-"><-!><:f>
<:s><:#293,9360><+!>C Prototype<-!>: extern x_rot_pal_raw(BYTE far * pal, WORD direction, WORD num_colrs);
<:s><:#286,9360>
<:#293,9360><+">pal<-"> - Pointer to the raw palette buffer to rotate.
<:s><:#286,9360>
<:s><:#293,9360><+">direction<-"> - The direction to rotate the palette.
<:s><:#286,9360>
<:s><:#293,9360><+">num_colrs<-"> - The number of colors in the buffer.
<:s><:#286,9360>
<:s>Rotate a raw palette buffer. Direction 0 = backward, 1 = forward.<:p<* >>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+">x_put_contrast_pal_struc<:X11,-32768;TOC 3 "x_put_contrast_pal_struc"><-"><-!><:f>
<:s><:#293,9360><+!>C Prototype:<-!> extern void x_put_contrast_pal_struc(BYTE far * pal, BYTE intensity);
<:s><:#286,9360>
<:#293,9360><+">pal<-"> - A pointer to the palette structure to modify.
<:s><:#286,9360>
<:s><:#293,9360><+">intensity<-"> - Number of units to decrement the palette.
<:s><:#286,9360>
<:#572,9360>Write DAC palette from annotated type buffer with specified intensity adjustment (i.e. palette entries are decremented where possible by "intensity" units).
<:s><:#286,9360>Designed for fading in or out a palette without using an intermediate working palette buffer!
<:#286,9360>(Slow but memory efficient ... OK for small pal structs}
<:s><:#286,9360>
<:s><:#286,9360>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+"><:X11,-32768;TOC 3 "x_transpose_pal_struc">x_transpose_pal_struc<-"><-!><:f>
<:s><:#293,9360><+!>C Prototype<-!>: extern void x_transpose_pal_struc(BYTE far * pal, WORD StartColor);
<:s><:#286,9360>
<:#293,9360><+">pal <-">- Pointer to the palette structure to modify.
<:s><:#286,9360>
<:s><:#293,9360><+">StartColor<-"> - Starting color index.
<:s><:#286,9360>
<:s><:#572,9360>Write DAC palette from annotated type buffer with interrupts disabled starting at a new palette index.
<:s><:#286,9360><+!><+">
<:s><:#286,9360><+!><+">
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+"><:X11,-32768;TOC 3 "x_cpcontrast_pal_struc">x_cpcontrast_pal_struc<-"><-!><:f>
<:#293,9360><+!>C Prototype<-!>: extern WORD x_cpcontrast_pal_struc(BYTE far *src_pal, BYTE far *dest_pal,
<:s><:#286,9360> BYTE Intensity);
<:s><:#286,9360>
<:#293,9360><+">src_pal<-"> - Pointer to the source palette structure.
<:s><:#286,9360>
<:#293,9360><+">dest_pal<-"><+"> <-">- Pointer to the destination palette structure.
<:s><:#286,9360>
<:s><:#293,9360><+">Intensity<-"> - Number of units to decrement the palette.
<:s><:#286,9360>
<:s>Copy one annotated palette buffer to another making the intensity adjustment. Used in fading in and out fast and smoothly.<:p<* >>
<+B><:#333,9360><:f280,2Times New Roman,0,0,0><+!>MODULE XLINE<:X11,-32768;TOC 1 "MODULE XLINE"><-!><:f>
<:s><:#293,9360><+">FontId<-"> - The font number you wish to use (See below)
<:s><:#286,9360>
<:s><:#572,9360>Select the working font where 0 = VGA ROM 8x8, 1 = VGA ROM 8x14 2 = User defined bitmapped font.
<:s><:#286,9360>
<:s><:#293,9360><+!>WARNING:<-!> A user font must be registered before setting <+">FontID<-"> to 2.
<:s><:#286,9360>
<:s><:#293,9360><+!>See Also:<-!> Defines for this module.
<:s><:#286,9360>
<:s><:#286,9360>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+"><:X11,-32768;TOC 3 "x_register_userfont">x_register_userfont<-"><-!><:f>
<:#293,9360><+!>C Prototype:<-!> extern void x_register_userfont( char far *UserFontPtr);
<:s><:#286,9360>
<:s><:#293,9360><+">UserFontPtr<-"> - A pointer to the user font structure.
<:s><:#286,9360>
<:s><:#572,9360>Register a user font for later selection. Only one user font can be registered at any given time. Registering a user font deregisters the previous user font. User fonts may be at most 8 pixels wide.
<:s><:#286,9360>
<:s><:#286,9360><+!>USER FONT STRUCTURE<-!>
<:#286,9360> Word: ASCII code of first char in font
<:s><:#286,9360> Byte: Height of chars in font
<:s><:#286,9360> Byte: Width of chars in font
<:s><:#286,9360> n*h*Byte: the font data where n = number of chars and h = height of chars
<:s><:#286,9360>
<:s><:#579,9360><+!>WARNING:<-!> The onus is on the program to ensure that all characters drawn whilst this font is active, are within the range of characters defined.
<:s><:#286,9360>
<:s><:p<* >>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+">x_char_put<:X11,-32768;TOC 3 "x_put_char"><-"><-!><:f>
<:#293,9360><+">x, y <-">- Screen coordinates at which to draw ch
<:s><:#286,9360>
<:#293,9360><+">ScrnOffs<-"> - Starting offset of page on which to draw
<:s><:#286,9360>
<:s><:#293,9360><+">Color<-"> - Color of the text
<:s><:#286,9360>
<:s><:#286,9360>Draw a text character at the specified location with the specified color.
<:s><:#286,9360><+!>
<:s><:#293,9360><+!>WARNING:<-!> InitTextDriver must be called before using this function
<:s><:#286,9360>
<:s><:#286,9360>
<:#333,9360><:f280, Times New Roman,0,0,0><+!><+"><:X11,-32768;TOC 3 "x_printf ">x_printf<-">
<-!><:f>
<:s><:#293,9360><+!>C Prototype<-!>: void x_printf(int x, int y, unsigned ScrnOffs, int color, char *ln,...);
<:s><:#286,9360>
<:#293,9360><+">x, y <-">- screen coordinates at which to draw ch
<:s><:#286,9360>
<:#293,9360><+">ScrnOffs<-"> - Starting offset of page on which to draw
<:s><:#286,9360>
<:s><:#293,9360><+">Color<-"> - Color of the text
<:s><:#286,9360>
<:s><:#293,9360><+">ln<-"> - A pointer to a text string containing formating codes.
<:s><:#286,9360>
<:s><:#293,9360>Parameters beyond <+">Color<-"> conform to the standard printf parameters.
<:s><:#286,9360>
<:s><:#286,9360>Display formated text in the specified color.
<:s><:#286,9360>
<:s><:p<* >>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+"><:X11,-32768;TOC 3 "x_bgprintf">x_bgprintf<-"><-!><:f>
<:s><:#293,9360><+!>C Prototype:<-!> void x_bgprintf(int x, int y, unsigned ScrnOffs, int fgcolor, int bgcolor, char *ln,...);
<:s><:#286,9360>
<:#293,9360><+">x, y<-"> - Screen coordinates at which to draw ch.
<:s><:#286,9360>
<:s><:#293,9360><+">ScrnOffs<-"> - Page offset on which to draw.
<:s><:#286,9360>
<:s><:#293,9360><+">fgcolor<-"> - Color of the text foreground.
<:s><:#286,9360>
<:s><:#293,9360><+">bgcolor<-"> - Color of the text background.
<:s><:#286,9360>
<:s><:#579,9360><+">ln<-"> - Pointer to a text string that contains formating commands that conform to the printf commands.
<:s><:#286,9360>
<:#293,9360>Parameters beyond <+">bgcolor<-"> conform to the standard printf parameters.
<:s><:#286,9360>
<:s><:#286,9360>Display formatted text in the specified foreground and background colors.
<:s><:#286,9360>
<:s><:#286,9360>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+"><:X11,-32768;TOC 3 "x_get_char_width">x_get_char_width<-"><-!><:f>
<:s><:#293,9360><+!>C Prototype:<-!> unsigned int x_get_char_width(char ch)
<:s><:#286,9360>
<:s><:#293,9360><+">ch <-">- Character to get the width of.
<:s><:#286,9360>
<:s><+!>Returns:<-!> The width the requested character.<:p<* >>
<+B><:#333,9360><:f280,2Times New Roman,0,0,0><+!>MODULE XPBITMAP<:X11,-32768;TOC 1 "MODULE XPBITMAP"><-!><:f>
<+B><:s><:#286,9360>
<:s><:#286,9360>
<:s><:#572,9360>This module implements a set of functions to operate on planar bitmaps. Planar bitmaps as used by these functions have the following structure:
<:s><:#286,9360>
<:s><:#286,9360> BYTE 0 The bitmap width in bytes (4 pixel groups) range 1..255
<:s><:#286,9360> BYTE 1 The bitmap height in rows range 1..255
<:s><:#286,9360> BYTE 2..n1 The plane 0 pixels width*height bytes
<:s><:#286,9360> BYTE n1..n2 The plane 1 pixels width*height bytes
<:s><:#286,9360> BYTE n2..n3 The plane 2 pixels width*height bytes
<:s><:#286,9360> BYTE n3..n4 The plane 3 pixels width*height bytes
<:s><:#286,9360>
<:#1144,9360>These functions provide the fastest possible bitmap blts from system ram to video and further, the single bitmap is applicable to all pixel alignments. The masked functions do not need separate masks since all non zero pixels are considered to be masking pi
xels, hence if a pixel is 0 the corresponding screen destination pixel is left unchanged.
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+"><:X11,-32768;TOC 3 "x_put_masked_pbm">x_put_masked_pbm<-"><-!><:f>
<:s><:#293,9360><+!>C Prototype<-!>: extern void x_put_masked_pbm(WORD X, WORD Y, WORD ScrnOffs,
<:s><:#286,9360> BYTE far * Bitmap);
<:s><:#286,9360>
<:s><:#293,9360><+">x, y<-"> - Coordinates for the upper left corner of the bitmap.
<:s><:#286,9360>
<:s><:#293,9360><+">ScrnOffs <-">- Page offset to place the bitmap at.
<:s><:#286,9360>
<:#293,9360><+">Bitmap<-"> - Pointer to the planar bitmap structure.
<:s><:#286,9360>
<:s><:#572,9360>Mask write a planar bitmap from system ram to video ram. All zero source bitmap bytes indicate destination byte to be left unchanged.
<:s><:#286,9360><+!>
<:#293,9360><+!>NOTE<-!><+!>: <-!>Width is in bytes i.e. lots of 4 pixels
<:s><:#286,9360>
<:s><:#579,9360><+!>LIMITATIONS:<-!> <+#>No clipping is supported.<-#> Only supports bitmaps with widths which are a multiple of 4 pixels
<:s><:#286,9360>
<:s><:#293,9360><+!>See Also:<-!> XBMTOOLS module for linear <<-<;> planar bitmap conversion functions.
<:s><:#286,9360>
<:s><:#286,9360>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+"><:X11,-32768;TOC 3 "x_put_pbm">x_put_pbm<-"><-!><:f>
<:s><:#293,9360><+!>C Prototype<-!>: extern void x_put_pbm(WORD X, WORD Y, WORD ScrnOffs,
<:s><:#286,9360> BYTE far *Bitmap);
<:s><:#286,9360>
<:s><:#293,9360><+">x, y<-"> - Coordinates for the upper left corner of the bitmap.
<:s><:#286,9360>
<:s><:#293,9360><+">ScrnOffs <-">- Page offset to place the bitmap at.
<:s><:#286,9360>
<:#293,9360><+">Bitmap<-"> - Pointer to the planar bitmap structure.
<:s><:#286,9360>
<:s><:#286,9360>Write a planar bitmap from system ram to video ram.
<:s><:#286,9360>
<:#293,9360><+!>NOTE:<-!> Width is in bytes i.e. lots of 4 pixels
<:s><:#286,9360>
<:s><:#579,9360><+!>LIMITATIONS:<-!> <+#>No clipping is supported<-#> Only supports bitmaps with widths which are a multiple of 4 pixels
<:s><:#286,9360>
<:s><:#293,9360><+!>See Also:<-!> XBMTOOLS module for linear <<-<;> planar bitmap conversion functions.
<:s><:p<* >>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+">x_get_pbm<:X11,-32768;TOC 3 "x_get_pbm"><-"><-!><:f>
<:s><:#293,9360><+!>C Prototype:<-!> extern void x_get_pbm(WORD X, WORD Y,BYTE Bw,BYTE Bh,
<:s><:#286,9360> WORD ScrnOffs, BYTE far * Bitmap);
<:s><:#286,9360>
<:s><:#293,9360><+">X, Y<-"> - Coordinates of the upper left corner of the bitmap.
<:s><:#286,9360>
<:s><:#293,9360><+">Bw <-">- Width of the bitmap to get.
<:s><:#286,9360>
<:s><:#293,9360><+">Bh<-"> - Height of the bitmap to get.
<:s><:#286,9360>
<:s><:#293,9360><+">ScrnOffs<-"> - Page offset to get the bitmap from.
<:s><:#286,9360>
<:s><:#293,9360><+">Bitmap<-"> - Pointer to a buffer allocated for receiveing this bitmap.
<:s><:#286,9360>
<:s><:#286,9360>Read a planar bitmap to system ram from video ram.
<:s><:#286,9360>
<:s><:#293,9360><+!>NOTE:<-!> Width is in bytes in lots of 4 pixels
<:s><:#286,9360>
<:s><:#579,9360><+!>LIMITATIONS:<-!> No clipping is supported. Only supports bitmaps with widths which are a multiple of 4 pixels
<:s><:#286,9360>
<:s><+!>See Also:<-!> XBMTOOLS module for linear <<-<;> planar bitmap conversion functions.<:p<* >>
<+B><:#333,9360><:f280,2Times New Roman,0,0,0><+!>MODULE XPBMCLIP<:X11,-32768;TOC 1 "MODULE XPBMCLIP"><-!><:f>
<:s><:#286,9360>
<:s><:#865,9360>This module implements a similar set of functions to operate on planar bitmaps as XPBITMAP but incorporates clipping to a user defined clipping rectangle (which is set by
<+!><+">x_set_cliprect<-"><-!> in module XMAIN).
<:s><:#286,9360>
<:s><:#286,9360>The planar bitmap format is identical to the above module
<:s><:#286,9360>
<:#2288,9360>There are three variations of the functions in XPBITMAP in this module identified by the three function name extensions: _clipx, _clipy _clipxy.
<+#>Because speed is critical in games programming you do not want to be checking for clipping if not necessary<-#> thus for sprites that move only horizontally you would use the _clipx version of the put function, for sprites that move vertically you woul
d use the _clipy version and for sprites that move both directions you would use the clipxy version. Keep in mind also that
<+#>the clipping components of these functions assume that the clipping rectangle is equal to or larger than the size of the bitmap<-#> i.e.. if a bitmap is top clipped, it is assumed that the bitmap's bottom is not also clipped. Similarly with horizontal c
lipping.
<:s><:#286,9360>
<:s><:#579,9360><+!>Note:<-!> Performance in decreasing order is as follows. _clipy,_clipx,_clipxy with masked puts being slower than unmasked puts.
<:s><:#286,9360>
<:s><:#1144,9360>Horizontal clipping is performed to byte boundaries (4 pixels) rather than pixels. This allows for the fastest implementation of the functions. It is not such a handicap because for one, your screen width a multiple of 4 pixels wide and for most purposes i
t is the screen edges that form the clipping rectangle.
<:s><:#286,9360>
<:s><:#286,9360>Following is an example of setting a clipping rectangle to the logical screen edges:
<:#579,9360><+!>NOTE:<-!> The functions now return a value; 1 if clipped image is fully clipped (i.e. no portion of it appears on the screen) otherwise it returns 0
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+"><:X11,-32768;TOC 3 "x_put_masked_pbm_clipx">x_put_masked_pbm_clipx<-"><-!><:f>
<:s><:#293,9360><+!>C Prototype<-!>: extern void x_put_masked_pbm_clipx(WORD X, WORD Y, WORD ScrnOffs,
<:s><:#286,9360> BYTE far * Bitmap);
<:s><:#286,9360>
<:s><:#293,9360><+">x, y<-"> - Coordinates for the upper left corner of the bitmap.
<:s><:#286,9360>
<:s><:#293,9360><+">ScrnOffs <-">- Page offset to place the bitmap at.
<:s><:#286,9360>
<:#293,9360><+">Bitmap<-"> - A far pointer to the planar bitmap structure.
<:s><:#286,9360>
<:s><:#572,9360>Mask write a planar bitmap from system ram to video ram. Horizontal clipping is performed. All zero source bitmap bytes indicate destination byte to be left unchanged.
<:s><:#286,9360><+!>
<:#293,9360><+!>NOTE<-!><+!>: <-!>Width is in bytes i.e. lots of 4 pixels
<:s><:#286,9360>
<:s><:#293,9360><+!>LIMITATIONS:<-!> Only supports bitmaps with widths which are a multiple of 4 pixels
<:s><:#286,9360>
<:s><:#293,9360><+!>See Also:<-!> XBMTOOLS module for linear <<-<;> planar bitmap conversion functions.
<:s><:#286,9360>
<:s><:#286,9360>
<:#326,9360><-!><-"><:f280, Times New Roman,0,0,0><+!><+">x_put_masked_pbm_clipy<:X11,-32768;TOC 3 "x_put_masked_pbm_clipy"><-"><-!><:f>
<:s><:#293,9360><+!>C Prototype<-!>: extern void x_put_masked_pbm_clipy(WORD X, WORD Y, WORD ScrnOffs,
<:s><:#286,9360> BYTE far * Bitmap);
<:s><:#286,9360>
<:s><:#293,9360><+">x, y<-"> - Coordinates for the upper left corner of the bitmap.
<:s><:#286,9360>
<:s><:#293,9360><+">ScrnOffs <-">- Page offset to place the bitmap at.
<:s><:#286,9360>
<:#293,9360><+">Bitmap<-"> - A far pointer to the planar bitmap structure.
<:s><:#286,9360>
<:#572,9360>Mask write a planar bitmap from system ram to video ram. Vertical clipping is performed. All zero source bitmap bytes indicate destination byte to be left unchanged.
<:s><:#286,9360><+!>
<:#293,9360><+!>NOTE<-!><+!>: <-!>Width is in bytes i.e. lots of 4 pixels
<:s><:#286,9360>
<:s><:#293,9360><+!>LIMITATIONS:<-!> Only supports bitmaps with widths which are a multiple of 4 pixels
<:s><:#286,9360>
<:s><:#293,9360><+!>See Also:<-!> XBMTOOLS module for linear <<-<;> planar bitmap conversion functions.
<:s><:#326,9360><+!><+"><:f280, Times New Roman,0,0,0>
<:s><+!><+"><:f280, Times New Roman,0,0,0><:p<* >>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+">x_put_masked_pbm_clipxy<:X11,-32768;TOC 3 "x_put_masked_pbm_clipxy"><-"><-!><:f>
<:s><:#293,9360><+!>C Prototype<-!>: extern void x_put_masked_pbm_clipxy(WORD X, WORD Y, WORD ScrnOffs,
<:s><:#286,9360> BYTE far * Bitmap);
<:s><:#286,9360>
<:s><:#293,9360><+">x, y<-"> - Coordinates for the upper left corner of the bitmap.
<:s><:#286,9360>
<:s><:#293,9360><+">ScrnOffs <-">- Page offset to place the bitmap at.
<:s><:#286,9360>
<:#293,9360><+">Bitmap<-"> - A far pointer to the planar bitmap structure.
<:s><:#286,9360>
<:#572,9360>Mask write a planar bitmap from system ram to video ram. Both horizontal and vertical clipping is performed. All zero source bitmap bytes indicate destination byte to be left unchanged.
<:s><:#286,9360><+!>
<:#293,9360><+!>NOTE<-!><+!>: <-!>Width is in bytes i.e. lots of 4 pixels
<:s><:#286,9360>
<:s><:#293,9360><+!>LIMITATIONS:<-!> Only supports bitmaps with widths which are a multiple of 4 pixels
<:s><:#286,9360>
<:s><:#293,9360><+!>See Also:<-!> XBMTOOLS module for linear <<-<;> planar bitmap conversion functions.
<:s><:#326,9360><+!><+"><:f280, Times New Roman,0,0,0>
<:s><:#326,9360><+!><+"><:f280, Times New Roman,0,0,0>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+">x_put_pbm<-"><-!><+!><+">_clipx<:X11,-32768;TOC 3 "x_put_pbm_clipx"><-"><-!><:f>
<:s><:#293,9360><+!>C Prototype<-!>: extern void x_put_pbm_clipx(WORD X, WORD Y, WORD ScrnOffs,
<:s><:#286,9360> BYTE far *Bitmap);
<:s><:#286,9360>
<:s><:#293,9360><+">x, y<-"> - Coordinates for the upper left corner of the bitmap.
<:s><:#286,9360>
<:s><:#293,9360><+">ScrnOffs <-">- Page offset to place the bitmap at.
<:s><:#286,9360>
<:#293,9360><+">Bitmap<-"> - A far pointer to the planar bitmap structure.
<:s><:#286,9360>
<:s><:#286,9360>Write a planar bitmap from system ram to video ram. Horizontal clipping is performed.
<:s><:#286,9360>
<:#293,9360><+!>NOTE:<-!> Width is in bytes i.e. lots of 4 pixels
<:s><:#286,9360>
<:s><:#293,9360><+!>LIMITATIONS:<-!> Only supports bitmaps with widths which are a multiple of 4 pixels
<:s><:#286,9360>
<:s><:#293,9360><+!>See Also:<-!> XBMTOOLS module for linear <<-<;> planar bitmap conversion functions.
<:s><:p<* >>
<:#326,9360><+!><+"><:f280, Times New Roman,0,0,0>x_put_pbm<-"><-!><:f><+!><+">_clipy<:X11,-32768;TOC 3 "x_put_pbm_clipy"><-"><-!>
<:s><:#293,9360><+!>C Prototype<-!>: extern void x_put_pbm_clipy(WORD X, WORD Y, WORD ScrnOffs,
<:s><:#286,9360> BYTE far *Bitmap);
<:s><:#286,9360>
<:s><:#293,9360><+">x, y<-"> - Coordinates for the upper left corner of the bitmap.
<:s><:#286,9360>
<:s><:#293,9360><+">ScrnOffs <-">- Page offset to place the bitmap at.
<:s><:#286,9360>
<:#293,9360><+">Bitmap<-"> - A far pointer to the planar bitmap structure.
<:s><:#286,9360>
<:#286,9360>Write a planar bitmap from system ram to video ram. Vertical clipping is performed.
<:s><:#286,9360>
<:#293,9360><+!>NOTE:<-!> Width is in bytes i.e. lots of 4 pixels
<:s><:#286,9360>
<:s><:#293,9360><+!>LIMITATIONS:<-!> Only supports bitmaps with widths which are a multiple of 4 pixels
<:s><:#286,9360>
<:s><:#293,9360><+!>See Also:<-!> XBMTOOLS module for linear <<-<;> planar bitmap conversion functions.
<:s><:#286,9360>
<:s><:#286,9360>
<:#326,9360><+!><+"><:f280, Times New Roman,0,0,0>x_put_pbm<-"><-!><:f><+!><+">_clipxy<:X11,-32768;TOC 3 "x_put_pbm_clipxy"><-"><-!>
<:s><:#293,9360><+!>C Prototype<-!>: extern void x_put_pbm_clipxy(WORD X, WORD Y, WORD ScrnOffs,
<:s><:#286,9360> BYTE far *Bitmap);
<:s><:#286,9360>
<:s><:#293,9360><+">x, y<-"> - Coordinates for the upper left corner of the bitmap.
<:s><:#286,9360>
<:s><:#293,9360><+">ScrnOffs <-">- Page offset to place the bitmap at.
<:s><:#286,9360>
<:#293,9360><+">Bitmap<-"> - A far pointer to the planar bitmap structure.
<:s><:#286,9360>
<:#572,9360>Write a planar bitmap from system ram to video ram. Both horizontal and vertical clipping is performed.
<:s><:#286,9360>
<:#293,9360><+!>NOTE:<-!> Width is in bytes i.e. lots of 4 pixels
<:s><:#286,9360>
<:s><:#293,9360><+!>LIMITATIONS:<-!> Only supports bitmaps with widths which are a multiple of 4 pixels
<:s><:#286,9360>
<:s><:#293,9360><+!>See Also:<-!> XBMTOOLS module for linear <<-<;> planar bitmap conversion functions.
<:s><:p<* >>
<+B><:#333,9360><:f280,2Times New Roman,0,0,0><+!>MODULE XCBITMAP<:X11,-32768;TOC 1 "MODULE XCBITMAP"><-!><:f>
<:s><:#286,9360>
<:s><:#286,9360>
<:#572,9360>Compiled bitmap functions. See "The care and feeding of compiled masked blits." in the reference section for more details on compiled bitmaps.
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+"><:X11,-32768;TOC 3 "x_compile_pbm">x_compile_pbm<-"><-!><:f>
<:s><:#293,9360><+!>C Prototype: <-!> x_compile_pbm( WORD lsw, char far *bitmap, char far *output );
<:s><:#286,9360>
<:s><:#293,9360><+">lsw<-"> - The logical screen width in bytes.
<:s><:#286,9360>
<:s><:#293,9360><+">bitmap<-"> - A pointer to the source planar bitmap.
<:s><:#286,9360>
<:s><:#293,9360><+">output<-"> - A far pointer to a buffer set up to receive the compiled bitmap.
<:s><:#286,9360>
<:s><:#293,9360><+!>Returns: <-!>The size of the compiled bitmap in bytes.
<:s><:#286,9360>
<:s><:#572,9360>Compiles a planar bitmap to generate machine code to plot it at any required screen coordinates FAST!
<:s><:#286,9360>
<:s><:#286,9360>
<:#326,9360><+!><+"><:f280, Times New Roman,0,0,0>x_sizeof_cpbm<:X11,-32768;TOC 3 "x_sizeof_cpbm"><:f><-"><-!>
<:s><:#293,9360><+!>C Prototype: <-!> int x_sizeof_cpbm( WORD lsw, char far *bitmap );
<:s><:#286,9360>
<:s><:#293,9360><+">lsw<-"> - The logical screen width in bytes.
<:s><:#286,9360>
<:s><:#293,9360><+">bitmap<-"> - A far pointer to the source planar bitmap.
<:s><:#286,9360>
<:s><:#293,9360><+!>Returns: <-!> The space in bytes required to hold the compiled bitmap.
<:s><:#286,9360>
<:s><:p<* >>
<+B><:#333,9360><:f280,2Times New Roman,0,0,0><+!>MODULE XVBITMAP<:X11,-32768;TOC 1 "MODULE XVBITMAP"><-!><:f>
<:s><:#286,9360>
<:s><:#286,9360>
<:#1430,9360>The XVBITMAP module implements yet another type of bitmap to complement planar and compiled bitmaps, VRAM based bitmaps. If a 4 cylinder car is analogous to planar bitmaps, that is thrifty on memory consumption but low performance and a V8 is analogous to C
ompiled bitmaps, memory guzzlers that really fly, then VRAM based bitmaps are the 6 cylinder modest performers with acceptable memory consumption.
<:s><:#286,9360>
<:#858,9360>To summarize their selling points, VBM's are moderately fast with fair memory consumption, and unlike compiled bitmaps, can be clipped. The disadvantages are that they are limited by the amount of free video ram and have a complex structure.
<:s><:#286,9360>
<:#1151,9360>The VRAM bitmap format is rather complex consisting of components stored in video ram and components in system ram working together. This complexity necessitates the existence of a creation function
<+!><+">x_make_vbm<-"><-!> which takes an input linear bitmap and generates the equivalent VBM (VRAM Bit Map).
<:s><:#286,9360>
<:s><:#286,9360>VBM structure:
<:s><:#286,9360> WORD 0 Size Total size of this VBM structure in bytes
<:#286,9360> WORD 1 ImageWidth Width in bytes of the image (for all alignments)
<:#286,9360> WORD 2 ImageHeight Height in scan lines of the image
<:#286,9360> WORD 3 Alignment 0 ImagePtr Offset in VidRAM of this aligned image
<:#286,9360> WORD 4 MaskPtr Offset (within this structure's DS) of alignment masks
<:s><:#286,9360> WORD 9 Alignment 3 ImagePtr Offset in VidRAM of this aligned image
<:s><:#286,9360> WORD 10 MaskPtr Offset (within this structure's DS) of alignment masks
<:#286,9360> (And don't forget the corresponding data in video ram)
<:s><:#286,9360>
<:s><:#286,9360>
You can see for yourself the complexity of this bitmap format. The image is stored in video ram in its 4 different alignments with pointers to these alignments in the VBM. Similarly there are 4 alignments of the corresponding masks within the VBM itself (to
wards the end). The mask bytes contain the plane settings for the corresponding video bytes so that one memory move can move up to 4 pixels at a time (depending on the mask settings) using the VGA's latches, theoretically giving you a 4x speed improvement o
ver conventional blits like the ones implemented in "XPBITMAP". In actual fact its anywhere between 2 and 3 due to incurred overheads.
<:p<* >>
<:#2002,9360>These bitmaps are more difficult to store in files than PBM'S and CBM's but still possible with a bit of work, so do not dismiss these as too difficult to use. Consider all the bitmap formats carefully before deciding on which to use. There may even be situ
ations that a careful application of all three types would be most effective i.e.. compiled bitmaps for Background tiles and the main game character (which never need clipping), VRAM based bitmaps for the most frequently occurring (opponent, alien etc.) cha
racters which get clipped as they come into and leave your current location and planar bitmaps for smaller or less frequently encountered characters.
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+"><:X11,-32768;TOC 3 "x_make_vbm">x_make_vbm<-"><-!><:f>
<:#293,9360><+!>C Prototype:<-!> extern char far * x_make_vbm( char far *lbm, WORD *VramStart);
<:s><:#286,9360>
<:#293,9360><+">lbm - <-">A far pointer to the input linear bitmap
<:s><:#286,9360>
<:#293,9360><+">VramStart<-"> - Pointer to variable containing Offset of first free VRAM byte
<:s><:#286,9360>
<:s><:#1158,9360>Create the VBM from the given linear bitmap and place the image alignments in video ram starting at the offset in the variable pointed to by
<+">VramStart<-">. <+">VramStart<-"> is then updated to point to the next free VRAM byte (just after the last byte of the image alignments). Usually you will point
<+">VramStart<-"> to <+">NonVisual_Offs<-">.
<:s><:#286,9360>
<:s><:#286,9360>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+">x_put_masked_vbm<:X11,-32768;TOC 3 "x_put_masked_vbm">
<-"><-!><:f>
<:#293,9360><+!>C Prototype:<-!> extern int x_put_masked_vbm( int X, int Y, WORD ScrnOffs,
<:#286,9360> BYTE far *VBitmap);
<:s><:#286,9360>
<:s><:#293,9360><+">X, Y <-">- Coordinates to draw the bitmap at.
<:s><:#286,9360>
<:s><:#293,9360><+">ScrnOffs<-"> - The page offset to draw the bitmap at.
<:s><:#293,9360><+">
<:#293,9360><+">VBitmap<-"> - A far pointer to the video bitmap.
<:s><:#286,9360>
<:#832,9360><+!>Returns:<-!> 1 if clipped image is fully clipped (i.e. no portion of it appears on the screen) otherwise it returns 0.
<:f200, NewsGothic,0,0,0>(Editors note: since this function doesn't support clipping the return value should be 0 at all times.)<:f>
<:s><:#286,9360>
<:s><:#293,9360>Draw a VRAM based bitmap at (X,Y) relative to the screen with starting offset
<+">ScrnOffs<-">.
<:s><:p<* >>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+"><:X11,-32768;TOC 3 "x_put_masked_vbm_clipx">x_put_masked_vbm_clipx<-!><-"><:f>
<:#293,9360><-!><+!>C Prototype:<-!> extern int x_put_masked_vbm_clipx(int X, int Y, WORD ScrnOffs,
<:s><:#286,9360> BYTE far *VBitmap);
<:s><:#286,9360>
<:s><:#293,9360><+">X, Y <-">- Coordinates to draw the bitmap at.
<:s><:#286,9360>
<:s><:#293,9360><+">ScrnOffs<-"> - The page offset to draw the bitmap at.
<:s><:#286,9360>
<:s><:#293,9360><+">VBitmap<-"> - A far pointer to the video bitmap.
<:s><:#286,9360>
<:s><:#293,9360><+!>Returns:<-!> 1 if clipped image is fully clipped otherwise it returns 0.
<:s><:#286,9360>
<:#579,9360>Draw a VRAM based bitmap at (X,Y) relative to the screen with starting offset
<+">ScrnOffs. <-">Horizontal clipping is performed.
<:#293,9360><-!><+!>C Prototype:<-!> extern int x_put_masked_vbm_clipy( int X, int Y, WORD ScrnOffs,
<:s><:#286,9360> BYTE far *VBitmap);
<:s><:#286,9360>
<:s><:#293,9360><+">X, Y <-">- Coordinates to draw the bitmap at.
<:s><:#286,9360>
<:s><:#293,9360><+">ScrnOffs<-"> - The page offset to draw the bitmap at.
<:s><:#286,9360>
<:s><:#293,9360><+">VBitmap<-"> - A far pointer to the video bitmap.
<:s><:#286,9360>
<:#579,9360><+!>Returns:<-!> 1 if clipped image is fully clipped (i.e. no portion of it appears on the screen) otherwise it returns 0
<:s><:#286,9360>
<:s><:#293,9360>Draw a VRAM based bitmap at (X,Y) relative to the screen with starting offset
<+">ScrnOffs<-">.
<:#286,9360>Vertical clipping is performed.
<:s><:p<* >>
<:#326,9360><:f280, Times New Roman,0,0,0><+"><+!>x_put_masked_vbm_clipxy<:X11,-32768;TOC 3 "x_put_masked_vbm_clipxy"><-"><-!><:f>
<:#293,9360><+!>C Prototype:<-!> extern int x_put_masked_vbm_clipxy( int X, int Y, WORD ScrnOffs,
<:s><:#286,9360> BYTE far *VBitmap);
<:s><:#286,9360>
<:s><:#293,9360><+">X, Y <-">- Coordinates to draw the bitmap at.
<:s><:#286,9360>
<:s><:#293,9360><+">ScrnOffs<-"> - The page offset to draw the bitmap at.
<:s><:#286,9360>
<:s><:#293,9360><+">VBitmap<-"> - A far pointer to the video bitmap.
<:s><:#286,9360>
<:#579,9360><+!>Returns:<-!> 1 if clipped image is fully clipped (i.e. no portion of it appears on the screen) otherwise it returns 0
<:s><:#286,9360>
<:s><:#293,9360>Draw a VRAM based bitmap at (X,Y) relative to the screen with starting offset
<+">ScrnOffs<-">.
<:#286,9360>Both horizontal and vertical clipping is performed.
<:s><:#286,9360>
<:s><:#286,9360>
<:s>See XPBMCLIP for more details on the type of clipping used as it is identical to XVBITMAP.<:p<* >>
<+B><:#333,9360><:f280,2Times New Roman,0,0,0><+!>MODULE XMOUSE<:X11,-32768;TOC 1 "MODULE XMOUSE"><-!><:f>
<:s><:#286,9360>
<:s><:#1144,9360>The XMOUSE module implements very basic mouse handling functions. The way in which it operates is by installing an event handler function during initialization which subsequently intercepts and processes mouse events and automatically updates status variabl
es such as mouse position and button pressed status.
<:s><:#286,9360>
<:s><:#286,9360>It does not support the full functionality of:
<:s><:#286,9360> SPLIT SCREENS, SCROLLED WINDOWS, or VIRTUAL WINDOWS
<:#858,9360>This was done to primarily prevent unnecessary impedences to performance, since the mouse handler function has the potential to degrade performance. It also saves me a lot of coding which I was too lazy to do.
<:s><:#286,9360>
<:s><:#1144,9360>Programs communicate with the mouse driver as with other devices, through an interrupt vector namely 33h. On generating an interrupt, the mouse driver expects a function number in AX and possibly other parameters in other registers and returns information v
ia the registers. A brief description of the mouse functions follows:
<:s><:#286,9360>Get Mouse Position & Button Status 3
<:s><:#286,9360>Set Mouse Cursor Position 4
<:s><:#286,9360>Get Button Press Information 5
<:s><:#286,9360>Get Button Release Information 6
<:s><:#286,9360>Set Min/Max Horizontal Position 7
<:s><:#286,9360>Set Min/Max Vertical Position 8
<:s><:#286,9360>Define Graphics Cursor Block 9
<:s><:#286,9360>Define Text Cursor 10
<:s><:#286,9360>Read Mouse Motion Counters 11
<:s><:#286,9360>Define Event Handler 12
<:s><:#286,9360>Light Pen Emulation Mode ON 13
<:s><:#286,9360>Light Pen Emulation Mode OFF 14
<:s><:#286,9360>Set Mouse Mickey/Pixel Ratio 15
<:s><:#286,9360>Conditional Hide Cursor 16
<:s><:#286,9360>Set Double-Speed Threshold 19
<:s><:#286,9360>
<:s><:#286,9360>
In practice only a few of these functions are used and even fewer when the mouse status is monitored by an event handler function such as is used in this module.<:p<* >>
<:#1151,9360>The most important thing to note when using the mouse module is that the mouse event handler must be removed before exiting the program. It is a good idea to have an exit function (see the C
<+!><+">atexit<-"><-!> function) and include the line <+!><+">x_mouse_remove<-"><-!>(); along with any other pre-exit cleanup code.
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+">x_mouse_init<:X11,-32768;TOC 3 "x_mouse_init"><-"><-!><:f>
<:s><:#293,9360><+!>C Prototype<-!>: int x_mouse_init()
<:s><:#286,9360>
<:s><:#858,9360>Initialize the mouse driver functions and install the mouse event handler function. This is the first function you must call before using any of the mouse functions. This mouse code uses the fastest possible techniques to save and restore mouse backgrounds
and to draw the mouse cursor.
<:s><:#286,9360>
<:#579,9360><+!>WARNING:<-!> This function uses and updates <+">NonVisual_Offset<-"> to allocate video ram for the saved mouse background.
<:s><:#286,9360>
<:s><:#586,9360><+!>LIMITATIONS:<-!> No clipping is supported horizontally for the mouse cursor. No validity checking is performed for
<+">NonVisual_Offs<-">
<:s><:#286,9360>
<:#2030,9360><+!>**WARNING**<-!> You must Hide or at least Freeze the mouse cursor while drawing using any of the other XLIB modules since the mouse handler may modify VGA register settings at any time. VGA register settings are not preserved which will result in unpre
dictable drawing behavior. If you know the drawing will occur away from the mouse cursor set
<+">MouseFrozen<-"> to TRUE (1), do your drawing then set it to FALSE (0). Alternatively call
<+!><+">x_hide_mouse<-"><-!>, perform your drawing and then call
<+!><+">x_show_mouse<-"><-!>. Another alternative is to disable interrupts while drawing but usually drawing takes up a lot of time and having interrupts disabled for too long is not a good
<:s><:#286,9360>idea.
<:s><:#286,9360>
<:s><:#286,9360>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+"><:X11,-32768;TOC 3 "x_define_mouse_cursor">x_define_mouse_cursor<-"><-!><:f>
<:#293,9360><+!>C Prototype:<-!> void x_define_mouse_cursor( char far *MouseDef, unsigned char MouseColor)
<:s><:#286,9360>
<:#293,9360><+">MouseDef<-"> - A far pointer to 14 characters containing a bitmask for all the cursor's rows.
<:s><:#286,9360>
<:s><:#293,9360><+">MouseColor<-"> - The color to use when drawing the mouse cursor.
<:s><:#286,9360>
<:#572,9360>Define a mouse cursor shape for use in subsequent cursor redraws. XMOUSE has a hardwired mouse cursor size of 8 pixels across by 14 pixels down.
<:s><:#286,9360>
<:s><:#293,9360><+!>WARNING<-!>: This function assumes<+#> <+">MouseDef<-#><-"> points to 14 bytes.
<:s><:#286,9360>
<:#586,9360><+!>Note: <-!><+#>Bit order is in reverse<-#>. i.e. bit 7 represents pixel 0, bit 0 represents pixel 7 in each byte of
<+">MouseDef<-"> .
<:s><:#286,9360>
<:s><:p<* >>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+"><:X11,-32768;TOC 3 "x_show_mouse">x_show_mouse<-"><-!><:f>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+"><:X11,-32768;TOC 3 "x_pbm_to_bm">x_pbm_to_bm<-"><-!><:f>
<:#293,9360><+!>C Prototype:<-!> extern int x_pbm_to_bm( char far * source_pbm, char far * dest_bm);
<:s><:#286,9360>
<:s><:#293,9360><+">source_pbm<-"> - A pointer to the source planar bitmap.
<:s><:#286,9360>
<:s><:#293,9360><+">dest_bm<-"> - A pointer to a buffer set up to receive the linear bitmap.
<:s><:#286,9360>
<:s><:#293,9360><+!>Returns:<-!> 0 on successful conversion.
<:s><:#286,9360>
<:s><:#579,9360>This function converts a bitmap in the planar format to the linear format as used by
<+!><+">x_compile_bitmap<-"><-!>.
<:s><:#286,9360>
<:s><:#293,9360><+!>WARNING:<-!> The source and destination bitmaps <+#>must<-#> be pre-allocated.
<:s><:#286,9360>
<:s><:#579,9360><+!>NOTE:<-!> This function can only convert planar bitmaps that are suitable. If the source planar bitmap's width (per plane) is <;>= 256/4 it cannot be converted. In this situation an error code
<:s><:#286,9360>BM_WIDTH_ERROR.
<:s><:#286,9360>
<:s><:#286,9360>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+">x_bm_to_pbm<:X11,-32768;TOC 3 "x_bm_to_pbm">
<-"><-!><:f>
<:#293,9360><+!>C Prototype<-!>: extern int x_bm_to_pbm( char far * source_lbm, char far * dest_bm);
<:s><:#286,9360>
<:s><:#293,9360><+">source_lbm <-"> - A pointer to the source linear bitmap.
<:s><:#286,9360>
<:s><:#293,9360><+">dest_bm <-">- A pointer to a buffer set up to receive the planar bitmap.
<:s><:#286,9360>
<:s><:#293,9360><+!>Returns: <-!>0 on successful conversion.
<:s><:#286,9360>
<:#572,9360>This function converts a bitmap in the linear format as used by x_compile_bitmap to the planar format.
<:s><:#286,9360>
<:s><:#293,9360><+!>WARNING:<-!> The source and destination bitmaps <+#>must<-#> be pre - allocated
<:s><:#286,9360>
<:s><:#579,9360><+!>NOTE: <-!>This function can only convert linear bitmaps that are suitable. If the source linear bitmap's width is not a multiple of 4 it cannot be converted. In this situation an error code
<:s>BM_WIDTH_ERROR. <:p<* >>
<+B><:#333,9360><:f280,2Times New Roman,0,0,0><+!>MODULE XCLIPPBM<:X11,-32768;TOC 1 "MODULE XCLIPPBM"><-!><:f>
<:s><:#286,9360>
<:s><:#286,9360>
<:#865,9360><+!>Note:<-!> VERY SIMILAR to XPBMCLIP. This module implements blits of clipped planar bitmaps. Blits are clipped to pixels, both horizontally. This makes the unmasked blit function here slightly slower than the equivalent functions in the XPBMCLIP module.
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+">x_triangle<:X11,-32768;TOC 3 "x_triangle"><-"><-!><:f>
<:#293,9360><+!>C Prototype:<-!> void x_triangle( int x0, int y0, int x1, int y1, int x2, int y2, WORD color,
<:s><:#286,9360> WORD PageBase);
<:s><:#286,9360>
<:s><:#293,9360><+">x0, y0<-"> - The coordinates of point one of the triangle.
<:s><:#286,9360>
<:s><:#293,9360><+">x1, y1<-"> - The coordinates of point two of the triangle.
<:s><:#286,9360>
<:s><:#286,9360>x2, y2 - The coordinates of the third (and final) point of the triangle.
<:s><:#286,9360>
<:s><:#293,9360><+">color<-"> - The color in which to draw the triangle in.
<:s><:#286,9360>
<:s><:#293,9360><+">PageBase<-"> - The page offset on which to draw the triangle.
<:s><:#286,9360>
<:#579,9360>This function draws a filled triangle which is clipped to the current clipping window defined by
<+">TopClip, BottomClip, LeftClip, RightClip<-">.
<:s><:#286,9360>
<:s><:#579,9360><+!>Remember: <-!><+#>The X clipping variable are in BYTES not PIXELS<-#> so you can only clip to 4 pixel byte boundaries.
<:s><:#286,9360>
<:s><:p<* >>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+"><:X11,-32768;TOC 3 "x_polygon">x_polygon<-"><-!><:f>
<:#293,9360><+!>C Prototype:<-!> void x_polygon( VERTEX *vertices, int num_vertices, WORD color,
<:s><:#286,9360> WORD PageBase);
<:s><:#293,9360><+">
<:#293,9360><+">vertices<-"> - A pointer to your vertex structure.
<:s><:#286,9360>
<:s><:#293,9360><+">num_vertices<-"> - The number of vertices to plot.
<:s><:#286,9360>
<:s><:#293,9360><+">color<-"> - The color in which to draw the polygon.
<:s><:#286,9360>
<:s><:#293,9360><+">PageBase<-"> - The page offset on which to draw the polygon.
<:s><:#286,9360>
<:s><:#572,9360>This function is similar to the triangle function but draws convex polygons. The vertices are supplied in the form of a FAR pointer.
<:s><:#286,9360>
<:s><:#579,9360><+!>NOTE:<-!> A convex polygon is one such that if you draw a line from any two vertices, every point on that line will be within the polygon.
<:s><:#286,9360>
<+@>This function works by splitting up a polygon into its component triangles and calling the triangle routine above to draw each one. Performance is respectable but a custom polygon routine might be faster.<:p<* >><:f280,2Times New Roman,0,0,0><+!>MODULE XBEZ
<-!><:f><+!><:f280,2Times New Roman,0,0,0>IER<-!><:f><:X11,-32768;TOC 1 "MODULE XBEZIER">
<+@><:s><:#286,9360>
<+@><:#286,9360>Bezier curve plotting function. See "What is a Bezier curve?" for more details.
<:s><:#293,9360><+">color<-"> - The color to use for the fill.
<:s><:#286,9360>
<:s><:#293,9360><+!>Returns:<-!> The number of pixels that were filled.
<:s><:#286,9360>
<:#1151,9360>This function performs the familiar flood filling used by many paint programs and, of course, the Borland BGI's flood fill function. The pixel at
<+">x, y<-"><+"> <-"> and all adjacent pixels of the same color are filled with the new color. Filling stops when there are no more adjacent pixels of the original pixels color.
<:s><:#286,9360>
<:s><:#286,9360>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+"><:X11,-32768;TOC 3 "x_boundry_fill">x_boundry_fill<-"><-!>
<:#293,9360><+!>C Prototype: <-!>int x_boundry_fill( int x, int y, WORD offs, int boundary, int color);
<:s><:#286,9360>
<:s><:#293,9360><+">x, y <-">- The starting coordinates.
<:s><:#286,9360>
<:s><:#293,9360><+">offs<-"> - The page offset to draw on.
<:s><:#286,9360>
<:#293,9360><+">boundary - Boundary color.
<:s><:#286,9360>
<:s><:#293,9360><+">color<-"> - The color to use for the fill.
<:s><:#286,9360>
<:s><:#293,9360><+!>Returns:<-!> The number of pixels that were filled.
<:s><:#286,9360>
<:#872,9360>This function performs a variant of the flood fill described above. The pixel at
<+">x, y<-"><+"> <-"> and all adjacent pixels of the same color are filled with the new color. Filling stops when the area being filled is fully enclosed by pixels of the color
<+">boundary.
<:s><:#326,9360><+!><+"><:f280, Times New Roman,0,0,0>
<+B><:p<* >><:f280, Times New Roman,0,0,0><+!>MODULE XVSYNC<:X11,-32768;TOC 1 "MODULE XVSYNC"><-!><:f>
<+@><:s><:#286,9360>
<:#286,9360>Inspired by REND386 v3.01 by Dave Stamps and Bernie Roehl
<:s><:#286,9360>
<:#1430,9360>This module uses timer 0 to simulate a vertical retrace interrupt. It's designed to significantly reduce the idle waiting time in XLIB. Why simulate the VRT interrupt? Simply because a true VRT interrupt is not implemented on many VGA cards. Using a VRT
interrupt as opposed to polling, can result in huge performance improvements for your code and help make animation much smoother than it would be using polling.
<:s><:#286,9360>
<:#1158,9360>Normally XLIB waits for vsync when <+!><+">x_page_flip, x_set_start_address<-!><-"> or
<+!><+">x_put_pal_???<-!><-"> is called. the waiting period could be better utilized to do housekeeping calculations or whatever. The
<+!><+">x_put_pal_???<-!><-"> functions also don't work very smoothly in conjunction with other functions that wait for the vertical retrace since each function introduces its own VRT delay.
<:s><:#286,9360>
<:#572,9360>When using the vsync handler, the VRT delay is reduced to the absolute minimum which can result in a huge performance boost for your programs.
<:s><:#286,9360>
<:s><:#572,9360>When using double buffering, you may still have to wait before drawing, but you could do as much other work as possible, like this:
<:s><:#286,9360>This function removes the vsync handler.
<:s><:#286,9360>
<:s><:#286,9360>You <+#>must<-#> call this function before exiting your program, or your system will crash!
<:s><:#286,9360>
<:s><:#286,9360>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+"><:X11,-32768;TOC 3 "x_set_user_vsync_handler">x_set_user_vsync_handler<-"><-!>
<:s><:#293,9360><-"><+!>C Prototype: <-!>void x_set_user_vsync_handler( void far (*f)() );
<:s><:#286,9360>
<:s><:#293,9360><+">f<-"> - A far pointer to a user function to be called once each vertical retrace.
<:s><:#286,9360>
<:#572,9360>This function installs a user routine to be called once each vertical retrace. The user handler has its own stack of 256 bytes, so be careful with the stack checking option in BC.
<:s><:#286,9360>
<:s><:#293,9360><+!>WARNING:<-!> This installs an interrupt driven handler, beware of the following:
@Bullet 1@<:s><:#286,9360>Only 8086 registers are preserved. If you're using 386 code, save all the 386 registers.
@Bullet 1@<:s><:#286,9360>Don't do any drawing.
@Bullet 1@<:s><:#286,9360>Don't call any DOS functions.
<:s><:#286,9360>
<:s>You CAN update global variables if you're careful. And it's nice for palette animation. You can even do fades while loading from disk. You should usee this instead of installing your own int 08h routine and chaining to the original.<:p<* >>
<:#326,9360><:f280, Times New Roman,0,0,0><+!><+"><-#>x_wait_start_addr<:X11,-32768;TOC 3 "x_wait_start_addr"><-"><-!>
<:s><:#286,9360>In my opinion <+#>Doctor Dobbs Journal<-#> is the best reference text for VGA Mode X graphics:
<:#286,9360> Issue 178 Jul. 1991 : First reference to Mode X Article Abstract : VGA's undocumented
<:s><:#286,9360> Mode X supports page flipping, makes off screen memory available,
<:s><:#286,9360> has square pixels, and increases performance by as much as 4 times.
<:s><:#286,9360>
<:#286,9360> Issue 179 Aug. 1991 : Continuation Article Abstract. Michael discusses latches and
<:#286,9360> VGA's undocumented Mode X.
<:s><:#286,9360>
<:#286,9360> Issue 181 Sept. 1991 : Continuation Article Abstract. Michael puts the moves on
<:#286,9360> animation using VGA's 256 colors.
<:s><:#286,9360>
<:#286,9360> Issue 184 Oct. 1991 : First of a continuing series covering 3-D animation using VGA's
<:s><:#286,9360> Mode X. This series is still ongoing
<:s><:#286,9360>
<:s><:#286,9360> (October 1992) Article Abstract. Michael moves into 3-D animation, starting with basic
<:s><:#286,9360> polygon fills and page flips.
<:s><:#286,9360>
<:s><:#286,9360>
<:#286,9360><+!><:X11,-32768;TOC 2 "WHAT IS MODE X ?">WHAT IS MODE X ?<-!>
<:#2002,9360>Mode X is a derivative of the VGA's standard mode 13h (320x200 256 color). It is a (family) of undocumented video modes that are created by tweaking the VGA's registers. The beauty of mode X is that it offers several benefits to the programmer: - Multiple g
raphic pages where mode 13h doesn't allowing for page flipping (also known as double buffering) and storage of images and data in offscreen video memory - A planar video ram organization which although more difficult to program, allows the VGA's plane-orie
nted hardware to be used to process pixels in parallel, improving performance by up to 4 times over mode 13h
<:s><:#286,9360>
<:s><:#286,9360>
<:#286,9360><+!><:X11,-32768;TOC 2 "WHAT IS A SPLIT SCREEN ?">WHAT IS A SPLIT SCREEN ?<-!>
<:#858,9360>A split screen is a hardware feature offered by the EGA and VGA video cards. A split screen is a mode of graphics operation in which the hardware splits the visual graphics screen horizontally and treats both halves as individual screens each starting at di
fferent locations in video RAM.
<:s><:#572,9360>The bottom half (which is usually referred to as the split screen) always starts at address A000:0000 but the top half's starting address is user definable.
<:s>The most common application of split screens in games is the status display in scrolling games. Split screens make this sort of game simpler to program because when the top half window is scrolled the programmer does not have to worry about redrawing the bo
ttom half.<:p<* >>
<:#286,9360><+!><:X11,-32768;TOC 2 "WHAT IS RLE?">WHAT IS RLE?<-!>
<:#1430,9360>RLE stands for RUN LENGTH ENCODING. It is a quick simple data compression scheme which is commonly used for image data compression or compression of any data. Although not the most efficient system, it is fast, which is why it is used in image storage syste
ms like PCX. This implementation is more efficient than the one used in PCX files because it uses 1 bit to identify a Run Length byte as opposed to two in PCX files, but more on this later.
<:s><:#286,9360>
<:s><:#572,9360>This set of functions can be used to implement your own compressed image file format or for example compress game maps for various levels etc. The uses are limited by your imagination.
<:s><:#286,9360>I opted for trading off PCX RLE compatibility for the improved compression efficiency.
<:s><:#286,9360>
<:s><:#286,9360>Here is how the data is un-compressed to give an idea of its structure.
<:s><:#286,9360> STEP 1 read a byte from the RLE compressed source buffer.
<:s><:#286,9360>
<:s><:#286,9360> STEP 2 If has its high bit is set then the lower 7 bits represent the number of times the next
<:s><:#286,9360> byte is to be repeated in the destination buffer. If the count (lower 7 bits) is zero
<:#286,9360> then we have finished decoding goto STEP 5 else goto STEP 4
<:s><:#286,9360>
<:s><:#286,9360> STEP 3 Read a data from the source buffer and copy it directly to the destination buffer.
<:s><:#286,9360> goto STEP 1
<:s><:#286,9360>
<:s><:#286,9360> STEP 4 Read a data byte from the source buffer and copy it to the destination buffer the
<:s><:#286,9360> number of times specified by step 2. goto STEP 1
<:s><:#286,9360>
<:s><:#286,9360> STEP 5 Stop, decoding done.
<:s><:#286,9360>
<:#286,9360>If the byte does not have the high bit set then the byte itself is transferred to the destination buffer.
<:#572,9360>Data bytes that have the high bit already set and are unique in the input stream are represented as a Run Length of 1 (i.e. 81 which includes high bit) followed by the data byte.
<:s><:#286,9360>
<:#1144,9360>If your original uncompressed data contains few consecutive bytes and most have high bit set (i.e. have values <;> 127) then your so called compressed data would require up to 2x the space of the uncompressed data, so be aware that the compression ratio is
extremely variable depending on the type of data being compressed.
<:s><:#286,9360>
<:s><:#858,9360>Apologies for this poor attempt at a description, but you can look up RLE in any good text. Alternatively, any text that describes the PCX file structure in any depth should have a section on RLE compression.
<:s><:#286,9360>
<:s><:#286,9360>
<:s><:p<* >>
<:#286,9360><+!>WHAT IS DOUBLE BUFFERING ?<:X11,-32768;TOC 2 "WHAT IS DOUBLE BUFFERING ?"><-!>
<:s><:#1430,9360>Double buffering (also known as page flipping) is the technique most often used to do animation. it requires hardware that is capable of displaying multiple graphics pages (or at least 2). Animation is achieved by drawing an image in the non visible screen
and then displaying the non visible screen. Once the page has been flipped the process starts again. The next frame of the animation is drawn on the non visible screen, the page is flipped again etc.
<:s><:#286,9360>
<:s><:#286,9360>
<:#286,9360><+!>WHAT IS TRIPLE BUFFERING?<-!><:X11,-32768;TOC 2 "WHAT IS TRIPLE BUFFERING?">
<:s><:#286,9360>
<:s><:#286,9360>
<:s><:#286,9360>
<:#286,9360><+!>WHAT IS A BEZIER CURVE?<:X11,-32768;TOC 2 "WHAT IS A BEZIER CURVE?"><-!>
<:#1144,9360>The Bezier curve was developedd by the French mathematician Pierre Bezier for the design of automobiles. This curve is defined by four points: two end points and two control points. The curve begins at one end point, ends at the other end point, and uses
the two control points to determine the curvature of the line.
<:s><:#286,9360>
<:s><:#286,9360><+!>
<:s><:#286,9360>
<:s><:#286,9360>
<+@><:s><+!><:p<* >>
<+B><:#286,9360><+!>The Care and Feeding of Compiled Masked Blits<:X11,-32768;TOC 2 "The Care and Feeding of Compiled Masked Blits"><-!>
<+B><:s><:#286,9360>by Matthew MacKenzie
<:s><:#286,9360>
<:s><:#286,9360>The XCBITMAP module is small, containing only three procedures:
<:s><:#293,9360> <+!><+">x_compile_bitmap<-"><-!> - Compiles your bitmap into native code which writes to the VGA
<:s><:#286,9360> screen in an X mode.
<:s><:#286,9360>
<:s><:#293,9360> <+!><+">x_put_cbitmap<-"><-!> - Converts X and Y coordinates into a location on the screen, sets up the
<:s><:#286,9360> necessary VGA registers, and executes the compiled bitmap as a
<:s><:#286,9360> subroutine.
<:s><:#286,9360>
<:s><:#293,9360> <+!><+">x_sizeof_cbitmap<-"><-!> - Takes a planar bitmap and returns an integer equal to the size of the
<:s><:#286,9360> compiled bitmap which the planar bitmap would produce. It is
<:s><:#293,9360> essentially a lobotomized version of <+!><+">x_compile_bitmap<-"><-!>, with all
<:s><:#286,9360> the code generation replaced with a size counter.
<:s><:#286,9360>
<:#2009,9360><+!><+">x_compile_bitmap<-"><-!> scans through a source bitmap and generates 8086 instructions to plot every non-zero pixel. It is designed to be used before the action begins rather than on-the-fly. The compiled bitmap contains no branches, and no referen
ce to the zero (transparent) pixels. Where two pixels are exactly four columns apart they are plotted with a single 16-bit store, and the VGA MAP_MASK register will be set at most four times. As a result your bitmap may run several times faster than a tradi
tional memory-to-VGA masked blit routine. There is no way to perform clipping on these bitmaps, or to plot a pixel of color zero.
<:s><:#286,9360>
<:#1151,9360><+!><+">x_compile_bitmap<-"><-!> works with bitmaps in the standard Xlib planar bitmap format. On a time scale of 60 frames per second, it is actually relatively slow. Since a compiled bitmap is relocatable you may just want to have it saved to disk, and no
t include the source bitmap in your program at all.
<:s><:#286,9360>
<:s><:#286,9360>The source bitmap format is an array of bytes, a little like this:
<:s><:#572,9360>This is actually a linear bitmap, which is the wrong format for compilation, but is easier on human eyes. Use the module XBMTOOLS to convert linear bitmaps into planar bitmaps, and vice-versa.
<:s><:#286,9360>
<:s><:#286,9360>To compile this image for a mode 360 pixels (90 byte columns) across:
<:#286,9360> char planar_eye<[>4*7 + 2];
<:#286,9360> char far * EyeSize;
<:#286,9360> (void) x_bm_to_pbm((char far *) eye, (char far *) planar_eye);
<:s><:#2016,9360>Notice that both buffers must exist beforehand. Since<+!><+"> x_compile_bitmap<-"><-!> returns the size of the compiled code, in bytes, you can reallocate the bitmap immediately to the right size if using
<+!><+">x_sizeof_cbitmap<-"><-!> seems inconvenient (reallocation may even be faster, though using the function is cleaner). The pointers are 32-bit because compiled bitmaps take so much space: they are at one end of the speed-versus-memory spectrum. A good
rule of thumb is to allocate (3.5 * buffer-height * buffer-width) + 25 bytes (rounding up), then pare your bitmap down when you find out how much space you've actually used.
<:s><:#286,9360>
<:s><:#1430,9360>Since the compiled bitmap has to fit within one segment of memory, it cannot contain more than about 19,000 pixels. This will not be a limitation for most sane programmers. If you are not a sane programmer try splitting your huge, unwieldy image up into sma
ller parts. You can use the same gigantic bitmap if you divide it into horizontal slices for compilation. For that matter, dividing the source up that way will let you use a source bitmap large than 64K, which is an even sicker idea.
<:s><:#286,9360>
<:#1430,9360>Back to business. A bitmap is compiled for only one width of screen. If you are using a logical screen larger than your physical screen, call the bitmap compiler with the logical width. The important thing is the number of bytes per line. Notice that you do
not have to be in a graphics mode to use this routine.This allows you to develop and compile bitmaps separately, with whatever utility programs you might cook up.
<:#286,9360>
<:s><:#293,9360>The final function is<+!><+"> x_put_cbitmap<-"><-!>.
<:s><:#286,9360>To plot our eye at (99, 4), on the page which starts at location 0:
<:s><:#579,9360>This function depends on the global variable <+">ScrnLogicalByteWidth<-"> from the module XMAIN, which should be the same number as the column parameter you used to compile your bitmap.
<:s><:#286,9360>
<:#858,9360>The XCBITMAP module supports memory-to-VGA blits only. XLIB also includes non-masking routines which can quickly save and restore the background screen behind your bitmap, using fast string operations.
<:s><:#286,9360>
<:#858,9360>This module is part of the XLIB package, and is in the public domain. If you write something which uses it, though, please send me a copy as a courtesy if for no other reason so I can tilt my chair back and reflect that it may have been worth the trouble a
fter all.
<:s><:#286,9360>
<+B><:#286,9360>The included program DEMO2.C demonstrates the performance difference between planar bitmap
<+@><:s> masked blits and compiled bitmap blits.<:p<* >>
<+B><:#286,9360><+!>Blits and Pieces<:X11,-32768;TOC 2 "Blits and Pieces"><-!>
<+B><:s><:#286,9360>by Matthew MacKenzie
<:s><:#286,9360>
<:s><:#572,9360>The XCLIPPBM module contains clipping versions of two of the three routines in the XPBITMAP module:
<:s><:#286,9360>
<:s><:#293,9360><+!><+">x_clip_pbm<-"><-!> - transfers a planar bitmap to the screen, clipping off any part outside a bounding box.
<:#293,9360><+!><+">x_clip_masked_pbm<-"><-!> - does the same thing, but transfers only non-zero pixels.
<:s><:#286,9360>
<:s><:#572,9360>The planar bitmap format is described elsewhere. Here we will look at the clipping itself, since it is the only distinguishing feature of this module.
<:s><:#286,9360>
<:#872,9360>The bounding box is made up of four integers,<+"> TopBound, BottomBound, LeftBound,<-"> and
<+">RightBound<-">. <+#>Unlike most global variables in XLIB, these are meant to be written to<-#>. In fact, they start out uninitialized.
<+#>Be sure to set them before you try plotting any clipped bitmaps<-#>.
<:#1430,9360>Note that these are not the same variables which are used in the other clipping modules in XLIB. This is because the two systems are incompatible: the other modules clip horizontally to columns while this one clips to pixels. As you might have guessed, tho
se functions and these were developed in different hemispheres of the planet. If it's any consolation, this does give you two independent bounding boxes to futz with, should the mood visit you.
<:s><:#286,9360>
<:#1158,9360>Bitmaps cannot go outside the perimeter of the bounding box, but they can overlap it. If
<+">TopBound<-"> equals <+">BottomBound<-">, for example, a horizontal slice of a bitmap may still be plotted. It is safe to turn the box "inside out" to make sure nothing will be plotted. This is the first thing each routine checks for.
<:s><:#286,9360>
<:s><:#286,9360>To plot a bitmap, minus its zero pixels, minus anything outside the bounding box:
<:s><:#286,9360>
<:s><:#293,9360><+!><+">x_clip_masked_pbm<-"><-!> (int X, int Y, int ScreenOffs, char far * Bitmap);
<:s><:#286,9360>
<:#1723,9360>The arguments are in the same order as those for <+!><+">x_put_masked_pbm<-"><-!> in the module XPBITMAP. The bounding box is relative to the given ScreenOffs ). This lets you perform page flipping without worrying about what screen you are clipping to it'
s always the current screen. The bitmap itself, of course, is not affected; clipping is performed on-the-fly. Both functions return an integer which indicates whether any part of the bitmap was inside the bounding box. If the entire bitmap was outside, a 1
is returned; otherwise, a 0.
<:s><:#286,9360>
<:s>The third function in XPBITMAP, for which this module has no equivalent, copies from video RAM to system RAM. The absence of such a routine may seem at first like a disadvantage but this, like so many things in this life, is an illusion. You can use the un
clipped routine, and clip the bitmap when you want to plot it back onto the screen.<:p<* >>
<+B><:#286,9360><+!>Wheel Have to See About That<:X11,-32768;TOC 2 "Wheel Have to See About That"><-!>
<+B><:s><:#286,9360>by Matthew MacKenzie
<:s><:#286,9360>
<:s><:#286,9360>
<:s><:#286,9360>The XCIRCLE module contains two functions, neither of which should be a big mystery:
<:#293,9360> <+!><+">x_circle<-"><-!>, oddly enough, draws a circle.
<:#293,9360> <+!><+">x_filled_circle<-"><-!> does too, only the circle is filled (in some libraries this is called a disc).
<:s><:#286,9360>
<:#3725,9360>The word `circle' here refers to a round thing which is as many pixels tall as across. It only looks like a circle in 320x240 mode, the original mode X, and in 376x282 mode. In both functions, the circle is specified by the coordinates of the upper-left-han
d corner of the smallest box which holds it, and the diameter. Some circle functions have you specify a center point; this system is kind of odd because a circle with an even diameter does not have a particular pixel for a center. Every circle, on the other
hand, has a box with an upper-left corner. <+#>No bounds are checked<-#>. A diameter of zero will draw nothing, and a negative diameter will blow your VGA board into hundreds of thousands of tiny little smoldering fragments. Neither function supports clipp
ing. The calculation of the circle is based on an algorithm described by Michael P. Lindner in a letter to the editor on page 8 of
<+#>Dr. Dobb's Journal <-#>#169 (October 1990). The algorithm has been rearranged to allow drawing and moving the plots in the eight octants to be performed in one step, so that each pixel does not have to be loaded into the CPU twice.
<+!><+"> x_filled_circle<-"><-!> does not take advantage of this optimization because it handles different parts of each plot at different times.