home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / games / backgmmn.zip / CLAIROL.C < prev    next >
Text File  |  1987-12-24  |  12KB  |  444 lines

  1.  
  2.  
  3. #include <setjmp.h>
  4. #include "ciao.h"
  5.  
  6.  
  7. /*
  8. **  clairol()  - modify screen colors or monochrome attributes "on the fly"
  9. **               popout window, updates previous screen on exit
  10. **               to reflect the newly selected values
  11. **
  12. **               returns on Control-C, resets to SIG_DFL, restores screen
  13. */
  14.  
  15.      /* Note:  Users who select a PLAIN screen create ambiguity */
  16.      /*        between the various message levels.  The NEXT    */
  17.      /*        time clairol() is called, the ambiguous colors   */
  18.      /*        default to the lower message level.  For example */
  19.      /*        if Normal and Bold have the same value on entry, */
  20.      /*        and the user changes the value of EITHER, BOTH   */
  21.      /*        Normal and Bold bytes in the screen buffer will  */
  22.      /*        be reset to the NEW NORMAL value.  This is       */
  23.      /*        because INFORMATION HAS BEEN LOST concerning the */
  24.      /*        meaning of the message levels, in the step where */
  25.      /*        user selected a PLAIN screen.                    */
  26.      /*                                                         */
  27.      /*        You should test the ambiguity flag on exit from  */
  28.      /*        clairol(), and take whatever corrective action   */
  29.      /*        is needed thereafter.                            */
  30.      /*                                                         */
  31.      /*        In cases where your program cannot tolerate the  */
  32.      /*        ambiguity a user MIGHT create (the possibility   */
  33.      /*        is there!), you should use video registers 4     */
  34.      /*        through 15, which clairol() does not alter, and  */
  35.      /*        to which users have no access; or else simply    */
  36.      /*        don't call clairol()...!  Clairol() gives the    */
  37.      /*        user permission to change things you may not     */
  38.      /*        want to be changed, in other words.              */
  39.  
  40.  
  41. #define MONOCHROME 7
  42.  
  43. int ambiguity = 0;
  44.  
  45. static void test_ambiguity()
  46. {
  47.      register int i, j;
  48.  
  49.      for ( ambiguity = i = 0; i < 3; i++ )
  50.      {
  51.          for ( j = i + 1; j < 4; j++ )
  52.          {
  53.              ambiguity |= vid[i] == vid[j]; 
  54.          }
  55.      }
  56. }
  57.  
  58.  
  59.  
  60. static jmp_buf remark;
  61. static int ch, tx, ty, which, eaSave, edSave, icon, flipflop,
  62.            nrmSave, bldSave, empSave, ntcSave;
  63.  
  64.  
  65. static void ControlC()
  66. {
  67.       longjmp(remark,-1); 
  68. }
  69.  
  70.  
  71. static void valSave()
  72. {
  73.       test_ambiguity();         /* detect plain screen */
  74.  
  75.       nrmSave = vid[0] & 0xFF;  /* normal       Vid_init() defines only these */
  76.       bldSave = vid[1] & 0xFF;  /* bold         four values for color text.   */
  77.       empSave = vid[2] & 0xFF;  /* emphasis     Programs may alter all 16     */
  78.       ntcSave = vid[3] & 0xFF;  /* notice       values of vid[], of course.   */
  79.  
  80.       eaSave  = vid[10] & 0xFF;
  81.       edSave  = vid[13] & 0xFF;
  82.       vid[10] = 0x0F;
  83.       vid[13] = 0x07;
  84. }
  85.  
  86.  
  87. static void reset()
  88. {
  89.       setwindow( tx, ty, tx + 3, ty + 5 );
  90.       wputs("^φ");
  91.       clrwindow();
  92.       setwindow( tx, ty, tx + 14, ty + 5 );
  93.       gotoxy(4,1);
  94.       wputs("^0Normal    ^φ");
  95.       gotoxy(4,2);
  96.       wputs("^1Bold      ^φ");
  97.       gotoxy(4,3);
  98.       wputs("^2Emphasis  ^φ");
  99.       gotoxy(4,4);
  100.       wputs("^3Attention!^φ");
  101. }
  102.  
  103.  
  104. static void position( line ) int line;
  105. {
  106.       reset();
  107.       gotoxy( 1,0 + line );
  108.       wink( 24 );
  109.       gotoxy( 2,1 + line );
  110.       wink( 26 );
  111.       gotoxy( 1,2 + line );
  112.       wink( 25 );
  113.       gotoxy( 0,1 + line );
  114.       wink( 27 );
  115.       gotoxy( 1,1 + line );
  116.  
  117.       wprintf("^Ω%c^φ",icon);;
  118. }
  119.  
  120.  
  121. static void normPos()
  122. {
  123.       position(0);
  124. }
  125.  
  126.  
  127. static void boldPos()
  128. {
  129.       position(1);
  130. }
  131.  
  132.  
  133. static void emphPos()
  134. {
  135.       position(2);
  136. }
  137.  
  138.  
  139. static void notePos()
  140. {
  141.       position(3);
  142. }
  143.  
  144.  
  145. static void pause()
  146. {
  147.       register int n;
  148.       for (n = 380; n; n--) if (kbhit()) break;
  149. }
  150.  
  151.  
  152. static void waitforuser()
  153. {
  154.       int flag;
  155.       flag = 0;
  156.       while (1)
  157.       {
  158.           icon = flag? 'K':'?'; normPos(); pause();
  159.           icon = flag? 'E':'A'; boldPos(); pause();
  160.           icon = flag? 'Y':'N'; emphPos(); pause();
  161.           icon = flag?  19:'Y'; notePos(); pause();
  162.           if (kbhit()) break;
  163.           else flag ^= 1;
  164.       }
  165.       while (kbhit()) getch();
  166.       icon = '?';
  167. }
  168.  
  169.  
  170. static void help()
  171. {
  172.       int k;
  173.       static char *p, *msg[] = { "re", "ob", "in" };
  174.  
  175.       if (vid_mode == MONOCHROME) p = msg[0]; /* absolute */
  176.       else p = flipflop? msg[1]: msg[2];
  177.  
  178.       wputs("^φ");
  179.       clrwindow();
  180.       wputs("^ΩF10^φ  help\n");
  181.       wprintf("^Ω%c%c%c%c^φ select\n",27,24,25,26);
  182.       wputs("^ΩF1^φ   bright\n");
  183.       wputs("^ΩF2^φ   blink\n");
  184.       wprintf("^ΩF9^φ   %sverse\n", p);
  185.       wputs("^ΩESC^φ  done!");
  186.       for (k = 20; k; k-- ) pause();
  187.       if (kbhit()) ch = keyin( noop ); else ch = '?';
  188.       clrwindow();
  189. }
  190.  
  191.  
  192.  
  193.  
  194. /*  The Monochrome Adapter case is simple... */
  195.  
  196.  
  197. static void mono()
  198. {
  199.       int ix, hibyte, lobyte, hibit, lobit;
  200.  
  201.       ix = which;
  202.       lobyte = vid[ ix ] & 0x07;  /* foreground color? */
  203.  
  204.       /* preserve status of blink and bright bits */
  205.  
  206.       lobit  = vid[ ix ] & 0x08;  /* intensity bit?    */
  207.       hibit  = vid[ ix ] & 0x80;  /* blink bit?        */
  208.  
  209.       hibyte = 0;
  210.       if (lobyte == 0) /* turn off reverse, turn on underline */
  211.       {
  212.              lobyte = 0x01;
  213.       }
  214.       else if (lobyte == 1) /* turn off underline, turn on normal */
  215.       {
  216.              lobyte = 0x07;
  217.       }
  218.       else /* turn off normal, turn on reverse */
  219.       {
  220.              lobyte = 0x00;
  221.              hibyte = 0x70;
  222.       }
  223.  
  224.       vid[ ix ] = hibyte | hibit | lobyte | lobit;
  225. }
  226.  
  227.  
  228.  
  229. /* The Color/Graphics Adapter case is even simpler...! */
  230.  
  231.  
  232. static void cgaright()
  233. {
  234.       int ix, hibyte, lobyte, hibit, lobit;
  235.  
  236.       ix = which;
  237.       lobyte = vid[ ix ] & 0x07;  /* foreground color? */
  238.       hibyte = vid[ ix ] & 0x70;  /* background color? */
  239.  
  240.       /* preserve status of blink and bright bits */
  241.  
  242.       lobit  = vid[ ix ] & 0x08;  /* intensity bit?    */
  243.       hibit  = vid[ ix ] & 0x80;  /* blink bit?        */
  244.  
  245.       if (flipflop)
  246.       {
  247.           hibyte += 0x10;
  248.           if (hibyte > 0x70) hibyte = 0;
  249.       }
  250.       else
  251.       {
  252.           ++lobyte;
  253.           if (lobyte > 7) lobyte = 0;
  254.       }
  255.       vid[ ix ] = hibyte | hibit | lobyte | lobit;
  256. }
  257.  
  258.  
  259. static void cgaleft()
  260. {
  261.       int ix, hibyte, lobyte, hibit, lobit;
  262.  
  263.       ix = which;
  264.       lobyte = vid[ ix ] & 0x07;  /* foreground color? */
  265.       hibyte = vid[ ix ] & 0x70;  /* background color? */
  266.  
  267.       /* preserve status of blink and bright bits */
  268.  
  269.       lobit  = vid[ ix ] & 0x08;  /* intensity bit?    */
  270.       hibit  = vid[ ix ] & 0x80;  /* blink bit?        */
  271.  
  272.       if (flipflop)
  273.       {
  274.           hibyte -= 0x10;
  275.           if (hibyte < 0) hibyte = 0x70;
  276.       }
  277.       else
  278.       {
  279.           --lobyte;
  280.           if (lobyte < 0) lobyte = 7;
  281.       }
  282.       vid[ ix ] = hibyte | hibit | lobyte | lobit;
  283. }
  284.  
  285.  
  286.  
  287.  
  288. static void inquire()
  289. {
  290.       unsigned bl, bt, flip;
  291.  
  292.       flipflop = which = 0;
  293.       while (ch != 27)
  294.       {
  295.             position( which );
  296.             ch = keyin( noop );
  297.             switch ( ch )
  298.             {
  299.                case  27:
  300.                {
  301.                     return;
  302.                }
  303.                case 187:   /* F1?  bright */
  304.                {
  305.                     vid[ which ] ^= 0x08;  /* toggle intensity bit */
  306.                     break;
  307.                }
  308.                case 188:   /* F2?  blink */
  309.                {
  310.                     vid[ which ] ^= 0x80;  /* toggle blink bit */
  311.                     break;
  312.                }
  313.                case 195:   /* F9?  reverse, or obverse/inverse */
  314.                {
  315.                     if (vid_mode == MONOCHROME)
  316.                     {
  317.                          flip = vid[ which ] & 0x07;  /* read foreground bits */
  318.                          bl   = vid[ which ] & 0x80;  /* save blink */
  319.                          bt   = vid[ which ] & 0x08;  /* save bright */
  320.                          if (flip)
  321.                          {
  322.                             vid[ which ] = 0x70 | bl | bt;
  323.                          }
  324.                          else
  325.                          {
  326.                             vid[ which ] = 0x07 | bl | bt;
  327.                          }
  328.                     }
  329.                     else
  330.                     {
  331.                          flipflop ^= 1;  /* foreground or background */
  332.                     }
  333.                     icon = (flipflop? 'b':'?');
  334.                     break;
  335.                }
  336.                case 196:   /* F10? */
  337.                {
  338.                     help();
  339.                     break;
  340.                }
  341.                case 200:   /* up arrow?    */
  342.                {
  343.                     if (--which < 0) which = 3;
  344.                     break;
  345.                }
  346.                case 203:   /* left arrow?  */
  347.                {
  348.                     if (vid_mode == MONOCHROME) mono();
  349.                     else cgaleft();
  350.                     break;
  351.                }
  352.                case 205:   /* right arrow? */
  353.                {
  354.                     if (vid_mode == MONOCHROME) mono();
  355.                     else cgaright();
  356.                     break;
  357.                }
  358.                case 208:   /* down arrow?  */
  359.                {
  360.                     if (++which > 3) which = 0;
  361.                     break;
  362.                }
  363.             }
  364.       }
  365. }
  366.  
  367.  
  368. static void set_hues_at( x,y ) int x,y;
  369. {
  370.       tx = x;
  371.       ty = y;
  372.       wputs("^φ");
  373.       windowbox( tx, ty, tx + 14, ty + 5 );
  374.       waitforuser(); 
  375.       help();
  376.       inquire();
  377. }
  378.  
  379.  
  380. static void setnewcolors( p ) char far *p;
  381. {
  382.      static int n, test;
  383.  
  384.      /* on entry, p points to first char in saved screen buffer */
  385.  
  386.      n = 2000;
  387.      while (n--)
  388.      {
  389.            p++;                   /* advance to attribute byte */
  390.            test = *p & 0xFF;      /* read old attribute, kill sign extension */
  391.            if (test == nrmSave)   /* update new attribute as indicated */
  392.            {
  393.                 *p = vid[0];
  394.            }
  395.            else if (test == bldSave)
  396.            {
  397.                 *p = vid[1];
  398.            }
  399.            else if (test == empSave)
  400.            {
  401.                 *p = vid[2];
  402.            }
  403.            else if (test == ntcSave)
  404.            {
  405.                 *p = vid[3];
  406.            }
  407.            p++;                   /* advance to next character */  
  408.      }
  409. }
  410.  
  411.  
  412. void clairol()
  413. {
  414.       char far *screen;
  415.       union REGS x;
  416.  
  417.       valSave();
  418.       screen = savescreen( &x );      /* get copy of original screen */
  419.       hidecursor();
  420.  
  421.       signal(SIGINT,ControlC);
  422.       if (setjmp(remark) != 0 ) 
  423.       {
  424.            vid[0] = nrmSave;          /* recover from user bailout */
  425.            vid[1] = bldSave;
  426.            vid[2] = empSave;
  427.            vid[3] = ntcSave;
  428.       }
  429.       else set_hues_at( 32,8 );
  430.  
  431.       signal(SIGINT,SIG_DFL);
  432.       while (kbhit()) getch();
  433.       vid[10] = eaSave;
  434.       vid[13] = edSave;
  435.       wputs("^0");                  /* set video attribute to new normal */
  436.       setnewcolors( screen );       /* update copy of original screen    */
  437.       restorescreen( screen, &x );  /* restore updated original screen   */
  438. }
  439.  
  440.  
  441. /* eof: clairol.c */
  442.  
  443. 
  444.