home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / S12264.ZIP / HELLO1.C < prev    next >
C/C++ Source or Header  |  1989-01-19  |  27KB  |  881 lines

  1. /* hello1.c    RHS    12/14/88
  2.  *
  3.  * OS/2    and    1988 version of    K&R's hello.c
  4.  * demonstrates    multiple threads
  5.  */
  6.  
  7. #define    INCL_SUB
  8. #define    INCL_DOSERRORS
  9. #define    INCL_DOS
  10. #include<stdio.h>
  11. #include<string.h>
  12. #include<assert.h>
  13. #include<stdlib.h>
  14. #include<process.h>
  15. #include<malloc.h>
  16. #include<conio.h>
  17. #include<dos.h>
  18. #include<os2.h>
  19.  
  20. #include"hello1.h"
  21.  
  22.     /* Data    ***********************************************/
  23.  
  24.     /*    "Enter Your Name In The Field Below:"    */
  25. CELL cellstr[] =
  26.     {
  27. {'E',C0},     {'n',C0},      {'t',C0},       {'e',C0},    {'r',C0},     {' ',C7},
  28. {'Y',C1},     {'o',C1},      {'u',C1},       {'r',C1},    {' ',C7},
  29. {'N',C2},     {'a',C2},      {'m',C2},       {'e',C2},    {' ',C7},
  30. {'I',C3},     {'n',C3},      {' ',C7},
  31. {'T',C4},     {'h',C4},      {'e',C4},       {' ',C7},
  32. {'F',C5},     {'i',C5},      {'e',C5},       {'l',C5},    {'d',C5},     {' ',C7},
  33. {'B',C6},     {'e',C6},      {'l',C6},       {'o',C6},    {'w',C6},     {':',C6}
  34.     };
  35.  
  36.     /* Graphics    bitmap for "Hi"    ***************************/
  37. char *hi_bitmap[MAPSIZE] =
  38.     {
  39.     { "111111111111000000000000111111111111000000000000000000000000" },
  40.     { "111111111111000000000000111111111111000000000000000000000000" },
  41.     { "111111111111000000000000111111111111000000000000000000000000" },
  42.     { "111111111111000000000000111111111111000000000000111111111111" },
  43.     { "111111111111000000000000111111111111000000000000111111111111" },
  44.     { "111111111111000000000000111111111111000000000000111111111111" },
  45.     { "111111111111000000000000111111111111000000000000111111111111" },
  46.     { "111111111111000000000000111111111111000000000000111111111111" },
  47.     { "111111111111000000000000111111111111000000000000111111111111" },
  48.     { "111111111111000000000000111111111111000000000000111111111111" },
  49.     { "111111111111000000000000111111111111000000000000000000000000" },
  50.     { "111111111111000000000000111111111111000000000000000000000000" },
  51.     { "111111111111111111111111111111111111000000000000000000000000" },
  52.     { "111111111111111111111111111111111111000000000000111111111111" },
  53.     { "111111111111111111111111111111111111000000000000111111111111" },
  54.     { "111111111111111111111111111111111111000000000000111111111111" },
  55.     { "111111111111111111111111111111111111000000000000111111111111" },
  56.     { "111111111111111111111111111111111111000000000000111111111111" },
  57.     { "111111111111000000000000111111111111000000000000111111111111" },
  58.     { "111111111111000000000000111111111111000000000000111111111111" },
  59.     { "111111111111000000000000111111111111000000000000111111111111" },
  60.     { "111111111111000000000000111111111111000000000000111111111111" },
  61.     { "111111111111000000000000111111111111000000000000111111111111" },
  62.     { "111111111111000000000000111111111111000000000000111111111111" },
  63.     { "111111111111000000000000111111111111000000000000111111111111" },
  64.     { "111111111111000000000000111111111111000000000000111111111111" },
  65.     { "111111111111000000000000111111111111000000000000111111111111" },
  66.     { "111111111111000000000000111111111111000000000000111111111111" },
  67.     { "111111111111000000000000111111111111000000000000111111111111" },
  68.     { "111111111111000000000000111111111111000000000000111111111111" },
  69.     { NULL }
  70.     };
  71.  
  72.  
  73. char *blank_str    =                                /* string for blanking frame*/
  74.     "                    ";
  75.  
  76.     /* frame data *************************/
  77. char *hello_str25[LINES25+1] =
  78.     {
  79.     "╒══════════════════╕",
  80.     "│   Hello, world!  │",
  81.     "│ from Thread #    │",
  82.     "╘══════════════════╛",
  83.     "\0"
  84.     };
  85.  
  86. char *hello_str43[LINES43+1] =
  87.     {
  88.     "╒══════════════════╕",
  89.     "│                  │",
  90.     "│   Hello, world!  │",
  91.     "│ from Thread #    │",
  92.     "│                  │",
  93.     "╘══════════════════╛",
  94.     "\0"
  95.     };
  96.  
  97. char *hello_str50[LINES50+1] =
  98.     {
  99.     "╒══════════════════╕",
  100.     "│                  │",
  101.     "│   Hello, world!  │",
  102.     "│                  │",
  103.     "│ from Thread #    │",
  104.     "│                  │",
  105.     "╘══════════════════╛",
  106.     "\0"
  107.     };
  108.  
  109.  
  110. char *hello_str2[LINES25+1]    =
  111.     {
  112.     "╒══════╕",
  113.     "│Hello │",
  114.     "│ World│",
  115.     "╘══════╛",
  116.     "\0"
  117.     };
  118.  
  119. char *adapters_displays[] =
  120.     {
  121.     "Monochrome",
  122.     "Color graphics",
  123.     "Enhanced graphics",
  124.     "Video graphics array",
  125.     "8503 monochrome",
  126.     "8512-8514 color"
  127.     };
  128.  
  129.  
  130. char **helloptr;
  131. int    numlines, maxrows, maxcols;
  132.                                                 /* minim sleep times        */
  133. long sleeptime = 1L, sleeptime2    = 1500L, sleeptime3    = 100L;
  134.  
  135. FRAME far *frames[MAXFRAMES];                    /* pointers    to frames        */
  136. unsigned maxframes;
  137. unsigned curframe;
  138. char keythreadstack[THREADSTACK];
  139. long doneSem = 0L;
  140. int    done = FALSE;
  141. VIOMODEINFO    viomodeinfo;
  142. int    orgrows;
  143. unsigned char screen[CGABUFSIZE];
  144. unsigned char far *video_base;
  145. unsigned char Savethreadstack[THREADSTACK];
  146.  
  147.  
  148.     /* main    *****************************************************************/
  149. void main(int argc,    char **argv)
  150.     {
  151.     startup(argc,argv);                            /* set/save    options    modes    */
  152.  
  153.     initialization();                            /* initialize FRAME    info    */
  154.  
  155.     flicker_frames();                            /* launch flicker frames    */
  156.  
  157.     chasing_frames();                            /* launch chasing frames    */
  158.  
  159.     displayconfig();                            /* get name, and show config*/
  160.  
  161.     togglebackground();                            /* toggle background color    */
  162.  
  163.     graphics();                                    /* say "Hi"    with save-redraw*/
  164.  
  165.     termination();                                /* kill    threads, restore    */
  166.     }
  167.  
  168.     /* startup **************************************************************/
  169. void startup(int argc, char    **argv)
  170.     {
  171.     if(argc    > 1)                                /* process any arguments    */
  172.         sleeptime =    atol(argv[1]);
  173.     if(sleeptime < 1L)
  174.         sleeptime =    1L;
  175.     if(argc    > 2)
  176.         sleeptime2 = atol(argv[2]);
  177.     if(argc    > 3)
  178.         sleeptime3 = atol(argv[3]);
  179.  
  180.                                                 /* start keyboard thread    */
  181.     if(_beginthread(keyboard_thread,keythreadstack,THREADSTACK,NULL) ==    -1)
  182.         exit(-1);
  183.  
  184.     Screen(SAVE);                                /* save    the    screen            */
  185.     Cursor(HIDECUR | SAVECUR);                    /* hide    and    save the cursor    */
  186.  
  187.     Sizeof(viomodeinfo);
  188.     VioGetMode(&viomodeinfo,VIOHDL);            /* get video info            */
  189.     orgrows    = viomodeinfo.row;                    /* save    original row value    */
  190.  
  191.     viomodeinfo.row    = 50;                        /* set for 50 lines            */
  192.     if(VioSetMode(&viomodeinfo,VIOHDL))            /* no can do?                */
  193.         {
  194.         viomodeinfo.row    = 43;                    /* try 43                    */
  195.         if(VioSetMode(&viomodeinfo,VIOHDL))        /* still bad news?            */
  196.             {
  197.             viomodeinfo.row    = orgrows;            /* set original    # of rows    */
  198.             VioSetMode(&viomodeinfo,VIOHDL);    /* this    has    to work            */
  199.             }
  200.         }
  201.  
  202.     maxrows    = viomodeinfo.row;                    /* maxrows available        */
  203.     maxcols    = viomodeinfo.col;                    /* maxcols available        */
  204.     }
  205.  
  206.     /* Screen ***************************************************************/
  207. void Screen(int    save)
  208.     {
  209.     static void    far    *lbuffer = NULL;
  210.     static unsigned    lbuffersize;
  211.     static void    *oldscreenbuffer = NULL;
  212.  
  213.     if(save)                                    /* if save screen            */
  214.         {                                        /* get address/size    of LVB    */
  215.         VioGetBuf((PULONG)&lbuffer,&lbuffersize,VIOHDL);
  216.  
  217.         if(oldscreenbuffer)                        /* if screen buffer    alloc'd */
  218.             free(oldscreenbuffer);                /* free    it first            */
  219.  
  220.                                                 /* allocate    buffer            */
  221.         if(!(oldscreenbuffer = (void far *)malloc(lbuffersize)))
  222.             {
  223.             printf("Unable to save screen buffer\n");
  224.             exit(-1);
  225.             }
  226.                                                 /* save    the    screen            */
  227.         movedata(FP_SEG(lbuffer),FP_OFF(lbuffer),FP_SEG(oldscreenbuffer),
  228.                 FP_OFF(oldscreenbuffer),lbuffersize);
  229.         }
  230.     else                                        /* if restore the screen    */
  231.         {
  232.         assert(lbuffer);
  233.                                                 /* update the logical buffer*/
  234.         movedata(FP_SEG(oldscreenbuffer),FP_OFF(oldscreenbuffer),
  235.                 FP_SEG(lbuffer),FP_OFF(lbuffer),lbuffersize);
  236.         free(oldscreenbuffer);                    /* free    the    buffer storage    */
  237.         oldscreenbuffer    = NULL;
  238.         VioShowBuf(0,lbuffersize,VIOHDL);        /* display original    screen    */
  239.         }
  240.     }
  241.  
  242.     /* Cursor ***************************************************************/
  243. void Cursor(unsigned op)
  244.     {
  245.     static VIOCURSORINFO viocursorinfo;
  246.     static int orgcurattr =    0;
  247.     static unsigned    orgcurrow =    0, orgcurcol = 0;
  248.  
  249.     if(op &    HIDECUR)                            /* if hide cursor            */
  250.         {
  251.         VioGetCurType(&viocursorinfo,VIOHDL);    /* get cursor type            */
  252.         if(orgcurattr == 0)
  253.             orgcurattr = viocursorinfo.attr;    /* save    old    cursor attribute*/
  254.         viocursorinfo.attr = 0xffff;            /* set to hide cursor        */
  255.         VioSetCurType(&viocursorinfo,VIOHDL);    /* set hidden cursor type    */
  256.         }
  257.     if(op &    SAVECUR)                            /* if save cursor position    */
  258.         VioGetCurPos(&orgcurrow,&orgcurcol,VIOHDL);
  259.  
  260.     if(op &    RESTORECUR)                            /* if restore cursor        */
  261.         {
  262.         VioGetCurType(&viocursorinfo,VIOHDL);    /* get cursor type            */
  263.         viocursorinfo.attr = orgcurattr;        /* set to restore cursor    */
  264.         VioSetCurType(&viocursorinfo,VIOHDL);    /* show    cursor type            */
  265.         VioSetCurPos(orgcurrow,orgcurcol,VIOHDL);/*    set    cursor position        */
  266.         }
  267.     }
  268.  
  269.     /* initialization ********************************************************/
  270. void initialization(void)
  271.     {
  272.     int    i, len,    row, col, loops;
  273.  
  274.     switch(maxrows)
  275.         {
  276.         case 25:
  277.             helloptr = hello_str25;
  278.             numlines = LINES25;
  279.             break;
  280.         case 43:
  281.             helloptr = hello_str43;
  282.             numlines = LINES43;
  283.             break;
  284.         case 50:
  285.             helloptr = hello_str50;
  286.             numlines = LINES50;
  287.             break;
  288.         default:                                /* fail    if not 25,43,50    lines*/
  289.             assert(0);
  290.             exit(-1);
  291.         }
  292.  
  293.     len    = strlen(*helloptr);
  294.  
  295.     maxframes =    (maxrows / numlines) * (maxcols    / len);
  296.  
  297.     assert(maxframes <=    MAXFRAMES);
  298.  
  299.     for( i = 0;    i <    maxframes; i++)                /* initialize structures    */
  300.         {
  301.         if(!(frames[i] = malloc(sizeof(FRAME))))
  302.             exit(0);
  303.         frames[i]->frame_cleared = FALSE;
  304.         frames[i]->startSem    = 0L;
  305.         frames[i]->attr    = (unsigned    char)((i*17) & 0x7f);
  306.         memset(frames[i]->threadstack,0xff,sizeof(frames[i]->threadstack));
  307.         }
  308.  
  309.     i =    RAND();                                    /* get first random    frame    */
  310.  
  311.                                                 /* set up random appearance    */
  312.                                                 /* set row/col each    frame    */
  313.     for(loops =    row    = col =    0; loops < maxframes ; )
  314.         {
  315.         if(!frames[i]->frame_cleared)
  316.             {
  317.             frames[i]->frame_cleared = TRUE;    /* set for empty frame        */
  318.             frames[i]->row = row;                /* frame upper row            */
  319.             frames[i]->col = col;                /* frame left column        */
  320.  
  321.             col    += len;                            /* next    column on this row    */
  322.  
  323.             if(col >= maxcols)                    /* go to next row?            */
  324.                 {
  325.                 col    = 0;                        /* reset for start column    */
  326.                 row    += numlines;                /* set for next    row            */
  327.                 }
  328.  
  329.             i =    RAND();                            /* get next    random frame    */
  330.             }
  331.         else
  332.             ++i;
  333.  
  334.         if(i >=    maxframes)
  335.             {
  336.             i -= maxframes;
  337.             loops++;                            /* keep    track of # of frames*/
  338.             }
  339.         }
  340.     }
  341.  
  342.     /* flicker_frames *******************************************************/
  343. void flicker_frames(void)
  344.     {
  345.     int    i;
  346.  
  347.     for( i = 0 ; i < maxframes;    i++)            /* start a thread for each    */
  348.         {
  349.         DosSemSet(&frames[i]->startSem);        /* initially set each sem.    */
  350.  
  351.                                                 /* start each thread        */
  352.         if((frames[i]->threadid    = _beginthread(
  353.                 (void far *)hello_thread,
  354.                 (void far *)frames[i]->threadstack,
  355.                 THREADSTACK,
  356.                 (void far *)frames[i]))    == -1)
  357.             {
  358.             maxframes =    i;                        /* reset maxframes            */
  359.             break;
  360.             }
  361.         }
  362.  
  363.     while(!done)                                /* when    keyboard thread        */
  364.         {                                        /* says    to                    */
  365.                                 /* swing thru frames, signalling to    threads    */
  366.         for( i = 0;    i <    maxframes; i++)
  367.             {
  368.             frames[i]->attr    += (unsigned char)(16+i);
  369.             if((frames[i]->attr    & 0x07)    == (frames[i]->attr    >> 4))
  370.                 frames[i]->attr--;
  371.             frames[i]->attr    &= NOBLINKING;
  372.             DosSemClear(&frames[i]->startSem);    /* clear: thread can go        */
  373.             DosSleep(sleeptime);                /* sleep a little            */
  374.             }
  375.         DosSemClear(&doneSem);                    /* tell    keyboard thread    ok    */
  376.         DosSleep(32L);                            /* sleep a little            */
  377.         DosSemSet(&doneSem);                    /* set it again                */
  378.         }
  379.  
  380.     for( i = 0;    i <    maxframes; i++)                /* make    each clear and die    */
  381.         {
  382.         frames[i]->frame_cleared = 0;
  383.         DosSemClear(&frames[i]->startSem);        /* clear: thread can go        */
  384.         }
  385.     WaitForThreadDeath(maxframes);                /* wait    for    threads    to die    */
  386.     }
  387.  
  388.  
  389.     /* hello_thread    *********************************************************/
  390. void hello_thread(FRAME    far    *frameptr)            /* frame thread    function    */
  391.     {
  392.     register char **p;
  393.     register int line;
  394.     int    len    = strlen(*helloptr);
  395.     unsigned row, col =    frameptr->col;
  396.     char idstr[20];
  397.     BYTE att = 0x07;
  398.  
  399.     while(TRUE)
  400.         {
  401.         if(done    && frameptr->frame_cleared)
  402.             break;
  403.         DosSemRequest(&frameptr->startSem,-1L);    /* block until cleared        */
  404.         itoa(frameptr->threadid,idstr,10);        /* init    idstr                */
  405.  
  406.         row    = frameptr->row;                    /* reset row                */
  407.  
  408.         if(!frameptr->frame_cleared)            /* if frame    in use,    erase    */
  409.             for( line =    0; line    < numlines;    line++,    row++)
  410.                 VioWrtCharStrAtt(blank_str,len,row,col,&att,VIOHDL);
  411.         else                                    /* else    frame not in use    */
  412.             {
  413.             p =    helloptr;                        /* print message            */
  414.             for( line =    0; **p;    line++,    row++, p++)
  415.                 VioWrtCharStrAtt(*p,len,row,col,&frameptr->attr,VIOHDL);
  416.                                                 /* write id    # in frame        */
  417.             VioWrtCharStrAtt(idstr,3,row-(numlines/2),IDCOL+col,
  418.                     &frameptr->attr,VIOHDL);
  419.             }
  420.         frameptr->frame_cleared    = !frameptr->frame_cleared;/*toggle    use    flag*/
  421.         }
  422.     DosSemClear(&frameptr->startSem);
  423.     _endthread();                                /* kill    thread                */
  424.     }
  425.  
  426.     /* keyboard_thread ******************************************************/
  427. void keyboard_thread(void)
  428.     {
  429.     KBDKEYINFO keyinfo;
  430.  
  431.     DosSemSet(&doneSem);                        /* set done    semaphore        */
  432.     while(TRUE)
  433.         {
  434.         KbdCharIn(&keyinfo,IO_WAIT,0);            /* wait    for    keystroke        */
  435.         if(keyinfo.chChar == ESC)                /* if ESC pressed, break    */
  436.             break;
  437.         }
  438.     DosSemRequest(&doneSem,    -1L);                /* block until cleared        */
  439.     done = TRUE;
  440.  
  441.     while(TRUE)
  442.         {
  443.         KbdCharIn(&keyinfo,IO_WAIT,0);            /* don't wait for keystroke */
  444.         if(keyinfo.chChar == ESC)                /* if ESC pressed, break    */
  445.             break;
  446.         }
  447.     done = TRUE;                                /* set it anyway            */
  448.     _endthread();                                /* kill    thread                */
  449.     }
  450.  
  451.     /* WaitForThreadDeath ***************************************************/
  452. void WaitForThreadDeath(int    nframes)
  453.     {
  454.     int    i;
  455.  
  456.     DosSleep(100L);                                /* time    for    first to die    */
  457.     for( i = 0;    i <    nframes; i++)                /* wait    for    each one to    die    */
  458.         DosSemRequest(&frames[i]->startSem,-1L);
  459.     }
  460.  
  461.     /* chasing_frames *******************************************************/
  462. void chasing_frames(void)
  463.     {
  464.     int    i;
  465.     unsigned char attr = 0;
  466.  
  467.     for( i = 0 ; i < maxframes;    i++, attr += 16)/* start each new thread    */
  468.         {
  469.         DosSemSet(&frames[i]->startSem);        /* initially set each sem.    */
  470.         frames[i]->attr    = attr;
  471.                                                 /* start each thread        */
  472.         if((frames[i]->threadid    = _beginthread(
  473.                 (void far *)box_thread,
  474.                 (void far *)frames[i]->threadstack,
  475.                 THREADSTACK,
  476.                 (void far *)frames[i]))    == -1)
  477.             {
  478.             maxframes =    i;                        /* reset maxframes            */
  479.             break;
  480.             }
  481.         }
  482.                                                 /* launch chasing threads    */
  483.     for( i = 0,    done = FALSE; i    < maxframes    && !done; i++ )
  484.         {
  485.         DosSemClear(&frames[i]->startSem);
  486.         DosSleep(sleeptime2);
  487.         }
  488.     done = TRUE;
  489.     WaitForThreadDeath(i);                        /* wait    for    threads    to die    */
  490.     }
  491.  
  492.     /* box_thread ***********************************************************/
  493. void box_thread(FRAME far *frameptr)
  494.     {
  495.     char **p;
  496.     int    line, len =    strlen(*hello_str2);
  497.     unsigned row, col;
  498.     int    top, left, bottom, right, count;
  499.     int    tborder    = 0, bborder = maxrows-1, lborder =    0, rborder = maxcols-1;
  500.     BYTE filler[2];
  501.  
  502.     filler[0] =    ' ';
  503.     filler[1] =    frameptr->attr;
  504.  
  505.     DosSemRequest(&frameptr->startSem,-1L);        /* block until cleared        */
  506.  
  507.     frameptr->attr += 0x07;
  508.     if((frameptr->attr & 0x07) == (frameptr->attr >> 4))
  509.         frameptr->attr--;
  510.  
  511.     col    = (maxcols-len);
  512.                                                 /* write the box            */
  513.     for(row    = line = 0,    p =    hello_str2;    **p; line++, row++,    p++)
  514.         VioWrtCharStrAtt(*p, len, row, col,    &frameptr->attr, VIOHDL);
  515.  
  516.     left = col;
  517.     bottom = LINES25-1;
  518.     right =    col+len-1;
  519.  
  520.     while(!done)                                /* main    chasing    frame loop    */
  521.         {
  522.         count =    0;                                /* move    to upper left        */
  523.         for(left--,    top    = tborder; left    > lborder-1; left--, right--, count++)
  524.             {
  525.             VioScrollLf(top, left, bottom, right, 1, filler, VIOHDL);
  526.             DosSleep(!done ? 1L    : 0L);
  527.             }
  528.                                                 /* move    to lower left        */
  529.         for(left = lborder,    bottom++; bottom < bborder+1;
  530.                 bottom++, top++, count++)
  531.             {
  532.             VioScrollDn(top, left, bottom, right, 1, filler, VIOHDL);
  533.             DosSleep(!done ? 1L    : 0L);
  534.             }
  535.                                                 /* move    to lower right        */
  536.         for(bottom = bborder, right++; right < rborder+1;
  537.                 right++, left++, count++)
  538.             {
  539.             VioScrollRt(top, left, bottom, right, 1, filler, VIOHDL);
  540.             DosSleep(!done ? 1L    : 0L);
  541.             }
  542.  
  543.         if((bborder    - tborder) > LINES25)        /* adjust top border        */
  544.             tborder    += LINES25;
  545.                                                 /* move    to upper right        */
  546.         for(right =    rborder, top--;    top    > tborder-1; top--,    bottom--, count++)
  547.             {
  548.             VioScrollUp(top, left, bottom, right, 1, filler, VIOHDL);
  549.             DosSleep(!done ? 1L    : 0L);
  550.             }
  551.         rborder    -= len;                            /* adjust right    border        */
  552.         lborder    += len;                            /* adjust left border        */
  553.         if((bborder    - tborder) > LINES25)        /* adjust bottom border        */
  554.             bborder    -= LINES25;
  555.         if((rborder-lborder) < len)                /* reached the center?        */
  556.             break;                                /* get out                    */
  557.         if(!count)                                /* made    no revolutions?        */
  558.             break;                                /* get out                    */
  559.         DosSleep(sleeptime3);                    /* wait    a second...            */
  560.         }
  561.     DosSemClear(&frameptr->startSem);            /* tell    main thread    we dead    */
  562.     _endthread();                                /* kill    thread                */
  563.     }
  564.  
  565.     /* displayconfig ********************************************************/
  566. void displayconfig(void)
  567.     {
  568.     char username[MAXUSERNAME+1];
  569.     unsigned len = sizeof(username), bytesread;
  570.     VIOCONFIGINFO vioconfiginfo;
  571.  
  572.     bytesread =    get_user_name();                /* get user    name            */
  573.                                                 /* read    name from screen    */
  574.     VioReadCharStr(username,&len,FIELDROW,FIELDCOL,VIOHDL);
  575.     username[bytesread]    = '\0';
  576.  
  577.     Sizeof(vioconfiginfo);
  578.     VioGetConfig(0,    &vioconfiginfo,    VIOHDL);    /* get configuration        */
  579.     VioSetCurPos(FIELDROW+2, 0,    VIOHDL);        /* set cursor position        */
  580.     printf("%s, VioGetConfig reports:\n"
  581.             "You\'re using a%s %s adapter with %ld bytes of video memory\n"
  582.             "and a%s %s display\n",
  583.             username,
  584.             (vioconfiginfo.adapter == 2    ? "n" :    ""),
  585.             adapter(vioconfiginfo.adapter),
  586.             vioconfiginfo.cbMemory,
  587.             (vioconfiginfo.display == 2    ? "n" :    ""),
  588.             display(vioconfiginfo.display));
  589.     }
  590.  
  591.     /* get_user_name ********************************************************/
  592. int    get_user_name(void)
  593.     {
  594.     char username[MAXUSERNAME+1];
  595.     unsigned char cell[2];
  596.     STRINGINBUF    kb;
  597.  
  598.     memset(username,' ',sizeof(username));
  599.                                                 /* print "Enter your name.."*/
  600.     VioWrtCellStr((PCH)cellstr,sizeof(cellstr),FIELDROW-2,
  601.             (maxcols-(sizeof(cellstr)/2))/2,VIOHDL);
  602.  
  603.     cell[0]    = LEFTMARKER;
  604.     cell[1]    = COLORS(WHITE,BLACK) |    BLINKING;    /* print left marker        */
  605.     VioWrtNCell(cell,1,FIELDROW,FIELDCOL-1,VIOHDL);
  606.  
  607.     cell[0]    = BLANK;
  608.     cell[1]    = COLORS(BLACK,CYAN);                /* print field                */
  609.     VioWrtNCell(cell,sizeof(username),FIELDROW,FIELDCOL,VIOHDL);
  610.  
  611.     cell[0]    = RIGHTMARKER;
  612.     cell[1]    = COLORS(WHITE,BLACK) |    BLINKING;    /* print right marker        */
  613.     VioWrtNCell(cell,1,FIELDROW,FIELDCOL+MAXUSERNAME,VIOHDL);
  614.  
  615.     Cursor(RESTORECUR);                            /* restore cursor            */
  616.     VioSetCurPos(FIELDROW,FIELDCOL,VIOHDL);        /* set cursor position        */
  617.     kb.cb =    sizeof(username);
  618.     KbdStringIn(username,&kb,IO_WAIT,KBDHDL);    /* get user    name            */
  619.     Cursor(HIDECUR);                            /* hide    cursor                */
  620.     return kb.cchIn;                            /* return chars    read        */
  621.     }
  622.  
  623.     /* adapter **************************************************************/
  624. char *adapter(unsigned n)
  625.     {
  626.     return adapters_displays[n];
  627.     }
  628.  
  629.     /* display **************************************************************/
  630. char *display(unsigned n)
  631.     {
  632.     if(n > 2)
  633.         n++;
  634.     return adapters_displays[n];
  635.     }
  636.  
  637.     /* togglebackground    *****************************************************/
  638. void togglebackground(void)
  639.     {
  640.     KBDKEYINFO keyinfo;
  641.  
  642.     printf("Use the Up/Down arrow keys to increment/decrement "
  643.             "the background color\n"
  644.             "\n\nPress Esc to enter graphics mode..."
  645.             "pressing Esc again will terminate the program\n\n"
  646.             "Don\'t press anything but Esc the 2nd time.");
  647.  
  648.     while(TRUE)
  649.         {
  650.         KbdCharIn(&keyinfo,IO_WAIT,0);            /* wait    for    keystroke        */
  651.         if(keyinfo.chChar == ESC)                /* if Esc key, break out    */
  652.             break;
  653.         if(keyinfo.chChar == 0)                    /* otherwise...                */
  654.             {
  655.             if(keyinfo.chScan == UPARROW)        /* Uparrow?    increment bkgrnd*/
  656.                 Background(1);
  657.             else if(keyinfo.chScan == DOWNARROW)/* Dnarrow?    decrement bkgrnd*/
  658.                 Background(-1);
  659.             }
  660.         DosSleep(1L);                            /* wait    a sec                */
  661.         }
  662.     }
  663.  
  664.     /* Background ***********************************************************/
  665. void Background(int    n)
  666.     {
  667.     unsigned char cell[2],backgroundattr, attr;
  668.     unsigned len = sizeof(cell);
  669.  
  670.     VioReadCellStr(cell,&len,0,0,VIOHDL);        /* read    corner cell            */
  671.  
  672.     backgroundattr = ((cell[1] >> 4) & 0x7);
  673.     backgroundattr += (unsigned    char)n;
  674.     if(backgroundattr &    0x08)
  675.         backgroundattr = (unsigned char)((n    > 0) ? 0 : 7);
  676.     attr = ((cell[1] & ~BACKGROUNDMASK)    | (backgroundattr << 4));
  677.     attr &=    NOBLINKING;                            /* set new attribute        */
  678.                                                 /* flood screen    with color    */
  679.     VioWrtNAttr(&attr,maxrows*maxcols,0,0,VIOHDL);
  680.     }
  681.  
  682.     /* graphics    *************************************************************/
  683. void graphics(void)
  684.     {
  685.     VIOPHYSBUF viophysbuf;
  686.     VIOMODEINFO    graphics_modeinfo;
  687.     KBDKEYINFO keyinfo;
  688.     char status;
  689.     int    x,y;
  690.     unsigned result, wait =    (VP_WAIT | VP_OPAQUE);
  691.     char *bitmap, **bitmapptr;
  692.  
  693.     viophysbuf.pBuf    = (unsigned    char far *)0xb8000;    /* address of buffer    */
  694.     viophysbuf.cb =    CGABUFSIZE;                    /* size    of buffer            */
  695.  
  696.     Sizeof(graphics_modeinfo);
  697.                                                 /* get the video mode        */
  698.     if(result =    VioGetMode(&graphics_modeinfo,VIOHDL))
  699.         {
  700.         printf("%u error getting video mode\n",result);
  701.         exit(1);
  702.         }
  703.  
  704.     graphics_modeinfo.fbType = 3;                /* set for non-mono    graphics*/
  705.     graphics_modeinfo.color    = 2;                /* set for 2 color bits        */
  706.     graphics_modeinfo.col =    40;                    /* set for 40 columns        */
  707.     graphics_modeinfo.row =    25;                    /* set for 25 lines            */
  708.     graphics_modeinfo.hres = 320;                /* set for 320 hor.    pels    */
  709.     graphics_modeinfo.vres = 200;                /* set for 200 ver.    pels    */
  710.  
  711.                                                 /* set the new video mode    */
  712.     if(result =    VioSetMode(&graphics_modeinfo,VIOHDL))
  713.         {
  714.         printf("%u error setting video mode\n",result);
  715.         exit(1);
  716.         }
  717.     if(result =    VioGetPhysBuf(&viophysbuf, 0))    /* get the buffer address    */
  718.         {
  719.         printf("%u error getting physical buffer selector\n",result);
  720.         exit(1);
  721.         }
  722.  
  723.     video_base = MAKEP(viophysbuf.asel[0],0);    /* convert to a    pointer        */
  724.                                                 /* lock    the    screen            */
  725.     if(result =    VioScrLock(LOCKIO_WAIT,    &status, VIOHDL))
  726.         {
  727.         printf("%u error locking screen\n",result);
  728.         exit(1);
  729.         }
  730.                                                 /* create save/restore thread*/
  731.     if(_beginthread((void far *)SaveRestoreScreen, (void far *)Savethreadstack,
  732.             sizeof(Savethreadstack),(void far *)video_base)    == -1)
  733.         {
  734.         printf("Unable to start Save/Redraw thread\n");
  735.         exit(1);
  736.         }
  737.  
  738.     clear_graphics_screen(video_base);            /* clear the screen            */
  739.  
  740.                                                 /* write "Hi"                */
  741.     for( x = UPPER_START_PIXEL,    bitmapptr =    hi_bitmap; *bitmapptr; x++,    bitmapptr++)
  742.         for( y = LEFT_START_PIXEL, bitmap =    (char *)*bitmapptr;    *bitmap; bitmap++, y++)
  743.             if(*bitmap == '1')
  744.                 putpixel(x,y,CGA_MAGENTA);
  745.  
  746.     if(result =    VioScrUnLock(VIOHDL))            /* unlock the screen        */
  747.         {
  748.         printf("%u error unlocking screen\n",result);
  749.         exit(1);
  750.         }
  751.  
  752.     while(TRUE)
  753.         {
  754.         KbdCharIn(&keyinfo,IO_WAIT,0);            /* wait    for    keystroke        */
  755.         if(keyinfo.chChar == ESC)                /* if ESC pressed, break    */
  756.             break;
  757.         else                                    /* else    something else pressed*/
  758.             {
  759.             VioPopUp(&wait,VIOHDL);                /* Pop-up new screen        */
  760.             printf("\n\n\n\nYou did not press the Esc key"
  761.                     "...now press a key to try it again\n"
  762.                     "\n(Note:\n"
  763.                     "As long as the graphics \'HI\' is on screen,\n"
  764.                     "the SaveRestoreScreen thread will be activated\n"
  765.                     "when you switch screens or this Pop-up appears)\n");
  766.             getch();                            /* wait    for    key                */
  767.             VioEndPopUp(VIOHDL);                /* end the pop-up            */
  768.             }
  769.         }
  770.     }
  771.  
  772.     /* SaveRestoreScreen ****************************************************/
  773. void SaveRestoreScreen(void)
  774.     {
  775.     unsigned result,notify;
  776.     unsigned char far *sbank1, *bank2, *sbank2,    *bank1;
  777.     unsigned count;
  778.     VIOMODEINFO    viomodeinfo;
  779.  
  780.     Sizeof(viomodeinfo);
  781.  
  782.                                                 /* save    current    video mode    */
  783.     if(result =    VioGetMode(&viomodeinfo,VIOHDL))
  784.         {
  785.         printf("%u error getting video mode\n",result);
  786.         exit(1);
  787.         }
  788.  
  789.     while(1)
  790.         {
  791.         sbank1 = screen;                        /* set pointers    for    copy    */
  792.         sbank2 = &screen[BANK2OFFSET];
  793.         bank1  = video_base;
  794.         bank2  = &video_base[BANK2OFFSET];
  795.         count  = 8000;
  796.                                                 /* wait    for    redraw            */
  797.         if(result =    VioSavRedrawWait(VSRWI_SAVEANDREDRAW,¬ify,0))
  798.             {
  799.             printf("%u error on SaveReDrawWait\n",result);
  800.             exit(1);
  801.             }
  802.  
  803.         if(notify == VSRWN_SAVE)                /* if save screen            */
  804.             {
  805.             for( ; count; count--)                /* copy    screen to buffer    */
  806.                 {
  807.                 *sbank1++ =    *bank1++;
  808.                 *sbank2++ =    *bank2++;
  809.                 }
  810.             }
  811.         if(notify == VSRWN_REDRAW)                /* if redraw screen            */
  812.             {                                    /* restore the video mode    */
  813.             if(result =    VioSetMode(&viomodeinfo,VIOHDL))
  814.                 {
  815.                 printf("%u error setting video mode\n",result);
  816.                 exit(1);
  817.                 }
  818.             for( ; count; count--)                /* copy    buffer to screen    */
  819.                 {
  820.                 *bank1++ = *sbank1++;
  821.                 *bank2++ = *sbank2++;
  822.                 }
  823.             }
  824.         }
  825.     }
  826.  
  827.     /* clear_graphics_screen ************************************************/
  828. void clear_graphics_screen(register    unsigned char far *bank1)
  829.     {
  830.     register unsigned char far *bank2;
  831.     unsigned count;
  832.  
  833.     for(bank2 =    (bank1+BANK2OFFSET), count = 0;
  834.             count <    8000; count++, bank1++,    bank2++)
  835.         {
  836.         *(bank1) = 0xff;
  837.         *(bank2) = 0xff;
  838.         }
  839.     }
  840.  
  841.     /* putpixel    *************************************************************/
  842. void putpixel(int row, int col,    unsigned color)
  843.     {
  844.     unsigned mask =    0xff3f;
  845.     unsigned char far *off;
  846.  
  847.         /* pixel is    at video_base +    (# of rows * bytes per row)                */
  848.         /* plus    # of columns/2 (since half are in next bank)                */
  849.         /* add BANK2OFFSET-BYTES_PER_ROW for 2nd bank if odd-numbered row           */
  850.     off    = (video_base +    (row * BYTES_PER_ROW) +    (col >>    2) +
  851.             ((row &    1) ? (BANK2OFFSET-BYTES_PER_ROW) : 0));
  852.  
  853.         /* put color bits into top pair, leave on bottom 2 bits    of col    */
  854.         /* col now has bit offset into byte    of the bits    to set            */
  855.     for( color <<= 6, col &= 0x03; col;    col--)
  856.         {
  857.         mask >>= 2;                                /* shift mask and color    bits*/
  858.         color >>= 2;
  859.         }
  860.     *off = ((*off &    (char)mask)    | color);        /* set byte    to color        */
  861.     }
  862.  
  863.     /* termination **********************************************************/
  864. void termination(void)
  865.     {
  866.     if(orgrows != viomodeinfo.row)                /* if screen mode changed    */
  867.         {
  868.         viomodeinfo.row    = orgrows;
  869.         VioSetMode(&viomodeinfo,VIOHDL);        /* reset orig. screen mode    */
  870.         }
  871.  
  872.     Screen(RESTORE);                            /* restore screen            */
  873.     Cursor(RESTORECUR);                            /* restore cursor            */
  874.  
  875.     DosExit(EXIT_PROCESS,0);                    /* terminate the process    */
  876.     }
  877.  
  878.     /******** end of hello1.c *********/
  879.  
  880.  
  881.