home *** CD-ROM | disk | FTP | other *** search
/ 1,001 Nights of Doom / 1001NightsOfDoom1995wickedSensations.iso / modem / ser6_src.zip / SERSETUP.C < prev    next >
C/C++ Source or Header  |  1994-11-21  |  54KB  |  2,258 lines

  1. // sersetup.c
  2. // Created by Id Software for SERSETUP.EXE, 1993, 1994.
  3. // Hacked by Russell Gilbert and others SER4.EXE, SER5.EXE, and SER6.EXE 1994.
  4. // Hacked by Paul T. Hermann for SER5.EXE, SER6.EXE 1994.
  5. //
  6. // Compiled under Borland C++ 3.1 using the Compact Memory module
  7. // Using 80386 instruction set and 80387 emualation support
  8. // Optimizations for speed enabled
  9. //
  10.  
  11. #include "sersetup.h"
  12. #include "DoomNet.h"
  13. #include <time.h>
  14. #include <dirent.h>
  15. #include <io.h>
  16.  
  17. #define PROG_NAME "SER6"
  18. #define PROG_EXE "SER6.EXE"
  19. #define PROG_CONFIG "SER6.CFG"
  20.  
  21. extern que_t inque;
  22. extern que_t outque;
  23. extern int uart_type;
  24.  
  25. int rgstrncpy (char *, char *, int );
  26. int getwadlevel ( char * );
  27. void pickdirectory ( void );
  28. void pickwads ( void );
  29. int sort_function (const void *a, const void *b);
  30. void parsewad ( char * , char * );
  31. int checkwad ( int , char * );
  32. void kill_nonwads ( void );
  33. int SendFile ( void );
  34. int ReceiveFile (char *);
  35. void dir ( int );
  36. void pause (void);
  37. void DOOM (void);
  38. void jump_start( void );
  39. void GetUart (void);
  40. void ModemCommand (char *str);
  41. int ModemResponse (char *resp);
  42. void configure (void);
  43. void reset_counters (void);
  44.  
  45. int usemodem = FALSE;
  46. time_t starttime = 0;
  47. time_t endtime = 0;
  48. time_t playtime = 0;
  49. char init1 [80+1];
  50. char init2 [80+1];
  51. char altbaudinit [80+1];
  52. int use_altbaudinit = FALSE;
  53. char hangup [80+1];
  54. char config [80+1];
  55. char devparm [256+1];
  56. char directory [39+1];
  57. char wadname [21][12+1];
  58. char add [50+1];
  59. char doomexe[12+1];
  60. char levels[32][5+1];
  61. char dial [50+1];
  62. unsigned long baud = 9600;
  63. unsigned long altbaud = 9600;
  64. int comport = 1;
  65. int irq = -1;
  66. int uart = -1;
  67. int nodropdtr = 0;
  68. int vector = -1;
  69. int loadgame = -1;
  70. int episode = -1;
  71. int map = -1;
  72. int skill = -1;
  73. int deathmatch = 0;
  74. int altdeath = 0;
  75. int pulsedial = 0;
  76. int player = 0;
  77. int nomonsters = 0;
  78. int respawn = 0;
  79. int doomver1_2 = 0;
  80. int doom2 = 0;
  81.  
  82. /* showReadStats() counters. */
  83. unsigned long writeBufferOverruns       = 0;
  84. unsigned long bytesRead                 = 0;
  85. unsigned long packetsRead               = 0;
  86. unsigned long largestReadPacket         = 0;
  87. unsigned long smallestReadPacket        = 0xFFFFFFFFl;
  88. unsigned long readBufferOverruns        = 0;
  89. unsigned long totalReadPacketBytes      = 0;
  90. unsigned long oversizeReadPackets       = 0;
  91. unsigned long largestOversizeReadPacket = 0;
  92. unsigned long overReadPacketLen         = 0;
  93.  
  94. /* showWriteStats() counters. */
  95. unsigned long bytesWritten               = 0;
  96. unsigned long packetsWrite               = 0;
  97. unsigned long largestWritePacket         = 0;
  98. unsigned long smallestWritePacket        = 0xFFFFFFFFl;
  99. unsigned long totalWritePacketBytes      = 0;
  100. unsigned long oversizeWritePackets       = 0;
  101. unsigned long largestOversizeWritePacket = 0;
  102.  
  103. /* showUartErrors() counters. */
  104. unsigned long numBreak          = 0;
  105. unsigned long numFramingError   = 0;
  106. unsigned long numParityError    = 0;
  107. unsigned long numOverrunError   = 0;
  108. unsigned long numTxInterrupts   = 0;
  109. unsigned long numRxInterrupts   = 0;
  110.  
  111. void showReadStats()
  112. {
  113.     if ( smallestReadPacket == 0xFFFFFFFFl )
  114.         smallestReadPacket = 0;
  115.  
  116.     printf ("Read statistics:\n");
  117.  
  118.     printf ("%9lu Largest packet      %9lu Smallest packet\n",
  119.                 largestReadPacket, smallestReadPacket);
  120.  
  121.     printf ("%9lu Oversize packets    %9lu Largest oversize packet\n",
  122.                 oversizeReadPackets, largestOversizeReadPacket);
  123.  
  124.     printf ("%9lu Total packets       %9lu Buffer overruns\n",
  125.                 packetsRead, readBufferOverruns);
  126.  
  127.     printf ("%9lu Total bytes         %9.1f Average bytes/minute\n",
  128.                 totalReadPacketBytes,
  129.                 starttime == 0 || playtime == 0 ? 0 :
  130.                     (float) totalReadPacketBytes / (float) ((float) playtime / 60));
  131.     printf ("%9lu Receive interrupts  %9.1f Average bytes/interrupt\n",
  132.         numRxInterrupts,
  133.         numRxInterrupts == 0 ? 0 :
  134.             (float) totalReadPacketBytes / (float) numRxInterrupts);
  135.     printf ("\n");
  136. }
  137.  
  138. void showWriteStats()
  139. {
  140.     if ( smallestWritePacket == 0xFFFFFFFFl )
  141.         smallestWritePacket = 0;
  142.  
  143.     printf ("Write statistics:\n");
  144.  
  145.     printf ("%9lu Largest packet      %9lu Smallest packet\n",
  146.                 largestWritePacket, smallestWritePacket);
  147.  
  148.     printf ("%9lu Oversize packets    %9lu Largest oversize packet\n",
  149.                 oversizeWritePackets, largestOversizeWritePacket);
  150.  
  151.     printf ("%9lu Total packets       %9lu Buffer overruns\n",
  152.                 packetsWrite, writeBufferOverruns);
  153.  
  154.     printf ("%9lu Total bytes         %9.1f Average bytes/minute\n",
  155.                 totalWritePacketBytes,
  156.                 starttime == 0 || playtime == 0 ? 0 :
  157.                     (float) totalWritePacketBytes / (float) ((float) playtime / 60));
  158.     printf ("%9lu Transmit interrupts %9.1f Average bytes/interrupt\n",
  159.         numTxInterrupts,
  160.         numTxInterrupts == 0 ? 0 :
  161.             (float) totalWritePacketBytes / (float) numTxInterrupts);
  162.     printf ("\n");
  163. }
  164.  
  165. void showUartErrors()
  166. {
  167.     printf ("UART line status\n");
  168.     printf ("%9lu Breaks detected     %9lu Framing errors\n",
  169.         numBreak, numFramingError);
  170.     printf ("%9lu Parity errors       %9lu Overrun errors\n",
  171.         numParityError, numOverrunError);
  172. }
  173.  
  174. /*
  175. ================
  176. =
  177. = write_buffer
  178. =
  179. ================
  180. */
  181. void write_buffer( char *buffer, unsigned int count )
  182. {
  183. // if this would overrun the buffer, throw everything else out
  184.     if (outque.size + count > QUESIZE)
  185.     {
  186.         ++writeBufferOverruns;
  187.         outque.tail = outque.head;
  188.         outque.size = 0;
  189.     }
  190.  
  191.     while (count--)
  192.         write_byte  (*buffer++);
  193.  
  194.     if ( INPUT( uart + LINE_STATUS_REGISTER ) & 0x40)
  195.         jump_start();
  196. }
  197.  
  198. void hangup_modem (void)
  199. {
  200.     if (nodropdtr == 1)
  201.         printf("\nLeaving DTR up!\n");
  202.     else
  203.     {
  204.         printf ("\n");
  205.         printf ("\nDropping DTR\n");
  206.         OUTPUT( uart + MODEM_CONTROL_REGISTER
  207.             , INPUT( uart + MODEM_CONTROL_REGISTER ) & ~MCR_DTR );
  208.         delay (1250);
  209.         OUTPUT( uart + MODEM_CONTROL_REGISTER
  210.             , INPUT( uart + MODEM_CONTROL_REGISTER ) | MCR_DTR );
  211.         ModemCommand("+++");
  212.         delay (1250);
  213.         if (hangup [0] != EOS)
  214.             ModemCommand(hangup);
  215.         else
  216.         {
  217.             printf ("Warning: No HANGUP= string in config file. Using default.\n");
  218.             ModemCommand("ATH0");
  219.         }
  220.         delay (1250);
  221.         while (read_byte () != -1)
  222.             ;
  223.     }
  224. }
  225.  
  226. /*
  227. =================
  228. =
  229. = Error
  230. =
  231. = For abnormal program terminations
  232. =
  233. =================
  234. */
  235. void Error (char *error, ...)
  236. {
  237.     va_list argptr;
  238.  
  239.     if (usemodem)
  240.         hangup_modem ();
  241.  
  242.     ShutdownPort ();
  243.  
  244.     if (vectorishooked)
  245.         setvect (doomcom.intnum,olddoomvect);
  246.     if (error)
  247.     {
  248.         va_start (argptr,error);
  249.         vprintf (error,argptr);
  250.         va_end (argptr);
  251.         printf ("\n\n");
  252.     }
  253.  
  254.     exit (error != (char *) NULL);
  255. }
  256.  
  257. /*
  258. ================
  259. =
  260. = ReadPacket
  261. =
  262. ================
  263. */
  264. #define MAXPACKET    512
  265. #define    FRAMECHAR    0x70
  266.  
  267. char    packet[MAXPACKET];
  268. int        packetlen;
  269. int        inescape;
  270. int        newpacket;
  271.  
  272. boolean ReadPacket (void)
  273. {
  274.     int    c;
  275.  
  276. // if the buffer has overflowed, throw everything out
  277.  
  278.     if (inque.size > QUESIZE - 4)    // check for buffer overflow
  279.     {
  280.         ++readBufferOverruns;           /* Count read overruns */
  281.         inque.tail = inque.head;
  282.         inque.size = 0;
  283.         newpacket = true;
  284.         return false;
  285.     }
  286.  
  287.     if (newpacket)
  288.     {
  289.         packetlen = 0;
  290.         newpacket = 0;
  291.         overReadPacketLen = 0;
  292.     }
  293.  
  294.     while ( 1 )
  295.     {
  296.         if ((c = read_byte ()) < 0)
  297.             return false;      // haven't read a complete packet
  298.         if (inescape)
  299.         {
  300.             inescape = false;
  301.             if (c != FRAMECHAR)
  302.             {
  303.                 newpacket = 1;
  304.                 ++packetsRead;  /* Count packets read */
  305.  
  306.                 if ( packetlen > largestReadPacket ) /* Track largest packet */
  307.                     largestReadPacket = packetlen;
  308.  
  309.                 if ( packetlen < smallestReadPacket ) /* Track smallest packet */
  310.                     smallestReadPacket = packetlen;
  311.  
  312.                 totalReadPacketBytes += packetlen;    /* Count total packet bytes */
  313.  
  314.                 return true;    // got a good packet
  315.             }
  316.         }
  317.         else if (c == FRAMECHAR)
  318.         {
  319.             inescape = true;
  320.             continue;            // don't know yet if it is a terminator
  321.         }                        // or a literal FRAMECHAR
  322.  
  323.         if (packetlen >= MAXPACKET)
  324.         {
  325.             ++overReadPacketLen;            /* Keep track of size of oversize packet */
  326.             oversizeReadPackets++;        /* Count oversize packets */
  327.  
  328.             if ( overReadPacketLen > largestOversizeReadPacket )
  329.                 largestOversizeReadPacket = overReadPacketLen;
  330.  
  331.             continue;            // oversize packet
  332.         }
  333.  
  334.         packet[packetlen] = c;
  335.         packetlen++;
  336.     }
  337. }
  338.  
  339. /*
  340. =============
  341. =
  342. = WritePacket
  343. =
  344. =============
  345. */
  346. void WritePacket (char *buffer, int len)
  347. {
  348.     int        b;
  349.     char    static localbuffer[MAXPACKET*2+2];
  350.  
  351.     b = 0;
  352.     if (len > MAXPACKET)
  353.     {
  354.         ++oversizeWritePackets;         /* Count oversize write packets */
  355.         if ( len > largestOversizeWritePacket )
  356.             ++largestOversizeWritePacket;
  357.  
  358.         return;
  359.     }
  360.  
  361.     if ( len > largestWritePacket )
  362.         largestWritePacket = len;
  363.  
  364.     if ( len < smallestWritePacket )
  365.         smallestWritePacket = len;
  366.  
  367.     totalWritePacketBytes += len;
  368.  
  369.     ++packetsWrite;
  370.  
  371.     while (len--)
  372.     {
  373.         if (*buffer == FRAMECHAR)
  374.             localbuffer[b++] = FRAMECHAR;    // escape it for literal
  375.         localbuffer[b++] = *buffer++;
  376.     }
  377.  
  378.     localbuffer[b++] = FRAMECHAR;
  379.     localbuffer[b++] = 0;
  380.  
  381.     write_buffer (localbuffer, b);
  382. }
  383.  
  384. /*
  385. =============
  386. =
  387. = NetISR
  388. =
  389. =============
  390. */
  391. void interrupt NetISR (void)
  392. {
  393.     if (doomcom.command == CMD_SEND)
  394.         WritePacket ((char *)&doomcom.data, doomcom.datalength);
  395.     else if (doomcom.command == CMD_GET)
  396.     {
  397.         if (ReadPacket () && packetlen <= sizeof(doomcom.data) )
  398.         {
  399.             doomcom.remotenode = 1;
  400.             doomcom.datalength = packetlen;
  401.             memcpy (&doomcom.data, &packet, packetlen);
  402.         }
  403.         else
  404.             doomcom.remotenode = -1;
  405.     }
  406. }
  407.  
  408. /*
  409. =================
  410. =
  411. = Connect
  412. =
  413. = Figures out who is player 0 and 1
  414. =================
  415. */
  416. int Connect (void)
  417. {
  418.     struct time        time;
  419.     int                oldsec;
  420.     int        localstage, remotestage;
  421.     char    str[10];
  422.  
  423. //
  424. // wait for a good packet
  425. //
  426.     printf ("Attempting to connect across serial link, press escape to abort.\n");
  427.  
  428.     doomcom.consoleplayer = player;
  429.     oldsec = -1;
  430.     localstage = remotestage = 0;
  431.     inque.tail = inque.head;   //clears the buffer.
  432.     inque.size = 0;
  433.     newpacket = TRUE;
  434.  
  435.     while (remotestage < 4)
  436.     {
  437.         while ( bioskey(1) )
  438.         {
  439.             if ( (bioskey (0) & 0xff) == ESC)
  440.             {
  441.                 printf ("\n\nSerial game synchronization aborted.\n");
  442.                 while (read_byte () != -1);
  443.                 return FALSE;
  444.             }
  445.         }
  446.         if (ReadPacket ())
  447.         {
  448.             packet[packetlen] = 0;
  449.             printf ("read: '%s'\n", packet);
  450.             if (packetlen != 7)
  451.             {
  452.                 printf ("bad packet len = %d (should be 7)\n", packetlen);
  453.                 continue;
  454.             }
  455.             if (strncmp(packet,"PLAY",4) )
  456.             {
  457.                 printf ("error: first 4 char's aren't 'PLAY'\n");
  458.                 continue;
  459.             }
  460.             remotestage = packet[6] - '0';
  461.             localstage = remotestage+1;
  462.             if (packet[4] == '0'+doomcom.consoleplayer)
  463.             {
  464.                 doomcom.consoleplayer ^= 1;
  465.                 localstage = remotestage = 0;
  466.             }
  467.             oldsec = -1;
  468.         }
  469.         gettime (&time);
  470.         if (time.ti_sec != oldsec)
  471.         {
  472.             oldsec = time.ti_sec;
  473.             sprintf (str,"PLAY%i_%i",doomcom.consoleplayer,localstage);
  474.             WritePacket (str,strlen(str));
  475.             printf ("wrote: '%s'\n",str);
  476.         }
  477.     }
  478.     while (ReadPacket ()) // flush out any extras
  479.     ;
  480.     return TRUE;
  481. }
  482.  
  483. /*
  484. ==============
  485. =
  486. = ModemCommand
  487. =
  488. ==============
  489. */
  490. void ModemCommand (char *str)
  491. {
  492.     int i;
  493.     char *ptr;
  494.  
  495.     printf ("Modem command : %s\n",str);
  496.     ptr = str;
  497.     for (i = 0; i < strlen (str); i++)
  498.     {
  499.         write_buffer (ptr++, 1);
  500.         delay (20);
  501.     }
  502.     write_buffer ("\r",1);
  503. }
  504.  
  505. /*
  506. ==============
  507. =
  508. = ModemResponse
  509. =
  510. = Waits for OK, RING, CONNECT, etc
  511. ==============
  512. */
  513. int ModemResponse (char *resp)
  514. {
  515.     int        c;
  516.     int        respptr;
  517.     char    response[80];
  518.  
  519.     do
  520.     {
  521.         printf ("Modem response: ");
  522.         respptr=0;
  523.         while (1)
  524.         {
  525.             while ( bioskey(1) )
  526.             {
  527.                 if ( (bioskey (0) & 0xff) == ESC)
  528.                 {
  529.                     printf ("\nModem response aborted.\n");
  530.                     hangup_modem ();
  531.                     return FALSE;
  532.                 }
  533.             }
  534.             c = read_byte ();
  535.             if (c==-1)
  536.                 continue;
  537.             if (c=='\n' || respptr == 79)
  538.             {
  539.                 response[respptr] = 0;
  540.                 printf ("%s\n",response);
  541.                 break;
  542.             }
  543.             if (c >= ' ')
  544.             {
  545.                 response[respptr] = c;
  546.                 respptr++;
  547.             }
  548.         }
  549.     }while (strncmp(response,resp,strlen(resp)));
  550.     return TRUE;
  551. }
  552.  
  553. /*
  554. =============
  555. =
  556. = InitModem
  557. =
  558. =============
  559. */
  560. void InitModem (void)
  561. {
  562.     if (init1 [0] != EOS)
  563.     {
  564.         ModemCommand (init1);
  565.         if (! ModemResponse ("OK"))
  566.             return;
  567.     }
  568.  
  569.     if (init2 [0] != EOS)
  570.     {
  571.         ModemCommand (init2);
  572.         if ( !ModemResponse ("OK"))
  573.             return;
  574.     }
  575.  
  576.     if (use_altbaudinit == TRUE && altbaudinit [0] != EOS)
  577.     {
  578.         ModemCommand (altbaudinit);
  579.         if ( !ModemResponse ("OK"))
  580.             return;
  581.     }
  582. }
  583.  
  584. void alt_init (void)
  585. {
  586.     int ch;
  587.  
  588.     printf ("\nUse %lu baud and init string '%s'? (y/n): ",
  589.         altbaud, altbaudinit);
  590.     if ((ch = getch()) == 'y' || ch == 'Y')
  591.     {
  592.         use_altbaudinit = TRUE;
  593.         baud = altbaud;
  594.         InitPort();   //Re-inits the port with new baud rate.
  595.         printf (
  596.             "\n\nPort re-initialized.  Alternate init string will be used for dial and answer.\n\n");
  597.         pause ();
  598.     }
  599.     printf ("\n");
  600. }
  601.  
  602. /*
  603. =============
  604. =
  605. = Dial_Modem
  606. =
  607. =============
  608. */
  609. int Dial_Modem (void)
  610. {
  611.     char    cmd[80];
  612.     int ch;
  613.     char line [50];
  614.     FILE    *infile;
  615.     int found_name = FALSE;
  616.     int prompt = TRUE;
  617.     char buf [50];
  618.  
  619.     usemodem = true;
  620.     InitModem ();
  621.  
  622.     if (dial [0] != EOS)
  623.     {
  624.         printf ("\nDial %s? (y/n): ", dial);
  625.         if ((ch = getch()) == 'y' || ch == 'Y')
  626.             prompt = FALSE;
  627.     }
  628.  
  629.     if (prompt)
  630.     {
  631.         printf ("\nEnter number to dial or phonebook name: ");
  632.         gets (line);
  633.         if (sscanf (line, "%s", dial) == EOF)
  634.             return FALSE;
  635.  
  636.         if ((infile = fopen (PROG_CONFIG, "r")) == NULL)
  637.         {
  638.             sprintf (buf, "Couldn't read file %s.\n", PROG_CONFIG);
  639.             Error (buf);
  640.         }
  641.  
  642.         while (fgets (line, 256, infile) != NULL)
  643.         {
  644.             if (line [0] == 'N' && line [1] == 'A')
  645.             {
  646.                 /* NAME */
  647.                 if (strncmp (&line [5], dial, strlen (dial)) == 0)
  648.                     found_name = TRUE;
  649.             }
  650.             else if (found_name && line [0] == 'N' && line [1] == 'U')
  651.             {
  652.                 /* NUMBER */
  653.                 sscanf (&line [7], "%s", dial);
  654.                 break;          // Found a number break out and dial
  655.             }
  656.         }
  657.         fclose (infile);
  658.     }
  659.  
  660.     printf ("\nDialing %s\n\n", dial);
  661.     if (pulsedial)
  662.         sprintf (cmd,"ATDP%s", dial);
  663.     else
  664.         sprintf (cmd,"ATDT%s", dial);
  665.  
  666.     ModemCommand(cmd);
  667.     return ModemResponse ("CONNECT");
  668. }
  669.  
  670. /*
  671. =============
  672. =
  673. = Answer
  674. =
  675. =============
  676. */
  677. int Answer (void)
  678. {
  679.     usemodem = true;
  680.     InitModem ();
  681.     printf ("\nWaiting for ring...\n\n");
  682.  
  683.     if (! ModemResponse ("RING"))
  684.         return FALSE;
  685.     ModemCommand ("ATA");
  686.     return ModemResponse ("CONNECT");
  687. }
  688.  
  689. int rgstrncpy (char *dest, char *src, int max)
  690. {
  691.     int i = 0;
  692.     char *srcptr;
  693.     char *destptr;
  694.  
  695.     /* Just like strncpy(), but force a null at the end regardless of
  696.      * whether we copied the max # of characters or not.
  697.      */
  698.     srcptr = src;
  699.     destptr = dest;
  700.     while (i < max)
  701.     {
  702.         if ((*destptr++ = *srcptr++) == EOS)
  703.             break;
  704.         ++i;
  705.     }
  706.     if (i == max)
  707.         dest [max-1] = EOS;
  708.     return i;
  709. }
  710.  
  711. void get_config_settings (void)
  712. {
  713.     char line [80+1];
  714.     char space[]=" ";
  715.     int len;
  716.     FILE    *infile;
  717.     int i;
  718.     unsigned char far *vectorptr;
  719.     unsigned long lnum;
  720.     char buf [50];
  721.  
  722.     if ((infile = fopen (PROG_CONFIG, "r")) == NULL)
  723.     {
  724.         sprintf (buf, "Couldn't read %s file.", PROG_CONFIG);
  725.         Error (buf);
  726.     }
  727.  
  728.     while (fgets (line, 81, infile) != NULL)
  729.     {
  730.         if (line [(len = strlen (line))-1] == '\n')    /* Get rid of cr at end */
  731.             line [len-1] = EOS;
  732.         switch (line [0])
  733.         {
  734.             case 'A' :
  735.                 if (line[3] == 'D')
  736.                 {        /* ALTDEATH */
  737.                     sscanf (&line [9], "%d", &altdeath);
  738.                 }
  739.                 else if (line [7] == 'I')
  740.                 {        /* ALTBAUDINIT */
  741.                     if ( line[12] != EOS )
  742.                         rgstrncpy (altbaudinit, &line [12], 80+1);
  743.                 }
  744.                 else if (line [3] == 'B')
  745.                 {        /* ALTBAUD */
  746.                     if (sscanf (&line [8], "%lu", &altbaud) != EOF &&
  747.                         altbaud != 9600 && altbaud != 14400 && altbaud != 19200 &&
  748.                         altbaud != 38400 && altbaud != 57600 && altbaud != 115200)
  749.                     {
  750.                         altbaud = 9600;
  751.                     }
  752.                 }
  753.                 break;
  754.             case 'B' :
  755.                 /* BAUD */
  756.                 if (sscanf (&line [5], "%lu", &baud) != EOF &&
  757.                     baud != 9600 && baud != 14400 && baud != 19200 &&
  758.                     baud != 38400 && baud != 57600 && baud != 115200)
  759.                 {
  760.                     baud = 9600;
  761.                 }
  762.                 break;
  763.             case 'C' :
  764.                 if (line [3] == 'F')
  765.                 {
  766.                     /* CONFIG */
  767.                     rgstrncpy (config, &line [7], 80+1);
  768.                 }
  769.                 else
  770.                 {
  771.                     /* COM */
  772.                     sscanf (&line [4], "%d", &comport);
  773.                 }
  774.                 break;
  775.             case 'D' :
  776.                 if (line [2] == 'V')
  777.                 {
  778.                     /* DEVPARM */
  779.                     rgstrncpy (devparm, &line [8], 256+1);
  780.                     if (strncmpi(devparm, "-f", 2) != 0 && devparm[0] != EOS)
  781.                     {
  782.                         rgstrncpy (add, devparm, 50);
  783.                         strcat(add, space);
  784.                     }
  785.                 }
  786.                 else if (line [3] == 'L')
  787.                 {
  788.                     /* DIAL */
  789.                     rgstrncpy (dial, &line [5], 50+1);
  790.                 }
  791.                 else if (line [2] == 'R')
  792.                 {
  793.                     /* DIRECTORY  */
  794.                     if (rgstrncpy (directory, &line [10], 40+1) > 0)
  795.                     {
  796.                         if (directory[(len = strlen (directory))-1] != ':'
  797.                             && directory[len-1] != '\\')
  798.                         {
  799.                             directory [len] = '\\';
  800.                             directory [len+1] = EOS;
  801.                         }
  802.                     }
  803.                     else
  804.                         strcpy (directory, ".\\");
  805.                 }
  806.                 else if (line [3] == 'T')
  807.                 {
  808.                     /* DEATHMATCH */
  809.                     sscanf (&line [11], "%d", &deathmatch);
  810.                 }
  811.                 else if (line [5]    == 'X')
  812.                 {
  813.                     /* DOOMEXE */
  814.                         rgstrncpy (doomexe, &line [8], 12+1);
  815.                 }
  816.                 else if (line [4] == '2')
  817.                 {   /* DOOM2 */
  818.                     sscanf (&line [6], "%d", &doom2);
  819.                 }
  820.                 else if (line [4] == 'V')
  821.                 {
  822.                     /* DOOMVER1_2 */
  823.                     sscanf (&line [11], "%d", &doomver1_2);
  824.                 }
  825.                 break;
  826.             case 'E' :
  827.                 /* EPISODE */
  828.                 sscanf (&line [8], "%d", &episode);
  829.                 break;
  830.             case 'H' :
  831.                 /* HANGUP */
  832.                 rgstrncpy (hangup, &line [7], 80+1);
  833.                 break;
  834.             case 'I' :
  835.                 if (line [1] == 'N')
  836.                 {
  837.                     if (line [4] == '1')
  838.                     {
  839.                         /* INIT1 */
  840.                         rgstrncpy (init1, &line [6], 80+1);
  841.                     }
  842.                     else
  843.                     {
  844.                         /* INIT2 */
  845.                         rgstrncpy (init2, &line [6], 80+1);
  846.                     }
  847.                 }
  848.                 else
  849.                 {
  850.                     /* IRQ */
  851.                     sscanf (&line [4], "%d", &irq);
  852.                 }
  853.                 break;
  854.             case 'L' :
  855.                 /* LOADGAME */
  856.                 sscanf (&line [9], "%d", &loadgame);
  857.                 break;
  858.             case 'M' :
  859.                 /* MAP */
  860.                 sscanf (&line [4], "%d", &map);
  861.                 break;
  862.             case 'N' :
  863.                 if (line [3] == 'O')
  864.                 {
  865.                     /* NOMONSTERS (as opposed to NAME or NUMBER) */
  866.                     sscanf (&line [11], "%d", &nomonsters);
  867.                 }
  868.                 else if (line [3] == 'R')
  869.                 {
  870.                     /* NODROPDTR */
  871.                     sscanf (&line [10], "%d", &nodropdtr);
  872.                 }
  873.                 break;
  874.             case 'P' :
  875.                 if (line [1] == 'O')
  876.                 {
  877.                     /* PORT */
  878.                     sscanf (&line [5], "0x%x", &uart);
  879.                 }
  880.                 else if (line [1] == 'L')
  881.                 {
  882.                     /* PLAYER */
  883.                     sscanf (&line [7], "%d", &player);
  884.                     if (player < 0 || player > 1)
  885.                         player = 0;
  886.                 }
  887.                 else
  888.                 {
  889.                     /* PULSEDIAL */
  890.                     sscanf (&line [10], "%d", &pulsedial);
  891.                 }
  892.                 break;
  893.             case 'R' :
  894.                 /* RESPAWN */
  895.                 sscanf (&line [8], "%d", &respawn);
  896.                 break;
  897.             case 'S' :
  898.                 /* SKILL */
  899.                 sscanf (&line [6], "%d", &skill);
  900.                 break;
  901.             case 'V' :
  902.                 /* VECTOR */
  903.                 sscanf (&line [7], "0x%x", &vector);
  904.                 break;
  905.             case 'W' :
  906.                 /* WADNAME */
  907.                 rgstrncpy (wadname [0], &line [8], 12+1);
  908.                 break;
  909.         }
  910.     }
  911.     fclose (infile);
  912.     if ( doomexe[0] == EOS )
  913.     {
  914.         if (doom2)
  915.             strcpy(doomexe, "DOOM2");
  916.         else
  917.             strcpy(doomexe, "DOOM");
  918.     }
  919.  
  920.     /* Get irq and uart if not already set */
  921.     if (irq == -1 || uart == -1)
  922.         GetUart ();
  923.  
  924.     /* Get an interrupt vector if not already set */
  925.     if (vector == -1)
  926.     {
  927.         for (vector = 0x60 ; vector <= 0x66 ; vector++)
  928.         {
  929.             vectorptr = *(unsigned char far * far *)(vector*4);
  930.             if ( !vectorptr || *vectorptr == 0xcf )
  931.                 break;
  932.         }
  933.         if (vector == 0x67)
  934.         {
  935.             printf ("Warning: no NULL or iret interrupt vectors were found in the 0x60 to 0x66\n");
  936.             printf ("range.  You can specify a vector with the VECTOR=0x<num> line in %s.\n\n", PROG_CONFIG);
  937.             pause ();
  938.             vector = 0x66;
  939.         }
  940.     }
  941.     doomcom.intnum = vector;
  942. }
  943.  
  944. void print_config_settings (void)
  945. {
  946.     clrscr ();
  947.     printf ("   Port settings (%s-type UART detected):\n\n",
  948.         uart_type == UART_8250 ? "8250" : "16550");
  949.     printf ("INIT1=%.73s\n", init1);
  950.     printf ("INIT2=%.73s\n", init2);
  951.     printf ("HANGUP=%.72s\n", hangup);
  952.     printf ("BAUD=%-6lu\n", baud);
  953.     printf ("COM=%d\n", comport);
  954.     printf ("IRQ=%d\n", irq);
  955.     printf ("PORT=0x%x\n", uart);
  956.     printf ("NODROPDTR=%d\n", nodropdtr);
  957.  
  958.     printf ("\n   DOOM settings:  ");
  959.     textcolor(RED);
  960.     if (doom2)
  961.         cprintf("DOOM ][: Hell on Earth\r\n\n");
  962.     else
  963.         cprintf("DOOM I\r\n\n");
  964.     textcolor(LIGHTGRAY);
  965.     if (doom2)
  966.         printf ("EPISODE=n/a          ");
  967.     else
  968.         printf ("EPISODE=%d            ", episode == -1 ? 1 : episode);
  969.     printf ("MAP=%d\n", map == -1 ? 1 : map);
  970.     printf ("DEATHMATCH=%d         ALTDEATH=%d\n", deathmatch, altdeath);
  971.     printf ("NOMONSTERS=%d         RESPAWN=%d\n", nomonsters, respawn);
  972.     printf ("LOADGAME=%c           DEVPARM=%.50s\n",
  973.         loadgame == -1 ? ' ' : loadgame + '0',
  974.         devparm);
  975.     printf ("SKILL=%d              DIAL=%.50s\n",
  976.         skill == -1 ? 3 : skill,
  977.         dial);
  978.     printf ("WADNAME=%-12.12s DIRECTORY=%.39s\n", wadname [0], directory);
  979.     printf ("DOOMEXE=%-12.12s CONFIG=%.51s\n", doomexe, config);
  980.     printf ("DOOMVER1_2=%d         PULSEDIAL=%d\n", doomver1_2, pulsedial);
  981.     printf ("PLAYER=%d             VECTOR=0x%x\n", player, vector);
  982. }
  983.  
  984. void configure (void)
  985. {
  986.     char line [256];
  987.     char files [256];
  988.     char space[]=" ";
  989.     int i = 0;
  990.     int j = 0;
  991.     int xpos;
  992.     int ypos;
  993.  
  994.     clrscr ();
  995.     printf ("Configure...  Press ENTER to keep current value shown in [].\n\n");
  996.  
  997.     printf ("  Wadfile directory [%s]: ", directory);
  998.     pickdirectory ();
  999.     printf ("\n");
  1000.     pickwads ();
  1001.  
  1002.     if (wadname [0][0] != EOS)       // Clear devparm for new wad files
  1003.         devparm [0] = EOS;
  1004.  
  1005.     files[0]=EOS;
  1006.     while(wadname[i][0] != EOS)
  1007.     {
  1008.         if (checkwad (i, wadname[i]) != FALSE)              // Check for wadfile existance , allow missing wads to remain
  1009.             strcat(files,devparm);                              // put all files into 1 string
  1010.         else if (i == 0)
  1011.             wadname [0][0] = EOS;
  1012.         i++;
  1013.     }
  1014.  
  1015.     if (wadname [0][0] != EOS)   // Construct file arguments into the devparm line
  1016.         sprintf(devparm,"%s-file%s\0",add,files);   // places devparm stuff first
  1017.     else
  1018.         strcpy(devparm,add);
  1019.  
  1020.     if ((wadname[0] == EOS) && (add [0] == EOS))
  1021.         devparm [0] = EOS;
  1022.      /* Prints the previous Devparm strings in a neat way */
  1023.     cprintf ("\r\n  Doom switches (-1 to Clear, \"+-switch\" to add, \"-switch\" to change)\r\n"
  1024.                      "                (This only changes Misc. switches)\r\n");
  1025.     cprintf ("   Misc. [");
  1026.     cprintf("]\r\n   Pwads [");
  1027.     xpos=wherex();
  1028.     ypos=wherey();
  1029.     printf("]");
  1030.     gotoxy(xpos,ypos-1);
  1031.     i=0;
  1032.     while (devparm[i] != EOS)      /* Displays previous arguments */
  1033.     {
  1034.         if ( (devparm[i] == '-') && (devparm[i+1] == 'f') )
  1035.         {
  1036.             cprintf("]");              //moves to the File section of the display
  1037.             gotoxy(xpos,ypos);
  1038.         }
  1039.         if ( (devparm[i] == ' ') && (devparm[i-4] == '.') )
  1040.             if (++j == 2)            //Allows 2 Pwads displayed per line
  1041.             {
  1042.                 j=0;
  1043.                 ypos++;
  1044.                 cprintf("]\r\n         [     ");
  1045.             }
  1046.         cprintf ("%c",devparm[i++]);
  1047.         }
  1048.     cprintf("]");
  1049.     gotoxy(1,ypos+1);
  1050.     cprintf("     ??? : ");
  1051.  
  1052.     gets (line);
  1053.     if (strcmp (line, "-1") == 0)
  1054.     {
  1055.         add [0] = EOS;
  1056.         if (files[0] != EOS)
  1057.             sprintf(devparm,"-file%s", files);   //resets devparm to just files
  1058.         else
  1059.             devparm[0]=EOS;
  1060.  
  1061.         printf("\nNew Misc. Options: (none)\n");  //redisplay options
  1062.     }
  1063.     else if (line [0] == '+')
  1064.     {
  1065.         strcat (add, &line[1]);        //Removes the "+"
  1066.         strcat (add, space);
  1067.  
  1068.         if (files[0] != EOS)
  1069.             sprintf(devparm, "%s-file%s", add, files);  //Places additional stuff first
  1070.         else
  1071.             strcpy(devparm, add);
  1072.         line [0] = EOS;
  1073.  
  1074.         printf("\nNew Misc. Options: %s\n",add);  //redisplay options
  1075.     }
  1076.     else if (line [0] != EOS)       //Completely new additional stuff
  1077.     {
  1078.         sprintf(add,"%s ", line);
  1079.         if (files[0] != EOS)
  1080.             sprintf(devparm,"%s-file%s", add, files);
  1081.         else
  1082.             strcpy(devparm, add);
  1083.  
  1084.         printf("\nNew Misc. Options: %s\n",add);  //redisplay options
  1085.     }
  1086.     printf ("\n");
  1087.  
  1088.     printf ("  deathmatch (0/1)     [%d]: ", deathmatch);
  1089.     gets (line);
  1090.     sscanf (line, "%d", &deathmatch);
  1091.  
  1092.     if (deathmatch == 1)
  1093.     {
  1094.         printf ("  altdeath (0/1)       [%d]: ",altdeath);
  1095.         gets (line);
  1096.         sscanf (line, "%d", &altdeath);
  1097.     }
  1098.     else
  1099.         altdeath = 0;
  1100.  
  1101.     printf ("  nomonsters (0/1)     [%d]: ", nomonsters);
  1102.     gets (line);
  1103.     sscanf (line, "%d", &nomonsters);
  1104.  
  1105.     printf ("  respawn (0/1)        [%d]: ", respawn);
  1106.     gets (line);
  1107.     sscanf (line, "%d", &respawn);
  1108.  
  1109.     if (!doom2)  //Doom 2 doesn't have episodes
  1110.     {
  1111.         printf ("  episode (1-3)        [%d]: ", episode == -1 ? 1 : episode);
  1112.         gets (line);
  1113.         sscanf (line, "%d", &episode);
  1114.         if (episode < 2 || episode > 3)    /* If default, set back to -1 */
  1115.             episode = -1;
  1116.     }
  1117.  
  1118.     printf ("  map (1-32)           [%d]: ", map == -1 ? 1 : map);
  1119.     gets (line);
  1120.     sscanf (line, "%d", &map);
  1121.     if (map < 2 || map > 32)                /* If default, set back to -1 */
  1122.         map = -1;
  1123.  
  1124.     printf ("  skill (1-5)          [%d]: ", skill == -1 ? 3 : skill);
  1125.     gets (line);
  1126.     sscanf (line, "%d", &skill);
  1127.     if (skill < 1 || skill > 5 || skill == 3)    /* If default, set back to -1 */
  1128.         skill = -1;
  1129.  
  1130.     printf ("  loadgame (0-5 or -1) [%c]: ", loadgame == -1 ? ' ' : loadgame + '0');
  1131.     gets (line);
  1132.     sscanf (line, "%d", &loadgame);
  1133.     if (loadgame < 0 || loadgame > 5)
  1134.         loadgame = -1;
  1135.  
  1136.     printf( "  player Num. (0 or 1) [%d]: ", player);
  1137.     gets(line);
  1138.     sscanf (line, "%d", &player);
  1139.     if (player < 0 || player > 1)
  1140.         player = 0;
  1141.  
  1142.     printf("\n");
  1143. }
  1144.  
  1145. void pickdirectory (void)
  1146. {
  1147.     char line [40];
  1148.     char *p;
  1149.  
  1150.     line[0]=39;                  //Limit to 38 chars + null
  1151.     p=cgets (line);
  1152.     strcpy(line, p);
  1153.     if (strcmp (line, "-1") == 0)
  1154.         directory [0] = EOS;
  1155.     else if (line [0] != EOS )
  1156.     {
  1157.         if( (line [strlen(line) - 1] != ':') && (line [strlen(line) -1] != '\\') )
  1158.             sprintf(directory, "%s\\", line);
  1159.         else
  1160.             strcpy (directory, line);
  1161.     }
  1162. }
  1163.  
  1164. void printselected ( int xpos)
  1165. {
  1166.     int i=0;
  1167.     int ypos;
  1168.  
  1169.     ypos=wherey();
  1170.     while (wadname [i][0] != EOS)      /* Displays previous arguments */
  1171.     {
  1172.         if ( (wherex() + strlen(wadname[i])) > 78 )   //avoids line wrapping
  1173.         {
  1174.             cprintf("]\r\n");
  1175.             ypos=wherey();
  1176.             gotoxy(xpos,ypos);
  1177.             cprintf("[");
  1178.         }
  1179.         cprintf ("%s, ",wadname[i++]);
  1180.     }
  1181.     if ( i == 0 ) cprintf("]");
  1182.     else cprintf("\b\b]");
  1183.     ypos=wherey();
  1184.     gotoxy(xpos-4, ypos+1);
  1185.     cprintf("??? :");
  1186. }
  1187.  
  1188. void pickwads (void)
  1189. {
  1190.     char line [100];
  1191.     char ext[]=".WAD";
  1192.  
  1193.     kill_nonwads();
  1194.     wadname[9][0]=EOS;            //Limit to 9 Pwads in configure
  1195.     cprintf ("\r\n  Enter Pwads to play (-1 to clear, separate wads with a \"space\")\r\n"
  1196.               "   Names (9 MAX) [");
  1197.     printselected(18);
  1198.     gets (line);
  1199.     if (strcmp (line, "-1") == 0)
  1200.     {
  1201.         wadname [0][0] = EOS;
  1202.         strcpy (devparm, add);
  1203.     }
  1204.     else if (line [0] != EOS)    //  Parse multiple wads
  1205.         parsewad( line, ext);
  1206. }
  1207.  
  1208. void parsewad (char *line, char *ext)
  1209. {
  1210.     int i=0;
  1211.     char *ptr;
  1212.  
  1213.     for (i = 0; i < 9; i++)
  1214.     {
  1215.         if ((ptr = strtok (i == 0 ? line : NULL, " ")) == NULL)
  1216.         {
  1217.             wadname [i][0] = EOS;
  1218.             return;
  1219.         }
  1220.         strcpy (wadname [i], ptr);
  1221.         if (strlen (wadname [i]) > 4)
  1222.         {
  1223.             if (strncmpi (
  1224.                 &wadname [i][strlen (wadname [i]) - 4], ext, strlen (ext)) == 0)
  1225.             {
  1226.                 /* Wad name already ends in given extension, so don't add it. */
  1227.                 continue;
  1228.             }
  1229.         }
  1230.         /* Wad name doesn't end in given extension already, so add it. */
  1231.         strcat (wadname [i], ext);
  1232.     }
  1233. }
  1234.  
  1235. int checkwad ( int numwad, char *wad )
  1236. {
  1237.     char junk [55];
  1238.     int tempmapnum;
  1239.     int j=0;
  1240.  
  1241.     sprintf(junk,"%s%s\0",directory,wad);
  1242.  
  1243.     if (getwadlevel( junk) == TRUE)
  1244.     {
  1245.         while (levels[j][0] != EOS)
  1246.         {
  1247.             if (numwad == 0) map = 32;
  1248.             if (doom2)
  1249.                 sscanf (&levels[j][3], "%d%d", &tempmapnum);
  1250.             else
  1251.                 sscanf (&levels[j][3], "%d", &tempmapnum);
  1252.             if ( tempmapnum < map )
  1253.             {
  1254.                 map=tempmapnum;
  1255.                 if (!doom2)
  1256.                     sscanf (&levels[j][1], "%d", &episode);
  1257.                 textcolor(YELLOW);
  1258.                 if (doom2)   // Doom 2 has no episode number
  1259.                     cprintf("  Setting to Map %d\r\n",map);
  1260.                 else
  1261.                     cprintf("  Setting to Episode %d, Map %d\r\n",episode,map);
  1262.                 textcolor(LIGHTGRAY);
  1263.                 numwad++;
  1264.             }
  1265.         j++;
  1266.         }
  1267.     }
  1268.     else if ( getwadlevel ( junk) == 2)
  1269.     {
  1270.         printf("\a\nFile %s does not exist.\n\n",junk);
  1271.         sprintf(devparm," %s",junk);
  1272.         return 2;  // Nonexist file
  1273.     }
  1274.     else
  1275.     {
  1276.         printf("\a\nWadfile, %s, is corrupted\n",junk);
  1277.         return FALSE;
  1278.     }
  1279.     sprintf(devparm," %s",junk);
  1280.     return TRUE;
  1281. }
  1282.  
  1283. int getwadlevel ( char *wadname)
  1284. {
  1285.     FILE *WadFile;
  1286.     char pwad[6];
  1287.     long dirstart;
  1288.     int direntries;
  1289.     int i=0;
  1290.     int j=0;
  1291.     char name[17];
  1292.  
  1293.     if ((WadFile = fopen(wadname, "rb")) == NULL)
  1294.         return 2;    // 2 Non-Existant File
  1295.     if (fread ( &pwad, 1 , 4, WadFile) != 4)
  1296.         return FALSE;
  1297.     if ( (strncmp( pwad, "PWAD", 4)) && (strncmp( pwad, "IWAD", 4)) )
  1298.         return FALSE;
  1299.     if (fread ( &direntries , 1 , 4, WadFile) != 4)
  1300.         return FALSE;
  1301.     if (fread( &dirstart, 1, 4, WadFile) != 4)   /* Reads 4 byte pointer */
  1302.         return FALSE;
  1303.     fseek(WadFile, dirstart, 0);
  1304.     while ( i++ != direntries )
  1305.     {
  1306.         if (fread( &name, 1, 16, WadFile) != 16 )
  1307.             return FALSE;
  1308.         if (doom2)  //Doom 2 wad directory uses MAP01-MAP32
  1309.         {
  1310.             if (( name [8] == 'M' ) && ( name [9] == 'A' ) && ( name [10] == 'P'))
  1311.                 strcpy(levels[j++], &name[8]);
  1312.             else levels[j][0]=EOS;
  1313.         }
  1314.         else      //Doom wad directory uses E1M1-E3M9
  1315.         {
  1316.             if (( name [8] == 'E' ) && ( name [10] == 'M' ))
  1317.                 strcpy(levels[j++], &name[8]);
  1318.             else levels[j][0]=EOS;
  1319.         }
  1320.     }
  1321.     fclose(WadFile);
  1322.     return TRUE;
  1323. }
  1324.  
  1325. void wadleveldisplay (void)
  1326. {
  1327.     char line[40];
  1328.     char test[55];
  1329.     char ext[]=".WAD";
  1330.     int i=0;
  1331.     int j=0;
  1332.     int done_first;
  1333.  
  1334.     clrscr ();
  1335.     printf ("  Enter directory name [%s]: ", directory);
  1336.     pickdirectory ();
  1337.     kill_nonwads ();
  1338.     cprintf ("\r\n  Enter the Wadfile(s) to be scanned (separate wads with spaces)\r\n    [");
  1339.     printselected(5);
  1340.     gets(line);
  1341.     printf("\n");
  1342.     if (line [0] != EOS)
  1343.         parsewad ( line , ext);
  1344.     i=0;
  1345.     while (wadname[i][0] != EOS)
  1346.     {
  1347.         done_first = FALSE;
  1348.         sprintf( test, "%s%s\0", directory, wadname [i++]);
  1349.         if (getwadlevel( test) == TRUE)
  1350.         {
  1351.             printf("%s contains:\n  ", test);
  1352.             while ( levels[j][0] != EOS)
  1353.             {
  1354.                 printf ("%s%s",
  1355.                     done_first ? ", " : "",
  1356.                     levels [j++]);
  1357.                 done_first = TRUE;
  1358.             }
  1359.             j=0;
  1360.             printf("\n");
  1361.             pause();
  1362.         }
  1363.         else
  1364.             printf("Error reading %s", test);
  1365.         printf ("\n\n");
  1366.     }
  1367. }
  1368.  
  1369. void kill_nonwads ( void )     //removes non-wad files from the tag list
  1370. {
  1371.     int i=0;
  1372.     int j;
  1373.  
  1374.     while ( wadname [i][0] != EOS )
  1375.     {
  1376.         if ( strncmpi(&wadname[i][ strlen(wadname[i]) - 4], ".WAD", 4) != 0)
  1377.         {
  1378.             for (j=i; j<9; j++)
  1379.                 strcpy(wadname[j], wadname[j+1]);  //moves all files up 1 position
  1380.             i--;     // Removed a file, we need to decriment to re-check 'i'
  1381.         }
  1382.         i++;
  1383.     }
  1384. }
  1385.  
  1386. int SendFile ( void )
  1387. {
  1388.     struct time t;
  1389.     char zipfile[13];            //Name of the Temperary Zipfile
  1390.     char ziplist[9];        //Name of the Temperary PKZIP response file
  1391.     char pkzip[35];            //Pkzip command line
  1392.     char dsz[130];          //DSZ command line
  1393.     char dszfiles[20][72];  //list of files to be 'strcat'ed to the DSZ command line
  1394.     char temp[55];                //what else...a temporary variable
  1395.     int i=0;                //just a counter
  1396.     int c;
  1397.     int runzip=FALSE;       //Do I run PKZIP ???
  1398.     int rundsz=FALSE;       //Do I run DSZ ???
  1399.     int dszloops=1;            //number of times to run dsz
  1400.     FILE *test;
  1401.  
  1402.     clrscr();
  1403.     if (wadname [0][0] == EOS )
  1404.     {
  1405.         printf("No Files were selected\n");   //duhh..
  1406.         pause();
  1407.         return FALSE;
  1408.     }
  1409.     for (c=0;c<4;c++)    //Initializes the files I just use a 'strcat' later
  1410.         dszfiles[c][0]=EOS;
  1411.  
  1412.     gettime(&t);         //I shouldn't ever overwrite a file this way :)
  1413.     sprintf(zipfile,"ID%02d%02d%02d.ZIP", t.ti_hour, t.ti_min, t.ti_sec);
  1414.     sprintf(ziplist,"ID%02d%02d%02d", t.ti_hour, t.ti_min, t.ti_sec);
  1415.     sprintf (pkzip,"pkzip -ex %s @%s", zipfile, ziplist);
  1416.  
  1417.     if ((test = fopen( ziplist, "w+t" )) == NULL )   // open a pkzip list file
  1418.         return FALSE;
  1419.     textcolor(YELLOW);
  1420.     while ( wadname[i][0] != EOS )
  1421.     {
  1422.         if (strncmpi( &wadname[i][ strlen(wadname[i]) - 4], ".ZIP", 4) != 0)
  1423.         {            //Adds non Zipfiles to the PKZIP response file
  1424.             fprintf(test, "%s%s\n", directory, wadname[i++]);
  1425.             runzip=TRUE;
  1426.         }
  1427.         else
  1428.         {            //Adds Pre Zipped files to lists for DSZ
  1429.             rundsz=TRUE;
  1430.             sprintf(temp, "%s%s ", directory, wadname[i++]);
  1431.             if ( (strlen(dszfiles[dszloops-1]) + strlen(temp)) >= 70)
  1432.                 dszloops++;
  1433.             strcat(dszfiles[dszloops-1], temp);
  1434.         }
  1435.     }
  1436.     fclose(test);
  1437.     if (runzip == TRUE)
  1438.     {
  1439.         printf("Running Pkzip......\n");
  1440.         if (system ( pkzip));
  1441.         if (access(zipfile, 0) == 0)
  1442.         {            //Makes sure you didn't <CTRL>Break Pkzip
  1443.             rundsz=TRUE;
  1444.             if ( (strlen(dszfiles[dszloops-1]) + strlen(zipfile)) >= 70)
  1445.                 dszloops++;
  1446.             strcat(dszfiles[dszloops-1], zipfile);
  1447.         }
  1448.         else     //You must have killed PKZIP, check whether there are other files to send
  1449.             if (rundsz == FALSE)
  1450.                 dszloops=0;
  1451.     }
  1452.     remove(ziplist);
  1453.     if (rundsz == TRUE)
  1454.     {
  1455.         clrscr();
  1456.         cprintf("<ALT>-N can be used to NUKE the DSZ transfer\r\n"
  1457.                  "but please don't unless you really screwed up :(\r\n\r\n");
  1458.     }
  1459.     if (dszloops > 1)
  1460.     {
  1461.         cprintf("Due to command line limitations with DSZ, DSZ needs to be called\r\n"
  1462.                   "%d times to send all flagged files.  Don't worry about the\r\n"
  1463.                   "negotiation, I handle the whole thing.  I Hope :)\r\n"
  1464.                   "BTW: You'll need to NUKE each call to DSZ to abort the transfer.\r\n\r\n",dszloops);
  1465.         delay(1000);
  1466.     }
  1467.     while (dszloops >= 1)
  1468.     {
  1469.         sprintf(dsz,"transfer\\dsz portx %x,%i speed %lu d ha on sz -rr %s", uart, irq, baud, dszfiles[dszloops-1] );
  1470.         if(system( dsz));
  1471.         if (--dszloops != 0)
  1472.         {
  1473.             cprintf("\r\n\r\nFile set complete.  Preparing for next set...\r\n");
  1474.             delay(3000);  //Delay for 3 seconds before writing negotiation byte
  1475.             c=0x19;
  1476.             write_buffer (&(char)c, 1);    //Sends command to reload DSZ
  1477.         }
  1478.         else
  1479.         {
  1480.             delay(3000);
  1481.             c=0x1A;
  1482.             write_buffer (&(char)c, 1);     //Sends command to quit
  1483.         }
  1484.     }
  1485.     textcolor(LIGHTGRAY);
  1486.     clrscr();
  1487.     printf("File transfer complete.\n");
  1488.     pause();
  1489.     remove ( zipfile);
  1490.     return TRUE;
  1491. }
  1492.  
  1493. int ReceiveFile ( char *ziptodir)
  1494. {
  1495.     char zipfile[15];
  1496.     char output[130];
  1497.     char temp[50];
  1498.     unsigned int i=0;
  1499.     int done=FALSE;
  1500.     int nextset;
  1501.     int c;
  1502.     struct time t;
  1503.     int time;
  1504.  
  1505.     chdir("TRANSFER");
  1506.     sprintf(output,"dsz portx %x,%i speed %lu d ha on rz -rr", uart, irq, baud);
  1507.  
  1508.     clrscr();
  1509.     textcolor(YELLOW);
  1510.     cprintf("<ALT>-N can be used to NUKE the DSZ transfer\r\n"
  1511.              "but please don't unless you really screwed up :(\r\n\r\n");
  1512.  
  1513.     cprintf("Press <ESC> to quit waiting.\r\n\r\nWaiting for Remote system to start sending");
  1514.  
  1515.     while (done != TRUE)
  1516.     {
  1517.         while ( bioskey(1) )  //Checks for the <ESC> key
  1518.         {
  1519.             if ( (bioskey (0) & 0xff) == ESC)
  1520.             {
  1521.                 printf ("\n\nTransfer aborted.\n");
  1522.                 while (read_byte () != -1);
  1523.                 chdir("..");
  1524.                 textcolor(LIGHTGRAY);
  1525.                 return FALSE;
  1526.             }
  1527.         }
  1528.  
  1529.         if (i == 30000 )     //Prints dots so you know its waiting
  1530.         {
  1531.             textcolor(random(15) + 1);   //I felt like it OK :)
  1532.             i=0;
  1533.             cprintf(".");
  1534.         }
  1535.         i++;
  1536.         if ((c = read_byte ()) != -1)
  1537.         {
  1538.             if (c == 0x18)     //check for the ZMODEM autostart
  1539.             {
  1540.                 printf("\n");
  1541.                 if(system( output) );
  1542.                 nextset=FALSE;
  1543.                 gettime(&t);
  1544.                 time=t.ti_sec+(t.ti_min*60);
  1545.                 textcolor(YELLOW);
  1546.                 while ( nextset != TRUE)
  1547.                 {
  1548.                     c = read_byte ();
  1549.                     gettime(&t);
  1550.                     if ( ((t.ti_min*60)+t.ti_sec - time) > 20)
  1551.                     {
  1552.                         cprintf("\r\nOops, I lost the other signal....Aborting\r\n");
  1553.                         pause();
  1554.                         nextset=TRUE;
  1555.                         done=TRUE;
  1556.                     }
  1557.                     if (c == 0x19)   //character to re-load DSZ
  1558.                     {
  1559.                         nextset = TRUE;
  1560.                         cprintf("\r\nDue to command line limitations with DSZ, the remote system\r\n"
  1561.                                   "needed to re-load DSZ to send all of the files\r\n");
  1562.                         cprintf("\nWaiting for next group of ZIP's");
  1563.                     }
  1564.                     if (c == 0x1A)        //character to quit
  1565.                     {
  1566.                         nextset=TRUE;
  1567.                         done=TRUE;
  1568.                     }
  1569.                 }
  1570.             }           // Yes they really all end here
  1571.         }
  1572.     }
  1573.     chdir("..");
  1574.     textcolor(LIGHTGRAY);
  1575.     clrscr();
  1576.     printf("\nFiles transfered.\n\n");
  1577.     printf("Do you wish to FLAG zip's to be extracted to %s? [Yes/No/All]:", directory);
  1578.     for (EVER)
  1579.     {
  1580.         c = tolower (getch());
  1581.         switch (c)
  1582.         {
  1583.             case 'a'    :
  1584.             {
  1585.                 sprintf(zipfile,"transfer\\*.zip");
  1586.                 printf("\nRunning Pkunzip......\n");
  1587.                 if (mkdir( ziptodir));
  1588.                 sprintf(output,"pkunzip %s %s", zipfile, ziptodir);
  1589.                 if (system( output));
  1590.                 printf("\n\nDo you want to remove the Zipfiles [Yes/No]:\n");
  1591.                 for (EVER)
  1592.                 {
  1593.                     c = tolower (getch());
  1594.                     switch (c)
  1595.                     {
  1596.                         case 'y'    :
  1597.                             sprintf(output,"del %s",zipfile);
  1598.                             system(output);
  1599.                             return TRUE;
  1600.                         case 'n' :
  1601.                             printf("\nOk, they're in the \".\\TRANSFER\\\" directory.\n");
  1602.                             pause();
  1603.                             return TRUE;
  1604.                     }
  1605.                 }
  1606.             }
  1607.             case 'y' :
  1608.             {
  1609.                 strcpy(temp,ziptodir);        //dir call changes dir
  1610.                 dir (DIR_TYPE_ZIP);
  1611.                 i=0;
  1612.                 if (mkdir( ziptodir));
  1613.                 while ( wadname[i][0] != EOS)
  1614.                 {
  1615.                     sprintf(output, "pkunzip %s%s %s", directory, wadname[i++], temp);
  1616.                     if (system( output));
  1617.                 }
  1618.                 strcpy(directory, temp);        //resets the directory to zip-output
  1619.                 printf("\n\nDo you want to remove FLAGGED Zipfiles [Yes/No]:");
  1620.                 for (EVER)
  1621.                 {
  1622.                     c = tolower (getch());
  1623.                     switch (c)
  1624.                     {
  1625.                         case 'y'    :
  1626.                             i=0;
  1627.                             while ( wadname [i][0] != EOS)
  1628.                             {
  1629.                                 sprintf(zipfile,"TRANSFER\\%s",wadname[i++]);
  1630.                                 remove (zipfile);
  1631.                             }
  1632.                             return TRUE;
  1633.                         case 'n' :
  1634.                             printf("\nOk, they're in the \".\\TRANSFER\\\" directory.\n");
  1635.                             pause();
  1636.                             return TRUE;
  1637.                     }
  1638.                 }
  1639.             }
  1640.             case 'n'    :
  1641.             {
  1642.                 printf("\nOK, you can just shell to DOS and do it.\n"
  1643.                          "Look in the \".\\TRANSFER\\\" directory for them.\n");
  1644.                 pause();
  1645.                 return TRUE;
  1646.             }
  1647.         }
  1648.     }
  1649. }
  1650.  
  1651. void file_transfer ( void )
  1652. {
  1653.     char line[100];
  1654.     char ext[]="";
  1655.     char ch;
  1656.  
  1657.     clrscr();
  1658.     if ( access("TRANSFER\\DSZ.EXE", 0) != 0)
  1659.     {
  1660.         printf("\a\n  DSZ.EXE is not in the \".\\TRANSFER\\\" subdirectory\n"
  1661.                  "    You must install DSZ.EXE properly before use.  Please consult the\n"
  1662.                  "    SER6.TXT for installation notes.\n\n");
  1663.         pause();
  1664.         clrscr();
  1665.         return;
  1666.     }
  1667.     printf("Send or Receive [S/R]:");
  1668.     ch = tolower (getch ());
  1669.     switch (ch)
  1670.     {
  1671.         case 's'    :
  1672.             cprintf ("\r\n\n  Enter the directory of the files to be sent [%s]: ", directory);
  1673.             pickdirectory();
  1674.             printf ("\r\n  Enter the Files [");
  1675.             printselected(19);
  1676.             gets(line);
  1677.             printf("\n");
  1678.             if (line [0] != EOS)
  1679.                 parsewad ( line, ext );
  1680.             if ( wadname[0][0] != EOS)
  1681.                 SendFile ();
  1682.             break;
  1683.  
  1684.         case 'r'    :
  1685.             cprintf ("\r\n\nEnter directory for zipfile extraction [%s]: ", directory);
  1686.             pickdirectory();
  1687.             ReceiveFile ( directory );
  1688.             break;
  1689.     }
  1690.     InitPort ();        //Re-inits the port, incase DSZ screwed with it
  1691.     clrscr();
  1692. }
  1693.  
  1694. void dir ( int type )
  1695. {
  1696.     DIR *dir;
  1697.     struct dirent *ent;
  1698.     char *p;
  1699.     char wad[13];
  1700.     char wadfiles[301][13];  //300 Files Max or qsort() pukes
  1701.     char line[6];
  1702.     char extension[5];
  1703.     const void *a;
  1704.     const void *b;
  1705.     int numfiles=0;
  1706.     int numflagged=0;
  1707.     int i=0;
  1708.     int j=0;
  1709.     int k=0;
  1710.     int pages;
  1711.     int xpos;
  1712.     int ypos;
  1713.     int wildcard=0;
  1714.  
  1715.     clrscr ();
  1716.  
  1717.     for (i=0; i<301 ; i++)     //Initialize wadfiles
  1718.         wadfiles[i][0]=EOS;
  1719.     wadname[0][0]=EOS;
  1720.  
  1721.     if (type == DIR_TYPE_ZIP)            //Sets the default extension & directory
  1722.     {
  1723.         sprintf(extension,"ZIP");
  1724.         sprintf(directory, "TRANSFER\\");
  1725.         line[0]=EOS;
  1726.     }
  1727.     else
  1728.     {
  1729.         sprintf(extension,"WAD");
  1730.         printf("Enter file extension for search (* for all) [%s]: ",extension);
  1731.         line[0]=4;                  //Limit to 3 chars + null
  1732.         p=cgets (line);
  1733.         strcpy(line, p);
  1734.     }
  1735.  
  1736.     if (line [0] == EOS )
  1737.         strcpy (line, extension);
  1738.     sprintf(extension,".%s",line);   // Add a '.' to extension
  1739.  
  1740.     //Check for wildcard
  1741.     if ( (extension[1] == '*') && (extension[2] == EOS) )
  1742.         wildcard=3;        // '3' is the number that needs to be removed from the 'strncmpi' line below
  1743.  
  1744.     if (type == DIR_TYPE_NORMAL)
  1745.     {
  1746.         printf ("\n  Enter the directory to be displayed [%s]: ", directory);
  1747.         pickdirectory ();
  1748.     }
  1749.  
  1750.     if (( dir = opendir(directory)) != NULL)
  1751.     {
  1752.         while( ((ent = readdir(dir)) != NULL) &&  (numfiles < 300 ) )
  1753.         {
  1754.             if (strlen(ent->d_name) > 4)
  1755.             {
  1756.                 if (strncmpi( &ent->d_name[strlen(ent->d_name) - 4], extension, (4-wildcard)) == 0)
  1757.                     strcpy(wadfiles[numfiles++], ent->d_name);
  1758.             }
  1759.             wadfiles[numfiles][0]=EOS;
  1760.         }
  1761.         if (closedir(dir) != 0)
  1762.         {
  1763.             printf("\n\nUnable to close Directory\n\n");
  1764.             pause ();
  1765.         }
  1766.     }
  1767.     else
  1768.     {
  1769.         printf("\n\nUnable to open Directory\n\n");
  1770.         pause ();
  1771.         return;
  1772.     }
  1773.     /*  Sorts the files  */
  1774.     qsort((void *)wadfiles, numfiles, sizeof(wadfiles[0]), sort_function);
  1775.     pages = (numfiles / 68)+1;     //68 files per page
  1776.     numfiles = 0;
  1777.     for ( i = 0; i < pages; i++)
  1778.     {
  1779.         clrscr();
  1780.         printf("****** Page %i of %i of %s*%s *******\n\n",(i+1), pages, directory, extension);
  1781.         for (j = (0 + numfiles); j < (68 + numfiles); )
  1782.         {
  1783.             for ( k = 0; k < 4; k++)        // 4 columns per page
  1784.             {
  1785.                 if (wadfiles[j][0] != EOS)
  1786.                 {
  1787.                     printf("[%3d] %+12s  ", (j+1), wadfiles[j]);
  1788.                     j++;
  1789.                 }
  1790.                 else
  1791.                 {
  1792.                     printf("\n");
  1793.                     k=4;
  1794.                     j=68+numfiles;
  1795.                 }
  1796.             }
  1797.         }
  1798.         numfiles = j;
  1799.         line [0] = ' ';
  1800.         cprintf("\r\nEnter the NUMBERS of the files to Flag. (20 FILES MAX)\r\n"
  1801.                  "Hit Enter to quit flagging or view next page\r\n"
  1802.                  "Files [");
  1803.         printselected(7);
  1804.         while ( (numflagged < 20 ) && (line[0] != EOS) )
  1805.         {
  1806.             xpos=wherex();
  1807.             ypos=wherey();
  1808.             gets(line);
  1809.             gotoxy( (xpos+strlen(line)) , ypos);  //Repositions cursor after linefeed
  1810.             if ( line[0] != EOS)
  1811.             {
  1812.                 printf(", ");
  1813.                 sscanf (line, "%d", &j);
  1814.                 j--;
  1815.                 if ( (j >= 0) && (j <= numfiles) )   //checks for a valid number
  1816.                 {
  1817.                     strcpy(wadname[numflagged],wadfiles[j]);
  1818.                     numflagged++;
  1819.                 }
  1820.             }
  1821.             else
  1822.                 printf("\n\n");
  1823.         }
  1824.         wadname[numflagged][0]=EOS;  //Just to make sure the last entry is a EOS
  1825.     }
  1826. }
  1827.  
  1828. int sort_function(const void *a, const void *b)
  1829. {
  1830.     return( strcmp((char *)a, (char *)b) );
  1831. }
  1832.  
  1833. void stats (void)
  1834. {
  1835.     time_t hrs;
  1836.     time_t mins;
  1837.     time_t secs;
  1838.     struct tm *timeptr;
  1839.  
  1840.     clrscr ();
  1841.     if (starttime != 0)
  1842.     {
  1843.         timeptr = localtime (&starttime);
  1844.         printf ("                 Start Time: %2d:%02d:%02d",
  1845.             timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec);
  1846.  
  1847.         playtime = endtime - starttime;
  1848.         hrs = playtime / 3600;
  1849.         mins = (playtime - (hrs * 3600)) / 60;
  1850.         secs = playtime - (hrs * 3600) - (mins * 60);
  1851.         printf ("      Playing Time: %2d:%02d:%02d\n\n",
  1852.             (int) hrs, (int) mins, (int) secs);
  1853.     }
  1854.     showReadStats();
  1855.     showWriteStats();
  1856.     showUartErrors();
  1857. }
  1858.  
  1859. int good_char ( int ch )
  1860. {
  1861.     if ( isprint(ch) || (ch == BACKSPACE) || (ch == '\n') )
  1862.         return TRUE;
  1863.     else
  1864.         return FALSE;
  1865. }
  1866.  
  1867. #define LOCAL_Y_MIN 3
  1868. #define LOCAL_Y_MAX 13
  1869. #define REMOTE_Y_MIN 15
  1870. #define REMOTE_Y_MAX 25
  1871.  
  1872. void split_talk (void)
  1873. {
  1874.     int i;
  1875.     int c;
  1876.     int local_xpos=1;
  1877.     int local_ypos= LOCAL_Y_MIN + 1;
  1878.     int remote_xpos=1;
  1879.     int remote_ypos= REMOTE_Y_MIN + 1;
  1880.     int pos;
  1881.     int start = 0x02;    // A little bit of noise trapping
  1882.     int good = FALSE;
  1883.  
  1884.     clrscr ();
  1885.     printf ("Talk mode...  Press ESC to return");
  1886.     gotoxy(1, LOCAL_Y_MIN - 1);
  1887.     printf ("(Local)");
  1888.     gotoxy(1, REMOTE_Y_MIN - 2);
  1889.     /* Two lines here...  80 '=' signs plus the title. */
  1890.     printf ("════════════════════════════════════════════════════════════════════════════════(Remote)");
  1891.     gotoxy(local_xpos, local_ypos);
  1892.     while (TRUE)
  1893.     {
  1894.         /* Check for keypress */
  1895.         if (bioskey (1))
  1896.         {
  1897.             if ((c = bioskey (0) & 0xff) == ESC)
  1898.             {
  1899.                 /* ESC key -- Exit talk mode -- Flush both sides */
  1900.                 while (read_byte () != -1)
  1901.                     ;
  1902.                 while (bioskey (1))
  1903.                     bioskey (0);
  1904.                 clrscr();
  1905.                 return;
  1906.             }
  1907.             if (c == '\r')        /* Change cr to crlf */
  1908.                 c = '\n';
  1909.             if (good_char(c))
  1910.             {
  1911.                 write_buffer (&(char)start, 1);
  1912.                 write_buffer (&(char)c, 1);
  1913.                 if((pos = wherey()) >= REMOTE_Y_MIN && pos <= REMOTE_Y_MAX)
  1914.                 {
  1915.                     /* We're on the remote side.  Save pos. and move to local. */
  1916.                     remote_xpos=wherex();
  1917.                     remote_ypos=pos;
  1918.                     gotoxy(local_xpos, local_ypos);
  1919.                 }
  1920.                 printf ("%c", c);
  1921.             /* If we're now in the 1st column and we didn't backspace here... */
  1922.                 if (( wherex() == 1) && ( c != BACKSPACE ) )
  1923.                 {
  1924.                     /* ... then we're on a new line, so increment ypos. */
  1925.                     local_ypos++;
  1926.                     /* If we're at the bottom of the local section, move to the top. */
  1927.                     if (wherey() == LOCAL_Y_MAX)
  1928.                     {
  1929.                         local_ypos = LOCAL_Y_MIN;
  1930.                         gotoxy ( 1, local_ypos);
  1931.                     }
  1932.                     /* Clear this line, and the next if not max. */
  1933.                     clreol();
  1934.                     if ( (local_ypos + 1) != LOCAL_Y_MAX )
  1935.                     {
  1936.                         gotoxy(1, local_ypos+1);
  1937.                         clreol();
  1938.                         gotoxy(1, local_ypos);
  1939.                     }
  1940.                 }
  1941.             }
  1942.         }
  1943.         /* Check for received byte */
  1944.         c = read_byte();
  1945.         if( (c != -1) && (good == TRUE) )
  1946.         {
  1947.             good = FALSE;
  1948.             if (good_char(c))
  1949.             {
  1950.                 if ((pos = wherey()) >= LOCAL_Y_MIN && pos <= LOCAL_Y_MAX)
  1951.                 {
  1952.                     /* We're on the local side.  Save pos and move to remote. */
  1953.                     local_xpos=wherex();
  1954.                     local_ypos=wherey();
  1955.                     gotoxy(remote_xpos, remote_ypos);
  1956.                 }
  1957.                 printf ("%c", c);
  1958.             /* If we're now in the 1st column and we didn't backspace here... */
  1959.                 if (( wherex() == 1) && ( c != BACKSPACE ) )
  1960.                 {
  1961.                     /* ... then we're on a new line, so increment ypos. */
  1962.                     remote_ypos++;
  1963.             /* If we're at the bottom of the remote section, move to the top. */
  1964.                     if (wherey () == REMOTE_Y_MAX)
  1965.                     {
  1966.                         remote_ypos = REMOTE_Y_MIN;
  1967.                         gotoxy ( 1, remote_ypos);
  1968.                     }
  1969.                     /* Clear this line, and the next if not max. */
  1970.                     clreol();
  1971.                     if ( (remote_ypos + 1) != REMOTE_Y_MAX )
  1972.                     {
  1973.                         gotoxy(1, remote_ypos+1);
  1974.                         clreol();
  1975.                         gotoxy(1, remote_ypos);
  1976.                     }
  1977.                 }
  1978.             }
  1979.         }
  1980.         if (c == start)
  1981.             good = TRUE;
  1982.     }
  1983. }
  1984.  
  1985. void reset_counters (void)
  1986. {
  1987.     /* showReadStats() counters. */
  1988.     writeBufferOverruns       = 0;
  1989.     bytesRead                 = 0;
  1990.     packetsRead               = 0;
  1991.     largestReadPacket         = 0;
  1992.     smallestReadPacket        = 0xFFFFFFFFl;
  1993.     readBufferOverruns        = 0;
  1994.     totalReadPacketBytes      = 0;
  1995.     oversizeReadPackets       = 0;
  1996.     largestOversizeReadPacket = 0;
  1997.     overReadPacketLen         = 0;
  1998.  
  1999.     /* showWriteStats() counters. */
  2000.     bytesWritten               = 0;
  2001.     packetsWrite               = 0;
  2002.     largestWritePacket         = 0;
  2003.     smallestWritePacket        = 0xFFFFFFFFl;
  2004.     totalWritePacketBytes      = 0;
  2005.     oversizeWritePackets       = 0;
  2006.     largestOversizeWritePacket = 0;
  2007.  
  2008.     /* showUartErrors() counters. */
  2009.     numBreak          = 0;
  2010.     numFramingError   = 0;
  2011.     numParityError    = 0;
  2012.     numOverrunError   = 0;
  2013.     numTxInterrupts   = 0;
  2014.     numRxInterrupts   = 0;
  2015. }
  2016.  
  2017. void title (void)
  2018. {
  2019.     clrscr();
  2020.     gotoxy (1, 4);
  2021.     cprintf("╔═════════════════════════╕\r\n");
  2022.     cprintf("║                         │\r\n");
  2023.     cprintf("║                         │\r\n");
  2024.     cprintf("║                         ├────────────┐\r\n");
  2025.     cprintf("║                         │            │\r\n");
  2026.     cprintf("║                         │            │\r\n");
  2027.     cprintf("╙─────────────────────────┘            │\r\n");
  2028.     cprintf("                         ┌─────────────┴─────────────┐\r\n");
  2029.     cprintf("                         │           %4.4s            │\r\n",PROG_NAME);
  2030.     cprintf("                         │ DOOM SERIAL DEVICE DRIVER │\r\n");
  2031.     cprintf("                         └─────────────┬─────────────┘\r\n");
  2032.     cprintf("                                       │            ┌──────────────────────────╖\r");
  2033.     cprintf("                                       │            │                          ║\r");
  2034.     cprintf("                                       │            │                          ║\r");
  2035.     cprintf("                                       └────────────┤                          ║\r");
  2036.     cprintf("                                                    │                          ║\r");
  2037.     cprintf("                                                    │                          ║\r");
  2038.     cprintf("                                                    ╘══════════════════════════╝\r");
  2039.     window(3,5,25,10);
  2040.     textcolor(DARKGRAY);
  2041.     DOOM();
  2042.     gotoxy(55,16);
  2043.     window(55,16,77,21);
  2044.     textcolor(GREEN);
  2045.     DOOM();
  2046.     window(1,1,80,25);
  2047.     textcolor(LIGHTGRAY);
  2048.     gotoxy(1,25);
  2049.     pause ();
  2050. }
  2051.  
  2052. void DOOM (void)
  2053. {
  2054.     cprintf("▄▄▄▄   ▄▄▄   ▄▄▄  ▄   ▄\r");
  2055.     cprintf("█   █ █   █ █   █ ██▄██\r");
  2056.     cprintf("█   █ █   █ █   █ █ ▀ █\r");
  2057.     cprintf("█   █ █   █ █   █ █   █\r");
  2058.     cprintf("▀▀▀▀   ▀▀▀   ▀▀▀  ▀   ▀\r");
  2059. }
  2060.  
  2061. void shell (void)
  2062. {
  2063.     char comspec[30];
  2064.     char oldprompt[128];
  2065.     static char prompt[128];   //setenv requires a static or global
  2066.     char path[80];
  2067.     int  drive;
  2068.  
  2069.     cprintf("\n\nDos Shell......\n\n");
  2070.     drive=getdisk();
  2071.     strcpy(path, "X:\\");      /* fill string with form of response: X:\ */
  2072.     path[0] = 'A' + getdisk();    /* replace X with current drive letter */
  2073.     getcurdir(0, path+3);  /* fill rest of string with current directory */
  2074.  
  2075.     strcpy(oldprompt,getenv("PROMPT"));
  2076.     sprintf(prompt,"PROMPT=Type 'EXIT' to return to %s$_%.80s",
  2077.         PROG_NAME, oldprompt);
  2078.     putenv(prompt);
  2079.     strcpy(comspec,getenv("COMSPEC"));
  2080.     if (comspec != NULL)
  2081.         spawnv(P_WAIT,comspec,NULL);
  2082.     else        //Just incase someone looses the COMSPEC env variable
  2083.     {
  2084.         printf("\nEnvironment Variable COMSPEC was not found!\nAssuming Command.Com\n");
  2085.         spawnvp(P_WAIT,"COMMAND.COM",NULL);
  2086.     }
  2087.     sprintf(prompt,"PROMPT=%.100s",oldprompt);  //resets environment
  2088.     putenv(prompt);
  2089.     setdisk(drive);          //returns to the DOOM dir.
  2090.     chdir(path);
  2091.     clrscr();
  2092. }
  2093.  
  2094. int promptdropdtr( void )
  2095. {
  2096.     char ch;
  2097.  
  2098.     printf("\n\nExit and Hangup the modem (Y)\n"
  2099.                   "Exit and Leave DTR up     (X)\n"
  2100.                   "Go Back to Main Menu      (N):");
  2101.     while(1)
  2102.     {
  2103.         ch = getch();
  2104.         tolower(ch);
  2105.         switch(ch)
  2106.         {
  2107.             case 'y':
  2108.                 nodropdtr = FALSE;
  2109.                 printf("\n\n");
  2110.                 return TRUE;
  2111.             case 'n':
  2112.                 printf("\n\n");
  2113.                 return FALSE;
  2114.             case 'x':
  2115.                 nodropdtr = TRUE;
  2116.                 printf("\n\n");
  2117.                 return TRUE;
  2118.             default :
  2119.                 break;
  2120.         }
  2121.     }
  2122. }
  2123.  
  2124. void pause (void)
  2125. {
  2126.     printf("Press any key to continue...");
  2127.     getch();
  2128. }
  2129.  
  2130. void usage (void)
  2131. {
  2132.     clrscr ();
  2133.     printf (
  2134.         "\n\n\n\n\n%s is run without arguments.  Just type \"%s\"\n\n",
  2135.         PROG_EXE, PROG_NAME);
  2136.     printf (
  2137.         "To change port-related settings, edit the %s file,\n", PROG_CONFIG);
  2138.     printf (
  2139.         "and to change game settings, use the CONFIGURE option while running.\n\n"
  2140.         "Yes, this means setup.exe won't work, but don't sweat the small stuff. :-)\n\n");
  2141.     pause ();
  2142. }
  2143.  
  2144. /*
  2145. =================
  2146. =
  2147. = main
  2148. =
  2149. =================
  2150. */
  2151.  
  2152. void main(void)
  2153. {
  2154.     int ch;
  2155.  
  2156.     if (_argc > 1)
  2157.         usage ();
  2158.  
  2159.     title();
  2160.  
  2161.     /* Setup the struct that we'll use to communicate with doom (via interrupt)*/
  2162.     doomcom.extratics = 1;            /* Make "extratics" default, it runs better. */
  2163.     doomcom.id = DOOMCOM_ID;        /* Used to verify that doomcom struct is ok. */
  2164.     doomcom.ticdup = 1;
  2165.     doomcom.numnodes = 2;            /* Don't waste your time trying 3 or 4. */
  2166.     doomcom.numplayers = 2;            /* Don't waste your time trying 3 or 4. */
  2167.     doomcom.drone = 0;
  2168.     doomcom.consoleplayer = 0;        /* Default - may be overridden later. */
  2169.  
  2170.     get_config_settings ();            /* Read config file and get uart & vector. */
  2171.     InitPort ();                        /* Initialize the port. */
  2172.     print_config_settings ();        /* Print out current settings. */
  2173.  
  2174.     while (read_byte() != -1)        /* Flush any old stuff from uart buffer */
  2175.         ;
  2176.  
  2177.     /* Get connected to the other computer. */
  2178.     while (TRUE)
  2179.     {
  2180.         printf ("\nSelect: [D] Dial     [A] Answer     [C] Connected already     [Q] Quit\n"
  2181.                      "        [U] Use Alternate BAUD and INIT");
  2182.         ch = tolower (getch ());
  2183.         printf ("\n");
  2184.         if (ch == 'd')
  2185.         {
  2186.             if (Dial_Modem ())
  2187.                 break;
  2188.         }
  2189.         else if (ch == 'a')
  2190.         {
  2191.             if (Answer ())
  2192.                 break;
  2193.         }
  2194.         else if (ch == 'q')
  2195.             Error (NULL);
  2196.         else if (ch == 'u')
  2197.             alt_init ();
  2198.         else if (ch == 'c')
  2199.             break;
  2200.     }
  2201.  
  2202.     /* Main menu. */
  2203.     clrscr();
  2204.     while (TRUE)
  2205.     {
  2206.         cprintf (
  2207.             "                               Main Menu\r\n\n");
  2208.         cprintf (
  2209.             "   [D] Play Doom     [C] Configure   [T] Talk to Remote    [Q] Quit\r\n"
  2210.             "   [F] File Dir      [W] Wad Levels  [Z] Zmodem File Xfer\r\n"
  2211.             "   [S] Serial Stats                                        [!] DOS Shell\r\n");
  2212.         ch = tolower (getch ());
  2213.         printf ("\n");
  2214.         switch (ch)
  2215.         {
  2216.             case 'd' :
  2217.                 if (Connect ())
  2218.                 {
  2219.                     reset_counters ();
  2220.                     time (&starttime);
  2221.                     if (doomver1_2 == 1)
  2222.                         LaunchDOOM1_2 ();
  2223.                     else
  2224.                         LaunchDOOM ();
  2225.                     time (&endtime);
  2226.                 }
  2227.                 break;
  2228.             case 's' :
  2229.                 stats ();
  2230.                 break;
  2231.             case 'c' :
  2232.                 configure ();
  2233.                 break;
  2234.             case 't' :
  2235.                 split_talk ();
  2236.                 break;
  2237.             case 'q' :
  2238.                 if (promptdropdtr() == TRUE)
  2239.                     Error (NULL);
  2240.                 break;
  2241.             case '!' :
  2242.                 shell ();
  2243.                 break;
  2244.             case 'w' :
  2245.                 wadleveldisplay ();
  2246.                 clrscr();
  2247.                 break;
  2248.             case 'z' :
  2249.                 file_transfer();
  2250.                 break;
  2251.             case 'f' :
  2252.                 dir (DIR_TYPE_NORMAL);
  2253.                 clrscr();
  2254.                 break;
  2255.         }
  2256.     }
  2257. }
  2258.