home *** CD-ROM | disk | FTP | other *** search
/ Over 1,000 Doom Levels / 1000DOOMLevels-3DSharewareGames.bin / pc / doomfaqs / ser4_src / sersetup.c < prev    next >
C/C++ Source or Header  |  1994-03-19  |  24KB  |  1,152 lines

  1. // sersetup.c
  2.  
  3. #include "sersetup.h"
  4. #include "DoomNet.h"
  5. #include <time.h>
  6.  
  7. extern    que_t        inque, outque;
  8.  
  9. void jump_start( void );
  10. void GetUart (void);
  11. extern int     uart;
  12.  
  13. int            usemodem;
  14.  
  15.  
  16. void ModemCommand (char *str);
  17. int ModemResponse (char *resp);
  18. void configure (void);
  19. void reset_counters (void);
  20.  
  21. time_t starttime = 0;
  22. time_t endtime = 0;
  23. time_t playtime = 0;
  24.  
  25. char init1 [256+1];
  26. char init2 [256+1];
  27. char hangup [256+1];
  28. char config [256+1];
  29. char devparm [256+1];
  30. unsigned long baud = 9600;
  31. char dial [256+1];
  32. int comport = 1;
  33. int irq = -1;
  34. int uart = -1;
  35. int vector = -1;
  36. int loadgame = -1;
  37. int episode = -1;
  38. int map = -1;
  39. int skill = -1;
  40. int deathmatch = 0;
  41. int pulsedial = 0;
  42. int player = 0;
  43. int nomonsters = 0;
  44. int respawn = 0;
  45.  
  46. /* showReadStats() counters. */
  47. unsigned long writeBufferOverruns       = 0;
  48. unsigned long bytesRead                 = 0;
  49. unsigned long packetsRead               = 0;
  50. unsigned long largestReadPacket         = 0;
  51. unsigned long smallestReadPacket        = 0xFFFFFFFFl;
  52. unsigned long readBufferOverruns        = 0;
  53. unsigned long totalReadPacketBytes      = 0;
  54. unsigned long oversizeReadPackets       = 0;
  55. unsigned long largestOversizeReadPacket = 0;
  56. unsigned long overReadPacketLen         = 0;
  57.  
  58. /* showWriteStats() counters. */
  59. unsigned long bytesWritten               = 0;
  60. unsigned long packetsWrite               = 0;
  61. unsigned long largestWritePacket         = 0;
  62. unsigned long smallestWritePacket        = 0xFFFFFFFFl;
  63. unsigned long totalWritePacketBytes      = 0;
  64. unsigned long oversizeWritePackets       = 0;
  65. unsigned long largestOversizeWritePacket = 0;
  66.  
  67. /* showUartErrors() counters. */
  68. unsigned long numBreak          = 0;
  69. unsigned long numFramingError   = 0;
  70. unsigned long numParityError    = 0;
  71. unsigned long numOverrunError   = 0;
  72. unsigned long numTxInterrupts   = 0;
  73. unsigned long numRxInterrupts   = 0;
  74.  
  75.  
  76. void showReadStats()
  77. {
  78.     if ( smallestReadPacket == 0xFFFFFFFFl )
  79.         smallestReadPacket = 0;
  80.  
  81.     printf ("Read statistics:\n");
  82.  
  83.     printf ("%9lu Largest packet      %9lu Smallest packet\n",
  84.                 largestReadPacket, smallestReadPacket);
  85.  
  86.     printf ("%9lu Oversize packets    %9lu Largest oversize packet\n",
  87.                 oversizeReadPackets, largestOversizeReadPacket);
  88.  
  89.     printf ("%9lu Total packets       %9lu Buffer overruns\n",
  90.                 packetsRead, readBufferOverruns);
  91.  
  92.     printf ("%9lu Total bytes         %9.1f Average bytes/minute\n",
  93.                 totalReadPacketBytes,
  94.                 starttime == 0 || playtime == 0 ? 0 :
  95.                     (float) totalReadPacketBytes / (float) ((float) playtime / 60));
  96.  
  97.     printf ("%9lu Receive interrupts  %9.1f Average bytes/interrupt\n",
  98.         numRxInterrupts,
  99.         numRxInterrupts == 0 ? 0 :
  100.             (float) totalReadPacketBytes / (float) numRxInterrupts);
  101.  
  102.     printf ("\n");
  103. }
  104.  
  105.  
  106.  
  107. void showWriteStats()
  108. {
  109.     if ( smallestWritePacket == 0xFFFFFFFFl )
  110.         smallestWritePacket = 0;
  111.  
  112.     printf ("Write statistics:\n");
  113.  
  114.     printf ("%9lu Largest packet      %9lu Smallest packet\n",
  115.                 largestWritePacket, smallestWritePacket);
  116.  
  117.     printf ("%9lu Oversize packets    %9lu Largest oversize packet\n",
  118.                 oversizeWritePackets, largestOversizeWritePacket);
  119.  
  120.     printf ("%9lu Total packets       %9lu Buffer overruns\n",
  121.                 packetsWrite, writeBufferOverruns);
  122.  
  123.     printf ("%9lu Total bytes         %9.1f Average bytes/minute\n",
  124.                 totalWritePacketBytes,
  125.                 starttime == 0 || playtime == 0 ? 0 :
  126.                     (float) totalWritePacketBytes / (float) ((float) playtime / 60));
  127.  
  128.     printf ("%9lu Transmit interrupts %9.1f Average bytes/interrupt\n",
  129.         numTxInterrupts,
  130.         numTxInterrupts == 0 ? 0 :
  131.             (float) totalWritePacketBytes / (float) numTxInterrupts);
  132.  
  133.     printf ("\n");
  134. }
  135.  
  136. void showUartErrors()
  137. {
  138.     puts ("UART line status");
  139.  
  140.     printf ("%9lu Breaks detected     %9lu Framing errors\n",
  141.         numBreak, numFramingError);
  142.     printf ("%9lu Parity errors       %9lu Overrun errors\n",
  143.         numParityError, numOverrunError);
  144. }
  145.  
  146. /*
  147. ================
  148. =
  149. = write_buffer
  150. =
  151. ================
  152. */
  153.  
  154. void write_buffer( char *buffer, unsigned int count )
  155. {
  156. // if this would overrun the buffer, throw everything else out
  157.     if (outque.size + count > QUESIZE)
  158.     {
  159.         ++writeBufferOverruns;
  160.         outque.tail = outque.head;
  161.         outque.size = 0;
  162.     }
  163.  
  164.    write_bytes (buffer, count);
  165.  
  166.     if ( INPUT( uart + LINE_STATUS_REGISTER ) & 0x40)
  167.         jump_start();
  168. }
  169.  
  170.  
  171. void hangup_modem (void)
  172. {
  173.     printf ("\n");
  174.     printf ("\nDropping DTR\n");
  175.     OUTPUT( uart + MODEM_CONTROL_REGISTER
  176.         , INPUT( uart + MODEM_CONTROL_REGISTER ) & ~MCR_DTR );
  177.     delay (1250);
  178.     OUTPUT( uart + MODEM_CONTROL_REGISTER
  179.         , INPUT( uart + MODEM_CONTROL_REGISTER ) | MCR_DTR );
  180.     ModemCommand("+++");
  181.     delay (1250);
  182.     if (hangup [0] != EOS)
  183.         ModemCommand(hangup);
  184.     else
  185.     {
  186.         printf ("Warning: No HANGUP= string in MODEM.CFG file. Using default.\n");
  187.         ModemCommand("ATH0");
  188.     }
  189.     delay (1250);
  190.     while (read_byte () != -1)
  191.     ;
  192. }
  193.  
  194.  
  195. /*
  196. =================
  197. =
  198. = Error
  199. =
  200. = For abnormal program terminations
  201. =
  202. =================
  203. */
  204.  
  205. void Error (char *error, ...)
  206. {
  207.     va_list argptr;
  208.  
  209.     if (usemodem)
  210.         hangup_modem ();
  211.  
  212.     ShutdownPort ();
  213.  
  214.     if (vectorishooked)
  215.         setvect (doomcom.intnum,olddoomvect);
  216.  
  217.     if (error)
  218.     {
  219.         va_start (argptr,error);
  220.         vprintf (error,argptr);
  221.         va_end (argptr);
  222.         printf ("\n\n");
  223.     //    exit (1);
  224.     }
  225.  
  226.     //    printf ("Clean exit from SERSETUP\n");
  227.  
  228.     exit (error != (char *) NULL);
  229. }
  230.  
  231.  
  232. /*
  233. ================
  234. =
  235. = ReadPacket
  236. =
  237. ================
  238. */
  239.  
  240. #define MAXPACKET    512
  241. #define    FRAMECHAR    0x70
  242.  
  243. char    packet[MAXPACKET];
  244. int        packetlen;
  245. int        inescape;
  246. int        newpacket;
  247.  
  248. boolean ReadPacket (void)
  249. {
  250.     int    c;
  251.  
  252. // if the buffer has overflowed, throw everything out
  253.  
  254.     if (inque.size > QUESIZE - 4)    // check for buffer overflow
  255.     {
  256.         ++readBufferOverruns;           /* Count read overruns */
  257.         inque.tail = inque.head;
  258.         inque.size = 0;
  259.         newpacket = true;
  260.         return false;
  261.     }
  262.  
  263.     if (newpacket)
  264.     {
  265.         packetlen = 0;
  266.         newpacket = 0;
  267.         overReadPacketLen = 0;
  268.     }
  269.  
  270.     do
  271.     {
  272.         if ((c = read_byte ()) < 0)
  273.             return false;      // haven't read a complete packet
  274.         if (inescape)
  275.         {
  276.             inescape = false;
  277.             if (c!=FRAMECHAR)
  278.             {
  279.                 newpacket = 1;
  280.  
  281.                 ++packetsRead;  /* Count packets read */
  282.  
  283.                 if ( packetlen > largestReadPacket ) /* Track largest packet */
  284.                     largestReadPacket = packetlen;
  285.  
  286.                 if ( packetlen < smallestReadPacket ) /* Track smallest packet */
  287.                     smallestReadPacket = packetlen;
  288.  
  289.                 totalReadPacketBytes += packetlen;    /* Count total packet bytes */
  290.  
  291.                 return true;    // got a good packet
  292.             }
  293.         }
  294.         else if (c==FRAMECHAR)
  295.         {
  296.             inescape = true;
  297.             continue;            // don't know yet if it is a terminator
  298.         }                        // or a literal FRAMECHAR
  299.  
  300.         if (packetlen >= MAXPACKET)
  301.         {
  302.             ++overReadPacketLen;            /* Keep track of size of oversize packet */
  303.             oversizeReadPackets++;        /* Count oversize packets */
  304.  
  305.             if ( overReadPacketLen > largestOversizeReadPacket )
  306.                 largestOversizeReadPacket = overReadPacketLen;
  307.  
  308.             continue;            // oversize packet
  309.         }
  310.  
  311.         packet[packetlen] = c;
  312.         packetlen++;
  313.     } while (1);
  314.  
  315. }
  316.  
  317.  
  318. /*
  319. =============
  320. =
  321. = WritePacket
  322. =
  323. =============
  324. */
  325.  
  326.  
  327.  
  328. void WritePacket (char *buffer, int len)
  329. {
  330.     int        b;
  331.     char    static localbuffer[MAXPACKET*2+2];
  332.  
  333.     b = 0;
  334.     if (len > MAXPACKET)
  335.     {
  336.         ++oversizeWritePackets;         /* Count oversize write packets */
  337.         if ( len > largestOversizeWritePacket )
  338.             ++largestOversizeWritePacket;
  339.  
  340.         return;
  341.     }
  342.  
  343.     if ( len > largestWritePacket )
  344.         largestWritePacket = len;
  345.  
  346.     if ( len < smallestWritePacket )
  347.         smallestWritePacket = len;
  348.  
  349.     totalWritePacketBytes += len;
  350.  
  351.     ++packetsWrite;
  352.  
  353.     while (len--)
  354.     {
  355.         if (*buffer == FRAMECHAR)
  356.             localbuffer[b++] = FRAMECHAR;    // escape it for literal
  357.         localbuffer[b++] = *buffer++;
  358.     }
  359.  
  360.     localbuffer[b++] = FRAMECHAR;
  361.     localbuffer[b++] = 0;
  362.  
  363.     write_buffer (localbuffer, b);
  364. }
  365.  
  366.  
  367. /*
  368. =============
  369. =
  370. = NetISR
  371. =
  372. =============
  373. */
  374.  
  375. void interrupt NetISR (void)
  376. {
  377.     if (doomcom.command == CMD_SEND)
  378.     {
  379. //I_ColorBlack (0,0,63);
  380.         WritePacket ((char *)&doomcom.data, doomcom.datalength);
  381.     }
  382.     else if (doomcom.command == CMD_GET)
  383.     {
  384. //I_ColorBlack (63,63,0);
  385.  
  386.         if (ReadPacket () && packetlen <= sizeof(doomcom.data) )
  387.         {
  388.             doomcom.remotenode = 1;
  389.             doomcom.datalength = packetlen;
  390.             memcpy (&doomcom.data, &packet, packetlen);
  391.         }
  392.         else
  393.             doomcom.remotenode = -1;
  394.  
  395.     }
  396. //I_ColorBlack (0,0,0);
  397. }
  398.  
  399.  
  400.  
  401.  
  402. /*
  403. =================
  404. =
  405. = Connect
  406. =
  407. = Figures out who is player 0 and 1
  408. =================
  409. */
  410.  
  411. int Connect (void)
  412. {
  413.     struct time        time;
  414.     int                oldsec;
  415.     int        localstage, remotestage;
  416.     char    str[20];
  417.  
  418. //
  419. // wait for a good packet
  420. //
  421.     printf ("Attempting to connect across serial link, press escape to abort.\n");
  422.  
  423.     doomcom.consoleplayer = player;
  424.     oldsec = -1;
  425.     localstage = remotestage = 0;
  426.  
  427.     do
  428.     {
  429.         while ( bioskey(1) )
  430.         {
  431.             if ( (bioskey (0) & 0xff) == ESC)
  432.             {
  433.                 // Error ("\n\nNetwork game synchronization aborted.");
  434.                 printf ("\n\nNetwork game synchronization aborted.\n");
  435.                 while (read_byte () != -1)
  436.                 ;
  437.                 return FALSE;
  438.             }
  439.         }
  440.  
  441.         while (ReadPacket ())
  442.         {
  443.             packet[packetlen] = 0;
  444.             printf ("read: '%s'\n", packet);
  445.             if (packetlen != 7)
  446.             {
  447.                 printf ("bad packet len = %d (should be 7)\n", packetlen);
  448.                 goto badpacket;
  449.             }
  450.             if (strncmp(packet,"PLAY",4) )
  451.             {
  452.                 printf ("error: first 4 char's aren't 'PLAY'\n");
  453.                 goto badpacket;
  454.             }
  455.             remotestage = packet[6] - '0';
  456.             localstage = remotestage+1;
  457.             if (packet[4] == '0'+doomcom.consoleplayer)
  458.             {
  459.                 doomcom.consoleplayer ^= 1;
  460.                 localstage = remotestage = 0;
  461.             }
  462.             oldsec = -1;
  463.         }
  464. badpacket:
  465.  
  466.         gettime (&time);
  467.         if (time.ti_sec != oldsec)
  468.         {
  469.             oldsec = time.ti_sec;
  470.             sprintf (str,"PLAY%i_%i",doomcom.consoleplayer,localstage);
  471.             WritePacket (str,strlen(str));
  472.             printf ("wrote: '%s'\n",str);
  473.         }
  474.  
  475.     } while (remotestage < 1);
  476.  
  477. //
  478. // flush out any extras
  479. //
  480.     while (ReadPacket ())
  481.     ;
  482.     return TRUE;
  483. }
  484.  
  485.  
  486.  
  487. /*
  488. ==============
  489. =
  490. = ModemCommand
  491. =
  492. ==============
  493. */
  494.  
  495. void ModemCommand (char *str)
  496. {
  497.     int i;
  498.     char *ptr;
  499.  
  500.     printf ("Modem command : %s\n",str);
  501.     ptr = str;
  502.     for (i = 0; i < strlen (str); i++)
  503.     {
  504.         write_buffer (ptr++, 1);
  505.         delay (20);
  506.     }
  507.     write_buffer ("\r",1);
  508. }
  509.  
  510.  
  511. /*
  512. ==============
  513. =
  514. = ModemResponse
  515. =
  516. = Waits for OK, RING, CONNECT, etc
  517. ==============
  518. */
  519.  
  520.  
  521. int ModemResponse (char *resp)
  522. {
  523.     int        c;
  524.     int        respptr;
  525.     char    response[80];
  526.  
  527.     do
  528.     {
  529.         printf ("Modem response: ");
  530.         respptr=0;
  531.         do
  532.         {
  533.             while ( bioskey(1) )
  534.             {
  535.                 if ( (bioskey (0) & 0xff) == ESC)
  536.                 {
  537.                     // Error ("\nModem response aborted.");
  538.                     printf ("\nModem response aborted.\n");
  539.                     hangup_modem ();
  540.                     return FALSE;
  541.                 }
  542.             }
  543.             c = read_byte ();
  544.             if (c==-1)
  545.                 continue;
  546.             if (c=='\n' || respptr == 79)
  547.             {
  548.                 response[respptr] = 0;
  549.                 printf ("%s\n",response);
  550.                 break;
  551.             }
  552.             if (c>=' ')
  553.             {
  554.                 response[respptr] = c;
  555.                 respptr++;
  556.             }
  557.         } while (1);
  558.  
  559.     } while (strncmp(response,resp,strlen(resp)));
  560.     return TRUE;
  561. }
  562.  
  563.  
  564. /*
  565. =============
  566. =
  567. = InitModem
  568. =
  569. =============
  570. */
  571.  
  572. void InitModem (void)
  573. {
  574.     if (init1 [0] != EOS)
  575.     {
  576.         ModemCommand (init1);
  577.         if (! ModemResponse ("OK"))
  578.             return;
  579.     }
  580.  
  581.     if (init2 [0] != EOS)
  582.     {
  583.         ModemCommand (init2);
  584.         ModemResponse ("OK");
  585.     }
  586. }
  587.  
  588.  
  589. /*
  590. =============
  591. =
  592. = Dial
  593. =
  594. =============
  595. */
  596.  
  597. int Dial (void)
  598. {
  599.     char    cmd[80];
  600.     int ch;
  601.     char line [256+1];
  602.     FILE    *infile;
  603.     int found_name = FALSE;
  604.     int prompt = TRUE;
  605.  
  606.     usemodem = true;
  607.     InitModem ();
  608.  
  609.     if (dial [0] != EOS)
  610.     {
  611.         printf ("\nDial %s? (y/n): ", dial);
  612.         if ((ch = getch()) == 'y' || ch == 'Y')
  613.             prompt = FALSE;
  614.     }
  615.  
  616.     if (prompt)
  617.     {
  618.         printf ("\nEnter number to dial or phonebook name: ");
  619.         gets (line);
  620.         if (sscanf (line, "%s", dial) == EOF)
  621.             return FALSE;
  622.  
  623.         if ((infile = fopen ("modem.cfg", "r")) == NULL)
  624.             Error ("Couldn't read MODEM.CFG file.");
  625.  
  626.         while (fgets (line, 256, infile) != NULL)
  627.         {
  628.             if (line [0] == 'N' && line [1] == 'A')    /* NAME */
  629.             {
  630.                 if (strncmp (&line [5], dial, strlen (dial)) == 0)
  631.                     found_name = TRUE;
  632.             }
  633.             else if (found_name && line [0] == 'N' && line [1] == 'U')
  634.             {
  635.                 sscanf (&line [7], "%s", dial);            /* NUMBER */
  636.                 break;
  637.             }
  638.         }
  639.         fclose (infile);
  640.     }
  641.  
  642.     printf ("\nDialing %s\n\n", dial);
  643.     if (pulsedial)
  644.         sprintf (cmd,"ATDP%s", dial);
  645.     else
  646.         sprintf (cmd,"ATDT%s", dial);
  647.  
  648.     ModemCommand(cmd);
  649.     return ModemResponse ("CONNECT");
  650.  
  651.     /** doomcom.consoleplayer = 1; **/
  652. }
  653.  
  654.  
  655. /*
  656. =============
  657. =
  658. = Answer
  659. =
  660. =============
  661. */
  662.  
  663. int Answer (void)
  664. {
  665.     usemodem = true;
  666.     InitModem ();
  667.     printf ("\nWaiting for ring...\n\n");
  668.  
  669.     if (! ModemResponse ("RING"))
  670.         return FALSE;
  671.     ModemCommand ("ATA");
  672.     return ModemResponse ("CONNECT");
  673.  
  674.     /** doomcom.consoleplayer = 0; **/
  675. }
  676.  
  677.  
  678. void get_config_settings (void)
  679. {
  680.     char line [256+1];
  681.     int len;
  682.     FILE    *infile;
  683.     int i;
  684.     unsigned char far *vectorptr;
  685.     unsigned long lnum;
  686.  
  687.     if ((infile = fopen ("modem.cfg", "r")) == NULL)
  688.         Error ("Couldn't read MODEM.CFG file.");
  689.  
  690.     printf ("\n\n\n\nReading MODEM.CFG file...\n\n");
  691.     while (fgets (line, 256, infile) != NULL)
  692.     {
  693.         switch (line [0])
  694.         {
  695.             case 'B' :
  696.                 /* BAUD */
  697.                 if (sscanf (&line [5], "%lu", &baud) != EOF &&
  698.                     baud != 9600 && baud != 14400 && baud != 19200 &&
  699.                     baud != 38400 && baud != 57600 && baud != 115200)
  700.                 {
  701.                     baud = 9600;
  702.                 }
  703.                 break;
  704.             case 'C' :
  705.                 if (line [2] == 'N')
  706.                 {
  707.                     /* CONFIG */
  708.                     strcpy (config, &line [7]);
  709.                     if (config [(len = strlen (config))-1] == '\n')
  710.                         config [len-1] = EOS;
  711.                 }
  712.                 else
  713.                 {
  714.                     /* COM */
  715.                     sscanf (&line [4], "%d", &comport);
  716.                     if (comport < 1 || comport > 4)
  717.                         comport = 1;
  718.                 }
  719.                 break;
  720.             case 'D' :
  721.                 if (line [3] == 'P')
  722.                 {
  723.                     /* DEVPARM */
  724.                     strcpy (devparm, &line [8]);
  725.                     if (devparm [(len = strlen (devparm))-1] == '\n')
  726.                         devparm [len-1] = EOS;
  727.                 }
  728.                 else if (line [3] == 'L')
  729.                 {
  730.                     /* DIAL */
  731.                     strcpy (dial, &line [5]);
  732.                     if (dial [(len = strlen (dial))-1] == '\n')
  733.                         dial [len-1] = EOS;
  734.                 }
  735.                 else
  736.                 {
  737.                     /* DEATHMATCH */
  738.                     sscanf (&line [11], "%d", &deathmatch);
  739.                 }
  740.                 break;
  741.             case 'E' :
  742.                 /* EPISODE */
  743.                 sscanf (&line [8], "%d", &episode);
  744.                 if (episode < 1 || episode > 3)
  745.                     episode = -1;
  746.                 break;
  747.             case 'H' :
  748.                 /* HANGUP */
  749.                 strcpy (hangup, &line [7]);
  750.                 if (hangup [(len = strlen (hangup))-1] == '\n')
  751.                     hangup [len-1] = EOS;
  752.                 break;
  753.             case 'I' :
  754.                 if (line [1] == 'N')
  755.                 {
  756.                     if (line [4] == '1')
  757.                     {
  758.                         /* INIT1 */
  759.                         strcpy (init1, &line [6]);
  760.                         if (init1 [(len = strlen (init1))-1] == '\n')
  761.                             init1 [len-1] = EOS;
  762.                     }
  763.                     else
  764.                     {
  765.                         /* INIT2 */
  766.                         strcpy (init2, &line [6]);
  767.                         if (init2 [(len = strlen (init2))-1] == '\n')
  768.                             init2 [len-1] = EOS;
  769.                     }
  770.                 }
  771.                 else
  772.                 {
  773.                     /* IRQ */
  774.                     sscanf (&line [4], "%d", &irq);
  775.                 }
  776.                 break;
  777.             case 'L' :
  778.                 /* LOADGAME */
  779.                 sscanf (&line [9], "%d", &loadgame);
  780.                 if (loadgame < 0 || loadgame > 5)
  781.                     loadgame = -1;
  782.                 break;
  783.             case 'M' :
  784.                 /* MAP */
  785.                 sscanf (&line [4], "%d", &map);
  786.                 if (map < 1 || map > 9)
  787.                     map = -1;
  788.                 break;
  789.             case 'N' :
  790.                 if (line [1] == 'O')
  791.                 {
  792.                     /* NOMONSTERS (as opposed to NAME or NUMBER) */
  793.                     sscanf (&line [11], "%d", &nomonsters);
  794.                 }
  795.                 break;
  796.             case 'P' :
  797.                 if (line [1] == 'O')
  798.                 {
  799.                     /* PORT */
  800.                     sscanf (&line [5], "0x%x", &uart);
  801.                 }
  802.                 else if (line [1] == 'L')
  803.                 {
  804.                     /* PLAYER */
  805.                     sscanf (&line [7], "%d", &player);
  806.                     if (player < 0 || player > 1)
  807.                         player = 0;
  808.                 }
  809.                 else
  810.                 {
  811.                     /* PULSEDIAL */
  812.                     sscanf (&line [10], "%d", &pulsedial);
  813.                 }
  814.                 break;
  815.             case 'R' :
  816.                 /* RESPAWN */
  817.                 sscanf (&line [8], "%d", &respawn);
  818.                 break;
  819.             case 'S' :
  820.                 /* SKILL */
  821.                 sscanf (&line [6], "%d", &skill);
  822.                 if (skill < 1 || skill > 5)
  823.                     skill = -1;
  824.                 break;
  825.             case 'V' :
  826.                 /* VECTOR */
  827.                 sscanf (&line [7], "0x%x", &vector);
  828.                 break;
  829.         }
  830.     }
  831.     fclose (infile);
  832.  
  833.     /* Get irq and uart if not already set */
  834.     if (irq == -1 || uart == -1)
  835.         GetUart ();
  836.  
  837.     /* Get an interrupt vector if not already set */
  838.     if (vector == -1)
  839.     {
  840.         for (vector = 0x60 ; vector <= 0x66 ; vector++)
  841.         {
  842.             vectorptr = *(unsigned char far * far *)(vector*4);
  843.             if ( !vectorptr || *vectorptr == 0xcf )
  844.                 break;
  845.         }
  846.         if (vector == 0x67)
  847.         {
  848.             printf ("Warning: no NULL or iret interrupt vectors were found in the 0x60 to 0x66\n"
  849.                     "range.  You can specify a vector with the VECTOR=0x<num> line in modem.cfg.\n"
  850.                     "Press a key to continue...\n");
  851.             getch ();
  852.             vector = 0x66;
  853.         }
  854.     }
  855.     doomcom.intnum = vector;
  856. }
  857.  
  858.  
  859. void print_config_settings (void)
  860. {
  861.     clrscr ();
  862.     printf ("\nUsing the following settings:\n");
  863.     printf ("  INIT1=%s\n", init1);
  864.     printf ("  INIT2=%s\n", init2);
  865.     printf ("  HANGUP=%s\n", hangup);
  866.     printf ("  CONFIG=%s\n", config);
  867.     printf ("  DEVPARM=%s\n", devparm);
  868.     printf ("  BAUD=%lu\n", baud);
  869.     printf ("  DIAL=%s\n", dial);
  870.     printf ("  COM=%d\n", comport);
  871.     printf ("  IRQ=%d\n", irq);
  872.     printf ("  PORT=0x%x\n", uart);
  873.     printf ("  VECTOR=0x%x\n", vector);
  874.     printf ("  LOADGAME=%c\n", loadgame == -1 ? ' ' : loadgame + '0');
  875.     printf ("  EPISODE=%d\n", episode == -1 ? 1 : episode);
  876.     printf ("  MAP=%d\n", map == -1 ? 1 : map);
  877.     printf ("  SKILL=%d\n", skill == -1 ? 3 : skill);
  878.     printf ("  PLAYER=%d\n", player);
  879.     printf ("  PULSEDIAL=%d\n", pulsedial);
  880.     printf ("  DEATHMATCH=%d\n", deathmatch);
  881.     printf ("  NOMONSTERS=%d\n", nomonsters);
  882.     printf ("  RESPAWN=%d\n", respawn);
  883. }
  884.  
  885.  
  886. void configure (void)
  887. {
  888.     char line [256];
  889.     int i = 0;
  890.  
  891.     clrscr ();
  892.     printf (
  893.         "Configure...  Press ENTER to keep current value shown in [].\n\n");
  894.  
  895.     printf ("  deathmatch (0/1)     [%d]: ", deathmatch);
  896.     gets (line);
  897.     sscanf (line, "%d", &deathmatch);
  898.  
  899.     printf ("  nomonsters (0/1)     [%d]: ", nomonsters);
  900.     gets (line);
  901.     sscanf (line, "%d", &nomonsters);
  902.  
  903.     printf ("  respawn (0/1)        [%d]: ", respawn);
  904.     gets (line);
  905.     sscanf (line, "%d", &respawn);
  906.  
  907.     printf ("  episode (1-3)        [%d]: ", episode == -1 ? 1 : episode);
  908.     gets (line);
  909.     sscanf (line, "%d", &episode);
  910.     if (episode < 2 || episode > 3)    /* If default, set back to -1 */
  911.         episode = -1;
  912.  
  913.     printf ("  map (1-9)            [%d]: ", map == -1 ? 1 : map);
  914.     gets (line);
  915.     sscanf (line, "%d", &map);
  916.     if (map < 2 || map > 9)                /* If default, set back to -1 */
  917.         map = -1;
  918.  
  919.     printf ("  skill (1-5)          [%d]: ", skill == -1 ? 3 : skill);
  920.     gets (line);
  921.     sscanf (line, "%d", &skill);
  922.     if (skill < 1 || skill > 5 || skill == 3)    /* If default, set back to -1 */
  923.         skill = -1;
  924.  
  925.     printf ("  loadgame (0-5 or -1) [%c]: ", loadgame == -1 ? ' ' : loadgame + '0');
  926.     gets (line);
  927.     sscanf (line, "%d", &loadgame);
  928.     if (loadgame < 0 || loadgame > 5)
  929.         loadgame = -1;
  930.  
  931.     printf ("  devparm (args or -1) [");
  932.     while (devparm [i] != EOS)
  933.         putchar (devparm [i++]);
  934.     if (i == 0)
  935.        putchar (' ');
  936.     printf ("]\n    new devparm string: ");
  937.     gets (line);
  938.     if (strcmp (line, "-1") == 0)
  939.         devparm [0] = EOS;
  940.     else if (line [0] != EOS)
  941.         strcpy (devparm, line);
  942.  
  943.     printf ("\n");
  944. }
  945.  
  946.  
  947. void stats (void)
  948. {
  949.     time_t hrs;
  950.     time_t mins;
  951.     time_t secs;
  952.  
  953.     clrscr ();
  954.     if (starttime != 0)
  955.     {
  956.         printf ("Start Time:    %s", ctime (&starttime));
  957.         playtime = endtime - starttime;
  958.         hrs = playtime / 3600;
  959.         mins = (playtime - (hrs * 3600)) / 60;
  960.         secs = playtime - (hrs * 3600) - (mins * 60);
  961.         printf ("Playing Time:  %d:%02d:%02d\n\n",
  962.             (int) hrs, (int) mins, (int) secs);
  963.     }
  964.     showReadStats();
  965.     showWriteStats();
  966.     showUartErrors();
  967.     printf ("\n");
  968. }
  969.  
  970.  
  971. void talk (void)
  972. {
  973.     int c;
  974.  
  975.     clrscr ();
  976.     printf ("Talk mode...  Press ESC to return\n\n");
  977.     while (TRUE)
  978.     {
  979.         /* Check for keypress */
  980.         if (bioskey (1))
  981.         {
  982.             if ((c = bioskey (0) & 0xff) == ESC)
  983.             {
  984.                 /* ESC key -- Exit talk mode -- Flush both sides */
  985.                 while (read_byte () != -1)
  986.                 ;
  987.                 while (bioskey (1))
  988.                     bioskey (0);
  989.                 printf ("\n\n");
  990.                 return;
  991.             }
  992.             if (c == 0x0D)        /* Change cr to crlf */
  993.                 c = 0x0A;
  994.             write_buffer (&(char)c, 1);
  995.             printf ("%c", c);
  996.         }
  997.         /* Check for received byte */
  998.         if ((c = read_byte ()) != -1)
  999.             printf ("%c", c);
  1000.     }
  1001. }
  1002.  
  1003.  
  1004. void reset_counters (void)
  1005. {
  1006.     /* showReadStats() counters. */
  1007.     writeBufferOverruns       = 0;
  1008.     bytesRead                 = 0;
  1009.     packetsRead               = 0;
  1010.     largestReadPacket         = 0;
  1011.     smallestReadPacket        = 0xFFFFFFFFl;
  1012.     readBufferOverruns        = 0;
  1013.     totalReadPacketBytes      = 0;
  1014.     oversizeReadPackets       = 0;
  1015.     largestOversizeReadPacket = 0;
  1016.     overReadPacketLen         = 0;
  1017.  
  1018.     /* showWriteStats() counters. */
  1019.     bytesWritten               = 0;
  1020.     packetsWrite               = 0;
  1021.     largestWritePacket         = 0;
  1022.     smallestWritePacket        = 0xFFFFFFFFl;
  1023.     totalWritePacketBytes      = 0;
  1024.     oversizeWritePackets       = 0;
  1025.     largestOversizeWritePacket = 0;
  1026.  
  1027.     /* showUartErrors() counters. */
  1028.     numBreak          = 0;
  1029.     numFramingError   = 0;
  1030.     numParityError    = 0;
  1031.     numOverrunError   = 0;
  1032.     numTxInterrupts   = 0;
  1033.     numRxInterrupts   = 0;
  1034. }
  1035.  
  1036.  
  1037. void usage (void)
  1038. {
  1039.     clrscr ();
  1040.     printf ("\n\n\n\n\nSER4.EXE is run without arguments.  Just type \"ser4.exe\"\n\n"
  1041.         "To change computer-related settings, edit the MODEM.CFG file,\n"
  1042.         "and to change game settings, use the CONFIGURE option while running.\n\n"
  1043.         "Yes, this means setup.exe won't work, but don't sweat the small stuff. :-)\n\n"
  1044.         "Press a key to continue...\n");
  1045.     getch ();
  1046. }
  1047.  
  1048.  
  1049. /*
  1050. =================
  1051. =
  1052. = main
  1053. =
  1054. =================
  1055. */
  1056.  
  1057. void main(void)
  1058. {
  1059.     int ch;
  1060.  
  1061.     if (_argc > 1)
  1062.         usage ();
  1063.  
  1064.     clrscr ();
  1065.     printf(
  1066.            "                         -----------------------------\n"
  1067.            "                                   SER4.EXE           \n"
  1068.            "                           DOOM SERIAL DEVICE DRIVER  \n"
  1069.            "                         -----------------------------\n");
  1070.  
  1071. //
  1072. // set network characteristics
  1073. //
  1074.     /* Make "extratics" the default, it runs much better */
  1075.     doomcom.extratics = 1;
  1076.  
  1077.     doomcom.id = DOOMCOM_ID;
  1078.     doomcom.ticdup = 1;
  1079.     doomcom.numnodes = 2;
  1080.     doomcom.numplayers = 2;
  1081.     doomcom.drone = 0;
  1082.     doomcom.consoleplayer = 0;        /* Default - may be overridden later. */
  1083.  
  1084.     get_config_settings ();
  1085.  
  1086. //
  1087. // establish communications
  1088. //
  1089.     InitPort ();
  1090.  
  1091.     printf ("Press any key to continue...");
  1092.     getch ();
  1093.     print_config_settings ();
  1094.  
  1095.     while ( 0 <= read_byte() );    /* Flush any old stuff from uart buffer */
  1096.  
  1097.     while (TRUE)
  1098.     {
  1099.         printf (
  1100.             "\nSelect an option: 'D'ial, 'A'nswer, 'C'onnected already, 'Q'uit: ");
  1101.         ch = tolower (getch ());
  1102.         printf ("\n");
  1103.         if (ch == 'd')
  1104.         {
  1105.             if (Dial ())
  1106.                 break;
  1107.         }
  1108.         else if (ch == 'a')
  1109.         {
  1110.             if (Answer ())
  1111.                 break;
  1112.         }
  1113.         else if (ch == 'q')
  1114.             Error (NULL);
  1115.         else
  1116.             break;
  1117.     }
  1118.  
  1119.     printf ("\n");
  1120.     while (TRUE)
  1121.     {
  1122.         printf (
  1123.             "Select an option: 'D'oom, 'S'tats, 'C'onfigure, 'T'alk, 'Quit': ");
  1124.         ch = tolower (getch ());
  1125.         printf ("\n");
  1126.         switch (ch)
  1127.         {
  1128.             case 'd' : 
  1129.                 if (Connect ())
  1130.                 {
  1131.                     reset_counters ();
  1132.                     time (&starttime);
  1133.                     LaunchDOOM ();
  1134.                     time (&endtime);
  1135.                 }
  1136.                 break;
  1137.             case 's' : 
  1138.                 stats ();
  1139.                 break;
  1140.             case 'c' : 
  1141.                 configure ();
  1142.                 break;
  1143.             case 't' : 
  1144.                 talk ();
  1145.                 break;
  1146.             case 'q' :
  1147.                 Error (NULL);
  1148.         }
  1149.     }
  1150. }
  1151.  
  1152.