home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / books / progem / raster.6 < prev    next >
Text File  |  1986-11-01  |  29KB  |  617 lines

  1.     Permission to reprint or excerpt is granted only if the following line
  2.     appears at the top of the article:
  3.  
  4.       ANTIC PUBLISHING INC., COPYRIGHT 1985.  REPRINTED BY PERMISSION.
  5.  
  6.  
  7.  
  8.     Professional GEM  by Tim Oren
  9.     Column #6 - Raster Operations
  10.  
  11.  
  12.     SEASONS GREETINGS!
  13.  
  14.        This  is  the  Yuletide  installment  of  ST  PRO  GEM,  devoted to
  15.     explaining  the  raster,  or  "bit-blit" portion of the Atari ST's VDI
  16.     functions.
  17.  
  18.        Please  note  that  this  is  NOT  an  attempt to show how to write
  19.     directly  to  the  video memory, although you will be able to deduce a
  20.     great deal from the discussion.
  21.  
  22.        As  usual,  there is a download with this column.  You will find it
  23.     in ATARI16 (PCS-58) in DL3 under the name of GEMCL6.C.
  24.  
  25.  
  26.     DEFINING TERMS
  27.  
  28.        To  understand  VDI  raster  operations, you need to understand the
  29.     jargon  used  to  describe them.  (Many programmers will be tempted to
  30.     skip  this  section  and  go directly to the code.  Please don't do it
  31.     this time: Learning the jargon is the larger half of understanding the
  32.     raster operations!)
  33.  
  34.        In VDI terms a raster area is simply a chunk of contiguous words of
  35.     memory,  defining a bit image.  This chunk is called a "form".  A form
  36.     may reside in the ST's video map area or it may be in the data area of
  37.     your application.  Forms are roughly analogous to "blits" or "sprites"
  38.     on other systems.  (Note, however, that there is no sprite hardware on
  39.     the ST.)
  40.  
  41.        Unlike  other  systems,  there is NO predefined organization of the
  42.     raster  form.   Instead, you determine the internal layout of the form
  43.     with  an  auxiliary  data  structure  called  the MFDB, or Memory Form
  44.     Definition  Block.  Before going into the details of the MFDB, we need
  45.     to  look at the various format options.  Their distinguishing features
  46.     are  monochrome  vs. color, standard vs. device-specific and even-word
  47.     vs. fringed.
  48.  
  49.  
  50.     MONOCHROME VS. COLOR
  51.  
  52.        Although  these  terms  are  standard,  it  might  be better to say
  53.     "single-color  vs. multi-color".  What we are actually defining is the
  54.     number  of bits which correspond to each dot, or pixel, on the screen.
  55.     In  the ST, there are three possible answers. The high-resolution mode
  56.     has one bit per pixel, because there is only one "color": white.
  57.  
  58.        In the medium resolution color mode, there are four possible colors
  59.     for each pixel.  Therefore, it takes two bits to represent each dot on
  60.     the  screen.   (The  actual  colors which appear are determined by the
  61.     settings of the ST's pallette registers.)
  62.  
  63.        In  the  low  resolution  color mode, sixteen colors are generated,
  64.     requiring  four bits per pixel.  Notice that as the number of bits per
  65.     pixel  has  been doubled for each mode, so the number of pixels on the
  66.     screen  has  been  halved:  640  by 400 for monochrome, 640 by 200 for
  67.     medium-res, and 320 by 200 by low-res.  In this way the ST always uses
  68.     the same amount of video RAM: 32K.
  69.  
  70.        Now we have determined how many bits are needed for each pixel, but
  71.     not  how they are laid out within the form.  To find this out, we have
  72.     to see whether the form is device-dependent or not.
  73.  
  74.  
  75.     STANDARD VS. DEVICE-SPECIFIC FORMAT
  76.  
  77.        The  standard  raster form format is a constant layout which is the
  78.     same  for  all  GEM  systems.   A device-specific form is one which is
  79.     stored in the internal format of a particular GEM system.  Just as the
  80.     ST  has  three  different  screen  modes,  so  it  has three different
  81.     device-specific  form  formats.   We will look at standard form first,
  82.     then the ST-specific forms.
  83.  
  84.        First,  it's  reasonable  to ask why a standard format is used. Its
  85.     main function is to establish a portability method between various GEM
  86.     systems.   For  instance, an icon created in standard format on an IBM
  87.     PC  GEM  setup  can be moved to the ST, or a GEM Paint picture from an
  88.     AT&T 6300 could be loaded into the ST version of Paint.
  89.  
  90.        The  standard  format  has some uses even if you only work with the
  91.     ST,  because  it gives a method of moving your application's icons and
  92.     images  amongst  the  three different screen modes.  To be sure, there
  93.     are  limits  to  this.  Since there are different numbers of pixels in
  94.     the  different  modes,  an icon built in the high-resolution mode will
  95.     appear  twice  as  large  in  low-res mode, and would appear oblong in
  96.     medium-res.   (You  can  see  this effect in the ST Desktop's icons.)
  97.     Also,  colors  defined  in  the  lower  resolutions will be useless in
  98.     monochrome.
  99.  
  100.        The  standard  monochrome format uses a one-bit to represent black,
  101.     and  uses a zero for white.  It is assumed that the form begins at the
  102.     upper left of the raster area, and is written a word at a time left to
  103.     right  on  each row, with the rows being output top to bottom.  Within
  104.     each word, the most significant bit is the left-most on the screen.
  105.  
  106.        The  standard  color  form  uses  a  storage  method  called "color
  107.     planes".  The high-order bits for all of the pixels are stored just as
  108.     for  monochrome, followed by the next-lowest bit in another contiguous
  109.     block,  and  so  on  until  all  of the necessary color bits have been
  110.     stored.
  111.  
  112.        For  example,  on  a 16-color system, there would be four different
  113.     planes.   The  color  of  the  upper-leftmost bit in the form would be
  114.     determined  by  concatenating  the high-order bit in the first word of
  115.     each plane of the form.
  116.  
  117.        The  system  dependent  form  for  the ST's monochrome mode is very
  118.     simple: it is identical to the standard form!  This occurs because the
  119.     ST   uses  a  "reverse-video"  setup  in  monochrome  mode,  with  the
  120.     background set to white.
  121.  
  122.        The video organization of the ST's color modes is more complicated.
  123.     It  uses an "interleaved plane" system to store the bits which make up
  124.     a  pixel.   In  the  low-resolution  mode, every four words define the
  125.     values of 16 pixels.  The high-order bits of the four words are merged
  126.     to  form  the  left-most pixel, followed by the next lower bit of each
  127.     word,  and  so  on.   This  method  is called interleaving because the
  128.     usually  separate  color  planes  described  above  have been shuffled
  129.     together in memory.
  130.  
  131.        The  organization  of the ST's medium-resolution mode is similar to
  132.     low-res,  except  the  only  two words are taken at a time.  These are
  133.     merged to create the two bits needed to address four colors.
  134.  
  135.        You  should  note  that  the  actual color produced by a particular
  136.     pixel value is NOT fixed.  The ST uses a color remapping system called
  137.     a  palette.   The  pixel value in memory is used to address a hardware
  138.     register  in  the  palette  which contains the actual RGB levels to be
  139.     sent to the display.  Programs may set the palette registers with BIOS
  140.     calls,  or the user may alter its settings with the Control Panel desk
  141.     accessory.  Generally, palette zero (background) is left as white, and
  142.     the highest numbered palette is black.
  143.  
  144.  
  145.     EVEN-WORD VS. FRINGES
  146.  
  147.        A  form always begins on a word boundary, and is always stored with
  148.     an  integral  number of words per row.  However, it is possible to use
  149.     only  a  portion  of  the  final  word.  This partial word is called a
  150.     "fringe".   If,  for instance, you had a form 40 pixels wide, it would
  151.     be  stored  with  four  words per row: three whole words, and one word
  152.     with the eight pixel fringe in its upper byte.
  153.  
  154.  
  155.     MFDBs
  156.  
  157.        Now  we  can  intelligently  define  the elements of the MFDB.  Its
  158.     exact  C  structure  definition  will  be  found  in the download. The
  159.     fd_nplanes  entry  determines  the  color  scheme:  a  value of one is
  160.     monochrome,  more than one denotes a color form.  If fd_stand is zero,
  161.     then the form is device-specific, otherwise it is in standard format.
  162.  
  163.        The  fd_w and fd_h fields contain the pixel width and height of the
  164.     form  respectively.   Fd_wdwidth  is  the width of a row in words.  If
  165.     fd_w  is  not exactly equal to sixteen times fd_wdwidth, then the form
  166.     has a fringe.
  167.  
  168.        Finally,  fd_addr  is the 32-bit memory address of the form itself.
  169.     Zero is a special value for fd_addr.  It denotes that this MFDB is for
  170.     the video memory itself.  In this case, the VDI substitutes the actual
  171.     address  of  the  screen,  and it ignores ALL of the other parameters.
  172.     They  are  replaced  with  the  size of the whole screen and number of
  173.     planes   in  the  current  mode,  and  the  form  is  (of  course)  in
  174.     device-specific format.
  175.  
  176.        This  implies  that  any  MFDB  which points at the screen can only
  177.     address  the entire screen.  This is not a problem, however, since the
  178.     the  VDI  raster calls allow you to select a rectangular region within
  179.     the  form.   (A  note  to  advanced  programmers: If this situation is
  180.     annoying, you can retrieve the address of the ST's video area from low
  181.     memory,  add  an  appropriate  offset, and substitute it into the MFDB
  182.     yourself to address a portion of the screen.)
  183.  
  184.  
  185.     LET'S OPERATE
  186.  
  187.        Now we can look at the VDI raster operations themselves.  There are
  188.     actually  three:  transform  form, copy raster opaque, and copy raster
  189.     transparent.   Both  copy  raster  functions  can perform a variety of
  190.     logic operatoins during the copy.
  191.  
  192.  
  193.     TRANSFORM FORM
  194.  
  195.        The  purpose  of  this operation is to change the format of a form:
  196.     from standard to device-specific, or vice-versa.  The calling sequence
  197.     is:
  198.  
  199.         vr_trnfm(vdi_handle,source,dest);
  200.  
  201.     where source and dest are each pointers to MFDBs.  They ARE allowed to
  202.     be  the  same.   Transform form checks the fd_stand flag in the source
  203.     MFDB,  toggles  it  and  writes  it  into  the  destination MFDB after
  204.     rewriting the form itself.  Note that transform form CANNOT change the
  205.     number  of color planes in a form: fd_nplanes must be identical in the
  206.     two MFDBs.
  207.  
  208.        If  you  are writing an application to run on the ST only, you will
  209.     probably  be  able to avoid transform form entirely.  Images and icons
  210.     are  stored  within  resources  as  standard forms, but since they are
  211.     monochrome, they will work "as is" with the ST.
  212.  
  213.        If  you  may  want to move your program or picture files to another
  214.     GEM  system,  then you will need transform form.  Screen images can be
  215.     transformed  to  standard  format  and stored to disk.  Another system
  216.     with  the  same  number  of color planes could the read the files, and
  217.     transform the image to ITS internal format with transform form.
  218.  
  219.        A  GEM  application  which  will be moved to other systems needs to
  220.     contain  code  to  transform the images and icons within its resource,
  221.     since standard and device-specific formats will not always coincide.
  222.  
  223.        If  you  are  in this situation, you will find several utilities in
  224.     the  download  which  you  can  use  to  transform  G_ICON and G_IMAGE
  225.     objects.  There  is  also  a routine which may be used with map_tree()
  226.     from the last column in order to transform all of the images and icons
  227.     in a resource tree at once.
  228.  
  229.  
  230.     COPY RASTER OPAQUE
  231.  
  232.        This  operation  copies  all  or  part  of the source form into the
  233.     destination  form.   Both  the source and destination forms must be in
  234.     device-specific  form.   Copy  raster opaque is for moving information
  235.     between  "like"  forms,  that  is,  it  can  copy  from  monochrome to
  236.     monochrome,  or  between  color forms with the same number of planes.
  237.     The calling format is:
  238.  
  239.         vro_cpyfm(vdi_handle, mode, pxy, source, dest);
  240.  
  241.        As  above,  the  source  and  dest parameters are pointers to MFDBs
  242.     (which in turn point to the actual forms).  The two MFDBs may point to
  243.     memory  areas  which  overlap.  In this case, the VDI will perform the
  244.     move in a non-destructive order.  Mode determines how the pixel values
  245.     in  the source and destination areas will be combined.  I will discuss
  246.     it separately later on.
  247.  
  248.        The  pxy  parameter  is  a pointer to an eight-word integer array.
  249.     This  array  defines the area within each form which will be affected.
  250.     Pxy[0]  and  pxy[1]  contain, respectively, the X and Y coordinates of
  251.     the  upper  left  corner  of the source rectangle.  These are given as
  252.     positive  pixel displacements from the upper left of the form.  Pxy[2]
  253.     and  pxy[3]  contain  the X and Y displacements for the lower right of
  254.     the source rectangle.
  255.  
  256.        Pxy[4] through pxy[7] contain the destination rectangle in the same
  257.     format.  Normally, the destination and source should be the same size.
  258.     If  not,  the  size  given  for the source rules, and the whole are is
  259.     transferred beginning at the upper left given for the destination.
  260.  
  261.        This  all  sounds  complex,  but  is  quite  simple in many cases.
  262.     Consider  an example where you want to move a 32 by 32 pixel area from
  263.     one  part  of the display to another.  You would need to allocate only
  264.     one MFDB, with a zero in the fd_addr field.  The VDI will take care of
  265.     counting color planes and so on.  The upper left raster coordinates of
  266.     the  source  and  destination  rectangles  go  into pxy[0], pxy[1] and
  267.     pxy[4],  pxy[5]  respectively.  You add 32 to each of these values and
  268.     insert the results in the corresponding lower right entries, then make
  269.     the  copy  call  using the same MFDB for both source and destination.
  270.     The VDI takes care of any overlaps.
  271.  
  272.  
  273.     COPY RASTER TRANSPARENT
  274.  
  275.        This  operation  is  used  for  copying from a monochrome form to a
  276.     color  form.   It is called transparent because it "writes through" to
  277.     all   of   the   color  planes.   Again,  the  forms  need  to  be  in
  278.     device-specific form.  The calling format is:
  279.  
  280.         vrt_cpyfm(vdi_handle, mode, pxy, source, dest, color);
  281.  
  282.        All  of  the  parameters  are  the same as copy opaque, except that
  283.     color has been added.  Color is a pointer to a two word integer array.
  284.     Color[0]  contains  the  color  index  which  will  be used when a one
  285.     appears  in  the  source form, and color[1] contains the index for use
  286.     when a zero occurs.
  287.  
  288.        Incidentally,  copy  transparent is used by the AES to draw G_ICONs
  289.     and  G_IMAGEs  onto  the screen.  This explains why you do not need to
  290.     convert them to color forms yourself.
  291.  
  292.        (A  note  for  advanced  VDI programmers: The pxy parameter in both
  293.     copy  opaque  and  transparent  may  be  given  in  normalized  device
  294.     coordinates  (NDC)  if  the workstation associated with vdi_handle was
  295.     opened for NDC work.)
  296.  
  297.  
  298.     THE MODE PARAMETER
  299.  
  300.        The  mode variable used in both of the copy functions is an integer
  301.     with  a  value between zero and fifteen.  It is used to select how the
  302.     copy   function  will  merge  the  pixel  values  of  the  source  and
  303.     destination  forms.   The  complete table of functions is given in the
  304.     download.   Since  a  number  of  these are of obscure or questionable
  305.     usefulness, I will only discuss the most commonly used modes.
  306.  
  307.  
  308.     REPLACE MODE
  309.  
  310.        A  mode  of 3 results in a straight-forward copy: every destination
  311.     pixel is replaced with the corresponding source form value.
  312.  
  313.  
  314.     ERASE MODE
  315.  
  316.        A  mode  value  of  4  will  erase  every  destination  pixel which
  317.     corresponds  to  a  one in the source form.  (This mode corresponds to
  318.     the  "eraser" in a Paint program.)  A mode value of 1 will erase every
  319.     destination pixel which DOES NOT correspond to a one in the source.
  320.  
  321.  
  322.     XOR MODE
  323.  
  324.        A mode value of 6 will cause the destination pixel to be toggled if
  325.     the  corresponding  source bit is a one. This operation is invertable,
  326.     that is, executing it again will reverse the effects.  For this reason
  327.     it  is  often used for "software sprites" which must be shown and then
  328.     removed  from the screens.  There are some problems with this in color
  329.     operations, though - see below.
  330.  
  331.  
  332.     TRANSPARENT MODE
  333.  
  334.        Don't  confuse this term with the copy transparent function itself.
  335.     In  this  case  it  simply  means  that  ONLY those destination pixels
  336.     corresponding  with  ones  in  the source form will be modified by the
  337.     operation.   If  a  copy  transparent is being performed, the value of
  338.     color[0]  is  substituted for each one bit in the source form.  A mode
  339.     value of 7 selects transparent mode.
  340.  
  341.  
  342.     REVERSE TRANSPARENT MODE
  343.  
  344.        This  is  like  transparent mode except that only those destination
  345.     pixels  corresponding  to  source  ZEROS  are  modified.   In  a  copy
  346.     transparent,  the  value of color[1] is substituted for each zero bit.
  347.     Mode 13 selects reverse transparent.
  348.  
  349.  
  350.     THE PROBLEM OF COLOR
  351.  
  352.        I  have  discussed  the  various modes as if they deal with one and
  353.     zero  pixel  values  only.   This  is exactly true when both forms are
  354.     monochrome, but is more complex when one or both are color forms.
  355.  
  356.        When  both  forms are color, indicating that a copy opaque is being
  357.     performed,  then  the  color  planes are combined bit-by-bit using the
  358.     rule  for  that  mode.   That  is,  for  each corresponding source and
  359.     destination  pixel,  the VDI extracts the top order bits and processes
  360.     them,  then  operates  on the next lower bit, and so on, stuffing each
  361.     bit  back  into  the  destination  form  as  the copy progresses.  For
  362.     example,  an XOR operation on pixels valued 7 and 10 would result in a
  363.     pixel value of 13.
  364.  
  365.        In  the  case of a copy transparent, the situation is more complex.
  366.     The  source  form  consists of one plane, and the destination form has
  367.     two  or  more.  In order to match these up, the color[] array is used.
  368.     Whenever  a one pixel is found, the value of color[0] is extracted and
  369.     used  in the bit-by-bit merge process described in the last paragraph.
  370.     When  a  zero  is  found,  the  value  of  color[1] is merged into the
  371.     destination form.
  372.  
  373.        As  you can probably see, a raster copy using a mode which combines
  374.     the  source and destination can be quite complex when color planes are
  375.     used!   The  situation is compounded on the ST, since the actual color
  376.     values  may  be  remapped  by the palette at any time.  In many cases,
  377.     just  using  black  and  white  in color[] may achieve the effects you
  378.     desire.   If need to use full color, experimentation is the best guide
  379.     to what looks good on the screen and what is garish or illegible.
  380.  
  381.  
  382.     OPTIMIZING RASTER OPERATIONS
  383.  
  384.        Because  the  VDI  raster functions are extremely generalized, they
  385.     are  also  slower than hand-coded screen drivers which you might write
  386.     for   your   own  special  cases.   If  you  want  to  speed  up  your
  387.     application's  raster  operations  without  writing  assembly language
  388.     drivers,  the  following  hints  will  help  you  increase  the  VDI's
  389.     performance.
  390.  
  391.  
  392.     AVOID MERGED COPIES
  393.  
  394.        These are copy modes, such as XOR, which require that words be read
  395.     from  the  destination  form.   This extra memory access increases the
  396.     running time by up to fifty percent.
  397.  
  398.  
  399.     MOVE TO CORRESPONDING PIXELS
  400.  
  401.        The  bit position within a word of the destination rectangle should
  402.     correspond  with the bit position of the source rectangle's left edge.
  403.     For  instance,  if  the  source's  left edge is one pixel in, then the
  404.     destination's  edge  could be at one, seventeen, thirty-three, and so.
  405.     Copies which do not obey this rule force the VDI to shift each word of
  406.     the form as it is moved.
  407.  
  408.  
  409.     AVOID FRINGES
  410.  
  411.        Put  the  left  edge of the source and destination rectangles on an
  412.     even  word  boundary, and make their widths even multiples of sixteen.
  413.     The VDI then does not have to load and modify partial words within the
  414.     destination forms.
  415.  
  416.  
  417.     USE ANOTHER METHOD
  418.  
  419.        Sometimes  a  raster operation is not the fastest way to accomplish
  420.     your  task.   For instance, filling a rectangle with zeros or ones may
  421.     be accomplished by using raster copy modes zero and fifteen, but it is
  422.     faster  to use the VDI v_bar function instead.  Likewise, inverting an
  423.     area  on the screen may be done more quickly with v_bar by using BLACK
  424.     in  XOR  mode.  Unfortunately, v_bar cannot affect memory which is not
  425.     in the video map, so these alternatives do not always work.
  426.  
  427.  
  428.     FEEDBACK RESULTS
  429.  
  430.        The  results  of  the  poll  on  keeping  or  dropping  the  use of
  431.     portability  macros  are in.  By a slim margin, you have voted to keep
  432.     them.   The vote was close enough that in future columns I will try to
  433.     include  ST-only  versions  of  routines  which  make heavy use of the
  434.     macros.   C  purists and dedicated Atarians may then use the alternate
  435.     code.
  436.  
  437.  
  438.     THE NEXT QUESTION
  439.  
  440.        This  time  I'd like to ask you to drop by the Feedback Section and
  441.     tell me whether the technical level of the columns has been:
  442.  
  443.          A)  Too hard!  Who do you think we are, anyway?
  444.          B)  Too easy!  Don't underestimate Atarians.
  445.          C)  About right, on the average.
  446.  
  447.        If  you  have  the  time, it would also help to know a little about
  448.     your   background,  for  instance,  whether  you  are  a  professional
  449.     programmer,  how  long  you have been computing, if you owned an 8-bit
  450.     Atari, and so on.
  451.  
  452.  
  453.     COMING UP SOON
  454.  
  455.        The next column will deal with GEM menus: How they are constructed,
  456.     how  to  decipher  menu  messages,  and  how to change menu entries at
  457.     run-time.   The  following  issue will contain more feedback response,
  458.     and a discussion on designing user interfaces for GEM programs.
  459.  
  460.  
  461.  
  462.  
  463. >>>>>>>>>>>>>>>>>>>>>>>>>>>>> MFDB Structure <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  464.  
  465.                     /* Memory Form Definition Block */
  466. typedef struct fdbstr
  467. {
  468.      long         fd_addr;        /* Form address               */
  469.      int          fd_w;           /* Form width in pixels       */
  470.      int          fd_h;           /* Form height in pixels      */
  471.      int          fd_wdwidth;     /* Form width in memory words */
  472.      int          fd_stand;       /* Standard form flag         */
  473.      int          fd_nplanes;     /* Number of color planes     */
  474.      int          fd_r1;          /* Dummy locations:           */
  475.      int          fd_r2;          /*  reserved for future use   */
  476.      int          fd_r3;
  477. } MFDB;
  478.  
  479.  
  480. >>>>>>>>>>>>>>>>>>>>>>> Resource Transform Utilities <<<<<<<<<<<<<<<<<<<<<
  481.  
  482. /*------------------------------*/
  483. /*          vdi_fix             */
  484. /*------------------------------*/
  485.      VOID
  486. vdi_fix(pfd, theaddr, wb, h)          /* This routine loads the MFDB  */
  487.      MFDB          *pfd;              /* Input values are the MFDB's  */
  488.      LONG          theaddr;           /* address, the form's address, */
  489.      WORD          wb, h;             /* the form's width in bytes,   */
  490.      {                                /* and the height in pixels     */
  491.      pfd->fww = wb >> 1;
  492.      pfd->fwp = wb << 3;
  493.      pfd->fh = h;
  494.      pfd->np = 1;                     /* Monochrome assumed           */
  495.      pfd->mp = theaddr;
  496.      }
  497.  
  498.  
  499. /*------------------------------*/
  500. /*          vdi_trans           */
  501. /*------------------------------*/
  502.      WORD
  503. vdi_trans(saddr, swb, daddr, dwb, h)      /* Transform the standard form  */
  504.      LONG          saddr;                 /* pointed at by saddr and      */
  505.      UWORD          swb;                  /* store in the form at daddr   */
  506.      LONG          daddr;                 /* Byte widths and pixel height */
  507.      UWORD          dwb;                  /* are given                    */
  508.      UWORD          h;
  509.      {
  510.      MFDB          src, dst;              /* These are on-the-fly MFDBs   */
  511.  
  512.      vdi_fix(&src, saddr, swb, h);        /* Load the source MFDB         */
  513.      src.ff = TRUE;                       /* Set it's std form flag       */
  514.  
  515.      vdi_fix(&dst, daddr, dwb, h);        /* Load the destination MFDB    */
  516.      dst.ff = FALSE;                      /* Clear the std flag           */
  517.      vr_trnfm(vdi_handle, &src, &dst );   /* Call the VDI                 */
  518.      }
  519.  
  520.  
  521. /*------------------------------*/
  522. /*        trans_bitblk          */
  523. /*------------------------------*/
  524.      VOID
  525. trans_bitblk(obspec)                /* Transform the image belonging  */
  526.      LONG     obspec;               /* to the bitblk pointed to by    */
  527.      {                              /* obspec.  This routine may also */
  528.      LONG     taddr;                /* be used with free images       */
  529.      WORD     wb, hl;
  530.  
  531.      if ( (taddr = LLGET(BI_PDATA(obspec))) == -1L)
  532.           return;                   /* Get and validate image address */
  533.      wb = LWGET(BI_WB(obspec));     /* Extract image dimensions       */
  534.      hl = LWGET(BI_HL(obspec));
  535.      vdi_trans(taddr, wb, taddr, wb, hl);     /* Perform a transform  */
  536.      }                                        /* in place             */
  537.  
  538.  
  539. /*------------------------------*/
  540. /*         trans_obj            */
  541. /*------------------------------*/
  542.      VOID
  543. trans_obj(tree, obj)               /* Examine the input object.  If  */
  544.      LONG     tree;                /* it is an icon or image, trans- */
  545.      WORD     obj;                 /* form the associated raster     */
  546.      {                             /* forms in place.                */
  547.      WORD     type, wb, hl;        /* This routine may be used with  */
  548.      LONG     taddr, obspec;       /* map_tree() to transform an     */
  549.                                    /* entire resource tree           */
  550.  
  551.      type = LLOBT(LWGET(OB_TYPE(obj)));            /* Load object type */
  552.      if ( (obspec = LLGET(OB_SPEC(obj))) == -1L)   /* Load and check   */
  553.           return (TRUE);                           /* ob_spec pointer  */
  554.      switch (type) {
  555.           case G_IMAGE:
  556.                trans_bitblk(obspec);               /* Transform image  */
  557.                return (TRUE);
  558.           case G_ICON:                             /* Load icon size   */
  559.                hl = LWGET(IB_HICON(obspec));
  560.                wb = (LWGET(IB_WICON(obspec)) + 7) >> 3;
  561.                                                   /* Transform data   */
  562.                if ( (taddr = LLGET(IB_PDATA(obspec))) != -1L)
  563.                     vdi_trans(taddr, wb, taddr, wb, hl);
  564.                                                   /* Transform mask   */
  565.                if ( (taddr = LLGET(IB_PMASK(obspec))) != -1L)
  566.                     vdi_trans(taddr, wb, taddr, wb, hl);
  567.                return (TRUE);
  568.           default:
  569.                return (TRUE);
  570.           }
  571.      }
  572.  
  573.  
  574. >>>>>>>>>>>>>>>>>>>  Macro definitions for the code above <<<<<<<<<<<<<<<<<<
  575.  
  576. #define BI_PDATA(x)     (x)
  577. #define BI_WB(x)        (x + 4)
  578. #define BI_HL(x)        (x + 6)
  579. #define OB_TYPE(x)      (tree + (x) * sizeof(OBJECT) + 6)
  580. #define OB_SPEC(x)      (tree + (x) * sizeof(OBJECT) + 12)
  581. #define IB_PMASK(x)     (x)
  582. #define IB_PDATA(x)     (x + 4)
  583. #define IB_WICON(x)     (x + 22)
  584. #define IB_HICON(x)     (x + 24)
  585.  
  586.  
  587. >>>>>>>>>>>>>>>>>>>>>>>>>>> VDI Copy Mode Table <<<<<<<<<<<<<<<<<<<<<<<<<<<<
  588.  
  589. Symbols: N = new destination pixel value (0 or 1)
  590.          D = old destination pixel value (0 or 1)
  591.          S = source pixel value (0 or 1)
  592.          ~ = Boolean not (inversion)
  593.          & = Boolean and
  594.          | = Boolean or
  595.          ^ = Boolean xor (exclusive-or)
  596.  
  597. Mode Number     Action
  598. -----------     ------
  599.     0          N = 0          (USE V_BAR INSTEAD)
  600.     1          N = S & D
  601.     2          N = S & ~D
  602.     3          N = S          (REPLACE)
  603.     4          N = ~S & D     (ERASE)
  604.     5          N = D          (USELESS)
  605.     6          N = S ^ D      (XOR)
  606.     7          N = S | D      (TRANSPARENT)
  607.     8          N = ~ (S | D)
  608.     9          N = ~ (S ^ D)
  609.    10          N = ~D         (USE V_BAR INSTEAD)
  610.    11          N = S | ~D
  611.    12          N = ~S
  612.    13          N = ~S | D     (REVERSE TRANSPARENT)
  613.    14          N = ~ (S & D)
  614.    15          N = 1          (USE V_BAR INSTEAD)
  615.  
  616. >>>>>>>>>>>>>>>>>>>>>>>>>>> END OF DOWNLOAD <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  617.