home *** CD-ROM | disk | FTP | other *** search
/ Chip 2011 November / CHIP_2011_11.iso / Programy / Inne / Gry / Atomic_Tanks / Atomic-Tanks-5.1.exe / src / globaldata.cpp < prev    next >
C/C++ Source or Header  |  2011-03-23  |  31KB  |  1,121 lines

  1. /*
  2.  * atanks - obliterate each other with oversize weapons
  3.  * Copyright (C) 2003  Thomas Hudson
  4.  *
  5.  * This program is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU General Public License
  7.  * as published by the Free Software Foundation; either version 2
  8.  * of the License, or (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  * */
  19.  
  20. #include <time.h>
  21. #include "player.h"
  22. #include "globaldata.h"
  23. #include "files.h"
  24. #include "network.h"
  25. #include "team.h"
  26.  
  27. GLOBALDATA::GLOBALDATA ():dataDir(NULL),configDir(NULL),updates(NULL),lastUpdates(NULL),allPlayers(NULL),
  28.     players(NULL),currTank(NULL),saved_game_list(NULL)
  29. {
  30.   tank_status = (char *)calloc(128, sizeof(char));
  31.   if (!tank_status)
  32.     {
  33.       perror ( "globaldata.cpp: Failed allocating memory for tank_status in GLOBALDATA::GLOBALDATA");
  34.       // exit (1);
  35.     }
  36.  
  37.   initialise ();
  38.   language = LANGUAGE_ENGLISH;
  39.   sound = 1.0;
  40.   name_above_tank = TRUE;
  41.   colourDepth = 0;
  42.   client_player = NULL;
  43.   screenWidth = DEFAULT_SCREEN_WIDTH;
  44.   screenHeight = DEFAULT_SCREEN_HEIGHT;
  45.   width_override = height_override = 0;
  46.   temp_screenWidth = screenWidth;
  47.   temp_screenHeight = screenHeight;
  48.   halfWidth = screenWidth / 2;
  49.   halfHeight = screenHeight / 2;
  50.   menuBeginY = (screenHeight - 400) / 2;
  51.   if (menuBeginY < 0) menuBeginY = 0;
  52.   menuEndY = screenHeight - menuBeginY;
  53.   frames_per_second = FRAMES_PER_SECOND;
  54.   numPermanentPlayers = 10;
  55.   violent_death = FALSE;
  56. /*
  57. #ifndef DOS
  58.   cacheCirclesBG = 1;
  59. #endif
  60.  
  61. #ifdef DOS
  62.   cacheCirclesBG = 0;
  63. #endif
  64. */
  65.   ditherGradients = 1;
  66.   detailedLandscape = 0;
  67.   detailedSky = 0;
  68.   colour_theme = COLOUR_THEME_CRISPY;
  69.   startmoney = 15000;
  70.   turntype = TURN_RANDOM;
  71.   skipComputerPlay = SKIP_HUMANS_DEAD;
  72.   // dataDir = DATA_DIR;
  73.   Find_Data_Dir();
  74.   os_mouse = 1.0;
  75.   full_screen = FULL_SCREEN_FALSE;
  76.   interest = 1.25;
  77.   scoreHitUnit = 75;
  78.   scoreSelfHit = 0;
  79.   scoreUnitDestroyBonus = 5000;
  80.   scoreUnitSelfDestroy = 0;
  81.   scoreRoundWinBonus = 10000;
  82.   sellpercent = 0.80;
  83.   game_name[0] = '\0';
  84.   load_game = 0.0;
  85.   campaign_mode = 0.0;
  86.   saved_game_index = 0;
  87.   saved_game_list = NULL;
  88.   max_fire_time = 0.0;
  89.   close_button_pressed = false;
  90.   divide_money = 0.0;
  91.   sound_driver = SOUND_AUTODETECT;
  92.   update_string = NULL;
  93.   check_for_updates = 1.0;
  94.   demo_mode = false;
  95.   env = NULL;
  96.   war_quotes = instructions = ingame = NULL;
  97.   gloat = revenge = retaliation = kamikaze = suicide = NULL;
  98.   client_message= NULL;
  99.  
  100.   updates = new BOX[MAXUPDATES];
  101.   if (!updates)
  102.     {
  103.       perror ( "globaldata.cc: Failed allocating memory for updates in GLOBALDATA::GLOBALDATA");
  104.       // exit (1);
  105.     }
  106.   lastUpdates = new BOX[MAXUPDATES];
  107.   if (!lastUpdates)
  108.     {
  109.       perror ( "globaldata.cc: Failed allocating memory for lastUpdates in GLOBALDATA::GLOBALDATA");
  110.       // exit (1);
  111.     }
  112.   updateCount = 0;
  113.   lastUpdatesCount = 0;
  114.  
  115.   // players = new PLAYER*[MAXPLAYERS];
  116.   players = (PLAYER **) calloc( MAXPLAYERS, sizeof(PLAYER *) );
  117.   if (!players)
  118.     {
  119.       perror ( "globaldata.cc: Failed allocating memory for players in GLOBALDATA::GLOBALDATA");
  120.       // exit (1);
  121.     }
  122.   numPlayers = 0;
  123.   rounds = 5;
  124.  
  125.   allPlayers = (PLAYER**) calloc (1, sizeof (PLAYER*));
  126.   if (!allPlayers)
  127.     {
  128.       fprintf (stderr, "Failed allocating memory for players in globaldata.cc\n");
  129.       // exit (1);
  130.     }
  131.  
  132.   for (int count = 0; count < 360; count++)
  133.     {
  134.       slope[count][0] = sin (count / (180 / PI));
  135.       slope[count][1] = cos (count / (180 / PI));
  136.     }
  137.   slope[270][1] = 0;
  138.   configDir = NULL;
  139.   bIsGameLoaded = true;
  140.   bIsBoxed = false;
  141.   iHumanLessRounds = -1;
  142.   dMaxVelocity = 0.0;    // Will be set in game()
  143. #ifdef DEBUG_AIM_SHOW
  144.   bASD = false; // will be set to true after the first drawing of the map
  145. #endif
  146.   enable_network = 0.0;
  147. #ifdef NETWORK
  148.   listen_port = DEFAULT_LISTEN_PORT;
  149. #endif
  150.   strcpy(server_name, "127.0.0.1");
  151.   strcpy(server_port, "25645");
  152.   play_music = 1.0;
  153.   background_music = NULL;
  154.   music_dir = NULL;
  155.   unicode = NULL;
  156.   regular_font = font;
  157.   draw_background = TRUE;
  158. }
  159.  
  160.  
  161.  
  162. GLOBALDATA::~GLOBALDATA()
  163. {
  164.   int index;
  165.  
  166.   if (tank_status)
  167.   {
  168.       tank_status[0] = 0;
  169.       free(tank_status);
  170.   }
  171.  
  172.   index = 0;
  173.   while (sounds[index])
  174.   {
  175.      destroy_sample(sounds[index]);
  176.   }
  177.   free(sounds);
  178.  
  179.   if (music_dir)
  180.      closedir(music_dir);
  181.   if (unicode)
  182.      destroy_font(unicode);
  183.  
  184.   if (war_quotes) delete war_quotes;
  185.   if (instructions) delete instructions;
  186.   if (ingame) delete ingame;
  187.   if (gloat) delete gloat;
  188.   if (revenge) delete revenge;
  189.   if (retaliation) delete retaliation;
  190.   if (kamikaze) delete kamikaze;
  191.   if (suicide) delete suicide;
  192. }
  193.  
  194.  
  195.  
  196.  
  197. /*
  198. This function saves the global data to a text file. If all goes
  199. well, TRUE is returned, on error, FALSE is returned.
  200. -- Jesse
  201. */
  202. int GLOBALDATA::saveToFile_Text( FILE *file)
  203. {
  204.   if (! file) return FALSE;
  205.  
  206.   setlocale(LC_NUMERIC, "C");
  207.  
  208.   screenWidth = (int) temp_screenWidth;
  209.   screenHeight = (int) temp_screenHeight;
  210.  
  211.   fprintf (file, "*GLOBAL*\n");
  212.  
  213.   fprintf (file, "NUMPLAYERS=%d\n", numPlayers);
  214.   fprintf (file, "ROUNDS=%f\n", rounds);
  215.   fprintf (file, "DITHER=%f\n", ditherGradients);
  216.   fprintf (file, "DETAILEDSKY=%f\n", detailedSky);
  217.   fprintf (file, "DETAILEDLAND=%f\n", detailedLandscape);
  218.   fprintf (file, "STARTMONEY=%f\n", startmoney);
  219.   fprintf (file, "TURNTYPE=%f\n", turntype);
  220.   fprintf (file, "INTEREST=%f\n", interest);
  221.   fprintf (file, "SCOREROUNDWINBONUS=%f\n", scoreRoundWinBonus);
  222.   fprintf (file, "SCOREHITUNIT=%f\n", scoreHitUnit);
  223.   fprintf (file, "SCOREUNITDESTROYBONUS=%f\n", scoreUnitDestroyBonus);
  224.   fprintf (file, "SCOREUNITSELFDESTROY=%f\n", scoreUnitSelfDestroy);
  225.   fprintf (file, "ACCELERATEDAI=%f\n", skipComputerPlay);
  226.   fprintf (file, "SELLPERCENT=%f\n", sellpercent);
  227.   fprintf (file, "ENABLESOUND=%f\n", sound);
  228.   fprintf (file, "SCREENWIDTH=%d\n", screenWidth);
  229.   fprintf (file, "SCREENHEIGHT=%d\n", screenHeight);
  230.   fprintf (file, "OSMOUSE=%f\n", os_mouse);
  231.   fprintf (file, "NUMPERMANENTPLAYERS=%d\n", numPermanentPlayers);
  232.   fprintf (file, "LANGUAGE=%f\n", language);
  233.   fprintf (file, "COLOURTHEME=%f\n", colour_theme);
  234.   fprintf (file, "FRAMES=%f\n", frames_per_second);
  235.   fprintf (file, "VIOLENTDEATH=%f\n", violent_death);
  236.   fprintf (file, "MAXFIRETIME=%f\n", max_fire_time);
  237.   fprintf (file, "DIVIDEMONEY=%f\n", divide_money);
  238.   fprintf (file, "CHECKUPDATES=%f\n", check_for_updates);
  239.   fprintf (file, "NETWORKING=%f\n", enable_network);
  240.   fprintf (file, "LISTENPORT=%f\n", listen_port);
  241.   fprintf (file, "SOUNDDRIVER=%f\n", sound_driver);
  242.   fprintf (file, "PLAYMUSIC=%f\n", play_music);
  243.   fprintf (file, "FULLSCREEN=%f\n", full_screen);
  244.   fprintf (file, "***\n");
  245.   return TRUE;
  246. }
  247.  
  248. /*
  249. This function loads global settings from a text
  250. file. The function returns TRUE on success and FALSE if
  251. any erors are encountered.
  252. -- Jesse
  253. */
  254.  
  255. int GLOBALDATA::loadFromFile_Text (FILE *file)
  256. {
  257.   char line[MAX_CONFIG_LINE];
  258.   int equal_position, line_length;
  259.   char field[MAX_CONFIG_LINE], value[MAX_CONFIG_LINE];
  260.   char *result = NULL;
  261.   bool done = false;
  262.   double sound_bookmark = 1.0;
  263.  
  264.   setlocale(LC_NUMERIC, "C");
  265.   if (! sound)
  266.     sound_bookmark = sound;
  267.  
  268.  // read until we hit line "*ENV*" or "***" or EOF
  269.   do
  270.     {
  271.       result = fgets(line, MAX_CONFIG_LINE, file);
  272.       if (! result)     // eof
  273.         return FALSE;
  274.       if (! strncmp(line, (char *)"***", 3) )     // end of record
  275.         return FALSE;
  276.     }
  277.   while ( strncmp(line, (char *)"*GLOBAL*", 5) );     // read until we hit new record
  278.  
  279.   while ( (result) && (!done) )
  280.     {
  281.       // read a line
  282.       memset(line, '\0', MAX_CONFIG_LINE);
  283.       result = fgets(line, MAX_CONFIG_LINE, file);
  284.       if (result)
  285.         {
  286.           // if we hit end of the record, stop
  287.           if (! strncmp(line, (char *)"***", 3) )
  288.             {
  289.               return TRUE;
  290.             }
  291.           // find equal sign
  292.           line_length = strlen(line);
  293.           // strip newline character
  294.           if ( line[line_length - 1] == '\n')
  295.             {
  296.               line[line_length - 1] = '\0';
  297.               line_length--;
  298.             }
  299.           equal_position = 1;
  300.           while ( ( equal_position < line_length) && (line[equal_position] != '=') )
  301.             equal_position++;
  302.           // make sure we have valid equal sign
  303.  
  304.           if ( equal_position <= line_length )
  305.             {
  306.               // seperate field from value
  307.               memset(field, '\0', MAX_CONFIG_LINE);
  308.               memset(value, '\0', MAX_CONFIG_LINE);
  309.               strncpy(field, line, equal_position);
  310.               strcpy(value, & (line[equal_position + 1]));
  311.               if (! strcasecmp(field, "numplayers") )
  312.                 sscanf(value, "%d", &numPlayers);
  313.               else if (! strcasecmp(field, "rounds") )
  314.                 sscanf(value, "%lf", &rounds);
  315.               else if (! strcasecmp(field, "dither"))
  316.                 sscanf(value, "%lf", &ditherGradients);
  317.               else if (! strcasecmp(field, "detailedsky"))
  318.                 sscanf(value, "%lf", &detailedSky);
  319.               else if (! strcasecmp(field, "detailedland"))
  320.                 sscanf(value, "%lf", &detailedLandscape);
  321.               else if (! strcasecmp(field, "startmoney"))
  322.                 sscanf(value, "%lf", &startmoney);
  323.               else if (! strcasecmp(field, "turntype"))
  324.                 sscanf(value, "%lf", &turntype);
  325.               else if (! strcasecmp(field, "interest"))
  326.                 sscanf(value, "%lf", &interest);
  327.               else if (! strcasecmp(field, "scoreroundwinbonus"))
  328.                 sscanf(value, "%lf", &scoreRoundWinBonus);
  329.               else if (! strcasecmp(field, "scorehitunit"))
  330.                 sscanf(value, "%lf", &scoreHitUnit);
  331.               else if (! strcasecmp(field, "scoreunitdestroybonus"))
  332.                 sscanf(value, "%lf", &scoreUnitDestroyBonus);
  333.               else if (! strcasecmp(field, "scoreunitselfdestroy"))
  334.                 sscanf(value, "%lf", &scoreUnitSelfDestroy);
  335.               else if (! strcasecmp(field, "acceleratedai"))
  336.                 sscanf(value, "%lf", &skipComputerPlay);
  337.               else if (! strcasecmp(field, "sellpercent"))
  338.                 sscanf(value, "%lf", &sellpercent);
  339.               else if (! strcasecmp(field, "enablesound"))
  340.                 sscanf(value, "%lf", &sound);
  341.               else if (! strcasecmp(field, "screenwidth"))
  342.                 sscanf(value, "%d", &screenWidth);
  343.               else if (! strcasecmp(field, "screenheight"))
  344.                 sscanf(value, "%d", &screenHeight);
  345.               else if (! strcasecmp(field, "OSMOUSE"))
  346.                 sscanf(value, "%lf", &os_mouse);
  347.               else if (! strcasecmp(field, "numpermanentplayers"))
  348.                 sscanf(value, "%d", &numPermanentPlayers);
  349.               else if (! strcasecmp(field, "language") )
  350.                 sscanf(value, "%lf", &language);
  351.               else if (! strcasecmp(field, "colourtheme") )
  352.                 sscanf(value, "%lf", &colour_theme);
  353.               else if (! strcasecmp(field, "frames") )
  354.                 sscanf(value, "%lf", &frames_per_second);
  355.               else if (! strcasecmp(field, "violentdeath") )
  356.                 sscanf(value, "%lf", &violent_death);
  357.               else if (! strcasecmp(field, "maxfiretime") )
  358.                 sscanf(value, "%lf", &max_fire_time);
  359.               else if (! strcasecmp(field, "dividemoney") )
  360.                 sscanf(value, "%lf", ÷_money);
  361.               else if (!strcasecmp(field, "checkupdates")) 
  362.                 sscanf(value, "%lf", &check_for_updates);
  363.               else if (!strcasecmp(field, "networking"))
  364.                 sscanf(value, "%lf", &enable_network);
  365.               else if (!strcasecmp(field, "listenport"))
  366.                 sscanf(value, "%lf", &listen_port);
  367.               else if (!strcasecmp(field, "sounddriver"))
  368.                 sscanf(value, "%lf", &sound_driver);
  369.               else if (!strcasecmp(field, "playmusic"))
  370.                 sscanf(value, "%lf", &play_music);
  371.               else if (!strcasecmp(field, "fullscreen"))
  372.                 sscanf(value, "%lf", &full_screen);
  373.       
  374.             }    // end of found field=value line
  375.  
  376.         }     // end of read a line properly
  377.     }     // end of while not done
  378.   if (! sound_bookmark)
  379.     sound = sound_bookmark;
  380.  
  381.   if (width_override)
  382.     screenWidth = width_override;
  383.   if (height_override)
  384.     screenHeight = height_override;
  385.  
  386.   halfWidth = screenWidth / 2;
  387.   halfHeight = screenHeight / 2;
  388.  
  389.   menuBeginY = (screenHeight - 400) / 2;
  390.   if (menuBeginY < 0) menuBeginY = 0;
  391.   menuEndY = screenHeight - menuBeginY;
  392.  
  393.   if (skipComputerPlay > SKIP_HUMANS_DEAD)
  394.     skipComputerPlay = SKIP_HUMANS_DEAD;
  395.  
  396.   return TRUE;
  397. }
  398.  
  399.  
  400.  
  401.  
  402.  
  403. void GLOBALDATA::initialise ()
  404. {
  405.   numTanks = 0;
  406. }
  407.  
  408. void GLOBALDATA::addPlayer (PLAYER *player)
  409. {
  410.   if (numPlayers < MAXPLAYERS)
  411.     {
  412.       players[numPlayers] = player;
  413.       numPlayers++;
  414.       if ((int)player->type == HUMAN_PLAYER)
  415.         {
  416.           numHumanPlayers++;
  417.           computerPlayersOnly = FALSE;
  418.         }
  419.     }
  420. }
  421.  
  422. void GLOBALDATA::removePlayer (PLAYER *player)
  423. {
  424.   int fromCount = 0;
  425.   int toCount = -1;
  426.  
  427.   if ((int)player->type == HUMAN_PLAYER)
  428.     {
  429.       numHumanPlayers--;
  430.       if (numHumanPlayers == 0)
  431.         {
  432.           computerPlayersOnly = TRUE;
  433.         }
  434.     }
  435.  
  436.   while (fromCount < numPlayers)
  437.     {
  438.       if (player != players[fromCount])
  439.         {
  440.           if ((toCount >= 0) && (fromCount > toCount))
  441.             {
  442.               players[toCount]    = players[fromCount];
  443.               players[fromCount]  = NULL;
  444.               toCount++;
  445.             }
  446.         }
  447.       else
  448.         // Position found,1G now move the remaining players down!
  449.         toCount = fromCount;
  450.       fromCount++;
  451.     }
  452.   numPlayers--;
  453. }
  454.  
  455. PLAYER *GLOBALDATA::getNextPlayer (int *playerCount)
  456. {
  457.   (*playerCount)++;
  458.   if (*playerCount >= numPlayers)
  459.     *playerCount = 0;
  460.   return (players[*playerCount]);
  461. }
  462.  
  463. PLAYER *GLOBALDATA::createNewPlayer (ENVIRONMENT *env)
  464. {
  465.   PLAYER **reallocatedPlayers;
  466.   PLAYER *player;
  467.  
  468.   reallocatedPlayers = (PLAYER**)realloc (allPlayers, sizeof (PLAYER*) * (numPermanentPlayers + 1));
  469.   if (reallocatedPlayers != NULL)
  470.     {
  471.       allPlayers = reallocatedPlayers;
  472.     }
  473.   else
  474.     {
  475.       perror ( (char *)"atanks.cc: Failed allocating memory for reallocatedPlayers in GLOBALDATA::createNewPlayer");
  476.       // exit (1);
  477.     }
  478.   player = new PLAYER (this, env);
  479.   if (!player)
  480.     {
  481.       perror ( (char *)"globaldata.cc: Failed allocating memory for player in GLOBALDATA::createNewPlayer");
  482.       // exit (1);
  483.     }
  484.   allPlayers[numPermanentPlayers] = player;
  485.   numPermanentPlayers++;
  486.  
  487.   return (player);
  488. }
  489.  
  490. void GLOBALDATA::destroyPlayer (PLAYER *player)
  491. {
  492.   int fromCount = 0;
  493.   int toCount = 0;
  494.  
  495.   for (; fromCount < numPermanentPlayers; fromCount++)
  496.     {
  497.       if (allPlayers[fromCount] != player)
  498.         {
  499.           allPlayers[toCount] = allPlayers[fromCount];
  500.           toCount++;
  501.         }
  502.     }
  503.   numPermanentPlayers--;
  504. }
  505.  
  506.  
  507.  
  508. // This function returns the path to the
  509. // config directory used by Atanks
  510. char *GLOBALDATA::Get_Config_Path()
  511. {
  512.   char *my_config_dir;
  513.   char *homedir;
  514.  
  515.   // figure out file name
  516.   homedir = getenv(HOME_DIR);
  517.   if (! homedir)
  518.     homedir = (char *)".";
  519.   my_config_dir = (char *) calloc( strlen(homedir) + 24,
  520.                                    sizeof(char) );
  521.   if (! my_config_dir)
  522.     return NULL;
  523.  
  524.   sprintf (my_config_dir, "%s/.atanks", homedir);
  525.   return my_config_dir;
  526.  
  527. }
  528.  
  529.  
  530.  
  531. // This function checks to see if one full second has passed since the
  532. // last time the function was called.
  533. // The function returns true if time has passed. The function
  534. // returns false if time hasn't passed or it was unable to tell
  535. // how much time has passed.
  536. bool GLOBALDATA::Check_Time_Changed()
  537. {
  538.   static time_t last_second = 0;
  539.   time_t current_second;
  540.  
  541.   current_second = time(NULL);
  542.   if ( current_second == last_second )
  543.     return false;
  544.  
  545.   // time has changed
  546.   last_second = current_second;
  547.   return true;
  548. }
  549.  
  550.  
  551.  
  552. /*
  553.  * This function Loads a music file (if there is one available.
  554.  * A pointer to the music file is returned. If no music can
  555.  * be found, then NULL is returned.
  556. */
  557. SAMPLE *GLOBALDATA::Load_Background_Music()
  558. {
  559.     SAMPLE *my_sample = NULL;;
  560.     struct dirent *folder_entry;
  561.  
  562.     // see if we should bother
  563.     if (! play_music)
  564.        return NULL;
  565.  
  566.     // see if we have the music folder open
  567.     if (! music_dir)
  568.     {
  569.         char *buffer = (char *) calloc( strlen(configDir) + 32, sizeof(char) );
  570.         if (! buffer)
  571.            return NULL;
  572.  
  573.         sprintf(buffer, "%s/music", configDir);
  574.         music_dir = opendir(buffer);
  575.         free(buffer);
  576.         if (! music_dir)
  577.            return NULL;
  578.     }
  579.  
  580.     // at this point we should have an open music folder
  581.     // the music folder is closed by global's deconstructor
  582.     // search for files ending in .wav
  583.     folder_entry = readdir(music_dir);
  584.     while ( (folder_entry) && (! my_sample) )
  585.     {
  586.         // we have something, see if it is a wav file
  587.         if ( strstr(folder_entry->d_name, ".wav") )
  588.         {
  589.             char *filename = (char *) calloc( strlen(configDir) + strlen(folder_entry->d_name) + 64, sizeof(char));
  590.             if (filename)
  591.             {
  592.                sprintf(filename, "%s/music/%s", configDir, folder_entry->d_name);
  593.                my_sample = load_sample(filename);
  594.                free(filename);
  595.             }
  596.         }
  597.         if (! my_sample)
  598.            folder_entry = readdir(music_dir);
  599.     }
  600.  
  601.     if (! folder_entry)  // hit end of folder
  602.     {
  603.        closedir(music_dir);
  604.        music_dir = NULL;
  605.     }
  606.  
  607.     return my_sample;
  608. }
  609.  
  610.  
  611.  
  612.  
  613. /*
  614.  * This function sets all variables, which get written to the
  615.  * config file, back to their defaults.
  616.  * -- Jesse
  617.  *  */
  618. void GLOBALDATA::Reset_Options()
  619. {
  620.   ditherGradients = 1;
  621.   detailedLandscape = 0;
  622.   detailedSky = 0;
  623.   interest = 1.25;
  624.   scoreRoundWinBonus = 10000;
  625.   scoreHitUnit = 75;
  626.   scoreUnitDestroyBonus = 5000;
  627.   scoreUnitSelfDestroy = 0;
  628.   sellpercent = 0.80;
  629.   startmoney = 15000;
  630.   turntype = TURN_RANDOM;
  631.   skipComputerPlay = SKIP_HUMANS_DEAD;
  632.   sound = 1.0;
  633.   screenWidth = DEFAULT_SCREEN_WIDTH;
  634.   screenHeight = DEFAULT_SCREEN_HEIGHT;
  635.   os_mouse = 1.0;
  636.   language = LANGUAGE_ENGLISH;
  637.   colour_theme = COLOUR_THEME_CRISPY;
  638.   frames_per_second = FRAMES_PER_SECOND;
  639.   violent_death = FALSE;
  640.   max_fire_time = 0.0;
  641.   divide_money = 0.0;
  642.   check_for_updates = 1.0;
  643.   enable_network = 0.0;
  644.   #ifdef NETWORK
  645.   listen_port = DEFAULT_LISTEN_PORT;
  646.   #endif
  647.   play_music = 1.0;
  648.  
  649.  
  650.  
  651.  
  652. /*
  653.  * This function loads all sounds from the data folder and saves them
  654.  * in an array.
  655.  * The function returns TRUE on success or FALSE if an error happens.
  656. */
  657. int GLOBALDATA::Load_Sounds()
  658. {
  659.    int file_count = 0, array_size = 10;
  660.    char *file_name;
  661.    FILE *my_file;
  662.    SAMPLE *temp_sample;
  663.  
  664.    file_name = (char *) calloc( strlen(dataDir) + 128, sizeof(char) );
  665.    if (! file_name)
  666.      return FALSE;
  667.  
  668.    // allocate space for sound samples
  669.    sounds = (SAMPLE **) calloc(10, sizeof(SAMPLE *) );
  670.    if (! sounds)
  671.    {
  672.        free(file_name);
  673.        printf("Unable to create sound array.\n");
  674.        return FALSE;
  675.    }
  676.  
  677.    // read from directory
  678.    sprintf(file_name, "%s/sound/%d.wav", dataDir, file_count);
  679.    my_file = fopen(file_name, "r");
  680.    while ( (my_file) && (sounds) )
  681.    {
  682.        fclose(my_file);
  683.        temp_sample = load_sample(file_name);
  684.        if (! temp_sample )
  685.          printf("An error occured loading sound file %s\n", file_name);
  686.        sounds[file_count] = temp_sample;
  687.        file_count++; 
  688.    
  689.        // make sure we have enough memory for more samples
  690.        if (file_count >= array_size)
  691.        {
  692.             array_size += 10;
  693.             sounds = (SAMPLE**) realloc(sounds, sizeof(SAMPLE*) * (array_size + 1));
  694.             if (! sounds)
  695.               printf("We just ran out of memory loading sound files.\n");
  696.             else
  697.             {
  698.               // zero out new memory pointers
  699.               int counter;
  700.               for (counter = file_count; counter <= array_size; counter++)
  701.                  sounds[counter] = NULL;
  702.             }
  703.        }
  704.        sprintf(file_name, "%s/sound/%d.wav", dataDir, file_count);
  705.        my_file = fopen(file_name, "r");
  706.    }
  707.  
  708.    free(file_name);
  709.    return TRUE;
  710. }
  711.  
  712.  
  713.  
  714. /*
  715.  * This function loads all the bitmaps needed by th game.
  716.  * Bitmaps are found in a series of sub-folders under the
  717.  * dataDir. The function returns TRUE on success and FALSE
  718.  * if an error occures.
  719. */
  720. int GLOBALDATA::Load_Bitmaps()
  721. {
  722.    int file_group = 0;
  723.    int array_size, file_count;
  724.    char *file_name;
  725.    char sub_folder[64];
  726.    FILE *my_file;
  727.    BITMAP *new_bitmap, **bitmap_array;
  728.  
  729.    file_name = (char *) calloc( strlen(dataDir) + 128, sizeof(char) );
  730.    if (!file_name)
  731.       return FALSE;
  732.  
  733.    while (file_group < 7)
  734.    {
  735.      // set the folder we're looking at
  736.      switch (file_group)
  737.      {
  738.         case 0: strcpy(sub_folder, "title"); break;
  739.         case 1: strcpy(sub_folder, "button"); break;
  740.         case 2: strcpy(sub_folder, "misc"); break;
  741.         case 3: strcpy(sub_folder, "missile"); break;
  742.         case 4: strcpy(sub_folder, "stock"); break;
  743.         case 5: strcpy(sub_folder, "tank"); break;
  744.         case 6: strcpy(sub_folder, "tankgun"); break;
  745.      }
  746.  
  747.      // set up empty array
  748.      array_size = 10;
  749.      bitmap_array = (BITMAP **) calloc(10, sizeof(BITMAP *) );
  750.      if (! bitmap_array)
  751.      {
  752.          printf("Ran out of memory, loading bitmaps.\n");
  753.          free(file_name);
  754.          return FALSE;
  755.      }
  756.  
  757.      // search for files
  758.      file_count = 0;
  759.      sprintf(file_name, "%s/%s/%d.bmp", dataDir, sub_folder, file_count);
  760.      my_file = fopen(file_name, "r");
  761.      while ( (my_file) && (bitmap_array) )
  762.      {
  763.          fclose(my_file);
  764.          new_bitmap = load_bitmap(file_name, NULL);
  765.          if (! new_bitmap)
  766.            printf("An error occured loading bitmap %s\n", file_name);
  767.          bitmap_array[file_count] = new_bitmap;
  768.          file_count++;
  769.  
  770.          // make sure array is large enough
  771.          if ( file_count >= array_size)
  772.          {
  773.             array_size += 10;
  774.             bitmap_array = (BITMAP **) realloc(bitmap_array, sizeof(BITMAP *) * (array_size + 1) );
  775.             if (! bitmap_array)
  776.                printf("Unable to increase array size while loading bitmaps.\n");
  777.             else
  778.             {
  779.                // clear memory
  780.                int count;
  781.                for (count = file_count; count <= array_size; count++)
  782.                   bitmap_array[count] = NULL;
  783.             }
  784.          }
  785.  
  786.          // get next file
  787.          sprintf(file_name, "%s/%s/%d.bmp", dataDir, sub_folder, file_count);
  788.          my_file = fopen(file_name, "r");
  789.      }
  790.  
  791.      // save the new array
  792.      switch (file_group)
  793.      {
  794.         case 0: title = bitmap_array; break;
  795.         case 1: button = bitmap_array; break;
  796.         case 2: misc = bitmap_array; break;
  797.         case 3: missile = bitmap_array; break;
  798.         case 4: stock = bitmap_array; break;
  799.         case 5: tank = bitmap_array; break;
  800.         case 6: tankgun = bitmap_array; break;
  801.      }
  802.  
  803.      file_group++;
  804.    }
  805.  
  806.    free(file_name);
  807.    return TRUE;
  808. }
  809.  
  810.  
  811.  
  812. // This file loads in extra fonts the game requires.
  813. // Fonts should be stored in the datafolder. On
  814. // success the function returns TRUE. When an
  815. // error occures, it returns FALSE.
  816. int GLOBALDATA::Load_Fonts()
  817. {
  818.    char *filename;
  819.  
  820.    filename = (char *) calloc( strlen(dataDir) + 32, sizeof(char));
  821.    if (!filename)
  822.      return FALSE;
  823.  
  824.    sprintf(filename, "%s/unicode.dat", dataDir);
  825.    unicode = load_font(filename, NULL, NULL);
  826.    if (! unicode)
  827.       printf("Unable to load font %s\n", filename);
  828.    free(filename);
  829.  
  830.    if (unicode)
  831.    {
  832.       Change_Font();
  833.       return TRUE;
  834.    }
  835.    else return FALSE;  
  836. }
  837.  
  838.  
  839. // This function selects the font to use. This should be called
  840. // right after a language change.
  841. void GLOBALDATA::Change_Font()
  842. {
  843.     // FONT *temp_font = font;
  844.  
  845.     if ( (language == LANGUAGE_RUSSIAN) || (language == LANGUAGE_GERMAN) )
  846.        font = unicode;
  847.     else
  848.        font = regular_font;
  849.  
  850.     // if (temp_font != font)     // font has changed
  851.     // {
  852.        Load_Weapons_Text(this);
  853.        Load_Text_Files();
  854.     // }
  855. }
  856.  
  857.  
  858.  
  859. void GLOBALDATA::Update_Player_Menu()
  860. {
  861.    int index;
  862.  
  863.    for (index = 0; index < numPermanentPlayers; index++)
  864.    {
  865.        if (allPlayers[index])
  866.           allPlayers[index]->initMenuDesc();
  867.    }
  868. }
  869.  
  870.  
  871.  
  872.  
  873. // This function loads all needed text files, based on
  874. // language, into memory. If a previous text was loaded, it is
  875. // removed from memory first.
  876. int GLOBALDATA::Load_Text_Files()
  877. {
  878.     char *filename;
  879.     char suffix[32];
  880.  
  881.     filename = (char *) calloc( strlen(dataDir) + 64, sizeof(char) );
  882.     if (! filename)
  883.        return FALSE;
  884.  
  885.     if (war_quotes) delete war_quotes;
  886.     if (instructions) delete instructions;
  887.     if (gloat) delete gloat;
  888.     if (revenge) delete revenge;
  889.     if (retaliation) delete retaliation;
  890.     if (suicide) delete suicide;
  891.     if (kamikaze) delete kamikaze;
  892.     if (ingame) delete ingame;
  893.  
  894.     if (language == LANGUAGE_RUSSIAN)
  895.        sprintf(filename, "%s/text/war_quotes_ru.txt", dataDir);
  896.     else if (language == LANGUAGE_SPANISH)
  897.        sprintf(filename, "%s/text/war_quotes_ES.txt", dataDir);
  898.     else
  899.        sprintf(filename, "%s/text/war_quotes.txt", dataDir);
  900.     war_quotes = new TEXTBLOCK(filename);
  901.  
  902.      if (language == LANGUAGE_PORTUGUESE)
  903.         strcpy(suffix, ".pt_BR.txt");
  904.      else if (language == LANGUAGE_FRENCH)
  905.         strcpy(suffix, "_fr.txt");
  906.      else if (language == LANGUAGE_GERMAN)
  907.         strcpy(suffix, "_de.txt");
  908.      else if (language == LANGUAGE_SLOVAK)
  909.         strcpy(suffix, "_sk.txt");
  910.      else if (language == LANGUAGE_RUSSIAN)
  911.         strcpy(suffix, "_ru.txt");
  912.      else if (language == LANGUAGE_SPANISH)
  913.         strcpy(suffix, "_ES.txt");
  914.      else if (language == LANGUAGE_ITALIAN)
  915.         strcpy(suffix, "_it.txt");
  916.      else
  917.         strcpy(suffix, ".txt");       // default to english
  918.  
  919.     sprintf(filename, "%s/text/instr%s", dataDir, suffix);
  920.     instructions = new TEXTBLOCK(filename);
  921.  
  922.     sprintf(filename, "%s/text/gloat%s", dataDir, suffix);
  923.     gloat = new TEXTBLOCK(filename);
  924.     sprintf(filename, "%s/text/revenge%s", dataDir, suffix);
  925.     revenge = new TEXTBLOCK(filename);
  926.     sprintf(filename, "%s/text/retaliation%s", dataDir, suffix);
  927.     retaliation = new TEXTBLOCK(filename);
  928.     sprintf(filename, "%s/text/suicide%s", dataDir, suffix);
  929.     suicide = new TEXTBLOCK(filename);
  930.     sprintf(filename, "%s/text/kamikaze%s", dataDir, suffix);
  931.     kamikaze = new TEXTBLOCK(filename);
  932.     sprintf(filename, "%s/text/ingame%s", dataDir, suffix);
  933.     ingame = new TEXTBLOCK(filename);
  934.  
  935.     free(filename);
  936.     return TRUE;
  937. }
  938.  
  939.  
  940. #ifdef NETWORK
  941. // This function sends a message to all connected game clients.
  942. // Returns TRUE on success or FALSE if the message could not be sent
  943. int GLOBALDATA::Send_To_Clients(char *message)
  944. {
  945.    int index;
  946.    int message_length;
  947.  
  948.    if (! message) return FALSE;
  949.    message_length = strlen(message);
  950.    for (index = 0; index < numPlayers; index++)
  951.    {
  952.        if ( (players[index]) && (players[index]->type == NETWORK_CLIENT) )
  953.           write(players[index]->server_socket, message, message_length);
  954.    }     // done all players
  955.    return TRUE;
  956. }
  957. #endif
  958.  
  959.  
  960.  
  961. // This function tries to figure out where the dataDir is. It
  962. // first checks the current working directory, ".". If the
  963. // proper files are not found, then we try the defined value of
  964. // DATA_DIR.
  965. // On success, TRUE is returned. If no usable directory is
  966. // found, then FALSE is returned.
  967. int GLOBALDATA::Find_Data_Dir()
  968. {
  969.      char *current_dir = NULL;
  970.      FILE *my_phile;
  971.  
  972.      current_dir = (char *) calloc( strlen(DATA_DIR) + 32, sizeof(char));
  973.      if (! current_dir)
  974.         return FALSE;
  975.  
  976.      // try current dir
  977.      strcpy(current_dir, "./unicode.dat");   // local dir
  978.      my_phile = fopen(current_dir, "r");
  979.      if (my_phile)
  980.      {
  981.          fclose(my_phile);
  982.          free(current_dir);
  983.          dataDir = ".";
  984.          return TRUE;
  985.      }
  986.  
  987.     // try system dir
  988.     sprintf(current_dir, "%s/unicode.dat", DATA_DIR);
  989.     my_phile = fopen(current_dir, "r");
  990.     if (my_phile)
  991.     {
  992.         fclose(my_phile);
  993.         free(current_dir);
  994.         dataDir = DATA_DIR;
  995.         return TRUE;
  996.     }
  997.  
  998.     dataDir = DATA_DIR;    // fall back
  999.     free(current_dir);
  1000.     return FALSE;
  1001. }
  1002.  
  1003.  
  1004.  
  1005. /*
  1006. Find the max velocity of a missile
  1007. */
  1008. double GLOBALDATA::Calc_Max_Velocity()
  1009. {
  1010.    dMaxVelocity = (double) MAX_POWER * (100.0 / (double) frames_per_second) / 100.0;
  1011.    return dMaxVelocity; 
  1012. }
  1013.  
  1014.  
  1015.  
  1016. /* See how many humans and networked players we have */
  1017. int GLOBALDATA::Count_Humans()
  1018. {
  1019.      int count;
  1020.      int humans = 0;
  1021.  
  1022.      for (count = 0; count < numPlayers; count++)
  1023.      {
  1024.         if (players[count]->type == HUMAN_PLAYER)
  1025.            humans++;
  1026.         else if (players[count]->type == NETWORK_CLIENT)
  1027.            humans++;
  1028.      }
  1029.  
  1030.      return humans;
  1031. }
  1032.  
  1033.  
  1034. /*
  1035. This function checks to see if there is a single player left standing.
  1036. If there is, that player's index is returned. If there is no winner, then
  1037. -1 is returned. If all tanks have been destroyed, then -2 is returned.
  1038. */
  1039. int GLOBALDATA::Check_For_Winner()
  1040. {
  1041.     int index = 0, tank_count = 0;
  1042.     int last_alive = -1;
  1043.     
  1044.     while ( (index < numPlayers) && (tank_count < 2) )
  1045.     {
  1046.          if (players[index]->tank)
  1047.          {
  1048.             last_alive = index;
  1049.             tank_count++;
  1050.          }
  1051.          index++;
  1052.     }
  1053.  
  1054.     if ( (last_alive >= 0) && (tank_count == 1) )
  1055.        return last_alive;
  1056.     else if (tank_count > 1)
  1057.        return -1;
  1058.     else      // all dead
  1059.        return -2;
  1060. }
  1061.  
  1062.  
  1063. /*
  1064. This function gives credits, score and money to the winner(s).
  1065. */
  1066. void GLOBALDATA::Credit_Winners(int winner)
  1067. {
  1068.    int team_members = 0;
  1069.    int index;
  1070.  
  1071.    if (winner < 0)    // no winner
  1072.       return;
  1073.  
  1074.    if (winner == JEDI_WIN)
  1075.    {
  1076.       for (index = 0; index < numPlayers; index++)
  1077.       {
  1078.           if (players[index]->team == TEAM_JEDI)
  1079.           {
  1080.              players[index]->score++;
  1081.              players[index]->won++;
  1082.              team_members++;
  1083.           }
  1084.       }
  1085.  
  1086.    }
  1087.  
  1088.    else if (winner == SITH_WIN)
  1089.    {
  1090.        for (index = 0; index < numPlayers; index++)
  1091.        {
  1092.           if (players[index]->team == TEAM_SITH)
  1093.           {
  1094.              players[index]->score++;
  1095.              players[index]->won++;
  1096.              team_members++;
  1097.           }
  1098.        }
  1099.    }
  1100.    else // credit single winner
  1101.    {
  1102.       players[winner]->score++;
  1103.       players[winner]->won++;
  1104.       players[winner]->money += (int) scoreRoundWinBonus; 
  1105.    }
  1106.  
  1107.    // team gets their money too
  1108.    if (team_members)
  1109.    {
  1110.        int team_bonus = (int) scoreRoundWinBonus / team_members;
  1111.        for (index = 0; index < numPlayers; index++)
  1112.        {
  1113.            if ( ((winner == JEDI_WIN) && (players[index]->team == TEAM_JEDI) ) ||
  1114.                 ((winner == SITH_WIN) && (players[index]->team == TEAM_SITH) ) )
  1115.                 players[index]->money += team_bonus;
  1116.        }
  1117.    }
  1118. }
  1119.  
  1120.