Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * OpenTyrian: A modern cross-platform port of Tyrian
  3.  * Copyright (C) 2007-2009  The OpenTyrian Development Team
  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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  18.  */
  19. #include "episodes.h"
  20.  
  21. #include "config.h"
  22. #include "file.h"
  23. #include "lvllib.h"
  24. #include "lvlmast.h"
  25. #include "opentyr.h"
  26.  
  27.  
  28. /* MAIN Weapons Data */
  29. JE_WeaponPortType weaponPort;
  30. JE_WeaponType     weapons[WEAP_NUM + 1]; /* [0..weapnum] */
  31.  
  32. /* Items */
  33. JE_PowerType   powerSys;
  34. JE_ShipType    ships;
  35. JE_OptionType  options[OPTION_NUM + 1]; /* [0..optionnum] */
  36. JE_ShieldType  shields;
  37. JE_SpecialType special;
  38.  
  39. /* Enemy data */
  40. JE_EnemyDatType enemyDat;
  41.  
  42. /* EPISODE variables */
  43. JE_byte    initial_episode_num, episodeNum = 0;
  44. JE_boolean episodeAvail[EPISODE_MAX]; /* [1..episodemax] */
  45. char       episode_file[13], cube_file[13];
  46.  
  47. JE_longint episode1DataLoc;
  48.  
  49. /* Tells the game whether the level currently loaded is a bonus level. */
  50. JE_boolean bonusLevel;
  51.  
  52. /* Tells if the game jumped back to Episode 1 */
  53. JE_boolean jumpBackToEpisode1;
  54.  
  55. void JE_loadItemDat( void )
  56. {
  57.         FILE *f = NULL;
  58.        
  59.         if (episodeNum <= 3)
  60.         {
  61.                 f = dir_fopen_die(data_dir(), "tyrian.hdt", "rb");
  62.                 efread(&episode1DataLoc, sizeof(JE_longint), 1, f);
  63.                 fseek(f, episode1DataLoc, SEEK_SET);
  64.         }
  65.         else
  66.         {
  67.                 // episode 4 stores item data in the level file
  68.                 f = dir_fopen_die(data_dir(), levelFile, "rb");
  69.                 fseek(f, lvlPos[lvlNum-1], SEEK_SET);
  70.         }
  71.  
  72.         JE_word itemNum[7]; /* [1..7] */
  73.         efread(&itemNum, sizeof(JE_word), 7, f);
  74.  
  75.         for (int i = 0; i < WEAP_NUM + 1; ++i)
  76.         {
  77.                 efread(&weapons[i].drain,           sizeof(JE_word), 1, f);
  78.                 efread(&weapons[i].shotrepeat,      sizeof(JE_byte), 1, f);
  79.                 efread(&weapons[i].multi,           sizeof(JE_byte), 1, f);
  80.                 efread(&weapons[i].weapani,         sizeof(JE_word), 1, f);
  81.                 efread(&weapons[i].max,             sizeof(JE_byte), 1, f);
  82.                 efread(&weapons[i].tx,              sizeof(JE_byte), 1, f);
  83.                 efread(&weapons[i].ty,              sizeof(JE_byte), 1, f);
  84.                 efread(&weapons[i].aim,             sizeof(JE_byte), 1, f);
  85.                 efread(&weapons[i].attack,          sizeof(JE_byte), 8, f);
  86.                 efread(&weapons[i].del,             sizeof(JE_byte), 8, f);
  87.                 efread(&weapons[i].sx,              sizeof(JE_shortint), 8, f);
  88.                 efread(&weapons[i].sy,              sizeof(JE_shortint), 8, f);
  89.                 efread(&weapons[i].bx,              sizeof(JE_shortint), 8, f);
  90.                 efread(&weapons[i].by,              sizeof(JE_shortint), 8, f);
  91.                 efread(&weapons[i].sg,              sizeof(JE_word), 8, f);
  92.                 efread(&weapons[i].acceleration,    sizeof(JE_shortint), 1, f);
  93.                 efread(&weapons[i].accelerationx,   sizeof(JE_shortint), 1, f);
  94.                 efread(&weapons[i].circlesize,      sizeof(JE_byte), 1, f);
  95.                 efread(&weapons[i].sound,           sizeof(JE_byte), 1, f);
  96.                 efread(&weapons[i].trail,           sizeof(JE_byte), 1, f);
  97.                 efread(&weapons[i].shipblastfilter, sizeof(JE_byte), 1, f);
  98.         }
  99.        
  100.         for (int i = 0; i < PORT_NUM + 1; ++i)
  101.         {
  102.                 fseek(f, 1, SEEK_CUR); /* skip string length */
  103.                 efread(&weaponPort[i].name,        1, 30, f);
  104.                 weaponPort[i].name[30] = '\0';
  105.                 efread(&weaponPort[i].opnum,       sizeof(JE_byte), 1, f);
  106.                 for (int j = 0; j < 2; ++j)
  107.                 {
  108.                         efread(&weaponPort[i].op[j],   sizeof(JE_word), 11, f);
  109.                 }
  110.                 efread(&weaponPort[i].cost,        sizeof(JE_word), 1, f);
  111.                 efread(&weaponPort[i].itemgraphic, sizeof(JE_word), 1, f);
  112.                 efread(&weaponPort[i].poweruse,    sizeof(JE_word), 1, f);
  113.         }
  114.  
  115.         for (int i = 0; i < SPECIAL_NUM + 1; ++i)
  116.         {
  117.                 fseek(f, 1, SEEK_CUR); /* skip string length */
  118.                 efread(&special[i].name,        1, 30, f);
  119.                 special[i].name[30] = '\0';
  120.                 efread(&special[i].itemgraphic, sizeof(JE_word), 1, f);
  121.                 efread(&special[i].pwr,         sizeof(JE_byte), 1, f);
  122.                 efread(&special[i].stype,       sizeof(JE_byte), 1, f);
  123.                 efread(&special[i].wpn,         sizeof(JE_word), 1, f);
  124.         }
  125.  
  126.         for (int i = 0; i < POWER_NUM + 1; ++i)
  127.         {
  128.                 fseek(f, 1, SEEK_CUR); /* skip string length */
  129.                 efread(&powerSys[i].name,        1, 30, f);
  130.                 powerSys[i].name[30] = '\0';
  131.                 efread(&powerSys[i].itemgraphic, sizeof(JE_word), 1, f);
  132.                 efread(&powerSys[i].power,       sizeof(JE_shortint), 1, f);
  133.                 efread(&powerSys[i].speed,       sizeof(JE_byte), 1, f);
  134.                 efread(&powerSys[i].cost,        sizeof(JE_word), 1, f);
  135.         }
  136.  
  137.         for (int i = 0; i < SHIP_NUM + 1; ++i)
  138.         {
  139.                 fseek(f, 1, SEEK_CUR); /* skip string length */
  140.                 efread(&ships[i].name,           1, 30, f);
  141.                 ships[i].name[30] = '\0';
  142.                 efread(&ships[i].shipgraphic,    sizeof(JE_word), 1, f);
  143.                 efread(&ships[i].itemgraphic,    sizeof(JE_word), 1, f);
  144.                 efread(&ships[i].ani,            sizeof(JE_byte), 1, f);
  145.                 efread(&ships[i].spd,            sizeof(JE_shortint), 1, f);
  146.                 efread(&ships[i].dmg,            sizeof(JE_byte), 1, f);
  147.                 efread(&ships[i].cost,           sizeof(JE_word), 1, f);
  148.                 efread(&ships[i].bigshipgraphic, sizeof(JE_byte), 1, f);
  149.         }
  150.  
  151.         for (int i = 0; i < OPTION_NUM + 1; ++i)
  152.         {
  153.                 fseek(f, 1, SEEK_CUR); /* skip string length */
  154.                 efread(&options[i].name,        1, 30, f);
  155.                 options[i].name[30] = '\0';
  156.                 efread(&options[i].pwr,         sizeof(JE_byte), 1, f);
  157.                 efread(&options[i].itemgraphic, sizeof(JE_word), 1, f);
  158.                 efread(&options[i].cost,        sizeof(JE_word), 1, f);
  159.                 efread(&options[i].tr,          sizeof(JE_byte), 1, f);
  160.                 efread(&options[i].option,      sizeof(JE_byte), 1, f);
  161.                 efread(&options[i].opspd,       sizeof(JE_shortint), 1, f);
  162.                 efread(&options[i].ani,         sizeof(JE_byte), 1, f);
  163.                 efread(&options[i].gr,          sizeof(JE_word), 20, f);
  164.                 efread(&options[i].wport,       sizeof(JE_byte), 1, f);
  165.                 efread(&options[i].wpnum,       sizeof(JE_word), 1, f);
  166.                 efread(&options[i].ammo,        sizeof(JE_byte), 1, f);
  167.                 efread(&options[i].stop,        1, 1, f); /* override sizeof(JE_boolean) */
  168.                 efread(&options[i].icongr,      sizeof(JE_byte), 1, f);
  169.         }
  170.  
  171.         for (int i = 0; i < SHIELD_NUM + 1; ++i)
  172.         {
  173.                 fseek(f, 1, SEEK_CUR); /* skip string length */
  174.                 efread(&shields[i].name,        1, 30, f);
  175.                 shields[i].name[30] = '\0';
  176.                 efread(&shields[i].tpwr,        sizeof(JE_byte), 1, f);
  177.                 efread(&shields[i].mpwr,        sizeof(JE_byte), 1, f);
  178.                 efread(&shields[i].itemgraphic, sizeof(JE_word), 1, f);
  179.                 efread(&shields[i].cost,        sizeof(JE_word), 1, f);
  180.         }
  181.        
  182.         for (int i = 0; i < ENEMY_NUM + 1; ++i)
  183.         {
  184.                 efread(&enemyDat[i].ani,           sizeof(JE_byte), 1, f);
  185.                 efread(&enemyDat[i].tur,           sizeof(JE_byte), 3, f);
  186.                 efread(&enemyDat[i].freq,          sizeof(JE_byte), 3, f);
  187.                 efread(&enemyDat[i].xmove,         sizeof(JE_shortint), 1, f);
  188.                 efread(&enemyDat[i].ymove,         sizeof(JE_shortint), 1, f);
  189.                 efread(&enemyDat[i].xaccel,        sizeof(JE_shortint), 1, f);
  190.                 efread(&enemyDat[i].yaccel,        sizeof(JE_shortint), 1, f);
  191.                 efread(&enemyDat[i].xcaccel,       sizeof(JE_shortint), 1, f);
  192.                 efread(&enemyDat[i].ycaccel,       sizeof(JE_shortint), 1, f);
  193.                 efread(&enemyDat[i].startx,        sizeof(JE_integer), 1, f);
  194.                 efread(&enemyDat[i].starty,        sizeof(JE_integer), 1, f);
  195.                 efread(&enemyDat[i].startxc,       sizeof(JE_shortint), 1, f);
  196.                 efread(&enemyDat[i].startyc,       sizeof(JE_shortint), 1, f);
  197.                 efread(&enemyDat[i].armor,         sizeof(JE_byte), 1, f);
  198.                 efread(&enemyDat[i].esize,         sizeof(JE_byte), 1, f);
  199.                 efread(&enemyDat[i].egraphic,      sizeof(JE_word), 20, f);
  200.                 efread(&enemyDat[i].explosiontype, sizeof(JE_byte), 1, f);
  201.                 efread(&enemyDat[i].animate,       sizeof(JE_byte), 1, f);
  202.                 efread(&enemyDat[i].shapebank,     sizeof(JE_byte), 1, f);
  203.                 efread(&enemyDat[i].xrev,          sizeof(JE_shortint), 1, f);
  204.                 efread(&enemyDat[i].yrev,          sizeof(JE_shortint), 1, f);
  205.                 efread(&enemyDat[i].dgr,           sizeof(JE_word), 1, f);
  206.                 efread(&enemyDat[i].dlevel,        sizeof(JE_shortint), 1, f);
  207.                 efread(&enemyDat[i].dani,          sizeof(JE_shortint), 1, f);
  208.                 efread(&enemyDat[i].elaunchfreq,   sizeof(JE_byte), 1, f);
  209.                 efread(&enemyDat[i].elaunchtype,   sizeof(JE_word), 1, f);
  210.                 efread(&enemyDat[i].value,         sizeof(JE_integer), 1, f);
  211.                 efread(&enemyDat[i].eenemydie,     sizeof(JE_word), 1, f);
  212.         }
  213.        
  214.         fclose(f);
  215. }
  216.  
  217. void JE_initEpisode( JE_byte newEpisode )
  218. {
  219.         if (newEpisode == episodeNum)
  220.                 return;
  221.        
  222.         episodeNum = newEpisode;
  223.        
  224.         sprintf(levelFile,    "tyrian%d.lvl",  episodeNum);
  225.         sprintf(cube_file,    "cubetxt%d.dat", episodeNum);
  226.         sprintf(episode_file, "levels%d.dat",  episodeNum);
  227.        
  228.         JE_analyzeLevel();
  229.         JE_loadItemDat();
  230. }
  231.  
  232. void JE_scanForEpisodes( void )
  233. {
  234.         for (int i = 0; i < EPISODE_MAX; ++i)
  235.         {
  236.                 char ep_file[20];
  237.                 snprintf(ep_file, sizeof(ep_file), "tyrian%d.lvl", i + 1);
  238.                 episodeAvail[i] = dir_file_exists(data_dir(), ep_file);
  239.         }
  240. }
  241.  
  242. unsigned int JE_findNextEpisode( void )
  243. {
  244.         unsigned int newEpisode = episodeNum;
  245.        
  246.         jumpBackToEpisode1 = false;
  247.        
  248.         while (true)
  249.         {
  250.                 newEpisode++;
  251.                
  252.                 if (newEpisode > EPISODE_MAX)
  253.                 {
  254.                         newEpisode = 1;
  255.                         jumpBackToEpisode1 = true;
  256.                         gameHasRepeated = true;
  257.                 }
  258.                
  259.                 if (episodeAvail[newEpisode-1] || newEpisode == episodeNum)
  260.                 {
  261.                         break;
  262.                 }
  263.         }
  264.        
  265.         return newEpisode;
  266. }
  267.  
  268.