home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_02_02 / 2n02019a < prev    next >
Text File  |  1991-01-01  |  15KB  |  483 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <dos.h>
  5. #include <conio.h>
  6. #include "defs.h"
  7.  
  8. #define YES    1
  9. #define NO     0
  10. #define ESCAPE 0x1B
  11. #define EGM    0x10
  12. #define VGM    0x12
  13. #define BYTESPERLINE 80
  14.  
  15. UCHAR _far *BiosData       = (UCHAR _far *) 0;
  16. UCHAR _far *BiosFontPtr    = (UCHAR _far *) 0;
  17. UCHAR _far *GraphicsBuffer = (UCHAR _far *) 0;
  18. UCHAR _far *BottomOfMemory = (UCHAR _far *) 0;
  19. UINT  DOS_Extender         = DOS_REALMODE;
  20. UINT  SelectorAliasMask    = 0;
  21.  
  22. USHORT  VideoSelectors[] = 
  23.     {
  24.     0xA000,  /*DOS VGA segment  */
  25.     0x001C,  /*PHARLAP selector */
  26.     0x00D0,  /*OS/286  selector */
  27.     0x00D0,  /*OS/386  selector */
  28.     };
  29.  
  30. typedef struct
  31.    {
  32.    int   Xul;            /* Upper Left X coordinate */
  33.    int   Yul;             /* Upper Left Y coordinate */
  34.    int   Xlr;             /* Lower Left X coordinate */
  35.    int   Ylr;             /* Lower Left Y coordinate */
  36.    int   BorderWidth;     /* Border Width            */
  37.    int   LeftEdgeColor;  /* Left/Top Edge Color     */
  38.    int   RightEdgeColor; /* Right/Bottom Edge Color */
  39.    int   InteriorColor;     /* Interior Window Color   */
  40.    int   BorderFillColor;/* Border Surface Color    */
  41.    int   BorderFillWidth;/* Border Surface Width    */
  42.    int   TitleBarColor;  /* Title Bar Color         */
  43.    int   TitleBarWidth;  /* Title Bar Width         */
  44.    char  Title[129];     /* Title String            */
  45.    }WIN, *WINPTR;
  46.  
  47. WIN  Win = {        200, /* Xul             _A */
  48.                     50, /* Yul             _B */
  49.                    440, /* Xlr             _C */
  50.                    300, /* Ylr             _D */
  51.                      3, /* BorderWidth     _E */
  52.                     15, /* LeftEdgeColor   _F */
  53.                      8, /* RightEdgeColor  _G */
  54.                      3, /* InteriorColor   _H */
  55.                      7, /* BorderFillColor _I */
  56.                      6, /* BorderFillWidth _J */
  57.                      7, /* TitleBarColor   _K */
  58.                     15, /* TitleBarWidth   _L */
  59.        "Clock Demo"};/* Title        _M */
  60.  
  61. #define _A W->Xul             
  62. #define _B W->Yul             
  63. #define _C W->Xlr             
  64. #define _D W->Ylr             
  65. #define _E W->BorderWidth     
  66. #define _F W->LeftEdgeColor   
  67. #define _G W->RightEdgeColor  
  68. #define _H W->InteriorColor   
  69. #define _I W->BorderFillColor 
  70. #define _J W->BorderFillWidth 
  71. #define _K W->TitleBarColor   
  72. #define _L W->TitleBarWidth   
  73. #define _M W->Title           
  74.  
  75. char timedisplay[12] = "  :  :   PM";
  76. UINT last_sec  = 3601;
  77. int  clock_x   = 240;
  78. int  clock_y   = 100;
  79. int  clock_f   =   3; /* Win.InteriorColor */
  80. int  clock_b   =   7; /* Win.TitleBarColor */
  81. int  inputc    = (char) 0xFF;
  82. int  Red       = 0;
  83. int  Green     = 30;
  84. int  Blue      = 30;
  85. int  VideoMode = EGM;
  86. int  VideoModeAtEntry;
  87.  
  88. void   main(void);
  89. void   Initialize(void);
  90. void   KeyStrokeLoop(void);
  91. void   Terminate(void);
  92. void   DrawWin(WINPTR W);
  93. void   SetDAC(int regnum, int red, int green, int blue);
  94. void   WriteTime(void);
  95. UINT   CalcTime(void);
  96. void   UpdateClock(void);
  97. UCHAR  SavRegVGAController(UCHAR IndexReg);
  98. void   SetRegVGAController(UCHAR IndexReg, UCHAR Value);
  99. void   DisplayChar(int c, int x, int y, int fgd, int bkgd);
  100. void   VerticleLine(int x1, int y1, int y2, int n);
  101. void   HorizontalLine(int x1, int y1, int x2, int n);
  102.  
  103. extern void SetVideoMode(int mode);
  104. extern int  GetVideoMode(void);
  105. extern UINT GetExtender(void);
  106. extern void HookTimer(void);
  107. extern void UnHookTimer(void);
  108.  
  109. void main(void)
  110. {
  111.    Initialize();
  112.    KeyStrokeLoop();
  113.    Terminate();
  114. }
  115.  
  116. void Initialize(void)
  117. {
  118.    union REGS regs;
  119.  
  120.    switch (DOS_Extender = GetExtender())
  121.       {
  122.       case ERGO_OS286:
  123.            FP_MAK(BiosData, 0x0000, 0x0040);
  124.        regs.x.AX = 0xE803;/* OS/286 create real window  */
  125.            regs.x.BX = 0x00;  /* SI:BX points to DOS zero   */
  126.            regs.x.CX = 0xFFFF;/* 64K segment length         */
  127.            regs.x.DX = 0x00;  /* high word of window length */
  128.            regs.x.SI = 0x00;
  129.            int86(0x21, ®s, ®s);
  130.            FP_MAK(BottomOfMemory, 0x0000, regs.x.AX);
  131.            regs.x.AX = 0xE803;/* OS/286 create real window  */
  132.            regs.x.BX = 0x00;  /* SI:BX VGA BIOS segment     */
  133.            regs.x.CX = 0xFFFF;/* 64K segment length         */
  134.            regs.x.DX = 0x00;  /* high word of window length */
  135.            regs.x.SI = 0x0C;
  136.            int86(0x21, ®s, ®s);
  137.            FP_MAK(BiosFontPtr, 0x0000, regs.x.AX);
  138.        SelectorAliasMask = 0x0008;
  139.            break;
  140.       #if defined(_I386) || defined(_I486) || defined(__386__)
  141.       case ERGO_OS386:
  142.            FP_MAK(BiosData, 0x0000, 0x0040);
  143.            FP_MAK(BottomOfMemory, 0x0000, 0x0037);
  144.        SelectorAliasMask = 0x0018;
  145.            break;
  146.       case PHARLAP_386:
  147.            FP_MAK(BiosData, 0x0400, 0x0034);
  148.            FP_MAK(BottomOfMemory, 0x0000, 0x0034);
  149.        SelectorAliasMask = 0x0018;
  150.            break;
  151.       #endif
  152.       default:
  153.            FP_MAK(BiosData, 0x0000, 0x0040);
  154.            FP_MAK(BottomOfMemory, 0x0000, 0x0000);
  155.        SelectorAliasMask = 0x0000;
  156.            break;
  157.       }
  158.    FP_MAK(GraphicsBuffer, 0, VideoSelectors[DOS_Extender]);
  159.    VideoModeAtEntry = GetVideoMode();
  160.    SetVideoMode(VideoMode);
  161.    CalcTime();
  162.    HookTimer();
  163. }
  164.  
  165. void KeyStrokeLoop(void)
  166. {
  167.    while(inputc != 'X' && inputc != 'x' && inputc != ESCAPE)
  168.       {
  169.       switch(inputc)
  170.          {
  171.          case 0:
  172.               inputc = getch();
  173.               break;
  174.          case 'R':
  175.          case 'r':
  176.               Red++;
  177.               Red %= 64;
  178.               break;
  179.          case 'G':
  180.          case 'g':
  181.               Green++;
  182.               Green %= 64;
  183.               break;
  184.          case 'B':
  185.          case 'b':
  186.               Blue++;
  187.               Blue %= 64;
  188.               break;
  189.          case 'M':
  190.          case 'm':
  191.               SetVideoMode(VideoMode ^= (VGM-EGM));
  192.               break;
  193.          case 'L':
  194.          case 'l':
  195.               Win.Xul--;
  196.               Win.Xul = max(Win.Xul, 0);
  197.               Win.Yul--;
  198.               Win.Yul = max(Win.Yul, 0);
  199.               Win.Xlr++;
  200.               Win.Xlr = min(Win.Xlr, 639);
  201.               Win.Ylr++;
  202.               Win.Ylr = min(Win.Ylr, 479);
  203.               break;
  204.          case 'S':
  205.          case 's':
  206.               VerticleLine(Win.Xul, Win.Yul, Win.Ylr, 0);
  207.               Win.Xul++;
  208.               Win.Xul = min(Win.Xul, 200);
  209.           HorizontalLine(Win.Xul, Win.Yul, Win.Xlr, 0);
  210.               Win.Yul++;                       
  211.               Win.Yul = min(Win.Yul, 200);
  212.           VerticleLine(Win.Xlr, Win.Yul, Win.Ylr, 0);
  213.               Win.Xlr--;
  214.               Win.Xlr = max(Win.Xlr, 440);
  215.           HorizontalLine(Win.Xul, Win.Ylr, Win.Xlr, 0);
  216.               Win.Ylr--;
  217.               Win.Ylr = max(Win.Ylr, 280);
  218.               break;
  219.          }
  220.       SetDAC(Win.InteriorColor, Red, Green, Blue);
  221.       DrawWin(&Win);
  222.       inputc = getch();
  223.       }    
  224. }
  225.  
  226. void Terminate(void)
  227. {
  228.    SetVideoMode(VideoModeAtEntry);
  229.    UnHookTimer();
  230. }
  231.  
  232. void DrawWin(WINPTR W)
  233. {
  234.    int i, CrossLineStart, CrossHatchStart;
  235.    int TitleLength, TitleStart_x, TitleStart_y;
  236.  
  237.    for (i=0; i< _E; i++)
  238.       {
  239.       VerticleLine(_A+i, _D-i, _B+i,  _F);
  240.       HorizontalLine(_A+i, _B+i, _C-i, _F);
  241.       VerticleLine(_A+_E+_J+i, _D-_E-_J-i, _B+_E+_J+_L+i, _G);
  242.       HorizontalLine(_A+_E+_J+i, _B+_E+_J+_L+i, _C-_E-_J-i, _G);
  243.       VerticleLine(_C-i, _B+i+1, _D-i, _G);
  244.       HorizontalLine(_C-i, _D-i, _A+i+1, _G);
  245.       VerticleLine(_C-_E-_J-i, _B+_E+_J+_L+i+1, _D-_E-_J-i, _F);
  246.       HorizontalLine(_C-_E-_J-i, _D-_E-_J-i, _A+_E+_J+i+1, _F);
  247.       }
  248.    for (i=0; i< _J; i++)
  249.       {
  250.       VerticleLine(_A+_E+i, _D-_E-i, _B+_E+_L+i, _I);
  251.       HorizontalLine(_A+_E+i, _B+_E+_L+i, _C-_E-i, _I);
  252.       VerticleLine(_C-_E-i, _B+_E+_L+i+1, _D-_E-i, _I);
  253.       HorizontalLine(_C-_E-i, _D-_E-i, _A+_E+i+1, _I);
  254.       }
  255.    for (i=_B+_E; i<_B+_E+_L; i++)
  256.        HorizontalLine(_A+_E, i, _C-_E, _K);  
  257.    TitleLength   = min((_C-_A-2*_E)/16, (signed int)strlen(_M));
  258.    TitleStart_x  = _A + _E + ((_C-_A-2*_E)/2 - 8*TitleLength)/2;
  259.    TitleStart_y  = _B + _E + (_L - 8)/2;
  260.    clock_x       = _A + _E + (_C-_A-2*_E)/2 + ((_C-_A-2*_E)/2 - 11*7)/2;
  261.    clock_y       = TitleStart_y;
  262.    for (i=0; i<TitleLength; i++)
  263.       DisplayChar(_M[i], TitleStart_x+8*i, TitleStart_y, _H, _K);
  264.    WriteTime();
  265.    CrossLineStart = _B + _E + _J + _L;
  266.    CrossHatchStart = _E / 2;
  267.    HorizontalLine(CrossHatchStart+_A, CrossLineStart, _A+_E+_J, _G);
  268.    HorizontalLine(CrossHatchStart+_A, CrossLineStart+1, _A+_E+_J, _F);
  269.    HorizontalLine(_C-CrossHatchStart, CrossLineStart, _C-_E-_J, _G);
  270.    HorizontalLine(_C-CrossHatchStart, CrossLineStart+1, _C-_E-_J, _F);
  271.    CrossLineStart = _C - _E - _J - _L;
  272.    VerticleLine(CrossLineStart, _D-_E-_J, _D-CrossHatchStart, _G);
  273.    VerticleLine(CrossLineStart+1, _D-_E-_J, _D-CrossHatchStart, _F);
  274.    CrossLineStart = _A + _E + _J + _L;
  275.    VerticleLine(CrossLineStart, _D-_E-_J, _D-CrossHatchStart, _G);
  276.    VerticleLine(CrossLineStart+1, _D-_E-_J, _D-CrossHatchStart, _F);
  277.    CrossLineStart = _D - _E - _J - _L;
  278.    HorizontalLine(CrossHatchStart+_A, CrossLineStart, _A+_E+_J, _G);
  279.    HorizontalLine(CrossHatchStart+_A, CrossLineStart+1, _A+_E+_J, _F);
  280.    HorizontalLine(_C-CrossHatchStart, CrossLineStart, _C-_E-_J, _G);
  281.    HorizontalLine(_C-CrossHatchStart, CrossLineStart+1, _C-_E-_J, _F);
  282.    for (i=_B+2*_E+_J+_L; i<=_D-2*_E-_J; i++)
  283.        HorizontalLine(_A+2*_E+_J, i, _C-2*_E-_J, _H);  
  284. }
  285.  
  286. void SetDAC(int regnum, int red, int green, int blue)
  287. {
  288.    union REGS regs;
  289.  
  290.    regs.x.AX = 0x1010;
  291.    regs.x.BX = regnum;
  292.    regs.h.dh = (char)red;
  293.    regs.h.ch = (char)green;
  294.    regs.h.cl = (char)blue;
  295.    int86(0x10, ®s, ®s);
  296. }
  297.  
  298. void WriteTime(void)
  299. {
  300.    int i;
  301.  
  302.    for(i=0;i<11;i++)
  303.       DisplayChar(timedisplay[i], clock_x+8*i, clock_y, clock_f, clock_b);
  304. }
  305.  
  306. UINT CalcTime(void)
  307. {
  308.     USHORT  hour, min, sec, TempMinSec;
  309.     int     AMPM = 0;
  310.  
  311.     TempMinSec = *(USHORT _far *)(BiosData + 0x6c);
  312.     sec = (USHORT)((ULONG)TempMinSec * (ULONG)3600 / (ULONG)65536);
  313.     if (sec == last_sec)
  314.       return((UINT) NO);
  315.     else
  316.       {
  317.       last_sec = sec;
  318.       min      = sec / 60;
  319.       sec     %= 60;
  320.       hour     = *(USHORT _far *)(BiosData + 0x6e);
  321.       if (hour >= 12) {hour -= 12; AMPM = 1;}
  322.       if (hour == 0) hour = 12;
  323.       timedisplay[0] = (char)((hour < 10) ? ' ' :(hour / 10) + '0');
  324.       timedisplay[1] = (char)((hour % 10) + '0');
  325.       timedisplay[3] = (char)((min  / 10) + '0');
  326.       timedisplay[4] = (char)((min  % 10) + '0');
  327.       timedisplay[6] = (char)((sec  / 10) + '0');
  328.       timedisplay[7] = (char)((sec  % 10) + '0');
  329.       timedisplay[9] = (char)((AMPM == 0) ? 'A' : 'P');
  330.       return((UINT) YES);
  331.       }
  332. }
  333.  
  334. void UpdateClock(void)
  335. {
  336.    if (CalcTime())
  337.       WriteTime();
  338. }
  339.  
  340. void DisplayChar(int c, int x, int y, int fgd, int bkgd)
  341. {
  342.    UCHAR  _far *PixelLocation;
  343.    UCHAR  _far *Font;
  344.    UCHAR  BitMaskRegister, ModeRegister, DataRotateRegister;
  345.    UCHAR  ColorDCRegister, LeftShiftBits, RightBitMask, PixRows;
  346.    USHORT TempShort;
  347.  
  348.    PixelLocation = GraphicsBuffer + y * BYTESPERLINE + x / 8;
  349.    LeftShiftBits = (UCHAR) ((x & 7 ^ 7 + 1) & 7);    
  350.    RightBitMask  = (UCHAR) (0xFF << LeftShiftBits);
  351.    PixRows       = *(BiosData + 0x85);
  352.    Font          = BiosFontPtr + c * PixRows;
  353.    BitMaskRegister    = SavRegVGAController(8);
  354.    ModeRegister       = SavRegVGAController(5);
  355.    DataRotateRegister = SavRegVGAController(3);
  356.    ColorDCRegister    = SavRegVGAController(7);
  357.    SetRegVGAController(5, 0xA);
  358.    SetRegVGAController(3, 0);
  359.    SetRegVGAController(7, 0);
  360.    if (LeftShiftBits == (UCHAR) 0)
  361.       while(PixRows > 0)
  362.          {
  363.          SetRegVGAController(8, *Font);
  364.          *PixelLocation &= (UCHAR) fgd;
  365.          SetRegVGAController(8, (UCHAR) ~*Font);
  366.          *PixelLocation &= (UCHAR) bkgd;
  367.          Font++;
  368.          PixelLocation += BYTESPERLINE;
  369.          PixRows--;
  370.          }
  371.    else
  372.       while(PixRows > 0)
  373.          {
  374.          TempShort = (USHORT) *Font << LeftShiftBits;
  375.          SetRegVGAController(8, HIGH_BYTE(TempShort));
  376.          *PixelLocation &= (UCHAR) fgd;
  377.          SetRegVGAController(8, (UCHAR) \
  378.                 (((UCHAR)~RightBitMask)^HIGH_BYTE(TempShort)));
  379.          *PixelLocation &= (UCHAR)bkgd;
  380.          PixelLocation++;
  381.          SetRegVGAController(8,  LOW_BYTE(TempShort));
  382.          *PixelLocation &= fgd;
  383.          SetRegVGAController(8, (UCHAR) (RightBitMask^LOW_BYTE(TempShort)));
  384.          *PixelLocation &= bkgd;
  385.          Font++;
  386.          PixelLocation += BYTESPERLINE - 1;
  387.          PixRows--;
  388.          }
  389.    SetRegVGAController(8, BitMaskRegister);
  390.    SetRegVGAController(5, ModeRegister);
  391.    SetRegVGAController(3, DataRotateRegister);
  392.    SetRegVGAController(7, ColorDCRegister);
  393. }
  394.  
  395. void SetRegVGAController(UCHAR IndexReg, UCHAR Value)
  396. {
  397.    outpw(0x3CE, MAKE_WORD(Value, IndexReg));
  398. }
  399.  
  400. UCHAR SavRegVGAController(UCHAR IndexReg)
  401. {
  402.    outp(0x3CE, IndexReg);
  403.    return(LOW_BYTE(inp(0x3CF)));
  404. }
  405.  
  406. void VerticleLine(int x1, int y1, int y2, int n)
  407. {
  408.    UCHAR _far *PixelLocation;
  409.    int  dy = y2 - y1;
  410.    UCHAR LeftShiftBits, BitMask;
  411.  
  412.    SetRegVGAController(0, (UCHAR) n);
  413.    SetRegVGAController(1, 0x0F);
  414.    SetRegVGAController(3, 0);
  415.    if (dy < 0)
  416.       {
  417.       dy *= -1;
  418.       y1  = y2;
  419.       }
  420.    dy++;
  421.    PixelLocation = GraphicsBuffer + y1 * BYTESPERLINE + x1 / 8;
  422.    LeftShiftBits = (UCHAR) ((x1 & 7) ^ 7);    
  423.    BitMask       = (UCHAR) (1 << LeftShiftBits);
  424.    SetRegVGAController(8, BitMask);
  425.    while ( dy-- > 0 )
  426.      {
  427.      *PixelLocation |= 0x08;
  428.      PixelLocation  += BYTESPERLINE;
  429.      }
  430.    SetRegVGAController(0, 0);
  431.    SetRegVGAController(1, 0);
  432.    SetRegVGAController(3, 0);
  433.    SetRegVGAController(8, 0xFF);
  434. }
  435.  
  436. void HorizontalLine(int x1, int y1, int x2, int n)
  437. {
  438.    volatile UCHAR _far *PixelLocation;
  439.    int   BytesInLine, temp, dx = x2 - x1;
  440.    UCHAR LeftShiftBits, BitMask, FirstByteBitMask, LastByteBitMask;
  441.    
  442.    SetRegVGAController(0, (UCHAR) n);
  443.    SetRegVGAController(1, 0x0F);
  444.    SetRegVGAController(3, 0);
  445.    if (dx < 0)
  446.       {
  447.       dx  *= -1;
  448.       temp = x1;
  449.       x1   = x2;
  450.       x2   = temp;
  451.       }
  452.    PixelLocation    = GraphicsBuffer + y1 * BYTESPERLINE + x1 / 8;
  453.    LeftShiftBits    = (UCHAR) ((x1 & 7) ^ 7);    
  454.    BitMask          = (UCHAR) 1;
  455.    FirstByteBitMask = (UCHAR) ~((~BitMask) << LeftShiftBits);
  456.    LastByteBitMask  = (UCHAR) (0xFF << (7 ^ (7 & LOW_BYTE(x2))));
  457.    BytesInLine      = (x2 >> 3) - (x1 >> 3);
  458.    if (FirstByteBitMask != (UCHAR) 0)
  459.       if (BytesInLine == 0)
  460.          LastByteBitMask &= FirstByteBitMask;
  461.       else
  462.          {
  463.          SetRegVGAController(8, FirstByteBitMask);
  464.          *PixelLocation += 1;
  465.          BytesInLine--;
  466.          PixelLocation++;
  467.          }
  468.    SetRegVGAController(8, 0xFF);
  469.    while (BytesInLine-- > 0)
  470.       {
  471.       *PixelLocation += 1;
  472.       PixelLocation++;
  473.       }
  474.    SetRegVGAController(8, LastByteBitMask);
  475.    *PixelLocation += 1;
  476.    SetRegVGAController(0, 0);
  477.    SetRegVGAController(1, 0);
  478.    SetRegVGAController(3, 0);
  479.    SetRegVGAController(8, 0xFF);
  480. }
  481.  
  482.  
  483.