home *** CD-ROM | disk | FTP | other *** search
/ Beijing Paradise BBS Backup / PARADISE.ISO / software / BBSDOORW / VPIDB100.ZIP / VPID.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-19  |  24.1 KB  |  833 lines

  1. /* FILENAME: VPID.C                     VERSION: Beta 1.00
  2. **
  3. ** DESCRIPTION: VGA Planets Interface Door for Bulletin Board Systems.
  4. **              Compile with OpenDoors BBS door programming toolkit.
  5. **
  6. ** AUTHOR: John Kristoff                START DATE: 06/07/94
  7. **         Internet: jkristof@interaccess.com
  8. **         Internet: jkristof@bsd.meddean.luc.edu
  9. **         FidoNet:  1:115/743
  10. **      CompuServe:  74111,3652
  11. **
  12. ** VERSION    DATE     WHO  DETAIL
  13. ** Beta1.00   19May96  JK   Initial design and coding
  14. **
  15. **      Copyright John Kristoff, 1994-96.  All rights reserved.
  16. **      You may use this program or any part there-of as desired
  17. **      without restriction.
  18. */
  19.  
  20. #include <stdio.h>                      /* Standard i/o functions      */
  21. #include <stdlib.h>                     /* Standard library functions  */
  22.  
  23. #include "opendoor.h"                   /* OpenDoors structures        */
  24. #include "od_error.h"                   /* Error control               */
  25.  
  26.  
  27. /* --- Standard defs --- */
  28. #define VERSION        "Beta 1.00"      /* Program version             */
  29.  
  30. #define MAX_PLAYERS    11               /* Max players allowed in game */
  31. #define NEW_PLAYER     -1               /* New player number           */
  32.  
  33. #define DATA_FILE      "VPID.DAT"       /* Program data file           */
  34. #define MSGS_FILE      "VPID.MSG"       /* User messages file          */
  35. #define WELCOME_SCREEN "VPID"           /* ASC/ANS/RIP welcome screen  */
  36. #define HELP_FILE      "VPIDHELP"       /* ASC/ANS/RIP help screen     */
  37. #define SCORE_FILE     "VPIDSCOR"       /* VGA Planets score file      */
  38.  
  39. #define YES            1                /* Yes answer                  */
  40. #define NO             0                /* No answer                   */
  41.  
  42. #define UPLOAD         1                /* Upload option               */
  43. #define DOWNLOAD       0                /* Download option             */
  44.  
  45. /* --- typedefs --- */
  46. typedef struct                          /* GAME DATA Structure         */
  47. {
  48.     char Username[MAX_PLAYERS][36];     /*  -  Players in game         */
  49.     int Status[MAX_PLAYERS];            /*  -  Result file D/L status  */
  50.     int Reserved[60];                   /*  -  Reserved struct space   */
  51. } GAMEDATA;
  52.  
  53.  
  54. /* --- Constants --- */
  55. const char
  56. RaceName[MAX_PLAYERS][16] =             /* Team names        */
  57. {
  58.     "Federation",
  59.     "Lizards",
  60.     "Birdmen",
  61.     "Fascists",
  62.     "Privateers",
  63.     "Cyborgs",
  64.     "Crystal People",
  65.     "Evil Empire",
  66.     "Robotic Empire",
  67.     "Rebels",
  68.     "Colonies of Man"
  69. };
  70.  
  71. const int
  72. RaceChar[MAX_PLAYERS] =                 /* Team character designator   */
  73. {
  74.      '1','2','3','4','5','6','7','8','9','A','B'
  75. };
  76.  
  77. const int
  78. RaceNum[MAX_PLAYERS] =                 /* Team number designator   */
  79. {
  80.      '1','2','3','4','5','6','7','8','9','10','11'
  81. };
  82.  
  83. /* --- Function declarations --- */
  84. int  main( int argc, char * argv[] );
  85. void DisplayWelcomeScreen( void );
  86. void DoMainMenu( void );
  87. int  DisplayMainMenu( void );
  88. int  FindPlayer( void );
  89. void ShowTurnStatus( int PlayerNum );
  90. int  JoinGame( void );
  91. void Messages( void );
  92. void Scores( void );
  93. void TransferFile( int PlayerNum, int Direction );
  94. void Help( void );
  95. void UpdateDlStatus( int PlayerNum );
  96. int  Confirm( void );
  97. void PressKey( void );
  98.  
  99.  
  100. /* --- HERE WE GO! --- */
  101.  
  102. int
  103. main( int argc, char * argv[] )
  104. {
  105.     /* --- Setup and initialize OpenDoors environment --- */
  106.  
  107.     strcpy( od_registered_to, "John Kristoff" );
  108.     od_registration_key = 0000000000;
  109.     od_control.od_nocopyright = TRUE;
  110.     od_init();                          /* Setup od_control.* struct   */
  111.     od_clr_scr();                       /* Clear screen if enabled     */
  112.  
  113.     DisplayWelcomeScreen();
  114.  
  115.     DoMainMenu();
  116.  
  117.     od_set_colour( D_GREY, D_BLACK );   /* Reset color before exit     */
  118.     od_printf( "Returning to BBS\n\r" );
  119.  
  120.     od_exit( EXIT_SUCCESS, FALSE );
  121.     return( EXIT_SUCCESS );
  122. }
  123.  
  124.  
  125.  
  126. /* ----------------------------------------------------------------- */
  127. /* Display opening program screen upon start-up                      */
  128. /* ----------------------------------------------------------------- */
  129.  
  130. void
  131. DisplayWelcomeScreen( void )
  132. {
  133.     if( od_send_file("WELCOME_SCREEN") == 0 )
  134.     {
  135.         od_printf( "`bright cyan`VPID v" VERSION ", " __DATE__ ".  " );
  136.         od_printf( "`bright white`The VGA Planets Interface Door.\n\r" );
  137.         od_printf( "`bright blue`Copyright John Kristoff, 1994-96.  " );
  138.         od_printf( "All rights reserved.\n\r" );
  139.         od_printf( "\n\r" );
  140.         PressKey();
  141.     }
  142. }
  143.  
  144.  
  145.  
  146. /* ----------------------------------------------------------------- */
  147. /* This is the function is the backbone of the program from the      */
  148. /* user's perspective.  Every major function is called from here.    */
  149. /* ----------------------------------------------------------------- */
  150.  
  151. void
  152. DoMainMenu( void )
  153. {
  154.     int PlayerNum;                      /* Number of choosen VGAP race */
  155.     int MenuChoice;                     /* Main menu selection         */
  156.  
  157.     PlayerNum = FindPlayer();           /* Is this a new player?       */
  158.  
  159.     do
  160.     {
  161.         if( PlayerNum != NEW_PLAYER )
  162.         {
  163.             ShowTurnStatus( PlayerNum );
  164.         }
  165.  
  166.         MenuChoice = DisplayMainMenu();
  167.         switch( MenuChoice )
  168.         {
  169.                        /* --- [D] Download RST file --- */
  170.  
  171.             case 'D' :  if( PlayerNum != NEW_PLAYER )
  172.                         {
  173.                             TransferFile( PlayerNum, DOWNLOAD );
  174.                         }
  175.                         else
  176.                         {
  177.                             od_printf( "\n\r" );
  178.                             od_printf( "WHAT?!?  You're not in this game yet.\n\r" );
  179.                             PressKey();
  180.                         }
  181.                        break;
  182.  
  183.  
  184.                        /* --- [J] Join the game --- */
  185.  
  186.             case 'J' : if( PlayerNum == NEW_PLAYER )
  187.                        {
  188.                            PlayerNum = JoinGame();
  189.                        }
  190.                        else
  191.                        {
  192.                            od_printf( "\n\r" );
  193.                            od_printf( "WHAT?!?  You can't " );
  194.                            od_printf( "do that.  You're playing The " );
  195.                            od_printf( "%s.  ", RaceName[PlayerNum] );
  196.                            od_printf( "Remeber?\n\r" );
  197.                            PressKey();
  198.                        }
  199.                        break;
  200.  
  201.  
  202.                        /* --- [M] Messages by users --- */
  203.  
  204.             case 'M' : Messages();
  205.                        break;
  206.  
  207.  
  208.                        /* --- [S] Scores display --- */
  209.  
  210.             case 'S' : Scores();
  211.                        break;
  212.  
  213.  
  214.                        /* --- [U] Upload TRN file --- */
  215.  
  216.             case 'U' : if( PlayerNum != NEW_PLAYER )
  217.                        {
  218.                            TransferFile( PlayerNum, UPLOAD );
  219.                        }
  220.                        else
  221.                        {
  222.                            od_printf( "\n\r" );
  223.                            od_printf( "WHAT?!?  You're not in this game yet.\n\r" );
  224.                            PressKey();
  225.                        }
  226.                        break;
  227.  
  228.  
  229.                        /* --- [H] Help file display --- */
  230.  
  231.             case '?' : Help();
  232.                        break;
  233.  
  234.  
  235.                        /* --- [Q] Quit to BBS --- */
  236.  
  237.             case 'Q' : break;
  238.         }
  239.         od_printf( "\n\r" );            /* Blank line after selection  */
  240.     }
  241.     while( MenuChoice != 'Q' );         /* Until user [Q] Quits to BBS */
  242. }
  243.  
  244.  
  245.  
  246. /* ----------------------------------------------------------------- */
  247. /* First check to see if DATA_FILE can be opened.  If it can, check  */
  248. /* to see if the player is in the current game.  If it can't be      */
  249. /* opened, assuse the file doesn't exist and assume a new game.      */
  250. /* ----------------------------------------------------------------- */
  251.  
  252. int
  253. FindPlayer( void )
  254. {
  255.     int PlayerNum       = NEW_PLAYER;   /* Number of choosen VGAP team */
  256.     int Counter         = 0;            /* Loop counter                */
  257.  
  258.     GAMEDATA * GameData = NULL;         /* Point to GAME DATA struct   */
  259.     FILE * fp           = NULL;         /* File pointer to DATA_FILE   */
  260.  
  261.  
  262.     /* --- Open DATA_FILE.  If can't be opened, new game assumed. --- */
  263.  
  264.     if( (fp = fopen(DATA_FILE, "rb")) != NULL )
  265.     {
  266.         GameData = (GAMEDATA *) calloc( 1, sizeof(GAMEDATA) );
  267.         if( GameData == NULL )
  268.         {
  269.             Error( MEM, __LINE__, NULL );
  270.         }
  271.  
  272.         if( fread( GameData, sizeof(GAMEDATA), 1, fp) == NULL )
  273.         {
  274.             Error( READ, __LINE__, DATA_FILE );
  275.         }
  276.  
  277.         fclose( fp );
  278.         if( ferror(fp) )
  279.         {
  280.             Error( CLOSE, __LINE__, DATA_FILE );
  281.         }
  282.  
  283.  
  284.         /* --- Search for user in GAME DATA struct --- */
  285.  
  286.         for( Counter = 0; Counter < MAX_PLAYERS; Counter++ )
  287.         {
  288.             if( strcmp(GameData->Username[Counter], od_control.user_name) == 0 )
  289.             {
  290.                 PlayerNum = Counter;    /* Found! */
  291.                 break;
  292.             }
  293.         }
  294.     }
  295.     return( PlayerNum );
  296. }
  297.  
  298.  
  299.  
  300. /* ----------------------------------------------------------------- */
  301. /* Check to see if this player has uploaded his PLAYERx.TRN yet.  If */
  302. /* not, see if he/she has downloaded the latest PLAYER.RST file.     */
  303. /* A message is displayed to the user depending on the status of     */
  304. /* his/her turn.                                                     */
  305. /* ----------------------------------------------------------------- */
  306.  
  307. void
  308. ShowTurnStatus( int PlayerNum )
  309. {
  310.     char TurnFile[13]   = "";           /* PLAYERx.TRN filename        */
  311.     char ResultFile[13] = "";           /* PLAYERx.RST filename        */
  312.     GAMEDATA * GameData = NULL;         /* Point to GAME DATA struct   */
  313.     FILE * fp           = NULL;         /* File pointer to PLAYERx.TRN */
  314.  
  315.  
  316.     od_printf( "Your team: The %s.  Good luck!\n\r", RaceName[PlayerNum] );
  317.  
  318.  
  319.     /* --- Build turn filename --- */
  320.  
  321.     sprintf( TurnFile, "PLAYER%d.TRN", RaceNum[PlayerNum] );
  322.  
  323.  
  324.     /* --- Let's see if this player has uploaded their turn file --- */
  325.  
  326.     fp = fopen( TurnFile, "rb" );
  327.     if( fp != NULL )
  328.     {
  329.         od_printf( "`bright white`You have uploaded your .TRN file " );
  330.         od_printf( "and are awaiting HOST to be run.\n\r" );
  331.  
  332.         fclose( fp );
  333.         if( ferror(fp) )
  334.         {
  335.             Error( CLOSE, __LINE__, TurnFile );
  336.         }
  337.     }
  338.     else
  339.     {
  340.         /* --- Didn't upload yet, has result file been downloaded? --- */
  341.  
  342.         GameData = (GAMEDATA *) calloc( 1, sizeof(GAMEDATA) );
  343.         if( GameData == NULL )
  344.         {
  345.             Error( MEM, __LINE__, NULL );
  346.         }
  347.  
  348.         /* --- Build result filename --- */
  349.  
  350.         sprintf( ResultFile, "PLAYER%d.RST", RaceNum[PlayerNum] );
  351.  
  352.         fp = fopen( ResultFile, "rb" );
  353.         if( fp != NULL )
  354.         {
  355.             if( fread( GameData, sizeof(GAMEDATA), 1, fp) == NULL )
  356.             {
  357.                 Error( READ, __LINE__, DATA_FILE );
  358.             }
  359.             fclose( fp );
  360.             if( ferror(fp) )
  361.             {
  362.                 Error( CLOSE, __LINE__, TurnFile );
  363.             }
  364.         }
  365.  
  366.         if( GameData->Status[PlayerNum] == FALSE )
  367.         {
  368.             od_printf( "`bright green`We've got a new RST file for you.\n\r" );
  369.         }
  370.         else
  371.         {
  372.             od_printf( "`bright green`We're waiting for your TRN file.\n\r" );
  373.         }
  374.     }
  375.     od_printf( "\n\r" );
  376. }
  377.  
  378.  
  379.  
  380. /* ----------------------------------------------------------------- */
  381. /* Display .ASC/.ANS/.RIP menu if it exists, else display internally */
  382. /* created menu.  Send back the menu option user selected.           */
  383. /* ----------------------------------------------------------------- */
  384.  
  385. int
  386. DisplayMainMenu( void )
  387. {
  388.     int MenuChoice = 0;
  389.  
  390.     od_set_colour( D_GREY, D_BLACK );
  391.     od_printf( "\n\r" );
  392.  
  393.     MenuChoice = od_hotkey_menu( "MAINMENU", "DJMSU?Q", TRUE );
  394.  
  395.     /* --- If menu file didn't exist, display a basic one now --- */
  396.     if( MenuChoice == 0 )
  397.     {
  398.         /* Download */
  399.         od_printf( "  `dark blue`[`bright cyan`D`dark blue`] " );
  400.         od_printf( "`bright blue`Download RST File\n\r" );
  401.  
  402.         /* Upload */
  403.         od_printf( "  `dark blue`[`bright cyan`U`dark blue`] " );
  404.         od_printf( "`bright blue`Upload RST File\n\r" );
  405.  
  406.         /* Join */
  407.         od_printf( "  `dark blue`[`bright cyan`J`dark blue`] " );
  408.         od_printf( "`bright blue`Join the Game\n\r" );
  409.  
  410.         /* Messages */
  411.         od_printf( "  `dark blue`[`bright cyan`M`dark blue`] " );
  412.         od_printf("`bright blue`Messages\n\r" );
  413.  
  414.         /* Scores */
  415.         od_printf( "  `dark blue`[`bright cyan`S`dark blue`] " );
  416.         od_printf( "`bright blue`Scores\n\r" );
  417.  
  418.         /* Help */
  419.         od_printf( "  `dark blue`[`bright cyan`?`dark blue`] " );
  420.         od_printf( "`bright blue`Help\n\r" );
  421.  
  422.         /* Quit */
  423.         od_printf( "  `dark blue`[`bright cyan`Q`dark blue`] " );
  424.         od_printf( "`bright blue`Quit to BBS\n\r" );
  425.  
  426.         od_printf( "\n\r" );
  427.         od_set_colour( L_BLUE, D_BLACK );
  428.         od_printf( "Command:" );
  429.         od_set_colour( D_GREY, D_BLACK );
  430.  
  431.         MenuChoice = od_get_answer( "DJMSU?Q" );
  432.  
  433.         od_printf( "\n\r" );
  434.     }
  435.     return( MenuChoice );
  436. }
  437.  
  438.  
  439.  
  440. /* ----------------------------------------------------------------- */
  441. /* Transfer the file based on user's selected protocol.              */
  442. /* ----------------------------------------------------------------- */
  443.  
  444. void
  445. TransferFile( int PlayerNum, int Direction )
  446. {
  447.     char Protocol;                      /* Protocol selected by user */
  448.     char CommandLine[256];              /* Complete protocol commandline */
  449.     char * SpawnArgs[3];                /* ...spawn..() arguments */
  450.  
  451.     SpawnArgs[0] = "DSZ";               /* Protocol program filename */
  452.     SpawnArgs[1] = CommandLine;         /* Complete commandline */
  453.     SpawnArgs[2] = NULL;                /* NULL terminate arg string */
  454.  
  455.     od_printf( "Select a protocol\n\r" );
  456.     od_printf( "\n\r" );
  457.     od_printf( "`dark blue`[`bright cyan`X`dark blue`] `bright blue`Xmodem\n\r" );
  458.     od_printf( "`dark blue`[`bright cyan`Y`dark blue`] `bright blue`Ymodem\n\r" );
  459.     od_printf( "`dark blue`[`bright cyan`Z`dark blue`] `bright blue`Zmodem\n\r" );
  460.     od_printf( "`dark blue`[`bright red`A`dark blue`] `bright red`Abort\n\r" );
  461.     od_printf( "\n\r" );
  462.     od_printf( "`bright blue`Command:" );
  463.  
  464.     Protocol = od_get_answer( "xyza" );
  465.     if( Protocol != 'a' )
  466.     {
  467.         if( Direction == DOWNLOAD )
  468.         {
  469.             sprintf( CommandLine,
  470.                      "%s port %d s%c PLAYER%c.RST",
  471.                      SpawnArgs[0],
  472.                      od_control.port+1,
  473.                      Protocol,
  474.                      RaceNum[PlayerNum]
  475.                    );
  476.         }
  477.         else
  478.         {
  479.             sprintf( CommandLine,
  480.                      "%s port %d r%c PLAYER%c.TRN",
  481.                      SpawnArgs[0],
  482.                      od_control.port+1,
  483.                      Protocol,
  484.                      RaceNum[PlayerNum]
  485.                    );
  486.         }
  487.  
  488.  
  489.         od_printf( "Start your transfer...\n\r" );
  490.  
  491.         if( od_spawnvpe(P_WAIT, SpawnArgs[0], SpawnArgs, NULL) == 0 )
  492.         {
  493.             od_printf( "`bright green`Transfer successful!\n\r" );
  494.             UpdateDlStatus( PlayerNum );
  495.         }
  496.         else
  497.         {
  498.             od_printf( "`bright red`ERROR: Transfer failed!\n\r" );
  499.         }
  500.         PressKey();
  501.     }
  502. }
  503.  
  504.  
  505.  
  506. /* ----------------------------------------------------------------- */
  507. /* Find the available teams and allow user to select one.  When they */
  508. /* do, write that info to the data file.  Otherwise, exit back to    */
  509. /* the main menu.                                                    */
  510. /* ----------------------------------------------------------------- */
  511.  
  512. int
  513. JoinGame( void )
  514. {
  515.     int PlayerNum = NEW_PLAYER;
  516.     int Available = 0;
  517.     int Counter   = 0;
  518.  
  519.     int MenuChoice;
  520.     char ValidMenuChoices[MAX_PLAYERS + 2] = "";
  521.  
  522.     GAMEDATA * GameData = NULL;
  523.  
  524.     FILE * fp;
  525.  
  526.     /* Allocate memory for game data */
  527.  
  528.     GameData = (GAMEDATA *) calloc( 1, sizeof(GAMEDATA) );
  529.     if( GameData == NULL )
  530.     {
  531.         Error( MEM, __LINE__, NULL );
  532.     }
  533.  
  534.  
  535.     /* Read game data into struct */
  536.  
  537.     fp = fopen( DATA_FILE, "rb" );
  538.     if( fp != NULL )
  539.     {
  540.         if( fread( GameData, sizeof(GAMEDATA), 1, fp) == NULL )
  541.         {
  542.             Error( READ, __LINE__, DATA_FILE );
  543.         }
  544.  
  545.         fclose( fp );
  546.         if( ferror(fp) )
  547.         {
  548.             Error( CLOSE, __LINE__, DATA_FILE );
  549.         }
  550.     }
  551.  
  552.  
  553.     /* Look for openings in the game */
  554.  
  555.     for( Counter = 0; Counter < MAX_PLAYERS; Counter++ )
  556.     {
  557.         if( GameData->Username[Counter][0] == '\0' )
  558.         {
  559.             od_printf( "`bright blue`[`bright white`%c`bright blue`]",
  560.                         RaceChar[Counter] );
  561.             od_printf( " `bright cyan`%-20s", RaceName[Counter] );
  562.             od_printf( " `bright yellow`AVAILABLE\n\r" );
  563.             ValidMenuChoices[Available++] = RaceChar[Counter];
  564.         }
  565.         else
  566.         {
  567.             od_printf( "`white`[%c]",RaceChar[Counter] );
  568.             od_printf( " %-20s", RaceName[Counter] );
  569.             od_printf( " Assigned to %s\n\r",GameData->Username[Counter] );
  570.         }
  571.     }
  572.  
  573.     od_disp_str( "\n\r" );
  574.  
  575.     if( Available == 0 )
  576.     {
  577.         od_printf( "`bright red`No teams Available!\n\r" );
  578.         od_disp_str( "\n\r" );
  579.     }
  580.  
  581.     od_printf( "`bright blue`[`bright white`Q`bright blue`]" );
  582.     od_printf( " `bright cyan`Abort\n\r" );
  583.     od_disp_str( "\n\r" );
  584.     od_printf( "`bright blue`Choose A Team:`bright cyan`" );
  585.  
  586.     strcat( ValidMenuChoices, "Q" );
  587.     MenuChoice = od_get_answer( ValidMenuChoices );
  588.  
  589.     od_printf( "\n\r" );
  590.  
  591.     if( MenuChoice != 'Q' )
  592.     {
  593.         /* Find which team the player selected */
  594.  
  595.         for( Counter = 0; Counter < MAX_PLAYERS; Counter++ )
  596.         {
  597.             if( RaceChar[Counter] == MenuChoice )
  598.             {
  599.                 PlayerNum = Counter;
  600.  
  601.                 fp = fopen( DATA_FILE, "rb" );
  602.                 if( fp != NULL )
  603.                 {
  604.                     if( fread( GameData, sizeof(GAMEDATA), 1, fp) == NULL )
  605.                     {
  606.                         Error( READ, __LINE__, DATA_FILE );
  607.                     }
  608.  
  609.                     fclose( fp );
  610.                     if( ferror(fp) )
  611.                     {
  612.                         Error( CLOSE, __LINE__, DATA_FILE );
  613.                     }
  614.                 }
  615.  
  616.                 strcpy( GameData->Username[Counter], od_control.user_name );
  617.  
  618.                 fp = fopen( DATA_FILE, "wb" );
  619.                 if( fp != NULL )
  620.                 {
  621.                     if( fwrite( GameData, sizeof(GAMEDATA), 1, fp) == NULL )
  622.                     {
  623.                         Error( WRITE, __LINE__, DATA_FILE );
  624.                     }
  625.  
  626.                     fclose( fp );
  627.                     if( ferror(fp) )
  628.                     {
  629.                         Error( CLOSE, __LINE__, DATA_FILE );
  630.                     }
  631.                 }
  632.  
  633.                 break;
  634.             }
  635.         }
  636.     }
  637.     return( PlayerNum );
  638. }
  639.  
  640.  
  641.  
  642. /* ----------------------------------------------------------------- */
  643. /* User messages function.                                           */
  644. /* ----------------------------------------------------------------- */
  645.  
  646. void
  647. Messages( void )
  648. {
  649.     char MessageText[76] = "";
  650.  
  651.     FILE * fp;
  652.  
  653.     od_printf( "\n\r" );
  654.     od_printf( "Babblings of the races...\n\r" );
  655.     od_repeat( '-', 78 );
  656.     od_printf( "\n\r" );
  657.     od_send_file( MSGS_FILE );
  658.     od_printf( "\n\r" );
  659.     od_printf( "Would you like to add to the conversation? [Y/N]" );
  660.  
  661.     if( od_get_answer("YN") == 'Y' )
  662.     {
  663.         od_printf( "\n\r" );
  664.         od_printf( "Enter a one line message.  Max 75 characters.\n\r" );
  665.         od_printf( "Hit <Enter> when done.\n\r" );
  666.         od_printf( ":" );
  667.         od_input_str( MessageText, 75, 32, 127 );
  668.         od_printf( "\n\r" );
  669.  
  670.         if( MessageText[0] != '\0' )
  671.         {
  672.             fp = fopen( MSGS_FILE, "a" );
  673.             if( fp != NULL )
  674.             {
  675.                 if( fprintf(fp, "%s:\n", od_control.user_name) == NULL )
  676.                 {
  677.                     Error( WRITE, __LINE__, MSGS_FILE );
  678.                 }
  679.  
  680.                 if( fprintf(fp, "  %s\n", MessageText) == NULL )
  681.                 {
  682.                     Error( WRITE, __LINE__, MSGS_FILE );
  683.                 }
  684.  
  685.                 fclose( fp );
  686.                 if( ferror(fp) )
  687.                 {
  688.                     Error( CLOSE, __LINE__, MSGS_FILE );
  689.                 }
  690.             }
  691.             PressKey();
  692.         }
  693.     }
  694. }
  695.  
  696.  
  697.  
  698. /* ----------------------------------------------------------------- */
  699. /* Display scores file.  Simple and incomplete.                      */
  700. /* ----------------------------------------------------------------- */
  701.  
  702. void
  703. Scores( void )
  704. {
  705.     od_set_colour( D_GREY, D_BLACK );
  706.     od_printf( "\n\r" );
  707.  
  708.     if( od_send_file(SCORE_FILE) == 0 )
  709.     {
  710.         if( od_send_file("SCORE.LOG") == 0 )
  711.         {
  712.             od_printf( "Couldn't find a score file!\n\r" );
  713.             PressKey();
  714.         }
  715.     }
  716.  
  717.     od_printf( "\n\r" );
  718. }
  719.  
  720.  
  721.  
  722. /* ----------------------------------------------------------------- */
  723. /* Display program help.                                             */
  724. /* ----------------------------------------------------------------- */
  725.  
  726. void
  727. Help( void )
  728. {
  729.     od_printf( "\n\r" );
  730.  
  731.     if( od_send_file(HELP_FILE) == 0 )
  732.     {
  733.         od_printf( "Sorry, no help is available\n\r" );
  734.         PressKey();
  735.     }
  736. }
  737.  
  738.  
  739.  
  740. /* ----------------------------------------------------------------- */
  741. /* If user downloaded the latest .RST file, change data file to      */
  742. /* reflect the change.                                               */
  743. /* ----------------------------------------------------------------- */
  744.  
  745. void
  746. UpdateDlStatus( int RaceNum )
  747. {
  748.     GAMEDATA * GameData = NULL;
  749.  
  750.     FILE * fp;
  751.  
  752.     GameData = (GAMEDATA *) calloc( 1, sizeof(GAMEDATA) );
  753.     if( GameData == NULL )
  754.     {
  755.         Error( MEM, __LINE__, NULL );
  756.     }
  757.  
  758.     fp = fopen( DATA_FILE, "rb" );
  759.     if( fp != NULL )
  760.     {
  761.         if( fread( GameData, sizeof(GAMEDATA), 1, fp) == NULL )
  762.         {
  763.             Error( READ, __LINE__, DATA_FILE );
  764.         }
  765.  
  766.         fclose( fp );
  767.         if( ferror(fp) )
  768.         {
  769.             Error( CLOSE, __LINE__, DATA_FILE );
  770.         }
  771.     }
  772.  
  773.     GameData->Status[RaceNum] = TRUE;
  774.  
  775.     fp = fopen( DATA_FILE, "wb" );
  776.     if( fp != NULL )
  777.     {
  778.         if( fwrite( GameData, sizeof(GAMEDATA), 1, fp) == NULL )
  779.         {
  780.             Error( WRITE, __LINE__, DATA_FILE );
  781.         }
  782.  
  783.         fclose( fp );
  784.         if( ferror(fp) )
  785.         {
  786.             Error( CLOSE, __LINE__, DATA_FILE );
  787.         }
  788.     }
  789. }
  790.  
  791.  
  792.  
  793.  
  794. /* ----------------------------------------------------------------- */
  795. /* Ask a yes/no question and send result back.                       */
  796. /* ----------------------------------------------------------------- */
  797.  
  798. int
  799. Confirm( void )
  800. {
  801.     od_printf( "`bright yellow`Are you sure? (Y/n):" );
  802.     if( od_get_answer("YN") == 'Y' )
  803.     {
  804.         return( YES );
  805.     }
  806.     else
  807.     {
  808.         return( NO );
  809.     }
  810. }
  811.  
  812.  
  813.  
  814. /* ----------------------------------------------------------------- */
  815. /* Pause and wait for a key press before continuing.                 */
  816. /* ----------------------------------------------------------------- */
  817.  
  818. void
  819. PressKey( void )
  820. {
  821.     od_set_colour( L_BLUE, D_BLUE );
  822.     od_printf( "░▒▓" );
  823.     od_set_colour( L_WHITE, D_BLUE );
  824.     od_printf( "PAUSED" );
  825.     od_set_colour( L_BLUE, D_BLUE );
  826.     od_printf( "░▒▓" );
  827.     od_set_colour( D_GREY, D_BLACK );
  828.     od_get_key( TRUE );
  829.     od_repeat( '\b', 26 );
  830.     od_repeat ( ' ', 26 );
  831.     od_repeat( '\b', 26 );
  832. }
  833.