home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / audio / synthia / kbd_dsp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  23.1 KB  |  1,004 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  * Copyright (C) 1991, Silicon Graphics, Inc.
  19.  * All Rights Reserved.
  20.  */
  21.     /*
  22.      *  Display a keyboard
  23.      *
  24.      *  Routines:
  25.      *    def_kbd ()
  26.      *    display_keys (downs)
  27.      *    hilight_keys (downs)
  28.      *    display_slider (volume)
  29.      *
  30.      *  Jim Bennett
  31.      *  1991
  32.      */
  33.  
  34. #include <stdio.h>
  35. #include <math.h>
  36. #include <gl/gl.h>
  37. #include "globj.h"
  38.  
  39. extern    int    valid_texture;        /* Set by def_tex        */
  40.  
  41.  
  42. static    int    keystate [TOTAL_KEYS] = {0};
  43.  
  44. static    float    v1[3];
  45. static    float    t1[2];
  46.  
  47. #define    vx(x,y,z)    v1[0]=(x); v1[1]=(y); v1[2] = -(z); v3f(v1)
  48. #define    tx(s,t)        t1[0]=(s); t1[1]=(t); t2f(t1)
  49.  
  50.     /*
  51.      *  Offset and object structure for keyboard
  52.      */
  53.  
  54. struct    s_dspk
  55.     {
  56.     Object    key;
  57.     Object    keytop;
  58.     float    xoff;
  59.     float    zoff;
  60.     }
  61.     dspkeys [TOTAL_KEYS];
  62.  
  63.     /*
  64.      *  static saved transformation variables (for displaying keys)
  65.      */
  66.  
  67. static    float    y_off;
  68. static    float    x_rot;
  69.  
  70.     /*
  71.      *  static saved location of slider panel, dimensions of
  72.      *  volume control peg
  73.      */
  74.  
  75. static    float    vslide_x;
  76.  
  77. static    float    vslide_z1;
  78. static    float    vslide_z2;
  79.  
  80. static    float    vslide_y1;
  81. static    float    vslide_y2;
  82.  
  83. static    float    vpeg_w;
  84. static    float    vpeg_d;
  85.  
  86.     /*
  87.      *  static saved location of button patch and button dimensions
  88.      */
  89.  
  90. static    float    bpatch_x1;
  91. static    float    bpatch_x2;
  92.  
  93. static    float    bpatch_z1;
  94. static    float    bpatch_z2;
  95.  
  96. static    float    bpatch_y1;
  97. static    float    bpatch_y2;
  98.  
  99. static    float    button_w;
  100. static    float    button_d;
  101.  
  102. static    float    gap_w;
  103. static    float    gap_d;
  104.  
  105.  
  106.     /*
  107.      *  def_kbd  -  Define all graphical objects for keyboard
  108.      */
  109.  
  110. def_kbd ()
  111.  
  112.     {
  113.     float    offset, intercept;
  114.     float    logo_w, key_w;
  115.     int    i;
  116.     float    cum_x, cum_z;
  117.  
  118.     def_tex ();            /* Define texture for logo    */
  119.  
  120.     offset = (CASE_W - INSET_W) / 2.0;
  121.     intercept = FRONT_H + ((INSET_D/CASE_D) * (BACK_H - FRONT_H));
  122.     
  123. /* Define the keyboard case, top, bottom, front, back, and sides    */
  124.  
  125.     makeobj (CASE_OBJ);
  126.     pushname (CASE_OBJ);
  127.     RGBcolor (CASE_FRONT);
  128.  
  129.     bgnpolygon ();            /* Front of case    */
  130.         vx (0.0, 0.0, 0.0);
  131.         vx (offset, 0.0, 0.0);
  132.         vx (offset, FRONT_H, 0.0);
  133.         vx (0.0, FRONT_H, 0.0);
  134.     endpolygon ();
  135.     bgnpolygon ();
  136.         vx (offset, 0.0, 0.0);
  137.         vx (CASE_W-offset, 0.0, 0.0);
  138.         vx (CASE_W-offset, FRONT_H-INSET_H, 0.0);
  139.         vx (offset, FRONT_H-INSET_H, 0.0);
  140.     endpolygon ();
  141.     bgnpolygon ();
  142.         vx (CASE_W-offset, 0.0, 0.0);
  143.         vx (CASE_W, 0.0, 0.0);
  144.         vx (CASE_W, FRONT_H, 0.0);
  145.         vx (CASE_W-offset, FRONT_H, 0.0);
  146.     endpolygon ();
  147.  
  148.     bgnpolygon ();            /* Back of the case        */
  149.         vx (0.0, 0.0, CASE_D);
  150.         vx (0.0, BACK_H, CASE_D);
  151.         vx (CASE_W, BACK_H, CASE_D);
  152.         vx (CASE_W, 0.0, CASE_D);
  153.     endpolygon ();
  154.  
  155.     RGBcolor (CASE_TOP);
  156.     bgnpolygon ();            /* Top of case        */
  157.         vx (0.0, FRONT_H, 0.0);
  158.         vx (offset, FRONT_H, 0.0);
  159.         vx (offset, intercept, INSET_D);
  160.         vx (0.0, intercept, INSET_D);
  161.     endpolygon ();
  162.  
  163.     logo_w = CASE_D - INSET_D;    /* Width of logo panel    */
  164.  
  165.     bgnpolygon ();            /* Tile to edge of logo    */
  166.         vx (0.0, intercept, INSET_D);
  167.         vx (CASE_W-logo_w, intercept, INSET_D);
  168.         vx (CASE_W-logo_w, BACK_H, CASE_D);
  169.         vx (0.0, BACK_H, CASE_D);
  170.     endpolygon ();
  171.     bgnpolygon ();        /* Draw panel without logo    */
  172.         vx (CASE_W-logo_w, intercept, INSET_D);
  173.         vx (CASE_W, intercept, INSET_D);
  174.         vx (CASE_W, BACK_H, CASE_D);
  175.         vx (CASE_W-logo_w, BACK_H, CASE_D);
  176.     endpolygon ();
  177.     bgnpolygon ();
  178.         vx (CASE_W-offset, FRONT_H, 0.0);
  179.         vx (CASE_W, FRONT_H, 0.0);
  180.         vx (CASE_W, intercept, INSET_D);
  181.         vx (CASE_W-offset, intercept, INSET_D);
  182.     endpolygon ();
  183.  
  184. /* Case top finished, now paint on logo and title    */
  185.  
  186.     if (valid_texture)
  187.         {
  188.         float    logo_inset = logo_w/6.0;
  189.         float    title_inset = logo_w/3.0;
  190.         float    title_w = CASE_W/4.0;
  191.         float    intercept1 = FRONT_H +
  192.             (((INSET_D+logo_inset)/CASE_D) * (BACK_H - FRONT_H));
  193.         float    intercept2 = FRONT_H +
  194.             (((CASE_D-logo_inset)/CASE_D) * (BACK_H - FRONT_H));
  195.  
  196.         intercept1 = 1.0001 * intercept1;
  197.         intercept2 = 1.0001 * intercept2;
  198.  
  199.         RGBcolor (CASE_FRONT);
  200.         texbind (TX_TEXTURE_0, LOGO_TEX);
  201.         tevbind (TV_ENV0, DECAL_ENV);
  202.         bgnpolygon ();        /* Draw panel with logo        */
  203.             tx (0.0, 0.0);
  204.             vx ((CASE_W-logo_w)+logo_inset,
  205.                     intercept1, INSET_D+logo_inset);
  206.             tx (1.0, 0.0);
  207.             vx (CASE_W-logo_inset,
  208.                     intercept1, INSET_D+logo_inset);
  209.             tx (1.0, 1.0);
  210.             vx (CASE_W-logo_inset,
  211.                     intercept2, CASE_D-logo_inset);
  212.             tx (0.0, 1.0);
  213.             vx ((CASE_W-logo_w)+logo_inset,
  214.                     intercept2, CASE_D-logo_inset);
  215.         endpolygon ();
  216.  
  217.         intercept1 = FRONT_H +
  218.             (((INSET_D+title_inset)/CASE_D) * (BACK_H - FRONT_H));
  219.         intercept2 = FRONT_H +
  220.             (((CASE_D-title_inset)/CASE_D) * (BACK_H - FRONT_H));
  221.  
  222.         intercept1 = 1.0001 * intercept1;
  223.         intercept2 = 1.0001 * intercept2;
  224.  
  225.         texbind (TX_TEXTURE_0, TITLE_TEX);
  226.         bgnpolygon ();        /* Draw panel with title    */
  227.             tx (0.0, 0.0);
  228.             vx ((CASE_W/2.0) - (title_w/2.0),
  229.                     intercept1, INSET_D+title_inset);
  230.             tx (1.0, 0.0);
  231.             vx ((CASE_W/2.0) + (title_w/2.0),
  232.                     intercept1, INSET_D+title_inset);
  233.             tx (1.0, 1.0);
  234.             vx ((CASE_W/2.0) + (title_w/2.0),
  235.                     intercept2, CASE_D-title_inset);
  236.             tx (0.0, 1.0);
  237.             vx ((CASE_W/2.0) - (title_w/2.0),
  238.                     intercept2, CASE_D-title_inset);
  239.         endpolygon ();
  240.         texbind (TX_TEXTURE_0, 0);
  241.         tevbind (TV_ENV0, 0);
  242.         RGBcolor (CASE_TOP);
  243.         }
  244.  
  245.     bgnpolygon ();            /* Bottom of the case        */
  246.         vx (0.0, 0.0, 0.0);
  247.         vx (0.0, 0.0, CASE_D);
  248.         vx (CASE_W, 0.0, CASE_D);
  249.         vx (CASE_W, 0.0, 0.0);
  250.     endpolygon ();
  251.  
  252.     RGBcolor (CASE_SIDE);
  253.     bgnpolygon ();            /* Both sides of the case    */
  254.         vx (0.0, 0.0, 0.0);
  255.         vx (0.0, FRONT_H, 0.0);
  256.         vx (0.0, BACK_H, CASE_D);
  257.         vx (0.0, 0.0, CASE_D);
  258.     endpolygon ();
  259.     bgnpolygon ();
  260.         vx (CASE_W, 0.0, 0.0);
  261.         vx (CASE_W, 0.0, CASE_D);
  262.         vx (CASE_W, BACK_H, CASE_D);
  263.         vx (CASE_W, FRONT_H, 0.0);
  264.     endpolygon ();
  265.  
  266.     RGBcolor (CASE_FRONT);
  267.     bgnpolygon ();            /* Base of inset    */
  268.         vx (offset, FRONT_H-INSET_H, 0.0);
  269.         vx (CASE_W-offset, FRONT_H-INSET_H, 0.0);
  270.         vx (CASE_W-offset, intercept-INSET_H, INSET_D);
  271.         vx (offset, intercept-INSET_H, INSET_D);
  272.     endpolygon ();
  273.  
  274.     bgnpolygon ();            /* Sides of inset    */
  275.         vx (offset, FRONT_H-INSET_H, 0.0);
  276.         vx (offset, intercept-INSET_H, INSET_D);
  277.         vx (offset, intercept, INSET_D);
  278.         vx (offset, FRONT_H, 0.0);
  279.     endpolygon ();
  280.     bgnpolygon ();
  281.         vx (CASE_W-offset, FRONT_H-INSET_H, 0.0);
  282.         vx (CASE_W-offset, FRONT_H, 0.0);
  283.         vx (CASE_W-offset, intercept, INSET_D);
  284.         vx (CASE_W-offset, intercept-INSET_H, INSET_D);
  285.     endpolygon ();
  286.  
  287.     bgnpolygon ();            /* Back of inset    */
  288.         vx (offset, intercept-INSET_H, INSET_D);
  289.         vx (CASE_W-offset, intercept-INSET_H, INSET_D);
  290.         vx (CASE_W-offset, intercept, INSET_D);
  291.         vx (offset, intercept, INSET_D);
  292.     endpolygon ();
  293.     popname ();
  294.     closeobj ();            /* END of CASE_OBJ    */
  295.  
  296.  
  297. /* Define objects for the volume control    */
  298.  
  299.     makeobj (VSLIDER);
  300.     pushname (VSLIDER);
  301.         {            /* Draw the volume slider    */
  302.         float    vslide_inset = offset/3.0;
  303.  
  304.         vslide_x = CASE_W - (offset/2.0);
  305.  
  306.         vslide_z1 = vslide_inset;
  307.         vslide_z2 = INSET_D;
  308.  
  309.         vslide_y1 = 1.0001 * (FRONT_H +
  310.             ((vslide_inset/CASE_D) * (BACK_H - FRONT_H)) );
  311.         vslide_y2 = 1.0001 * intercept;
  312.  
  313.         vpeg_w = vslide_inset * 0.65;
  314.         vpeg_d = (vslide_z2 - vslide_z1) * 0.08;
  315.  
  316.         RGBcolor (CASE_FRONT);
  317.         bgnpolygon ();
  318.             vx ((CASE_W-offset)+vslide_inset,
  319.                         vslide_y1, vslide_z1);
  320.             vx (CASE_W-vslide_inset, vslide_y1, vslide_z1);
  321.             vx (CASE_W-vslide_inset, vslide_y2, vslide_z2);
  322.             vx ((CASE_W-offset)+vslide_inset,
  323.                         vslide_y2, vslide_z2);
  324.         endpolygon ();
  325.         }
  326.     popname ();
  327.     closeobj ();            /* END of VSLIDER    */
  328.  
  329.     makeobj (VPEG);
  330.     pushname (VPEG);
  331.         RGBcolor (WHITE_KEY_TOP);
  332.         bgnpolygon ();            /* Top surface        */
  333.             vx (0.0, VPEG_H, 0.0);
  334.             vx (vpeg_w, VPEG_H, 0.0);
  335.             vx (vpeg_w, VPEG_H, vpeg_d);
  336.             vx (0.0, VPEG_H, vpeg_d);
  337.         endpolygon ();
  338.  
  339.         RGBcolor (WHITE_KEY_SIDE);
  340.         bgnpolygon ();            /* Front surface    */
  341.             vx (0.0, 0.0, 0.0);
  342.             vx (vpeg_w, 0.0, 0.0);
  343.             vx (vpeg_w, VPEG_H, 0.0);
  344.             vx (0.0, VPEG_H, 0.0);
  345.         endpolygon ();
  346.         bgnpolygon ();            /* Side surfaces    */
  347.             vx (vpeg_w, 0.0, 0.0);
  348.             vx (vpeg_w, 0.0, vpeg_d);
  349.             vx (vpeg_w, VPEG_H, vpeg_d);
  350.             vx (vpeg_w, VPEG_H, 0.0);
  351.         endpolygon ();
  352.         bgnpolygon ();
  353.             vx (0.0, 0.0, vpeg_d);
  354.             vx (0.0, 0.0, 0.0);
  355.             vx (0.0, VPEG_H, 0.0);
  356.             vx (0.0, VPEG_H, vpeg_d);
  357.         endpolygon ();
  358.         bgnpolygon ();            /* Back surface        */
  359.             vx (vpeg_w, 0.0, vpeg_d);
  360.             vx (0.0, 0.0, vpeg_d);
  361.             vx (0.0, VPEG_H, vpeg_d);
  362.             vx (vpeg_w, VPEG_H, vpeg_d);
  363.         endpolygon ();
  364.     popname ();
  365.     closeobj ();            /* END of VPEG        */
  366.  
  367. /* Define objects for the button panel (voice select)    */
  368.  
  369.     makeobj (BPATCH);
  370.     pushname (BPATCH);
  371.         {            /* Draw the background patch    */
  372.         float    bpatch_inset = logo_w/6.0;
  373.  
  374.         bpatch_x1 = bpatch_inset;
  375.         bpatch_x2 = (5.0*CASE_W)/16.0;
  376.  
  377.         bpatch_z1 = INSET_D + bpatch_inset;
  378.         bpatch_z2 = CASE_D - bpatch_inset;
  379.  
  380.         bpatch_y1 = 1.0001 * (FRONT_H +
  381.             ((bpatch_z1/CASE_D) * (BACK_H - FRONT_H)) );
  382.         bpatch_y2 = 1.0001 * (FRONT_H +
  383.             ((bpatch_z2/CASE_D) * (BACK_H - FRONT_H)) );
  384.  
  385.         RGBcolor (CASE_FRONT);
  386.         bgnpolygon ();
  387.             vx (bpatch_x1, bpatch_y1, bpatch_z1);
  388.             vx (bpatch_x2, bpatch_y1, bpatch_z1);
  389.             vx (bpatch_x2, bpatch_y2, bpatch_z2);
  390.             vx (bpatch_x1, bpatch_y2, bpatch_z2);
  391.         endpolygon ();
  392.         }
  393.     popname ();
  394.     closeobj ();            /* END of BPATCH    */
  395.  
  396.         {            /* Compute the button sizes and    */
  397.                     /* spacings.            */
  398.         int    nwide = NUM_BUTTONS/2;
  399.         int    nhigh = 2;
  400.         int    wgaps = nwide+1;
  401.         int    hgaps = nhigh+1;
  402.  
  403.         button_w = (0.6*(bpatch_x2-bpatch_x1)) / nwide;
  404.         gap_w = (0.4*(bpatch_x2-bpatch_x1)) / wgaps;
  405.         button_d = (0.4*(bpatch_z2-bpatch_z1)) / nhigh;
  406.         gap_d = (0.6*(bpatch_z2-bpatch_z1)) / hgaps;
  407.         }
  408.  
  409.     makeobj (SEL_BUTTON);
  410.         RGBcolor (WHITE_KEY_TOP);
  411.         bgnpolygon ();            /* Top surface        */
  412.             vx (0.0, BUTTON_H, 0.0);
  413.             vx (button_w, BUTTON_H, 0.0);
  414.             vx (button_w, BUTTON_H, button_d);
  415.             vx (0.0, BUTTON_H, button_d);
  416.         endpolygon ();
  417.  
  418.         RGBcolor (WHITE_KEY_SIDE);
  419.         bgnpolygon ();            /* Front surface    */
  420.             vx (0.0, 0.0, 0.0);
  421.             vx (button_w, 0.0, 0.0);
  422.             vx (button_w, BUTTON_H, 0.0);
  423.             vx (0.0, BUTTON_H, 0.0);
  424.         endpolygon ();
  425.         bgnpolygon ();            /* Side surfaces    */
  426.             vx (button_w, 0.0, 0.0);
  427.             vx (button_w, 0.0, button_d);
  428.             vx (button_w, BUTTON_H, button_d);
  429.             vx (button_w, BUTTON_H, 0.0);
  430.         endpolygon ();
  431.         bgnpolygon ();
  432.             vx (0.0, 0.0, button_d);
  433.             vx (0.0, 0.0, 0.0);
  434.             vx (0.0, BUTTON_H, 0.0);
  435.             vx (0.0, BUTTON_H, button_d);
  436.         endpolygon ();
  437.         bgnpolygon ();            /* Back surface        */
  438.             vx (button_w, 0.0, button_d);
  439.             vx (0.0, 0.0, button_d);
  440.             vx (0.0, BUTTON_H, button_d);
  441.             vx (button_w, BUTTON_H, button_d);
  442.         endpolygon ();
  443.     closeobj ();
  444.  
  445.     makeobj (DOWN_BUTTON);
  446.         RGBcolor (WHITE_KEY_TOP);
  447.         bgnpolygon ();            /* Top surface        */
  448.             vx (0.0, DOWN_BUTTON_H, 0.0);
  449.             vx (button_w, DOWN_BUTTON_H, 0.0);
  450.             vx (button_w, DOWN_BUTTON_H, button_d);
  451.             vx (0.0, DOWN_BUTTON_H, button_d);
  452.         endpolygon ();
  453.  
  454.         RGBcolor (WHITE_KEY_SIDE);
  455.         bgnpolygon ();            /* Front surface    */
  456.             vx (0.0, 0.0, 0.0);
  457.             vx (button_w, 0.0, 0.0);
  458.             vx (button_w, DOWN_BUTTON_H, 0.0);
  459.             vx (0.0, DOWN_BUTTON_H, 0.0);
  460.         endpolygon ();
  461.         bgnpolygon ();            /* Side surfaces    */
  462.             vx (button_w, 0.0, 0.0);
  463.             vx (button_w, 0.0, button_d);
  464.             vx (button_w, DOWN_BUTTON_H, button_d);
  465.             vx (button_w, DOWN_BUTTON_H, 0.0);
  466.         endpolygon ();
  467.         bgnpolygon ();
  468.             vx (0.0, 0.0, button_d);
  469.             vx (0.0, 0.0, 0.0);
  470.             vx (0.0, DOWN_BUTTON_H, 0.0);
  471.             vx (0.0, DOWN_BUTTON_H, button_d);
  472.         endpolygon ();
  473.         bgnpolygon ();            /* Back surface        */
  474.             vx (button_w, 0.0, button_d);
  475.             vx (0.0, 0.0, button_d);
  476.             vx (0.0, DOWN_BUTTON_H, button_d);
  477.             vx (button_w, DOWN_BUTTON_H, button_d);
  478.         endpolygon ();
  479.     closeobj ();
  480.  
  481.     key_w = 0.85 * (INSET_W/WHITE_KEYS);
  482.     makeobj (KEYL);
  483.  
  484.     RGBcolor (WHITE_KEY_SIDE);
  485.     bgnpolygon ();            /* Front surface    */
  486.         vx (0.0, 0.0, 0.0);
  487.         vx (key_w, 0.0, 0.0);
  488.         vx (key_w, INSET_H, 0.0);
  489.         vx (0.0, INSET_H, 0.0);
  490.     endpolygon ();
  491.  
  492.     bgnpolygon ();            /* Left side        */
  493.         vx (0.0, 0.0, 0.0);
  494.         vx (0.0, INSET_H, 0.0);
  495.         vx (0.0, INSET_H, INSET_D/3.0);
  496.         vx (0.0, 0.0, INSET_D/3.0);
  497.     endpolygon ();
  498.  
  499.     bgnpolygon ();            /* Right side        */
  500.         vx (key_w, 0.0, 0.0);
  501.         vx (key_w, 0.0, INSET_D);
  502.         vx (key_w, INSET_H, INSET_D);
  503.         vx (key_w, INSET_H, 0.0);
  504.     endpolygon ();
  505.  
  506.     RGBcolor (WHITE_KEY_TOP);
  507.     callobj (KEYL_TOP);
  508.  
  509.     closeobj ();            /* END of KEYL        */
  510.  
  511.     makeobj (KEYL_TOP);
  512.     bgnpolygon ();            /* Top surface        */
  513.         vx (0.0, INSET_H, 0.0);
  514.         vx (key_w, INSET_H, 0.0);
  515.         vx (key_w, INSET_H, INSET_D/3.0);
  516.         vx (0.0, INSET_H, INSET_D/3.0);
  517.     endpolygon ();
  518.     bgnpolygon ();
  519.         vx (key_w/3.0, INSET_H, INSET_D/3.0);
  520.         vx (key_w, INSET_H, INSET_D/3.0);
  521.         vx (key_w, INSET_H, INSET_D);
  522.         vx (key_w/3.0, INSET_H, INSET_D);
  523.     endpolygon ();
  524.     closeobj ();            /* END of KEYL_TOP    */
  525.  
  526.  
  527.     makeobj (KEYR);
  528.  
  529.     RGBcolor (WHITE_KEY_SIDE);
  530.     bgnpolygon ();            /* Front surface    */
  531.         vx (0.0, 0.0, 0.0);
  532.         vx (key_w, 0.0, 0.0);
  533.         vx (key_w, INSET_H, 0.0);
  534.         vx (0.0, INSET_H, 0.0);
  535.     endpolygon ();
  536.  
  537.     bgnpolygon ();            /* Left side        */
  538.         vx (0.0, 0.0, 0.0);
  539.         vx (0.0, INSET_H, 0.0);
  540.         vx (0.0, INSET_H, INSET_D);
  541.         vx (0.0, 0.0, INSET_D);
  542.     endpolygon ();
  543.  
  544.     bgnpolygon ();            /* Right side        */
  545.         vx (key_w, 0.0, 0.0);
  546.         vx (key_w, 0.0, INSET_D/3.0);
  547.         vx (key_w, INSET_H, INSET_D/3.0);
  548.         vx (key_w, INSET_H, 0.0);
  549.     endpolygon ();
  550.  
  551.     RGBcolor (WHITE_KEY_TOP);
  552.     callobj (KEYR_TOP);
  553.  
  554.     closeobj ();            /* END of KEYR        */
  555.  
  556.     makeobj (KEYR_TOP);
  557.     bgnpolygon ();            /* Top surface        */
  558.         vx (0.0, INSET_H, 0.0);
  559.         vx (key_w, INSET_H, 0.0);
  560.         vx (key_w, INSET_H, INSET_D/3.0);
  561.         vx (0.0, INSET_H, INSET_D/3.0);
  562.     endpolygon ();
  563.     bgnpolygon ();
  564.         vx (0.0, INSET_H, INSET_D/3.0);
  565.         vx ((2.0*key_w)/3.0, INSET_H, INSET_D/3.0);
  566.         vx ((2.0*key_w)/3.0, INSET_H, INSET_D);
  567.         vx (0.0, INSET_H, INSET_D);
  568.     endpolygon ();
  569.     closeobj ();            /* END of KEYR_TOP    */
  570.  
  571.  
  572.     makeobj (KEYB);
  573.  
  574.     RGBcolor (WHITE_KEY_SIDE);
  575.     bgnpolygon ();            /* Front surface    */
  576.         vx (0.0, 0.0, 0.0);
  577.         vx (key_w, 0.0, 0.0);
  578.         vx (key_w, INSET_H, 0.0);
  579.         vx (0.0, INSET_H, 0.0);
  580.     endpolygon ();
  581.  
  582.     bgnpolygon ();            /* Left side        */
  583.         vx (0.0, 0.0, 0.0);
  584.         vx (0.0, INSET_H, 0.0);
  585.         vx (0.0, INSET_H, INSET_D/3.0);
  586.         vx (0.0, 0.0, INSET_D/3.0);
  587.     endpolygon ();
  588.  
  589.     bgnpolygon ();            /* Right side        */
  590.         vx (key_w, 0.0, 0.0);
  591.         vx (key_w, 0.0, INSET_D/3.0);
  592.         vx (key_w, INSET_H, INSET_D/3.0);
  593.         vx (key_w, INSET_H, 0.0);
  594.     endpolygon ();
  595.  
  596.     RGBcolor (WHITE_KEY_TOP);
  597.     callobj (KEYB_TOP);
  598.  
  599.     closeobj ();            /* END of KEYB        */
  600.  
  601.     makeobj (KEYB_TOP);
  602.     bgnpolygon ();            /* Top surface        */
  603.         vx (0.0, INSET_H, 0.0);
  604.         vx (key_w, INSET_H, 0.0);
  605.         vx (key_w, INSET_H, INSET_D/3.0);
  606.         vx (0.0, INSET_H, INSET_D/3.0);
  607.     endpolygon ();
  608.     bgnpolygon ();
  609.         vx (key_w/3.0, INSET_H, INSET_D/3.0);
  610.         vx ((2.0*key_w)/3.0, INSET_H, INSET_D/3.0);
  611.         vx ((2.0*key_w)/3.0, INSET_H, INSET_D);
  612.         vx (key_w/3.0, INSET_H, INSET_D);
  613.     endpolygon ();
  614.     closeobj ();            /* END of KEYB_TOP    */
  615.  
  616.  
  617.     makeobj (KEYN);
  618.  
  619.     RGBcolor (WHITE_KEY_SIDE);
  620.     bgnpolygon ();            /* Front surface    */
  621.         vx (0.0, 0.0, 0.0);
  622.         vx (key_w, 0.0, 0.0);
  623.         vx (key_w, INSET_H, 0.0);
  624.         vx (0.0, INSET_H, 0.0);
  625.     endpolygon ();
  626.  
  627.     bgnpolygon ();            /* Left side        */
  628.         vx (0.0, 0.0, 0.0);
  629.         vx (0.0, INSET_H, 0.0);
  630.         vx (0.0, INSET_H, INSET_D);
  631.         vx (0.0, 0.0, INSET_D);
  632.     endpolygon ();
  633.  
  634.     bgnpolygon ();            /* Right side        */
  635.         vx (key_w, 0.0, 0.0);
  636.         vx (key_w, 0.0, INSET_D);
  637.         vx (key_w, INSET_H, INSET_D);
  638.         vx (key_w, INSET_H, 0.0);
  639.     endpolygon ();
  640.  
  641.     RGBcolor (WHITE_KEY_TOP);
  642.     callobj (KEYN_TOP);
  643.  
  644.     closeobj ();            /* END of KEYN        */
  645.  
  646.     makeobj (KEYN_TOP);
  647.     bgnpolygon ();            /* Top surface        */
  648.         vx (0.0, INSET_H, 0.0);
  649.         vx (key_w, INSET_H, 0.0);
  650.         vx (key_w, INSET_H, INSET_D);
  651.         vx (0.0, INSET_H, INSET_D);
  652.     endpolygon ();
  653.     closeobj ();            /* END of KEYN_TOP    */
  654.  
  655.  
  656.     makeobj (BLKEY);
  657.     RGBcolor (BLACK_KEY_SIDE);
  658.     bgnpolygon ();            /* Front surface    */
  659.         vx (0.0, 0.0, 0.0);
  660.         vx ((2.0*key_w)/3.0, 0.0, 0.0);
  661.         vx ((2.0*key_w)/3.0, BLACK_KEY_H, 0.0);
  662.         vx (0.0, BLACK_KEY_H, 0.0);
  663.     endpolygon ();
  664.  
  665.     bgnpolygon ();            /* Left side        */
  666.         vx ((2.0*key_w)/3.0, 0.0, 0.0);
  667.         vx ((2.0*key_w)/3.0, 0.0, (2.0*INSET_D)/3.0);
  668.         vx ((2.0*key_w)/3.0, BLACK_KEY_H, (2.0*INSET_D)/3.0);
  669.         vx ((2.0*key_w)/3.0, BLACK_KEY_H, 0.0);
  670.     endpolygon ();
  671.  
  672.     bgnpolygon ();            /* Right side        */
  673.         vx (0.0, 0.0, 0.0);
  674.         vx (0.0, BLACK_KEY_H, 0.0);
  675.         vx (0.0, BLACK_KEY_H, (2.0*INSET_D)/3.0);
  676.         vx (0.0, 0.0, (2.0*INSET_D)/3.0);
  677.     endpolygon ();
  678.  
  679.     RGBcolor (BLACK_KEY_TOP);
  680.     callobj (BLKEY_TOP);
  681.  
  682.     closeobj ();            /* END of BLKEY        */
  683.  
  684.     makeobj (BLKEY_TOP);
  685.     bgnpolygon ();            /* Top surface        */
  686.         vx (0.0, BLACK_KEY_H, 0.0);
  687.         vx ((2.0*key_w)/3.0, BLACK_KEY_H, 0.0);
  688.         vx ((2.0*key_w)/3.0, BLACK_KEY_H, (2.0*INSET_D)/3.0);
  689.         vx (0.0, BLACK_KEY_H, (2.0*INSET_D)/3.0);
  690.     endpolygon ();
  691.     closeobj ();            /* END of BLKEY_TOP    */
  692.  
  693.  
  694.     makeobj (OCTAVE);
  695.     pushmatrix ();
  696.     callobj (KEYR);
  697.     translate ((2.0*key_w)/3.0, 0.0, -INSET_D/3.0);
  698.     callobj (BLKEY);
  699.     translate ((INSET_W/WHITE_KEYS) - ((2.0*key_w)/3.0), 0.0, INSET_D/3.0);
  700.  
  701.     callobj (KEYB);
  702.     translate ((2.0*key_w)/3.0, 0.0, -INSET_D/3.0);
  703.     callobj (BLKEY);
  704.     translate ((INSET_W/WHITE_KEYS) - ((2.0*key_w)/3.0), 0.0, INSET_D/3.0);
  705.  
  706.     callobj (KEYL);
  707.     translate (INSET_W/WHITE_KEYS, 0.0, 0.0);
  708.  
  709.     callobj (KEYR);
  710.     translate ((2.0*key_w)/3.0, 0.0, -INSET_D/3.0);
  711.     callobj (BLKEY);
  712.     translate ((INSET_W/WHITE_KEYS) - ((2.0*key_w)/3.0), 0.0, INSET_D/3.0);
  713.  
  714.     callobj (KEYB);
  715.     translate ((2.0*key_w)/3.0, 0.0, -INSET_D/3.0);
  716.     callobj (BLKEY);
  717.     translate ((INSET_W/WHITE_KEYS) - ((2.0*key_w)/3.0), 0.0, INSET_D/3.0);
  718.  
  719.     callobj (KEYB);
  720.     translate ((2.0*key_w)/3.0, 0.0, -INSET_D/3.0);
  721.     callobj (BLKEY);
  722.     translate ((INSET_W/WHITE_KEYS) - ((2.0*key_w)/3.0), 0.0, INSET_D/3.0);
  723.  
  724.     callobj (KEYL);
  725.     popmatrix ();
  726.     closeobj ();            /* END of OCTAVE    */
  727.  
  728.  
  729.     makeobj (ALL_KEYS);
  730.     pushmatrix ();
  731.     translate (offset+(0.075*(INSET_W/WHITE_KEYS)), FRONT_H-INSET_H,
  732.             INSET_D/20.0);
  733.     rot (180.0 * fatan((BACK_H-FRONT_H)/CASE_D) / M_PI, 'x');
  734.     callobj (OCTAVE);
  735.     translate (7.0 * (INSET_W/WHITE_KEYS), 0.0, 0.0);
  736.     callobj (OCTAVE);
  737.     translate (7.0 * (INSET_W/WHITE_KEYS), 0.0, 0.0);
  738.     callobj (OCTAVE);
  739.     translate (7.0 * (INSET_W/WHITE_KEYS), 0.0, 0.0);
  740.     callobj (OCTAVE);
  741.     translate (7.0 * (INSET_W/WHITE_KEYS), 0.0, 0.0);
  742.     callobj (OCTAVE);
  743.     translate (7.0 * (INSET_W/WHITE_KEYS), 0.0, 0.0);
  744.     callobj (KEYN);
  745.     popmatrix ();
  746.     closeobj ();            /* END of ALL_KEYS    */
  747.  
  748. /* Objects all made, fill in the dspkeys structure    */
  749. /* Set the initial offsets to the keys    */
  750.  
  751.     cum_x = offset+(0.075*(INSET_W/WHITE_KEYS));
  752.     cum_z = INSET_D/20.0;
  753.  
  754.     for (i=0; i<LAST_KEY; )
  755.         {
  756.         dspkeys[i].key = KEYR;
  757.         dspkeys[i].keytop = KEYR_TOP;
  758.         if (i != 0)
  759.             {
  760.             cum_x += INSET_W/WHITE_KEYS;
  761.             cum_z += 0.0;
  762.             }
  763.         dspkeys[i].xoff = cum_x;
  764.         dspkeys[i].zoff = cum_z;
  765.         i++;
  766.  
  767.  
  768.         dspkeys[i].key = BLKEY;
  769.         dspkeys[i].keytop = BLKEY_TOP;
  770.         cum_x += (2.0*key_w)/3.0;
  771.         cum_z += -INSET_D/3.0;
  772.         dspkeys[i].xoff = cum_x;
  773.         dspkeys[i].zoff = cum_z;
  774.         i++;
  775.  
  776.         dspkeys[i].key = KEYB;
  777.         dspkeys[i].keytop = KEYB_TOP;
  778.         cum_x += (INSET_W/WHITE_KEYS) - ((2.0*key_w)/3.0);
  779.         cum_z += INSET_D/3.0;
  780.         dspkeys[i].xoff = cum_x;
  781.         dspkeys[i].zoff = cum_z;
  782.         i++;
  783.  
  784.         dspkeys[i].key = BLKEY;
  785.         dspkeys[i].keytop = BLKEY_TOP;
  786.         cum_x += (2.0*key_w)/3.0;
  787.         cum_z += -INSET_D/3.0;
  788.         dspkeys[i].xoff = cum_x;
  789.         dspkeys[i].zoff = cum_z;
  790.         i++;
  791.  
  792.         dspkeys[i].key = KEYL;
  793.         dspkeys[i].keytop = KEYL_TOP;
  794.         cum_x += (INSET_W/WHITE_KEYS) - ((2.0*key_w)/3.0);
  795.         cum_z += INSET_D/3.0;
  796.         dspkeys[i].xoff = cum_x;
  797.         dspkeys[i].zoff = cum_z;
  798.         i++;
  799.  
  800.         dspkeys[i].key = KEYR;
  801.         dspkeys[i].keytop = KEYR_TOP;
  802.         cum_x += INSET_W/WHITE_KEYS;
  803.         cum_z += 0.0;
  804.         dspkeys[i].xoff = cum_x;
  805.         dspkeys[i].zoff = cum_z;
  806.         i++;
  807.  
  808.         dspkeys[i].key = BLKEY;
  809.         dspkeys[i].keytop = BLKEY_TOP;
  810.         cum_x += (2.0*key_w)/3.0;
  811.         cum_z += -INSET_D/3.0;
  812.         dspkeys[i].xoff = cum_x;
  813.         dspkeys[i].zoff = cum_z;
  814.         i++;
  815.  
  816.         dspkeys[i].key = KEYB;
  817.         dspkeys[i].keytop = KEYB_TOP;
  818.         cum_x += (INSET_W/WHITE_KEYS) - ((2.0*key_w)/3.0);
  819.         cum_z += INSET_D/3.0;
  820.         dspkeys[i].xoff = cum_x;
  821.         dspkeys[i].zoff = cum_z;
  822.         i++;
  823.  
  824.         dspkeys[i].key = BLKEY;
  825.         dspkeys[i].keytop = BLKEY_TOP;
  826.         cum_x += (2.0*key_w)/3.0;
  827.         cum_z += -INSET_D/3.0;
  828.         dspkeys[i].xoff = cum_x;
  829.         dspkeys[i].zoff = cum_z;
  830.         i++;
  831.  
  832.         dspkeys[i].key = KEYB;
  833.         dspkeys[i].keytop = KEYB_TOP;
  834.         cum_x += (INSET_W/WHITE_KEYS) - ((2.0*key_w)/3.0);
  835.         cum_z += INSET_D/3.0;
  836.         dspkeys[i].xoff = cum_x;
  837.         dspkeys[i].zoff = cum_z;
  838.         i++;
  839.  
  840.         dspkeys[i].key = BLKEY;
  841.         dspkeys[i].keytop = BLKEY_TOP;
  842.         cum_x += (2.0*key_w)/3.0;
  843.         cum_z += -INSET_D/3.0;
  844.         dspkeys[i].xoff = cum_x;
  845.         dspkeys[i].zoff = cum_z;
  846.         i++;
  847.  
  848.         dspkeys[i].key = KEYL;
  849.         dspkeys[i].keytop = KEYL_TOP;
  850.         cum_x += (INSET_W/WHITE_KEYS) - ((2.0*key_w)/3.0);
  851.         cum_z += INSET_D/3.0;
  852.         dspkeys[i].xoff = cum_x;
  853.         dspkeys[i].zoff = cum_z;
  854.         i++;
  855.         }
  856.     dspkeys[LAST_KEY].key = KEYN;
  857.     dspkeys[LAST_KEY].keytop = KEYN_TOP;
  858.     dspkeys[LAST_KEY].xoff = dspkeys[LAST_KEY-1].xoff + INSET_W/WHITE_KEYS;
  859.     dspkeys[LAST_KEY].zoff = dspkeys[LAST_KEY-1].zoff;
  860.  
  861.     y_off = FRONT_H-INSET_H;
  862.     x_rot = 180.0 * fatan((BACK_H-FRONT_H)/CASE_D) / M_PI;
  863.     }
  864.  
  865.     /*
  866.      *  display_keys  -  Display all of the keys in their current
  867.      *            state (up or down)
  868.      */
  869.  
  870. display_keys (downs)
  871.  
  872.     int    *downs;
  873.  
  874.     {
  875.     int    i;
  876.  
  877.     pushmatrix ();
  878.     rot (x_rot, 'x');
  879.  
  880.     for (i=0; i<TOTAL_KEYS; i++)
  881.         {
  882.         pushname (KEYNAMES+i);
  883.         pushmatrix ();
  884.         if (downs[i])
  885.             translate (dspkeys[i].xoff, y_off-DEPRESS_H,
  886.                             dspkeys[i].zoff);
  887.         else
  888.             translate (dspkeys[i].xoff, y_off, dspkeys[i].zoff);
  889.         keystate[i] = downs[i];
  890.         callobj (dspkeys[i].key);
  891.         popmatrix ();
  892.         popname ();
  893.         }
  894.     popmatrix ();
  895.     }
  896.  
  897.     /*
  898.      *  hilight_keys  -  Hilight the keys that are depressed
  899.      *
  900.      *    Only updates keys whose states have changed
  901.      */
  902.  
  903. hilight_keys (downs)
  904.  
  905.     int    *downs;
  906.  
  907.     {
  908.     int    i;
  909.  
  910.     pushmatrix ();
  911.     rot (x_rot, 'x');
  912.  
  913. /* Display the changed key tops        */
  914.  
  915.     for (i=0; i<TOTAL_KEYS; i++)
  916.         {
  917.         if (downs[i] != keystate[i])
  918.             {
  919.             pushmatrix ();
  920.             if (downs[i])
  921.                 RGBcolor (HILIGHT);
  922.             else
  923.                 {
  924.                 if (dspkeys[i].key == BLKEY)
  925.                     RGBcolor (BLACK_KEY_TOP);
  926.                 else
  927.                     RGBcolor (WHITE_KEY_TOP);
  928.                 }
  929.             translate (dspkeys[i].xoff, y_off, dspkeys[i].zoff);
  930.             callobj (dspkeys[i].keytop);
  931.             keystate[i] = downs[i];
  932.             popmatrix ();
  933.             }
  934.         }
  935.     popmatrix ();
  936.     }
  937.  
  938.     /*
  939.      *  display_slider  -  Display volume slider at given volume
  940.      */
  941.  
  942. display_slider (volume)
  943.  
  944.     float    volume;
  945.  
  946.     {
  947.     zbuffer (FALSE);        /* So redraw works    */
  948.     callobj (VSLIDER);
  949.  
  950.     pushmatrix ();
  951.     translate ( vslide_x - (vpeg_w/2),
  952.             (vslide_y1 + volume*(vslide_y2-vslide_y1)),
  953.             -(vslide_z1 + volume*(vslide_z2-vslide_z1)) + vpeg_d/2 );
  954.     callobj (VPEG);
  955.     popmatrix ();
  956.  
  957.     zbuffer (TRUE);
  958.     }
  959.  
  960.     /*
  961.      *  display_buttons  -  Display instrument selection buttons
  962.      */
  963.  
  964. display_buttons (selection)
  965.  
  966.     int    selection;
  967.  
  968.     {
  969.     int    i;
  970.     float    x, y, z;
  971.  
  972.     zbuffer (FALSE);        /* So redraw works      */
  973.     callobj (BPATCH);
  974.  
  975.     x = bpatch_x1+gap_w;
  976.     z = bpatch_z1+gap_d;
  977.     y = 1.0001 * (FRONT_H + ((z/CASE_D) * (BACK_H - FRONT_H)) );
  978.  
  979.     for (i=0; i<NUM_BUTTONS; i++)
  980.         {
  981.         if (i == (NUM_BUTTONS/2))
  982.             {
  983.             x = bpatch_x1+gap_w;
  984.             z += button_d + gap_d;
  985.             y = 1.0001 * (FRONT_H +
  986.                       ((z/CASE_D) * (BACK_H - FRONT_H)) );
  987.             }
  988.  
  989.         pushmatrix ();
  990.         translate (x, y, -z);
  991.         pushname (SEL_BUTTON+i);
  992.         if (i == selection)
  993.             callobj (DOWN_BUTTON);
  994.         else
  995.             callobj (SEL_BUTTON);
  996.         popname ();
  997.         popmatrix ();
  998.  
  999.         x += (button_w + gap_w);
  1000.         }
  1001.  
  1002.     zbuffer (TRUE);
  1003.     }
  1004.