Zbex Graphics

From CCARH Wiki
Revision as of 05:58, 20 October 2010 by Craig (talk | contribs) (added chapter navigator at top and bottom of page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
Previous chapter
Controlling the text display with putc
Next Chapter
MIDI instructions

The normal mode of operation for an Zbex mode is text mode, using the current Dmuse window for input and output. It is possible with Zbex to display data in graphics mode (music, for example). Zbex is not designed for constructing images in graphics mode. It is not good at drawing lines or circles. It is good at displaying letters and other glyph like characters, and it is reasonably efficient at displaying bitmap images that have been constructed "off screen".

Graphics instructions

There are eleven Zbex instructions that relate to graphics.

     bitmode   =  change to graphics display 
     textmode  =  change to normal, character based, window display 
     setup     =  setup a string as graphics buffer 
     activate  =  identify a graphics buffer with a particular graphics 
     setb      =  turn on a group of bits in a graphics buffer 
     clearb    =  turn off a group of bits in a graphics buffer 
     getk      =  get a keystroke (spin until keystroke arrives) 
     getx      =  if a keystroke is pending, deliver it; otherwise return 0
     dscale2   =  scale a graphics buffer to 50% of its original size 
     dscale3   =  scale a graphics buffer to 33% of its original size 
     dscale5   =  scale a graphics buffer to 66% of its original size 

In order to use these instructions, you need to know how the graphics mode is implemented in Zbex and how this relates to the (Linux) X Diplay window. Dmuse implements graphics as a set of four single-plane Pixmaps, each one designed to display its contents in a different color. As a concept, think of these planes as a stacked set, labled 1, 2, 3, and 4, with 4 on the top. Imagine that the background of the bottom plane is always white, and the foreground is the base color, black. Then think of the remaining three planes as being like "tranperancies," with one opaque color for writing and a background that is "see-through." The default colors for planes 2 thorough 4 are respectively, green, red, and blue. The planes never change their position, but things written to them can be erased and re-written in a different places. If the "blue" (top) image is fixed and something on the "red" (3rd plane) is moved, this can give the impression that the red image is changing under the blue image. Parts of the red image that were previously "eclipsed" by the blue image would appear to move out from behind the blue image. Similarly, if the "red" plane is fixed and something on the "blue" plane is moved (like a blue cursor shape, for example), the blue cursor would appear to move around on top of the red plane, but never destroying what was written there (cursor like behavior).

These Pixmap planes form the "hand-off" between what Zbex wants to display and what Dmuse passes on to X Windows. Dmuse knows how to combine the information on the Pixmaps so that the rules of eclipse are followed. All the Zbex programmer needs to concern himself/herself about is what is written to each of the four Pixmap color planes. Zbex does this through a mechanism called a graphics buffer. Zbex does not have a separate data type called a graphics buffer; it uses strings for this. The setup instruction is provided to make it easy to format a string as a graphics buffer. A graphics buffer consists of a base plane and zero to nine "scratch" planes. When Zbex writes a graphics buffer to one of the four Pixmap planes, it does this by first clearing the base plane, then copying (OR-ing) all of the set (on = 1) bits on each scratch plane to the base plane. The base plane is then copied to the specified Pixmap plane. This system has the advantage that features such as musical staff lines on one scratch plane are uneffected by movements of notes and other musical notation on another scratch plane.

Graphics buffer

The format of a graphics buffer (string) is this:

     bytes 1-5:  array paramteers 
       bytes 1-2:  m  =  number of BYTES in the horizontal dimension 
       bytes 3-4:  n  =  number of rows in the vertical dimension 
       byte 5:     p  =  number of "scratch" planes plus 1 
     bytes 6-10: activation parameters (dynamic at run time) 
       byte 6:        Pixmap plane to which buffer was last written 
                           0 = no plane designated 
                      1 to 4 = designated Pixmap plane; buffer is 
                                 said to be active 
       bytes 7-8:  x  =  x offset of last activation command 
       bytes 9-10: y  =  y offset of last activation command 
     bytes 11-18: left, top, right, and bottom exposure boundaries 
       bytes 11-12:   =  left boundary (x1) 
       bytes 13-14:   =  top  boundary (y1) 
       bytes 15-16:   =  right  boundary (x2) 
       bytes 17-18:   =  bottom boundary (y2) 
     bytes 19-20: unused 
     bytes 21...      m*n*p   bytes of data space 
        If m*n*p + 20 > declared length of string, a length error occurs 
        If m*n*p = 0, the string is invalid as a graphics buffer 

setup instruction

The setup instruction is designed to simplify the process of formating a string as a graphics buffer. The setup instruction takes a string name, and three integer variables. It is functionally equivalent to the following Zbex code:

         setup s,i,j,k      s = zpd(i*j*k+20)  /* check length */ 
                            s{1,2} = ch2(i) 
                            s{3,2} = ch2(j) 
                            s{5}   = ch(k) 
                            s{11,2} = ch2(0x3fff) 
                            s{13,2} = ch2(0x3fff) 
                            s{15,2} = ch2(0) 
                            s{15,7} = ch2(0) 

The exposure boundaries are initially set to opposite extremes. When the first write to buffer s occurs, these limits take on real-time values.

A graphics buffer need not have the same dimensions as a Pixmap; it may be larger or smaller in either dimension. Only that portion of the buffer lying within the Pixmap's dimensions will be written to the Pixmap plane.

The activate instruction provides a means of associating a particular graphics buffer with a particular Pixmap plane, and for actually writing that buffer to that plane. The format for the activate instruction is shown below.

     activate S-str,int1,int2,int3
         S-str  =  name of a string that serves as a graphics buffer 
          int1  =  horizontal offset expressed in BYTES for mapping 
                     S-str onto its display plane 
          int2  =  vertical offset expressed in ROWS for mapping 
                     S-str onto its display plane 
          int3  =  action parameter 
                          -1 = flush buffer to Pixmap plane 
                                 if byte 6 of S-str is positive 
                           0 = deactive this buffer; 
                                 set byte 6 of S-str to 0 
                     1,2,3,4 = write buffer to Pixmap plane <#> 
                                 set byte 6 of S-str to <#> 
                           5 = erase area covered by S-str on 
                                 Pixmap plane designated by byte 6 
                                 of S-str           
                 11,12,13,14 = set byte 6 of S-str to <#-10> but 
                                 do not write buffer to Pixmap plane 

The first two integer expressions supplied by the instruction indicate the values of the <x,y> offsets for mapping S-str to the display. The <x> coordinate is expressed in BYTES, not bits. <0,0> is the upper left-hand corner; and positive offsets move down and to the right.

The third integer expression, p, determines the action of the activate instruction. If p = 0, action is minimal. Byte 6 of S-str is simply set to 0, thus "deactivating" the variable. If p = 5, this means that the Pixmap plane designated by byte 6 (assuming its value is 1--4) is erased (set to 0) over the area covered by S-str (as offset by the x and y coordinates in bytes 7--10). If p = 1, 2, 3, or 4, then a write to Pixmap plane <p> will occur. If p = 11, 12, 13, or 14, S-str will be activated on Pixmap plane (p-10), but a write to that plane will not occur.

Once the these actions are completed, and if p = 1, 2, 3, 4, or 5, Dmuse combines all color Pixmaps in the appropriate way and sends them to the Display screen. If the offset <x,y> expressed in the first two integer expressions of the instruction is different than the the previous offsets stored in bytes 7--10 of S-str, AND the value of byte 6 and p are the same, then an erase of the former area will occur before the write. In the case where S-str covers an area smaller than the graphics bitplane, this will have the effect of "moving the image" from one location to another; in the case where S-str covers an area larger than the graphics bitplane, this will be an effective way to implement "panning" or "scrolling" of a larger image.

If p = -1, this asks that the portion of S-str described by the rectangle <x1,y1>, <x2,y2> be written to the Pixmap plane referenced by byte 6 of S-str. Of course, if byte-6 = 0, no write will occur. This use of the activate instruction is new with the Linux version of Dmuse. In the older DOS version, it was quick and easy to write to the computer display screen, and every call to setb/clearb (described below) did this automatically. In X Windows every write to a color Pixmap requires a write from the X Client to the X Server, so we want to keep the number of these writes to minimum. The graphics buffers are part of the Client application, so calls to setb and clearb are fast and require no "X" communication. But we need a way to "flush" these buffers to their destination Pixmaps (byte 6) at selected points in Zbex programs. This explains the purpose of the exposure boundaries, bytes 11-18 in S-str. They outline the rectangle containing all setb/clearb writes since the last flush command. After the flush write is completed the exposure boundaries are reset to <0x3fff,0x3fff>, <0,0>.

Note that the flush version of activate (activate S-str,0,0,-1) DOES NO WRITING to the Display screen; this can only be done with activate in its regular form. Also note that the x and y values are ignored in this call. The idea is that this information is already stored in bytes 1-4 of S-str. Flush simply does all at once what use to be done piecemeal by setb and clearb.

Graphics buffer bits

The real work of building a graphics page is in turning bits on and off bits in the graphics buffer. Theoretically, this could be done using conventional Zbex instructions, but this would be time consuming to program and the code would be slow to execute. Instead, Zbex has two specially designed instructions, setb and clearb, to do this in the fastest possible manner.

These instructions come in two formats: one using a bit-string array as a source, and the other using an integer array as a source. The operation of the instruction under each of these formats is slightly different. The only difference between setb and clearb is that setb turns bits on and clearb turns bits off.

     Format 1 
     setb/clearb S-str,A-bstr,int1,int2,int3,int4,int5,int6; 
         S-str  =  name of a string that serves as a graphics buffer 
        A-bstr  =  a array of bit strings containing a collection 
                     of bitmap images
          int1  =  horizontal offset expressed in BITS for the 
                     destination of a bitmap image in S-str 
          int2  =  vertical offset expressed in ROWS for the 
                     destination of bitmap image in S-str 
          int3  =  height of bitmap image to be transferred 
          int4  =  width of bitmap image to be transferred 
          int5  =  starting row in A-bstr for the bitmap image 
                     (number of rows to transfer is <int3>     
          int6  =  destination plane in S-str (1 = base plane, 
                     2 = scratch plane 1, etc.) 
     Format 2 
     setb/clearb S-str,A-int,int1,int2,int3,int4: 
         S-str  =  name of a string that serves as a graphics buffer 
         A-int  =  an array of integers (treated as 32 bit wide bit 
                     strings) representing a collection of bitmap 
          int1  =  horizontal offset expressed in BITS for the 
                     destination of a bitmap image in S-str 
          int2  =  vertical offset expressed in ROWS for the 
                     destination of bitmap image in S-str 
          int3  =  array element (number) in A-int.  This element 
                     contains the offset (element number) in A-int 
                     for the bitmap data to be transferred.  At the 
                     offset address, the first integer (array element) 
                     contains four 8-bit data fields:  the height and 
                     width of the image, and the local horizonal and 
                     vertical offsets of image relative to the <x,y> 
                     placement parameters.  The second integer contains 
                     one (left justified) 8-bit field:  the increment 
                     to the <x> placement parameter after a set/clear 
                        First integer contains: 
                        ¦height¦width ¦local h. offset¦local v. offset¦ 
                        Second integer contains: 
                        ¦increment to <x>¦        |   zeros  |        ¦ 
                        Third and following integers contain the 
                          bitmap image.  If the image is less than 
                          33 bits wide, each row of the image will 
                          require one integer; if the image is less 
                          than 65 bits wide, each row of the image 
                          will require two integers; etc.  
          int4 = destination plane in S-str 

If byte 6 of S-str is 1,2,3 or 4 (S-str is activated), then setb (clearb) will adjust the size of the exposure rectangle (bytes 11-18 in S-str) to include the area changed by the write. This way, with one instruction you can look up a bitmap image, transfer it to a graphics buffer, record this action for later "flushing," and increment the variable which specifies the <x> position for writing.

     The first variable is interpreted as a graphics buffer.  It acts 
     as <p> independent bitmap planes, where <p> is the dimension 
     specified in byte 5 of S-str (see diagram). The second variable 
     is a one dimensional bitstring array, A-bstr, or a one dimensional 
                               integer array, A-int(q).  This variable 
              S-str(m,n,p)     functions as a source for a set of 
            p+--------------+  bitmats (see 2nd diagram).  
          .+--------------+¦¦  Now we can describe the action of the 
         .+--------------+¦¦¦  command.  Let's talk about setb.  This 
        .+--------------+¦¦¦¦  instruction is used to turn on bits 
       3+--------------+¦¦¦¦¦  in S-str.  The integers supplied with 
      2+--------------+¦¦¦¦¦¦  the instruction determine what pattern 
     1+--------------+¦¦¦¦¦++  of bits is turned on and where it is 
      ¦ ?            ¦¦¦¦¦++   turned on.  The first two integers are 
      ¦?+- m bytes -?¦¦¦¦++   the <x,y> offset in S-str where the 
      ¦ ¦            ¦¦¦++   pattern will start.  Notice that <x> is 
      ¦n rows        ¦¦++   given as a BIT offset, not a byte offset.  
      ¦ ¦            ¦++   <0,0> is the top lefthand corner of S-str.  
      ¦ ?            ++   The meaning of the remaining variables depends 
      +--------------+   on the format.   In the case of the first 
                        format type (using a bit-string source, the 
                       third integer is the height (vertical dimension) 
       A-bstr(.)      of the "box" image to be copied to S-str.  The 
       +-------+     fourth integer is the width (horizontal dimension) 
       ¦       ¦    measured in BITs.  This is the maximum width of this 
       ¦       ¦   particular image in A-bstr.  The fifth integer is 
       +-------¦   the array row number in A-bstr(.) of the first bit 
       +-------¦   string to copy.  Notice that since this number is a 
       +-------¦   subscript, it follows the rules of subscripts, 
       ¦       ¦   e.g., it cannot be less than one.  The sixth integer 
       ¦       ¦   is a value from 1 to <p> and is the plane to which 
       +-------¦   the copy should be made.  
       ¦       ¦ 
       +-------+   This technique will allow us to store entire fonts
                   in long, bitstring arrays.  To select a glyph for
     copying, we simply need to know the beginning array row number 
     in A-bstr(.) and the number of rows (height).  The fact that we 
     have <p> planes to write in means that we can build up complex 
     notations such as music from a series of glyphs.  It also means 
     that we can selectively turn on and off various glyphs, without 
     disturbing other glyphs.  For example, we could turn off a music 
     note and turn it back on in another location, without disturbing 
     the music staff lines in the background.  
     The operation of the second format (using an A-int source) is 
     slightly more complicated, but for certain kinds of tasks, it is 
     more streamline and faster.  The idea is that if we are using 
     these instructions to turn on and off letters of a font, much of 
     the information about the letters is known and can therefore be 
     put directly in the integer array.  In this case, the first and 
     second integers (represent the <x,y> position) must be integer 
                    variables, not literal numbers or expressions, 
       A-int(.)     as allowed in the first format.  It is possible 
      1+-------+    for this instruction to modify first variable 
       +       ¦    <x> after the image is copied to the graphics 
       +       ¦    buffer.  The third integer (expression) is an 
       +       ¦    offset to an array element in A-int.  The fourth 
     97+-------¦    integer is a value from 1 to <p> and is the 
     +<¦pointer¦    plane in the graphics buffer to which the copy 
     ¦ +-------¦    should be made.  
     ¦ ¦       ¦ 
     ¦ +-------¦    One way of conceptualizing the role of the third 
     +?¦param1 ¦    integer (expression) is to think of it as acting 
       ¦-------¦    like a font number.  For example, the number 97 
       ¦param2 ¦    might point to a small 'a'.  This would mean that 
       ¦-------¦    the 97-th entry in A-int would contain the offset 
       ¦bit    ¦    to the data for the 'a'.  In effect, this offset 
       ¦image  ¦    would be the equivalent of the fifth integer in 
       ¦       ¦    the first format.  The first two integers of the 
       +-------¦    data block for the letter 'a' are reserved for 
       ¦       ¦    data about the letter.  The first integer contains 
                    the following information: 

       high order byte: height of the box (equivalent of third integer) 
                byte 2: width of the box (equivalent of fourth integer) 
                byte 1: horz offset (signed)  added to <x> 
        low order byte: vert offset (signed)  added to <y> 

The high order byte of second integer contains the increment to <x> following execution of instruction. The third and following integers contain the data for the letter 'a'. Note that the number of integers required per row will depend on the width of the box (given in byte 2). If the width is 32 or less, one integer per row is required; 64 or less, two integers per row are required; etc. One can see that the integer array, A-int, must be constructed rather carefully by the user programmer. The payoff, however, is much greater speed at run time for applications that write fonts to the screen in a linear fashion.

setb is used to turn bits on; clearb is used to turn bits off. The exact mechanism for writing will depend on whether bits are being set or cleared. In the first case, the specified plane needs to be OR-ed to plane 1 (the base plane in the graphics buffer); in the second case, all of the planes 2 and higher need to be OR-ed together and the result placed in plane 1 (the base plane).

graphics flag

When a Zbex program is compiled, a flag is set if graphics instructions are used anywhere in the program. When the program is handed off to the Zbex interpreter, if this flag is set, the interpreter allocates a set of four backup color Pixmaps for storing the program's graphics. The four operational color Pixmaps are also cleared at this time, but no writing is done to the user's X-Window display. If the Zbex program's operation is suspended (either by a switch to text mode, or by a change to another window), the four operational color Pixmaps are automatically copied to the backup Pixmaps for this program. If a Zbex program is re-entered (by a window change), the backup color Pixmaps are automatically copied back to the operational color Pixmaps, and if the program is currently running in graphics mode, the color Pixmaps are then written to the user's X-Window display. In this way, it is possible to have more than one Zbex program running in graphics mode.

In order to run in graphics mode, Zbex needs to have a mechanism for clearing the screen and for determining the size of the active screen. This is the task of the bitmode instruction. The bitmode instruction has the following format:

         bitmode int-exp,int,int 

The format consists of the instruction, one integer expression and two integer variables. The value of the integer expression must be 1 or 2. This value determines the operation of the instruction.

  1. Since Zbex programs should be able to run in any size X-window there needs to be a way for a Zbex program to access the current size of the Display Window in which it is running.
  2. Zbex also needs to have a way of clearing all four of the color Pixmaps and asking that the Display be cleared as well.

If the value of int-exp is 1, then only task (1) will be done. If the value of int-exp is 2, both task (1) and task (2) will be done. The values returned in the two integers are the current width and height of the user's X-Window Display. The bitmode instruction may be issued anywhere in a Zbex program. If the display is not already using bitmap graphics, the window display mechanism will be switched from text (glyph) based to bitmap based.

textmode instruction

The Zbex textmode instruction is used to switch the display from graphics mode to character mode. The current window with its current contents will reappear. The contents of the four operational color Pixmaps will be copied to the backup Pixmaps.

The normal way to send Zbex imput from the keyboard is with the getc command. This is fine for sending the program lines from a window, but it does not give the programmer control of the keyboard. In graphics mode, we often need to have control of the keyboard so that we can program the effect of certain keystrokes. For example, we may want to scroll the graphics screen using the cursor keys. The way to get keystroke input directly from the keyboard is with the getk instruction. getk takes one integer variable as an input argument.

Listed below are the keystrokes from the keyboard which will return a value to getk (not all keystrokes will). The values are represented in HEX format.

      ¦      SORTED BY NUMBER         ¦        SORTED BY KEYSTROKE      ¦ 
      ¦    --------------------       ¦      -----------------------    ¦ 
      ¦Value                          ¦                          Value  ¦ 
      ¦Returned     Keystroke         ¦       Keystroke         Returned¦ 
      ¦-------  ------------------    ¦ --------------------   ---------¦ 
      ¦0x10001  <ctrl-shft> a         ¦ <esc>                    0x1001b¦ 
      ¦0x10002  <ctrl-shft> b         ¦ F1                       0x31000¦ 
      ¦0x10003  <ctrl-shft> c         ¦ <shft> F1                0x31010¦ 
      ¦0x10004  <ctrl-shft> d         ¦ <ctrl> F1                0x31020¦ 
      ¦0x10005  <ctrl-shft> e         ¦ <ctrl-shft> F1           0x31040¦ 
      ¦0x10006  <ctrl-shft> f         ¦ F2                       0x31001¦ 
      ¦0x10007  <shft-alt> 9          ¦ <shft> F2                0x31011¦ 
      ¦0x10009  <shft-alt> 0          ¦ <ctrl> F2                0x31021¦ 
      ¦0x10008  <ctrl-shft> g         ¦ <ctrl-shft> F2           0x31041¦ 
      ¦0x1000a  <shft-alt> -          ¦ F3                       0x31002¦ 
      ¦0x1000b  <ctrl-shft> k         ¦ <shft> F3                0x31012¦ 
      ¦0x1000c  <ctrl-shft> h         ¦ <ctrl> F3                0x31022¦ 
      ¦0x1000d  <ctrl-shft> l         ¦ <ctrl-shft> F3           0x31042¦ 
      ¦0x1000e  <ctrl-shft> m         ¦ F4                       0x31003¦ 
      ¦0x1000f  <ctrl-shft> o         ¦ <shft> F4                0x31013¦ 
      ¦0x10010  <ctrl-shft> p         ¦ <ctrl> F4                0x31023¦ 
      ¦0x10011  <ctrl-shft> q         ¦ <ctrl-shft> F4           0x31043¦ 
      ¦0x10012  <ctrl-shft> r         ¦ F5                       0x31004¦ 
      ¦0x10013  <ctrl-shft> s         ¦ <shft> F5                0x31014¦ 
      ¦0x10014  <ctrl-shft> t         ¦ <ctrl> F5                0x31024¦ 
      ¦0x10015  <ctrl-shft> u         ¦ <ctrl-shft> F5           0x31044¦ 
      ¦0x10016  <ctrl-shft> v         ¦ F6                       0x31005¦ 
      ¦0x10017  <ctrl-shft> w         ¦ <shft> F6                0x31015¦ 
      ¦0x10018  <ctrl-shft> x         ¦ <ctrl> F6                0x31025¦ 
      ¦0x10019  <ctrl-shft> y         ¦ <ctrl-shft> F6           0x31045¦ 
      ¦0x1001a  <shft-alt> =          ¦ F7                       0x31006¦ 
      ¦0x1001b  <esc>                 ¦ <shft> F7                0x31016¦ 
      ¦0x1001c  <ctrl-shft> n         ¦ <ctrl> F7                0x31026¦ 
      ¦0x1001e  <ctrl-shft> i         ¦ <ctrl-shft> F7           0x31046¦ 
      ¦0x1001f  <ctrl-shft> j         ¦ F8                       0x31007¦ 
      ¦0x10020  SPACE                 ¦ <shft> F8                0x31017¦ 
      ¦0x10021  <shft> 1              ¦ <ctrl> F8                0x31027¦ 
      ¦0x10022  <shft> '              ¦ <ctrl-shft> F8           0x31047¦ 
      ¦0x10023  <shft> 3              ¦ F9                       0x31008¦ 
      ¦0x10024  <shft> 4              ¦ <shft> F9                0x31018¦ 
      ¦0x10025  <shft> 5              ¦ <ctrl> F9                0x31028¦ 
      ¦0x10026  <shft> 7              ¦ <ctrl-shft> F9           0x31048¦ 
      ¦0x10027  '                     ¦ F10                      0x31009¦ 
      ¦0x10028  <shft> 9              ¦ <shft> F10               0x31019¦ 
      ¦0x10029  <shft> 0              ¦ <ctrl> F10               0x31029¦ 
      ¦0x1002a  <shft> 8              ¦ <ctrl-shft> F10          0x31049¦ 
      ¦0x1002b  <shft> =              ¦ F11                      0x3100a¦ 
      ¦0x1002c  ,                     ¦ <shft> F11               0x3101a¦ 
      ¦0x1002d  -                     ¦ <ctrl> F11               0x3102a¦ 
      ¦0x1002e  .                     ¦ <ctrl-shft> F11          0x3104a¦ 
      ¦0x1002f  /                     ¦ F12                      0x3100b¦ 
      ¦0x10030  0                     ¦ <shft> F12               0x3101b¦ 
      ¦0x10031  1                     ¦ <ctrl> F12               0x3102b¦ 
      ¦0x10032  2                     ¦ <ctrl-shft> F12          0x3104b¦ 
      ¦0x10033  3                     ¦ `                        0x10060¦ 
      ¦0x10034  4                     ¦ <shft> `                 0x1007e¦ 
      ¦0x10035  5                     ¦ 1                        0x10031¦ 
      ¦0x10036  6                     ¦ <shft> 1                 0x10021¦ 
      ¦0x10037  7                     ¦ <shft-alt> 1             0x100ad¦ 
      ¦0x10038  8                     ¦ 2                        0x10032¦ 
      ¦0x10039  9                     ¦ <shft> 2                 0x10040¦ 
      ¦0x1003a  <shft> ;              ¦ <shft-alt> 2             0x1009d¦ 
      ¦0x1003b  ;                     ¦ 3                        0x10033¦ 
      ¦0x1003c  <shft> ,              ¦ <shft> 3                 0x10023¦ 
      ¦0x1003d  =                     ¦ <shft-alt> 3             0x1009c¦ 
      ¦0x1003e  <shft> .              ¦ 4                        0x10034¦ 
      ¦0x1003f  <shft> /              ¦ <shft> 4                 0x10024¦ 
      ¦0x10040  <shft> 2              ¦ <shft-alt> 4             0x1009b¦ 
      ¦0x10041  <shft> a              ¦ 5                        0x10035¦ 
      ¦0x10042  <shft> b              ¦ <shft> 5                 0x10025¦ 
      ¦0x10043  <shft> c              ¦ <shft-alt> 5             0x1009f¦ 
      ¦0x10044  <shft> d              ¦ 6                        0x10036¦ 
      ¦0x10045  <shft> e              ¦ <shft> 6                 0x1005e¦ 
      ¦0x10046  <shft> f              ¦ <shft-alt> 6             0x100fd¦ 
      ¦0x10047  <shft> g              ¦ 7                        0x10037¦ 
      ¦0x10048  <shft> h              ¦ <shft> 7                 0x10026¦ 
      ¦0x10049  <shft> i              ¦ <shft-alt> 7             0x100ac¦ 
      ¦0x1004a  <shft> j              ¦ 8                        0x10038¦ 
      ¦0x1004b  <shft> k              ¦ <shft> 8                 0x1002a¦ 
      ¦0x1004c  <shft> l              ¦ <shft-alt> 8             0x100ab¦ 
      ¦0x1004d  <shft> m              ¦ 9                        0x10039¦ 
      ¦0x1004e  <shft> n              ¦ <shft> 9                 0x10028¦ 
      ¦0x1004f  <shft> o              ¦ <shft-alt> 9             0x10007¦ 
      ¦0x10050  <shft> p              ¦ 0                        0x10030¦ 
      ¦0x10051  <shft> q              ¦ <shft> 0                 0x10029¦ 
      ¦0x10052  <shft> r              ¦ <shft-alt> 0             0x10009¦ 
      ¦0x10053  <shft> s              ¦ -                        0x1002d¦ 
      ¦0x10054  <shft> t              ¦ <shft> -                 0x1005f¦ 
      ¦0x10055  <shft> u              ¦ <alt> -                  0x100aa¦ 
      ¦0x10056  <shft> v              ¦ <shft-alt> -             0x1000a¦ 
      ¦0x10057  <shft> w              ¦ =                        0x1003d¦ 
      ¦0x10058  <shft> x              ¦ <shft> =                 0x1002b¦ 
      ¦0x10059  <shft> y              ¦ <alt> =                  0x100a9¦ 
      ¦0x1005a  <shft> z              ¦ <shft-alt> =             0x1001a¦ 
      ¦0x1005b  [                     ¦ BackSpace                0x3040a¦ 
      ¦0x1005c  \                     ¦ <shft> BackSpace         0x3040b¦ 
      ¦0x1005d  ]                     ¦ Tab                      0x30810¦ 
      ¦0x1005e  <shft> 6              ¦ <left-shft> Tab          0x30811¦ 
      ¦0x1005f  <shft> -              ¦ <right-shft>  Tab        0x30812¦ 
      ¦0x10060  `                     ¦ <ctrl> Tab               0x30814¦ 
      ¦0x10061  a                     ¦ <left-ctrl-shft> Tab     0x30815¦ 
      ¦0x10062  b                     ¦ <right-ctrl-shft> Tab    0x30813¦ 
      ¦0x10063  c                     ¦ q                        0x10071¦ 
      ¦0x10064  d                     ¦ <shft> q                 0x10051¦ 
      ¦0x10065  e                     ¦ <ctrl> q                 0x30471¦ 
      ¦0x10066  f                     ¦ <alt>  q                 0x100da¦ 
      ¦0x10067  g                     ¦ <ctrl-shft> q            0x10011¦ 
      ¦0x10068  h                     ¦ <shft-alt>  q            0x100d6¦ 
      ¦0x10069  i                     ¦ w                        0x10077¦ 
      ¦0x1006a  j                     ¦ <shft> w                 0x10057¦ 
      ¦0x1006b  k                     ¦ <ctrl> w                 0x30477¦ 
      ¦0x1006c  l                     ¦ <alt>  w                 0x100c2¦ 
      ¦0x1006d  m                     ¦ <ctrl-shft> w            0x10017¦ 
      ¦0x1006e  n                     ¦ <shft-alt>  w            0x100d2¦ 
      ¦0x1006f  o                     ¦ e                        0x10065¦ 
      ¦0x10070  p                     ¦ <shft> e                 0x10045¦ 
      ¦0x10071  q                     ¦ <ctrl> e                 0x30465¦ 
      ¦0x10072  r                     ¦ <alt>  e                 0x100bf¦ 
      ¦0x10073  s                     ¦ <ctrl-shft> e            0x10005¦ 
      ¦0x10074  t                     ¦ <shft-alt>  e            0x100b7¦ 
      ¦0x10075  u                     ¦ r                        0x10072¦ 
      ¦0x10076  v                     ¦ <shft> r                 0x10052¦ 
      ¦0x10077  w                     ¦ <ctrl> r                 0x30472¦ 
      ¦0x10078  x                     ¦ <alt>  r                 0x100c4¦ 
      ¦0x10079  y                     ¦ <ctrl-shft> r            0x10012¦ 
      ¦0x1007a  z                     ¦ t                        0x10074¦ 
      ¦0x1007b  <shft> [              ¦ <shft> t                 0x10054¦ 
      ¦0x1007c  <shft> \              ¦ <ctrl> t                 0x30474¦ 
      ¦0x1007d  <shft> ]              ¦ <alt>  t                 0x100c9¦ 
      ¦0x1007e  <shft> `              ¦ <ctrl-shft> t            0x10014¦ 
      ¦0x1007f  <ctrl-shft> z         ¦ <shft-alt>  t            0x100d5¦ 
      ¦0x10091  <shft-alt> i          ¦ y                        0x10079¦ 
      ¦0x10092  <shft-alt> o          ¦ <shft> y                 0x10059¦ 
      ¦0x1009b  <shft-alt> 4          ¦ <ctrl> y                 0x30479¦ 
      ¦0x1009c  <shft-alt> 3          ¦ <alt>  y                 0x100cb¦ 
      ¦0x1009d  <shft-alt> 2          ¦ <ctrl-shft> y            0x10019¦ 
      ¦0x1009e  <shft-alt> p          ¦ <shft-alt>  y            0x100d1¦ 
      ¦0x1009f  <shft-alt> 5          ¦ u                        0x10075¦ 
      ¦0x100a8  <shft-alt>  /         ¦ <shft> u                 0x10055¦ 
      ¦0x100a9  <alt> =               ¦ <ctrl> u                 0x30475¦ 
      ¦0x100aa  <alt> -               ¦ <alt>  u                 0x100bb¦ 
      ¦0x100ab  <shft-alt> 8          ¦ <ctrl-shft> u            0x10015¦ 
      ¦0x100ac  <shft-alt> 7          ¦ <shft-alt>  u            0x100b8¦ 
      ¦0x100ad  <shft-alt> 1          ¦ i                        0x10069¦ 
      ¦0x100ae  <shft-alt>  ,         ¦ <shft> i                 0x10049¦ 
      ¦0x100af  <shft-alt>  .         ¦ <ctrl> i                 0x30469¦ 
      ¦0x100b0  <alt>  o              ¦ <alt>  i                 0x100cd¦ 
      ¦0x100b1  <alt>  p              ¦ <ctrl-shft> i            0x1001e¦ 
      ¦0x100b2  <alt>  [              ¦ <shft-alt>  i            0x10091¦ 
      ¦0x100b3  <alt>  f              ¦ o                        0x1006f¦ 
      ¦0x100b4  <alt>  d              ¦ <shft> o                 0x1004f¦ 
      ¦0x100b5  <shft-alt>  j         ¦ <ctrl> o                 0x3046f¦ 
      ¦0x100b6  <shft-alt>  d         ¦ <alt>  o                 0x100b0¦ 
      ¦0x100b7  <shft-alt>  e         ¦ <ctrl-shft> o            0x1000f¦ 
      ¦0x100b8  <shft-alt>  u         ¦ <shft-alt>  o            0x10092¦ 
      ¦0x100b9  <alt>  j              ¦ p                        0x10070¦ 
      ¦0x100ba  <alt>  k              ¦ <shft> p                 0x10050¦ 
      ¦0x100bb  <alt>  u              ¦ <ctrl> p                 0x30470¦ 
      ¦0x100bc  <alt>  m              ¦ <alt>  p                 0x100b1¦ 
      ¦0x100bd  <shft-alt>  c         ¦ <ctrl-shft> p            0x10010¦ 
      ¦0x100be  <shft-alt>  m         ¦ <shft-alt>  p            0x1009e¦ 
      ¦0x100bf  <alt>  e              ¦ [                        0x1005b¦ 
      ¦0x100c0  <alt>  z              ¦ <shft> [                 0x1007b¦ 
      ¦0x100c1  <alt>  x              ¦ <alt>  [                 0x100b2¦ 
      ¦0x100c2  <alt>  w              ¦ <shft-alt> [             0x100fe¦ 
      ¦0x100c3  <alt>  a              ¦ ]                        0x1005d¦ 
      ¦0x100c4  <alt>  r              ¦ <shft> ]                 0x1007d¦ 
      ¦0x100c5  <alt>  s              ¦ <alt>  ]                 0x100db¦ 
      ¦0x100c6  <shft-alt>  g         ¦ <shft-alt> ]             0x100fa¦ 
      ¦0x100c7  <shft-alt>  a         ¦ \                        0x1005c¦ 
      ¦0x100c8  <alt>  b              ¦ <shft> \                 0x1007c¦ 
      ¦0x100c9  <alt>  t              ¦ a                        0x10061¦ 
      ¦0x100ca  <alt>  n              ¦ <shft> a                 0x10041¦ 
      ¦0x100cb  <alt>  y              ¦ <ctrl> a                 0x30461¦ 
      ¦0x100cc  <alt>  g              ¦ <alt>  a                 0x100c3¦ 
      ¦0x100cd  <alt>  i              ¦ <ctrl-shft> a            0x10001¦ 
      ¦0x100ce  <alt>  h              ¦ <shft-alt>  a            0x100c7¦ 
      ¦0x100cf  <shft-alt>  n         ¦ s                        0x10073¦ 
      ¦0x100d0  <shft-alt>  x         ¦ <shft> s                 0x10053¦ 
      ¦0x100d1  <shft-alt>  y         ¦ <ctrl> s                 0x30473¦ 
      ¦0x100d2  <shft-alt>  w         ¦ <alt>  s                 0x100c5¦ 
      ¦0x100d3  <shft-alt>  z         ¦ <ctrl-shft> s            0x10013¦ 
      ¦0x100d4  <shft-alt>  b         ¦ <shft-alt>  s            0x100d7¦ 
      ¦0x100d5  <shft-alt>  t         ¦ d                        0x10064¦ 
      ¦0x100d6  <shft-alt>  q         ¦ <shft> d                 0x10044¦ 
      ¦0x100d7  <shft-alt>  s         ¦ <ctrl> d                 0x30464¦ 
      ¦0x100d8  <shft-alt>  h         ¦ <alt>  d                 0x100b4¦ 
      ¦0x100d9  <alt>  c              ¦ <ctrl-shft> d            0x10004¦ 
      ¦0x100da  <alt>  q              ¦ <shft-alt>  d            0x100b6¦ 
      ¦0x100db  <alt>  ]              ¦ f                        0x10066¦ 
      ¦0x100dc  <alt>  ;              ¦ <shft> f                 0x10046¦ 
      ¦0x100dd  <alt>  ,              ¦ <ctrl> f                 0x30466¦ 
      ¦0x100de  <alt>  .              ¦ <alt>  f                 0x100b3¦ 
      ¦0x100df  <alt>  l              ¦ <ctrl-shft> f            0x10006¦ 
      ¦0x100fa  <shft-alt> ]          ¦ g                        0x10067¦ 
      ¦0x100fd  <shft-alt> 6          ¦ <shft> g                 0x10047¦ 
      ¦0x100fe  <shft-alt> [          ¦ <ctrl> g                 0x30467¦ 
      ¦0x30101  ?-                    ¦ <alt>  g                 0x100cc¦ 
      ¦0x30102  ?                     ¦ <ctrl-shft> g            0x10008¦ 
      ¦0x30103  -?                    ¦ <shft-alt>  g            0x100c6¦ 
      ¦0x30104  ?                     ¦ h                        0x10068¦ 
      ¦0x30105  <left-shft>  ?-       ¦ <shft> h                 0x10048¦ 
      ¦0x30106  <left-shft>  ?        ¦ <ctrl> h                 0x30468¦ 
      ¦0x30107  <left-shft>  -?       ¦ <alt>  h                 0x100ce¦ 
      ¦0x30108  <left-shft>  ?        ¦ <ctrl-shft> h            0x1000c¦ 
      ¦0x30109  <ctrl> ?-             ¦ <shft-alt>  h            0x100d8¦ 
      ¦0x30109  <right-shft> ?-       ¦ j                        0x1006a¦ 
      ¦0x3010a  <ctrl> ?              ¦ <shft> j                 0x1004a¦ 
      ¦0x3010a  <right-shft> ?        ¦ <ctrl> j                 0x3046a¦ 
      ¦0x3010b  <ctrl> -?             ¦ <alt>  j                 0x100b9¦ 
      ¦0x3010b  <right-shft> -?       ¦ <ctrl-shft> j            0x1001f¦ 
      ¦0x3010c  <ctrl> ?              ¦ <shft-alt>  j            0x100b5¦ 
      ¦0x3010c  <right-shft> ?        ¦ k                        0x1006b¦ 
      ¦0x3010d  <alt>  ?-             ¦ <shft> k                 0x1004b¦ 
      ¦0x3010e  <alt>  ?              ¦ <ctrl> k                 0x3046b¦ 
      ¦0x3010f  <alt>  -?             ¦ <alt>  k                 0x100ba¦ 
      ¦0x30110  <alt>  ?              ¦ <ctrl-shft> k            0x1000b¦ 
      ¦0x30111  <left-shft-alt>  ?-   ¦ l                        0x1006c¦ 
      ¦0x30112  <left-shft-alt>  -?   ¦ <shft> l                 0x1004c¦ 
      ¦0x30113  <right-shft-alt> ?-   ¦ <ctrl> l                 0x3046c¦ 
      ¦0x30114  <right-shft-alt> -?   ¦ <alt>  l                 0x100df¦ 
      ¦0x30115  <ctrl-shft>  ?-       ¦ <ctrl-shft> l            0x1000d¦ 
      ¦0x30116  <ctrl-shft>  ?        ¦ ;                        0x1003b¦ 
      ¦0x30117  <ctrl-shft>  -?       ¦ <shft> ;                 0x1003a¦ 
      ¦0x30118  <ctrl-shft>  ?        ¦ <alt>  ;                 0x100dc¦ 
      ¦0x30119  <left-shft-alt>  ?    ¦ '                        0x10027¦ 
      ¦0x3011a  <left-shft-alt>  ?    ¦ <shft> '                 0x10022¦ 
      ¦0x3011b  <right-shft-alt> ?    ¦ Enter                    0x3080c¦ 
      ¦0x3011c  <right-shft-alt> ?    ¦ <shft> Enter             0x3080d¦ 
      ¦0x30120  PageUP                ¦ <ctrl> Enter             0x3080e¦ 
      ¦0x30121  PageDOWN              ¦ <alt>  Enter             0x3080f¦ 
      ¦0x30122  Home                  ¦ z                        0x1007a¦ 
      ¦0x30123  End                   ¦ <shft> z                 0x1005a¦ 
      ¦0x30124  <shft> PageUP         ¦ <ctrl> z                 0x3047a¦ 
      ¦0x30125  <shft> PageDOWN       ¦ <alt>  z                 0x100c0¦ 
      ¦0x30126  <shft> Home           ¦ <ctrl-shft> z            0x1007f¦ 
      ¦0x30127  <shft> End            ¦ <shft-alt>  z            0x100d3¦ 
      ¦0x30130  <ctrl> PageUP         ¦ x                        0x10078¦ 
      ¦0x30131  <ctrl> PageDOWN       ¦ <shft> x                 0x10058¦ 
      ¦0x30132  <ctrl> Home           ¦ <ctrl> x                 0x30478¦ 
      ¦0x30133  <ctrl> End            ¦ <alt>  x                 0x100c1¦ 
      ¦0x30134  <ctrl-shft> PageUP    ¦ <ctrl-shft> x            0x10018¦ 
      ¦0x30135  <ctrl-shft> PageDOWN  ¦ <shft-alt>  x            0x100d0¦ 
      ¦0x30136  <ctrl-shft> Home      ¦ c                        0x10063¦ 
      ¦0x30137  <ctrl-shft> End       ¦ <shft> c                 0x10043¦ 
      ¦0x30400  Insert                ¦ <ctrl> c                 0x30463¦ 
      ¦0x30401  <shft> Insert         ¦ <alt>  c                 0x100d9¦ 
      ¦0x30402  <ctrl> Insert         ¦ <ctrl-shft> c            0x10003¦ 
      ¦0x30403  <alt>  Insert         ¦ <shft-alt>  c            0x100bd¦ 
      ¦0x30404  <shft-alt>  Insert    ¦ v                        0x10076¦ 
      ¦0x30405  Delete                ¦ <shft> v                 0x10056¦ 
      ¦0x30406  <shft> Delete         ¦ <ctrl> v                 0x30476¦ 
      ¦0x30407  <ctrl> Delete         ¦ <ctrl-shft> v            0x10016¦ 
      ¦0x30408  <alt>  Delete         ¦ b                        0x10062¦ 
      ¦0x30409  <shft-alt>  Delete    ¦ <shft> b                 0x10042¦ 
      ¦0x3040a  BackSpace             ¦ <ctrl> b                 0x30462¦ 
      ¦0x3040b  <shft> BackSpace      ¦ <alt>  b                 0x100c8¦ 
      ¦0x3040c  <ctrl-shft> Insert    ¦ <ctrl-shft> b            0x10002¦ 
      ¦0x30461  <ctrl> a              ¦ <shft-alt>  b            0x100d4¦ 
      ¦0x30462  <ctrl> b              ¦ n                        0x1006e¦ 
      ¦0x30463  <ctrl> c              ¦ <shft> n                 0x1004e¦ 
      ¦0x30464  <ctrl> d              ¦ <ctrl> n                 0x3046e¦ 
      ¦0x30465  <ctrl> e              ¦ <alt>  n                 0x100ca¦ 
      ¦0x30466  <ctrl> f              ¦ <ctrl-shft> n            0x1001c¦ 
      ¦0x30467  <ctrl> g              ¦ <shft-alt>  n            0x100cf¦ 
      ¦0x30468  <ctrl> h              ¦ m                        0x1006d¦ 
      ¦0x30469  <ctrl> i              ¦ <shft> m                 0x1004d¦ 
      ¦0x3046a  <ctrl> j              ¦ <ctrl> m                 0x3046d¦ 
      ¦0x3046b  <ctrl> k              ¦ <alt>  m                 0x100bc¦ 
      ¦0x3046c  <ctrl> l              ¦ <ctrl-shft> m            0x1000e¦ 
      ¦0x3046d  <ctrl> m              ¦ <shft-alt>  m            0x100be¦ 
      ¦0x3046e  <ctrl> n              ¦ ,                        0x1002c¦ 
      ¦0x3046f  <ctrl> o              ¦ <shft> ,                 0x1003c¦ 
      ¦0x30470  <ctrl> p              ¦ <alt>  ,                 0x100dd¦ 
      ¦0x30471  <ctrl> q              ¦ <shft-alt>  ,            0x100ae¦ 
      ¦0x30472  <ctrl> r              ¦ .                        0x1002e¦ 
      ¦0x30473  <ctrl> s              ¦ <shft> .                 0x1003e¦ 
      ¦0x30474  <ctrl> t              ¦ <alt>  .                 0x100de¦ 
      ¦0x30475  <ctrl> u              ¦ <shft-alt>  .            0x100af¦ 
      ¦0x30476  <ctrl> v              ¦ /                        0x1002f¦ 
      ¦0x30477  <ctrl> w              ¦ <shft> /                 0x1003f¦ 
      ¦0x30478  <ctrl> x              ¦ <shft-alt>  /            0x100a8¦ 
      ¦0x30479  <ctrl> y              ¦ SPACE                    0x10020¦ 
      ¦0x3047a  <ctrl> z              ¦ Insert                   0x30400¦ 
      ¦0x30800  Pad *                 ¦ <shft> Insert            0x30401¦ 
      ¦0x30801  <shft> Pad *          ¦ <ctrl> Insert            0x30402¦ 
      ¦0x30802  Pad +                 ¦ <alt>  Insert            0x30403¦ 
      ¦0x30803  <shft> Pad +          ¦ <ctrl-shft> Insert       0x3040c¦ 
      ¦0x30804  Pad -                 ¦ <shft-alt>  Insert       0x30404¦ 
      ¦0x30805  <shft> Pad -          ¦ Delete                   0x30405¦ 
      ¦0x30806  Pad /                 ¦ <shft> Delete            0x30406¦ 
      ¦0x30807  <ctrl> Pad +          ¦ <ctrl> Delete            0x30407¦ 
      ¦0x3080b  <ctrl-shft> Pad +     ¦ <alt>  Delete            0x30408¦ 
      ¦0x3080c  Enter                 ¦ <shft-alt>  Delete       0x30409¦ 
      ¦0x3080d  <shft> Enter          ¦ Home                     0x30122¦ 
      ¦0x3080e  <ctrl> Enter          ¦ <shft> Home              0x30126¦ 
      ¦0x3080f  <alt>  Enter          ¦ <ctrl> Home              0x30132¦ 
      ¦0x30810  Tab                   ¦ <ctrl-shft> Home         0x30136¦ 
      ¦0x30811  <left-shft> Tab       ¦ End                      0x30123¦ 
      ¦0x30812  <right-shft> Tab      ¦ <shft> End               0x30127¦ 
      ¦0x30813  <right-ctrl-shft> Tab ¦ <ctrl> End               0x30133¦ 
      ¦0x30814  <ctrl> Tab            ¦ <ctrl-shft> End          0x30137¦ 
      ¦0x30815  <left-ctrl-shft> Tab  ¦ PageUP                   0x30120¦ 
      ¦0x30820  Pad Enter             ¦ <shft> PageUP            0x30124¦ 
      ¦0x30821  <shft> Pad Enter      ¦ <ctrl> PageUP            0x30130¦ 
      ¦0x30822  <ctrl> Pad Enter      ¦ <ctrl-shft> PageUP       0x30134¦ 
      ¦0x30823  <ctrl-shft> Pad Enter ¦ PageDOWN                 0x30121¦ 
      ¦0x30824  <alt>  Pad Enter      ¦ <shft> PageDOWN          0x30125¦ 
      ¦0x30825  <shft-alt>  Pad Enter ¦ <ctrl> PageDOWN          0x30131¦ 
      ¦0x30826  <ctrl-alt>  Pad Enter ¦ <ctrl-shft> PageDOWN     0x30135¦ 
      ¦0x30827  <shft-ctrl-alt> Pad En¦ ?-                       0x30101¦ 
      ¦0x31000  F1                    ¦ <left-shft>  ?-          0x30105¦ 
      ¦0x31001  F2                    ¦ <right-shft> ?-          0x30109¦ 
      ¦0x31002  F3                    ¦ <ctrl> ?-                0x30109¦ 
      ¦0x31003  F4                    ¦ <alt>  ?-                0x3010d¦ 
      ¦0x31004  F5                    ¦ <ctrl-shft>  ?-          0x30115¦ 
      ¦0x31005  F6                    ¦ <left-shft-alt>  ?-      0x30111¦ 
      ¦0x31006  F7                    ¦ <right-shft-alt> ?-      0x30113¦ 
      ¦0x31007  F8                    ¦ ?                        0x30102¦ 
      ¦0x31008  F9                    ¦ <left-shft>  ?           0x30106¦ 
      ¦0x31009  F10                   ¦ <right-shft> ?           0x3010a¦ 
      ¦0x3100a  F11                   ¦ <ctrl> ?                 0x3010a¦ 
      ¦0x3100b  F12                   ¦ <alt>  ?                 0x3010e¦ 
      ¦0x31010  <shft> F1             ¦ <ctrl-shft>  ?           0x30116¦ 
      ¦0x31011  <shft> F2             ¦ <left-shft-alt>  ?       0x30119¦ 
      ¦0x31012  <shft> F3             ¦ <right-shft-alt> ?       0x3011b¦ 
      ¦0x31013  <shft> F4             ¦ -?                       0x30103¦ 
      ¦0x31014  <shft> F5             ¦ <left-shft>  -?          0x30107¦ 
      ¦0x31015  <shft> F6             ¦ <right-shft> -?          0x3010b¦ 
      ¦0x31016  <shft> F7             ¦ <ctrl> -?                0x3010b¦ 
      ¦0x31017  <shft> F8             ¦ <alt>  -?                0x3010f¦ 
      ¦0x31018  <shft> F9             ¦ <ctrl-shft>  -?          0x30117¦ 
      ¦0x31019  <shft> F10            ¦ <left-shft-alt>  -?      0x30112¦ 
      ¦0x3101a  <shft> F11            ¦ <right-shft-alt> -?      0x30114¦ 
      ¦0x3101b  <shft> F12            ¦ ?                        0x30104¦ 
      ¦0x31020  <ctrl> F1             ¦ <left-shft>  ?           0x30108¦ 
      ¦0x31021  <ctrl> F2             ¦ <right-shft> ?           0x3010c¦ 
      ¦0x31022  <ctrl> F3             ¦ <ctrl> ?                 0x3010c¦ 
      ¦0x31023  <ctrl> F4             ¦ <alt>  ?                 0x30110¦ 
      ¦0x31024  <ctrl> F5             ¦ <ctrl-shft>  ?           0x30118¦ 
      ¦0x31025  <ctrl> F6             ¦ <left-shft-alt>  ?       0x3011a¦ 
      ¦0x31026  <ctrl> F7             ¦ <right-shft-alt> ?       0x3011c¦ 
      ¦0x31027  <ctrl> F8             ¦ Pad /                    0x30806¦ 
      ¦0x31028  <ctrl> F9             ¦ Pad *                    0x30800¦ 
      ¦0x31029  <ctrl> F10            ¦ <shft> Pad *             0x30801¦ 
      ¦0x3102a  <ctrl> F11            ¦ Pad -                    0x30804¦ 
      ¦0x3102b  <ctrl> F12            ¦ <shft> Pad -             0x30805¦ 
      ¦0x31040  <ctrl-shft> F1        ¦ Pad +                    0x30802¦ 
      ¦0x31041  <ctrl-shft> F2        ¦ <shft> Pad +             0x30803¦ 
      ¦0x31042  <ctrl-shft> F3        ¦ <ctrl> Pad +             0x30807¦ 
      ¦0x31043  <ctrl-shft> F4        ¦ <ctrl-shft> Pad +        0x3080b¦ 
      ¦0x31044  <ctrl-shft> F5        ¦ Pad Enter                0x30820¦ 
      ¦0x31045  <ctrl-shft> F6        ¦ <shft> Pad Enter         0x30821¦ 
      ¦0x31046  <ctrl-shft> F7        ¦ <ctrl> Pad Enter         0x30822¦ 
      ¦0x31047  <ctrl-shft> F8        ¦ <alt>  Pad Enter         0x30824¦ 
      ¦0x31048  <ctrl-shft> F9        ¦ <ctrl-shft> Pad Enter    0x30823¦ 
      ¦0x31049  <ctrl-shft> F10       ¦ <shft-alt>  Pad Enter    0x30825¦ 
      ¦0x3104a  <ctrl-shft> F11       ¦ <ctrl-alt>  Pad Enter    0x30826¦ 
      ¦0x3104b  <ctrl-shft> F12       ¦ <shft-ctrl-alt> Pad Ent  0x30827¦ 

Notice that Pad 0 through Pad 9 (also <shft> Pad 0 to 9, and <alt> Pad 0 to 9) are not included in this list. The reason is that these keystrokes are still needed by Dmuse for changing windows. Consequently, they are not available to Zbex.

getx instruction

There is also a getx instruction in Zbex. This instruction is different from getk in that it does not block the execution of the Zbex program. If there has been one or more keystrokes (from the set above) that has not yet been processed, and the Zbex interpreter encounters a getx instruction, then the value of the most recent keystroke will be delivered, and the keystroke queue will be cleared. If the keystroke queue is empty, a getx instruction will simply return 0x0000 in the output variable. The Zbex program will continue to execute.

Scaling graphics images

Zbex provides three commands for scaling a graphics image: dscale2, which produces a 1/2 size image, dscale3, which produces a 1/3 size image, and dscale5, which produces a 2/3 size image. A common use of these instructions is scaling an image, constructed at 300 dots/inch (for printing), down to a size that can viewed on a screen (e.g., 75 dots/inch).

There are two forms for these instructions: (1) complete scaling and (2) partial scaling. Both forms require two graphic string variables, a source and a destination. At compile time, any simple strings will suffice. It is at run time that the program must check values to see that the strings are properly formatted (setup) as graphics buffers. In particular, the following conditions for the string variables must hold:

For both strings, 0 < m*n*p <= len(S-str) - 20, where

           m = value represented in bytes 1-2  (BYTES in row) 
           n = value represented in bytes 3-4  (number of rows) 
           p = value represented in bytes 5    (number of planes) 

It is possible to specify four additional integer parameters to the dscale instructions. These are respectively the left boundary, the top boundary, the right boundary, and the bottom boundary of the space that is to be scaled. Left and right boundaries are measured in COLUMNS; top and bottom boundaries are measured in ROWS. If these variables are not specified, the values <0,0> and <90000,90000> are supplied by the compiler.

The format for the dscale instructions is then:

         dscale3 S-str1, S-str2      or 
         dscale3 S-str1, S-str2, int,int,int,int 

Operation (for the instruction dscale3):

     Let m1 = value for m for S-str1; and m2 = value of m for S-str2 
     Let n1 = value for n for S-str1; and n2 = value of n for S-str2 
     If m1 = 3 * m2, rows will be mapped directly from S-str1 to 
                     S-str2 (three rows to one).  
     If m1 > 3 * m2, scaled rows from S-str1 will be concatinated 
                     to fit in S-str2.  
     If m1 < 3 * m2, scaled rows from S-str1 will be padded with 
                     zero bytes to fill up S-str2.  
     If n1 = 3 * n2, all rows will be scaled directly from S-str1 
                     to S-str2 (three rows to one).  
     If n1 > 3 * n2, only a sufficent number of rows from S-str1 
                     will be scaled to S-str2 to fill it up.  
     If n1 < 3 * n2, all rows from S-str1 will be scaled directly 
                     to S-str2.  The remaining rows will be set to 
                     zero bytes.  

In dealing with the space to be scaled, the COLUMN values are converted (expanded outward) to the nearest 3-BYTE boundaries, and the row values are expanded outward to the nearest 3-ROW boundaries. The minimum values for <BTYES,ROWS> are adjusted to be no less than <0,0> and the maximum values for <BTYES,ROWS> are adjusted to no greater than <m1,n1>. Then, only those rows and bytes between the minimum and maximum values are scaled.

In describing the operation for dscale2, all values of 3 should be replaced by 2. For the dscale5 instruction, all values of 3 would be replaced by 3/2.

run-time situations

In a Zbex program that uses graphics mode, certain run-time situations can occur whose behavior needs to be specified.

  1. If graphics instructions, activate, setb, or clearb, are encountered before the first execution of the bitmode instruction, this is not a problem. The graphics screen is initialized, but the user's Zbex program will not know the size of the user's X-Window display. If one of these instructions is encountered while Zbex is running in textmode, then the mode will be changed to graphics mode, and the graphics screen restored. Remember, using the bitmode instruction to change to graphics mode will clear the graphics screen.
  2. textmode may be executed any time. If Zbex is in graphics mode at the time, then textmode will cause the graphics screen to be temporarily stored.
  3. If a Zbex program is running in graphics mode, it may be temporarily suspended by changing to another window. It will be terminated if "disconnected" (<shft> KeyPad *) in the same window. If a program with graphics is suspended, it will not execute in the background. Also, when a program with graphics applications is running, all other Zbex programs are suspended. This is because the getk instruction preempts the event loop.
  4. If getc or putc is encountered while Zbex is running in graphics mode, the effect will be the same as if a textmode instruction were executed and then the getc or putc. This allows the seamless (although probably not instantaneous) transition from graphics to text and back (see 1 above).

Previous chapter
Controlling the text display with putc
Next Chapter
MIDI instructions