home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / VSCPPv8.zip / VACPP / IBMCPP / samples / TOOLKIT / OS2 / CONSOLIO / WORMS.C < prev    next >
C/C++ Source or Header  |  1994-11-17  |  23KB  |  845 lines

  1. /*=========================================================================\
  2.  *                                                                         *
  3.  *       FILE:worms.c                                                      *
  4.  *                                                                         *
  5.  *       DESCRIPTION:    Full Screen Mixed-mode programming sample         *
  6.  *                                                                         *
  7.  *      Created 1991  IBM Corp.                                            *
  8.  *                                                                         *
  9.  *      DISCLAIMER OF WARRANTIES.  The following [enclosed] code is        *
  10.  *      sample code created by IBM Corporation. This sample code is not    *
  11.  *      part of any standard or IBM product and is provided to you solely  *
  12.  *      for  the purpose of assisting you in the development of your       *    *
  13.  *      applications.  The code is provided "AS IS", without               *
  14.  *      warranty of any kind.  IBM shall not be liable for any damages     *
  15.  *      arising out of your use of the sample code, even if they have been *
  16.  *      advised of the possibility of   such damages.                      *                               *
  17.  *                                                                         *
  18.  *-------------------------------------------------------------------------*
  19.  *  This source file contains the following functions:
  20.  *
  21.  *  main
  22.  *  WormsMainProcess
  23.  *  ProcessCmdLine
  24.  *  ErrorMessage
  25.  *  WormsExit
  26.  *
  27. \*==============================================================*/
  28.  
  29. /*--------------------------------------------------------------*\
  30.  *  Include files, macros, defined constants, and externs
  31. \*--------------------------------------------------------------*/
  32.  
  33.  
  34. #define  INCL_VIO
  35. #define  INCL_KBD
  36. #define  INCL_MOU
  37. #define  INCL_DOSPROCESS
  38. #define  INCL_DOSSEMAPHORES
  39.  
  40.  
  41. #include <os2.h>
  42. #include <string.h>
  43. #include <stddef.h>
  44. #include <string.h>
  45. #include <stdlib.h>
  46. #include "worms.h"
  47. #include "wrmthrd.h"
  48. #include "init.h"
  49. #include "wrmhelp.h"
  50.  
  51. /*--------------------------------------------------------------*\
  52.  *Global definitions for this module
  53. \*--------------------------------------------------------------*/
  54.  
  55.  
  56. #define STACK_SIZE_WORMTHRD    32678
  57. #define BOX_ROW 6
  58. #define BOX_COL 10
  59. #define HEIGHT_BOX 9
  60. #define BOX_WIDTH  70
  61. #define DEBUG   1
  62.  
  63. /*--------------------------------------------------------------*\
  64.  *  Global  variables for this module
  65. \*--------------------------------------------------------------*/
  66.  
  67. SHORT  sCurrentThread = 0;
  68. BOOL   fThreadsContinue = TRUE;
  69. BOOL   fSilent = FALSE;
  70. SHORT  sStartWorms = 1;
  71. BOOL   fQuit  = FALSE;                        /*Global quit flag all threads*/
  72. BOOL   fDraw  = TRUE;                         /*Global draw flag all threads*/
  73. BOOL   bHelpEnabled  = FALSE;
  74. BOOL   bMessage      = FALSE;
  75.  
  76. VIOCURSORINFO viociCursor;
  77. VIOMODEINFO   VioModeInfo;
  78. HVIO  hvio = 0 ;
  79. THREAD_DATA ThreadData[] =
  80. /*                                       background/text                           */
  81. /*  TID Active Row           Col          Attribute               sCurrentDirection*/
  82. {
  83.     0L, FALSE, BOT_ROW  / 2 ,FIRST_COL  ,MKATRB(WM_BLUE,WM_RED)        ,0,
  84.     0L, FALSE, FIRST_ROW    ,RGT_COL    ,MKATRB(WM_BROWN,WM_CYAN)      ,0,
  85.     0L, FALSE, BOT_ROW      ,RGT_COL / 2,MKATRB(WM_MAGENTA,WM_PALEGRAY),0,
  86.     0L, FALSE, FIRST_ROW + 5,RGT_COL / 4,MKATRB(WM_LRED,WM_GREEN)      ,0,
  87.     0L, FALSE, BOT_ROW      ,RGT_COL - 3,MKATRB(WM_YELLOW,WM_WHITE)    ,0,
  88.     0L, FALSE, BOT_ROW  - 4 ,FIRST_COL  ,MKATRB(WM_GREEN,WM_LBLUE)     ,0,
  89.     0L, FALSE, FIRST_ROW + 4,RGT_COL    ,MKATRB(WM_BROWN,WM_YELLOW)    ,0,
  90.     0L, FALSE, BOT_ROW  - 2 ,RGT_COL / 2,MKATRB(WM_DKGREY,WM_GREEN)    ,0,
  91.     0L, FALSE, FIRST_ROW    ,RGT_COL / 4,MKATRB(WM_BLUE,WM_RED)        ,0,
  92.     0L, FALSE, BOT_ROW  - 3 ,RGT_COL - 3,MKATRB(WM_WHITE,WM_LBLUE)     ,0,
  93.  
  94.     0L, FALSE, BOT_ROW  / 2 ,FIRST_COL  ,MKATRB(WM_BLUE,WM_RED)        ,0,
  95.     0L, FALSE, FIRST_ROW    ,RGT_COL    ,MKATRB(WM_BROWN,WM_CYAN)      ,0,
  96.     0L, FALSE, BOT_ROW      ,RGT_COL / 2,MKATRB(WM_MAGENTA,WM_PALEGRAY),0,
  97.     0L, FALSE, FIRST_ROW + 5,RGT_COL / 4,MKATRB(WM_LRED,WM_GREEN)      ,0,
  98.     0L, FALSE, BOT_ROW      ,RGT_COL - 3,MKATRB(WM_YELLOW,WM_WHITE)    ,0,
  99.     0L, FALSE, BOT_ROW  - 4 ,FIRST_COL  ,MKATRB(WM_GREEN,WM_LBLUE)     ,0,
  100.     0L, FALSE, FIRST_ROW + 4,RGT_COL    ,MKATRB(WM_BROWN,WM_YELLOW)    ,0,
  101.     0L, FALSE, BOT_ROW  - 2 ,RGT_COL / 2,MKATRB(WM_DKGREY,WM_GREEN)    ,0,
  102.     0L, FALSE, FIRST_ROW    ,RGT_COL / 4,MKATRB(WM_BLUE,WM_RED)        ,0,
  103.     0L, FALSE, BOT_ROW  - 3 ,RGT_COL - 3,MKATRB(WM_WHITE,WM_LBLUE)     ,0,
  104.  
  105.     0L, FALSE, BOT_ROW  / 2 ,FIRST_COL  ,MKATRB(WM_BLUE,WM_RED)        ,0,
  106.     0L, FALSE, FIRST_ROW    ,RGT_COL    ,MKATRB(WM_BROWN,WM_CYAN)      ,0,
  107.     0L, FALSE, BOT_ROW      ,RGT_COL / 2,MKATRB(WM_MAGENTA,WM_PALEGRAY),0,
  108.     0L, FALSE, FIRST_ROW + 5,RGT_COL / 4,MKATRB(WM_LRED,WM_GREEN)      ,0,
  109.     0L, FALSE, BOT_ROW      ,RGT_COL - 3,MKATRB(WM_YELLOW,WM_WHITE)    ,0,
  110.     0L, FALSE, BOT_ROW  - 4 ,FIRST_COL  ,MKATRB(WM_GREEN,WM_LBLUE)     ,0,
  111.     0L, FALSE, FIRST_ROW + 4,RGT_COL    ,MKATRB(WM_BROWN,WM_YELLOW)    ,0,
  112.     0L, FALSE, BOT_ROW  - 2 ,RGT_COL / 2,MKATRB(WM_DKGREY,WM_GREEN)    ,0,
  113.     0L, FALSE, FIRST_ROW    ,RGT_COL / 4,MKATRB(WM_BLUE,WM_RED)        ,0,
  114.     0L, FALSE, BOT_ROW  - 3 ,RGT_COL - 3,MKATRB(WM_WHITE,WM_LBLUE)     ,0,
  115. };
  116. CHAR *pszBox [HEIGHT_BOX]=
  117. {
  118. "╔════════════════════════════════════════════════════════╗",
  119. "║                                                        ║",
  120. "║               Process  Message:                        ║",
  121. "║                                                        ║",
  122. "║                                                        ║",
  123. "║                                                        ║",
  124. "║                                                        ║",
  125. "║                                                        ║",
  126. "╚════════════════════════════════════════════════════════╝",
  127. };
  128. CHAR *pszWormMessages [] =
  129. {
  130.      "Worms Mixed-Mode Program Normal Exit",
  131.      "Undetermined Error Occurred",
  132.      "Worms Mixed Mode Program Initialization Failure",
  133.      "Maximum Number of Threads Reached for this Process",
  134.      "Error Creating Thread",
  135.      "Unable To Display Help Screen",
  136.      "Unable To Create  Mouse Event Thread",
  137.      "Hit Any Key to Exit Process",
  138.      "Waiting for Threads To Exit",
  139.      "Any Key to Continue",
  140. };
  141.  
  142. #define    MAX_ERROR_MSGS (sizeof (pszErrorMessage) )
  143. #define    MAX_THREADS    ( ( sizeof(ThreadData) / sizeof(THREAD_DATA) ) -1 )
  144. #define    ONCE         while( 0 )
  145. /*--------------------------------------------------------------*\
  146.  *  Entry point declarations
  147. \*--------------------------------------------------------------*/
  148. INT
  149. main (SHORT sArgc , CHAR *ppArgv[]);
  150. VOID
  151. WormsExit(SHORT sExitStatus);
  152. BOOL
  153. WormsMainProcess(SHORT *psStatus);
  154. BOOL
  155. ProcessCmdLine(SHORT sArgc,CHAR **ppArgv);
  156.  
  157. /****************************************************************\
  158.  *  Routine Name:main()
  159.  *--------------------------------------------------------------
  160.  *
  161.  *  Name: main()
  162.  *
  163.  *  Purpose:Main entry point for  the worms program
  164.  *
  165.  *
  166.  *
  167.  *  Usage: Main entry point for the worms program.
  168.  *
  169.  *  Method:
  170.  *          -
  171.  *
  172.  *          -
  173.  *          -
  174.  *
  175.  *          -
  176.  *          -
  177.  *
  178.  *  Returns:
  179.  *
  180.  *
  181. \****************************************************************/
  182. INT
  183. main (SHORT sArgc,CHAR  *ppArgv[])
  184. {
  185.  
  186.     SHORT     sExitStatus = WRM_NORMAL_EXIT;
  187.  
  188.     do
  189.     {
  190.  
  191.          /*
  192.           *process the command line
  193.           */
  194.          if(ProcessCmdLine(sArgc,ppArgv) )
  195.          {
  196.                break;
  197.          }
  198.  
  199.          /*
  200.           *initialize resources
  201.           */
  202.          if(Init(&sExitStatus) )
  203.          {
  204.                ErrorMessage(sExitStatus,TRUE);
  205.                break;
  206.  
  207.          }
  208.          /*
  209.           *start up the main process
  210.           */
  211.          if(WormsMainProcess(&sExitStatus) )
  212.          {
  213.                ErrorMessage(sExitStatus,TRUE);
  214.                break;
  215.  
  216.          }
  217.  
  218.     } ONCE;
  219.     WormsExit(WRM_NORMAL_EXIT);
  220.  
  221.     return( (INT) sExitStatus);
  222.  
  223.  
  224. }/*main entry point*/
  225.  
  226. /****************************************************************\
  227.  *
  228.  *--------------------------------------------------------------
  229.  *
  230.  *  Name:WormsMainProcess
  231.  *
  232.  *  Purpose:
  233.  *
  234.  *
  235.  *
  236.  *  Usage:
  237.  *
  238.  *  Method:
  239.  *          -
  240.  *
  241.  *          -
  242.  *          -
  243.  *
  244.  *          -
  245.  *          -
  246.  *
  247.  *  Returns:
  248.  *          FALSE - if sucessful execution completed
  249.  *          TRUE  - if error ,See *psStatus for error definition
  250. \****************************************************************/
  251. BOOL
  252. WormsMainProcess(SHORT *psStatus)
  253. {
  254.     BOOL fError = FALSE;
  255.     KBDKEYINFO    kbdkeyinfo;
  256.     USHORT      usId;
  257.     ULONG ulPosts;
  258.  
  259.  
  260.     do
  261.     {
  262.           /*
  263.            *sit here and wait on
  264.            *user input
  265.            */
  266.           KbdCharIn(&kbdkeyinfo,IO_WAIT,
  267.                      0) ;
  268.           /*
  269.            *if help was enabled don't allow any other input
  270.            */
  271.           if(!bHelpEnabled && !bMessage)
  272.           {
  273.                /*
  274.                 *regular keys
  275.                 */
  276.                if( kbdkeyinfo.chChar )
  277.                {
  278.                     switch(kbdkeyinfo.chChar)
  279.                     {
  280.                     case 'd':
  281.                     case 'D':
  282.                            WormDelete();
  283.                            break;
  284.                     case 'e':
  285.                     case 'E':
  286.                          fQuit = TRUE;
  287.                          fDraw = FALSE;
  288.                          break;
  289.                     case 'a':
  290.                     case 'A':
  291.                          WormCreate();
  292.                          break;
  293.                     case 'h':
  294.                     case 'H':
  295.                          if( WormHelp() )
  296.                          {
  297.                               ErrorMessage(ERROR_DISP_HELP,TRUE);
  298.                          }
  299.                          break;
  300.                     default:
  301.                          DosBeep(1200,175);
  302.                          break;
  303.                     }
  304.                }
  305.                /*
  306.                 *extended keys
  307.                 */
  308.                else
  309.                {
  310.                     switch(kbdkeyinfo.chScan )
  311.                     {
  312.                     case F1:
  313.                          if( WormHelp() )
  314.                          {
  315.                               ErrorMessage(ERROR_DISP_HELP,TRUE);
  316.                          }
  317.                          break;
  318.                     default:
  319.                          DosBeep(1200,175);
  320.                          break;
  321.                     }
  322.                }
  323.  
  324.           }
  325.           /*
  326.            *another threads  waiting for keyboard input
  327.            *free them up
  328.            */
  329.           else
  330.           {
  331.                DosPostEventSem(hevWormSem);
  332.           }
  333.  
  334.     }while(!fQuit );
  335.  
  336.     /*
  337.      *set each thread as inactive
  338.      */
  339.     for(usId = 2; usId <= MAX_THREADS + 2; usId++)
  340.     {
  341.           ThreadData[usId - 2].fActive = FALSE;
  342.     }
  343.  
  344.      /*
  345.       *make sure we don't get
  346.       *pre-empted
  347.       */
  348.      DosEnterCritSec();
  349.      ulPosts = 0;
  350.      DosResetEventSem(hevDrawOk,&ulPosts);
  351.      DosExitCritSec();
  352.  
  353.      /*
  354.       *wait till all of the
  355.       *threads have
  356.       *posted on the way out
  357.       */
  358.      while(ulPosts < sCurrentThread)
  359.      {
  360.           DosWaitEventSem(hevDrawOk,SEM_INDEFINITE_WAIT);
  361.           DosQueryEventSem(hevDrawOk,&ulPosts);
  362.      }
  363.     /*
  364.      *display message that process is shutting down
  365.      */
  366.     Message(WAITING_THREADS_EXIT,FALSE,FALSE,TRUE,FALSE);
  367.     return ( fError) ;
  368. }/*main process loop */
  369.  
  370. /****************************************************************\
  371.  *
  372.  *--------------------------------------------------------------
  373.  *
  374.  *  Name: WormCreate()
  375.  *
  376.  *  Purpose:
  377.  *
  378.  *
  379.  *
  380.  *  Usage:
  381.  *
  382.  *  Method:
  383.  *          -
  384.  *
  385.  *          -
  386.  *          -
  387.  *
  388.  *          -
  389.  *          -
  390.  *
  391.  *  Returns:
  392.  *          TRUE   - Error occurred
  393.  *          FALSE  - No error occurred
  394. \****************************************************************/
  395. BOOL
  396. WormCreate(VOID )
  397. {
  398.  
  399.     if( sCurrentThread  == MAX_THREADS )
  400.     {
  401.           /*
  402.            *thread limit exceeeded
  403.            */
  404.            ErrorMessage(MAX_THREADS_EXCEEDED,TRUE );
  405.            return(TRUE);
  406.  
  407.     }
  408.     ThreadData[sCurrentThread].fActive = TRUE;
  409.     ThreadData[sCurrentThread].tidWorm =
  410.                             _beginthread( WormThread,
  411.                                        NULL,
  412.                                        STACK_SIZE_WORMTHRD,
  413.                                        &ThreadData[sCurrentThread]);
  414.     if(ThreadData[sCurrentThread].tidWorm ==  -1 )
  415.     {
  416.           ErrorMessage(ERROR_CREATING_THREAD,TRUE );
  417.           return(TRUE);
  418.     }
  419.     sCurrentThread++;
  420.  
  421.     return(FALSE);
  422.  
  423. }
  424. /****************************************************************\
  425.  *
  426.  *--------------------------------------------------------------
  427.  *
  428.  *  Name: ErrorMessage()
  429.  *
  430.  *  Purpose: Display Error Messages to the user.
  431.  *
  432.  *
  433.  *
  434.  *  Usage: sErrorMessage - Message number to display.
  435.  *         fBeep         - Beep or not.
  436.  *
  437.  *  Method:
  438.  *          -
  439.  *
  440.  *          -
  441.  *          -
  442.  *
  443.  *          -
  444.  *          -
  445.  *
  446.  *  Returns:   VOID
  447. \****************************************************************/
  448. VOID ErrorMessage(SHORT sErrorMessage,BOOL fBeep)
  449.  
  450. {
  451.  
  452.     KBDKEYINFO    kbdkeyinfo;
  453.     BYTE  bAttr  = MKATRB(WM_RED,WM_WHITE );
  454.     USHORT usAttrib = VP_WAIT | VP_OPAQUE;
  455.     USHORT  usRow,usIndex;
  456.     USHORT  usStatus = MOUSE_DISABLED;
  457.     BYTE bCell[2];
  458.     PVOID pvSaveWindBuf;
  459.     PTIB   ptib ;
  460.     PPIB   ppib  ;
  461.     ULONG  ulPosts;
  462.  
  463.     bCell[0] = 0x20;
  464.     bCell[1] = WM_BACKGROUND;
  465.     bMessage = TRUE;
  466.  
  467.  
  468.     if(fBeep)
  469.     {
  470.           DosBeep(675,1200);
  471.     }
  472.  
  473.      /*
  474.       *freeze all threads
  475.       *while pop-up is up
  476.       */
  477.      SuspendAllThreads();
  478.      /*
  479.       *make sure each thread has had enough time
  480.       *to complete
  481.       *what they are doin before waiting on the drawing semaphore
  482.       */
  483. //   DosSleep(PAUSE_TIME * 40);
  484.      /*
  485.       *read the screen and save
  486.       *it
  487.       */
  488.      if(SaveScreen(&pvSaveWindBuf) )
  489.      {
  490.           return;
  491.      }
  492.  
  493.      VioScrollDn(0,0,0xFFFF,0xFFFF,0xFFFF,bCell,hvio);
  494.  
  495.  
  496.     /*
  497.      *put up the  message box
  498.      */
  499.      for(usRow = BOX_ROW,usIndex = 0;usIndex < HEIGHT_BOX; usIndex++,
  500.                                                           usRow++ )
  501.      {
  502.         VioWrtCharStrAtt(pszBox[usIndex],strlen(pszBox[usIndex]),
  503.                      usRow,
  504.                      BOX_COL,
  505.                      &bAttr,
  506.                      hvio );
  507.      }
  508.  
  509.      /*
  510.       *display
  511.       *error message
  512.       */
  513.       VioWrtCharStrAtt( pszWormMessages[sErrorMessage],
  514.                          strlen(pszWormMessages[sErrorMessage]),
  515.                          BOX_ROW + 5,
  516.                          ( ((LAST_COL - FIRST_COL ) -
  517.                                     strlen(pszWormMessages[sErrorMessage])) / 2) ,
  518.                          &bAttr,
  519.                          hvio );
  520.        /*
  521.         *any key to continue
  522.         */
  523.        VioWrtCharStrAtt( pszWormMessages[ANY_KEY_TO_CONTINUE],
  524.                          strlen(pszWormMessages[ANY_KEY_TO_CONTINUE]),
  525.                          BOX_ROW + 6,
  526.                          ( ((LAST_COL - FIRST_COL ) -
  527.                                     strlen(pszWormMessages[ANY_KEY_TO_CONTINUE])) / 2) ,
  528.                          &bAttr,
  529.                          hvio );
  530.  
  531.       DosGetInfoBlocks(&ptib,&ppib);
  532.       /*
  533.        *if we are not
  534.        *calling from thread
  535.        *one suspend the calling thread
  536.        *so only one thread at a time
  537.        *is hitting the keyboard queue
  538.        */
  539.       if(ptib->tib_ptib2->tib2_ultid != 1 )
  540.       {
  541.           DosWaitEventSem(hevWormSem,SEM_INDEFINITE_WAIT);
  542.           DosResetEventSem(hevWormSem,&ulPosts);
  543.       }
  544.       else
  545.       {
  546.          /*
  547.           *wait for any
  548.           *response if thread 1
  549.           */
  550.           KbdCharIn(&kbdkeyinfo,IO_WAIT,
  551.                          0) ;
  552.       }
  553.  
  554.       VioScrollDn(0,0,0xFFFF,0xFFFF,0xFFFF,bCell,hvio);
  555.       /*
  556.        *restore the screen
  557.        */
  558.       ReDisplayScreen(pvSaveWindBuf);
  559.  
  560.        /*
  561.         *resume all threads
  562.         */
  563.      ResumeAllThreads();
  564.  
  565.      bMessage = FALSE;
  566. }
  567.  
  568. /****************************************************************\
  569.  *
  570.  *--------------------------------------------------------------
  571.  *
  572.  *  Name: Message()
  573.  *
  574.  *  Purpose:Generic message routine. Allows all threads to continue,
  575.  *          while message is up.
  576.  *
  577.  *
  578.  *
  579.  *  Usage:
  580.  *
  581.  *  Method:
  582.  *          -
  583.  *
  584.  *          -
  585.  *          -
  586.  *
  587.  *          -
  588.  *          -
  589.  *
  590.  *  Returns:   VOID
  591.  *
  592.  *
  593. \****************************************************************/
  594. VOID Message( SHORT sErrorMessage,BOOL fBeep,BOOL fKeyBoardWait,
  595.                    BOOL fClsConsole,BOOL fSuspendThreads )
  596. {
  597.     KBDKEYINFO    kbdkeyinfo;
  598.     BYTE  bAttr  = MKATRB(WM_RED,WM_WHITE );
  599.     USHORT usAttrib = VP_WAIT | VP_OPAQUE;
  600.     USHORT  usRow,usIndex;
  601.     BYTE bCell[2];
  602.     BYTE bhAttr = WM_BACKGROUND;
  603.  
  604.     bCell[0] = 0x20;
  605.     bCell[1] = WM_BACKGROUND;
  606.  
  607.      /*
  608.       *display
  609.       *the error message to the
  610.       *screen
  611.       */
  612.       if(fBeep)
  613.       {
  614.           DosBeep(675,1200);
  615.       }
  616.  
  617.       if(fSuspendThreads)
  618.       {
  619.           SuspendAllThreads();
  620.       }
  621.  
  622.       DosSleep(1000L);
  623.       if(fClsConsole)
  624.       {
  625.           /*
  626.            *clear the screen
  627.            */
  628.           VioScrollDn(0,0,0xFFFF,0xFFFF,0xFFFF,bCell,hvio);
  629.       }
  630.  
  631.        /*
  632.         *put up the  message box
  633.         */
  634.  
  635.        for(usRow = BOX_ROW,usIndex = 0;usIndex < HEIGHT_BOX; usIndex++,
  636.                                                              usRow++ )
  637.        {
  638.           VioWrtCharStrAtt(pszBox[usIndex],strlen(pszBox[usIndex]),
  639.                         usRow,
  640.                         BOX_COL,
  641.                         &bAttr,
  642.                         hvio );
  643.        }
  644.  
  645.        /*
  646.         *display
  647.         *message
  648.         */
  649.        VioWrtCharStrAtt( pszWormMessages[sErrorMessage],
  650.                          strlen(pszWormMessages[sErrorMessage]),
  651.                          BOX_ROW + 5,
  652.                          ( ((LAST_COL - FIRST_COL ) -
  653.                                     strlen(pszWormMessages[sErrorMessage])) / 2) ,
  654.                          &bAttr,
  655.                          hvio );
  656.  
  657.        /*
  658.         *sit here and wait on
  659.         *user input
  660.         */
  661.        if(fKeyBoardWait)
  662.        {
  663.  
  664.            VioWrtCharStrAtt( pszWormMessages[sErrorMessage],
  665.                              strlen(pszWormMessages[sErrorMessage]),
  666.                              BOX_ROW + 6,
  667.                              ( ((LAST_COL - FIRST_COL ) -
  668.                                         strlen(pszWormMessages[ANY_KEY_TO_CONTINUE])) / 2) ,
  669.                              &bAttr,
  670.                              hvio );
  671.            KbdCharIn(&kbdkeyinfo,IO_WAIT,
  672.                       0 ) ;
  673.        }
  674.  
  675. }
  676.  
  677. /****************************************************************\
  678.  *
  679.  *--------------------------------------------------------------
  680.  *
  681.  *  Name:WormsExit()
  682.  *
  683.  *  Purpose: Generic exit routine. All exit processing should be done
  684.  *           at this point.
  685.  *
  686.  *
  687.  *
  688.  *  Usage:
  689.  *
  690.  *  Method:
  691.  *          -
  692.  *
  693.  *          -
  694.  *          -
  695.  *
  696.  *          -
  697.  *          -
  698.  *
  699.  *  Returns:   VOID
  700.  *
  701.  *
  702. \****************************************************************/
  703. VOID
  704. WormsExit(SHORT sExitStatus)
  705. {
  706.  
  707.      USHORT usRow,usCol;
  708.      BYTE bCell[2];
  709.      BYTE bhAttr = MKATRB(WM_BLUE,WM_RED);
  710.  
  711.      bCell[0] = 0x20;
  712.      bCell[1] = WM_BACKGROUND;
  713.  
  714.  
  715.      /*
  716.       *do any clean up
  717.       *necessary
  718.       */
  719.  
  720.  
  721.      /*
  722.       *clear the screen
  723.       */
  724.      VioScrollDn(0,0,0xFFFF,0xFFFF,0xFFFF,bCell,hvio);
  725.  
  726.      /*
  727.       *reset the old
  728.       *cursor
  729.       */
  730.      VioSetCurType(&viociCursor,hvio);
  731.      /*
  732.       *display the exit message
  733.       */
  734.      VioWrtCharStrAtt( pszWormMessages[sExitStatus],
  735.                        strlen(pszWormMessages[sExitStatus]),
  736.                        2,1,
  737.                        &bhAttr,hvio );
  738.      VioSetCurPos(3,2,hvio);
  739.  
  740. }
  741. /****************************************************************\
  742.  *
  743.  *--------------------------------------------------------------
  744.  *
  745.  *  Name:ProcessCmdLine()
  746.  *
  747.  *  Purpose:Parse arguments passed on the command line.
  748.  *
  749.  *
  750.  *
  751.  *  Usage:
  752.  *
  753.  *  Method:
  754.  *          -
  755.  *
  756.  *          -
  757.  *          -
  758.  *
  759.  *          -
  760.  *          -
  761.  *
  762.  *  Returns:
  763.  *        FALSE   - at present time
  764.  *
  765. \****************************************************************/
  766. BOOL ProcessCmdLine(SHORT sArgc,CHAR **ppArgv)
  767. {
  768.      SHORT sArgnum = 1;
  769.      BOOL  fError = FALSE;
  770.  
  771.      while(--sArgc )
  772.      {
  773.           if( *ppArgv[sArgnum] == '-'   ||
  774.               *ppArgv[sArgnum] == '/' )
  775.           {
  776.  
  777.                switch(*(ppArgv[sArgnum] + 1) )
  778.                {
  779.                case 'S':
  780.                case 's':
  781.                     fSilent = TRUE;
  782.                     break;
  783.                case '1':
  784.                case '2':
  785.                case '3':
  786.                case '4':
  787.                case '5':
  788.                case '6':
  789.                case '7':
  790.                case '8':
  791.                case '9':
  792.                     sStartWorms = atoi(ppArgv[sArgnum] + 1);
  793.                     if(sStartWorms > MAX_THREADS )
  794.                     {
  795.                          sStartWorms = MAX_THREADS;
  796.                     }
  797.                     break;
  798.                }
  799.           }
  800.           sArgnum++;
  801.      }
  802.      return(fError);
  803. }
  804. /****************************************************************\
  805.  *
  806.  *--------------------------------------------------------------
  807.  *
  808.  *  Name:WormDelete()
  809.  *
  810.  *  Purpose:Set the active flag to false for the last active
  811.  *  thread to FALSE.
  812.  *
  813.  *
  814.  *  Usage:
  815.  *
  816.  *  Method:
  817.  *          -
  818.  *
  819.  *          -
  820.  *          -
  821.  *
  822.  *          -
  823.  *          -
  824.  *
  825.  *  Returns:
  826.  *
  827.  *          VOID
  828. \****************************************************************/
  829. VOID WormDelete(VOID )
  830. {
  831.  
  832.       if(sCurrentThread > 0 )
  833.       {
  834.          ThreadData[--sCurrentThread].fActive = FALSE;
  835.       }
  836.       else
  837.       {
  838.           DosBeep(675,1200);
  839.       }
  840.  
  841. }
  842.  
  843.  
  844.  
  845.