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 "helptext.h"
  20.  
  21. #include "config.h"
  22. #include "episodes.h"
  23. #include "file.h"
  24. #include "fonthand.h"
  25. #include "menus.h"
  26. #include "opentyr.h"
  27. #include "video.h"
  28.  
  29. #include <assert.h>
  30. #include <string.h>
  31.  
  32.  
  33. const JE_byte menuHelp[MENU_MAX][11] = /* [1..maxmenu, 1..11] */
  34. {
  35.         {  1, 34,  2,  3,  4,  5,                  0, 0, 0, 0, 0 },
  36.         {  6,  7,  8,  9, 10, 11, 11, 12,                0, 0, 0 },
  37.         { 13, 14, 15, 15, 16, 17, 12,                 0, 0, 0, 0 },
  38.         {                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  39.         {                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  40.         {                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  41.         {                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  42.         {                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  43.         {                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  44.         {  4, 30, 30,  3,  5,                   0, 0, 0, 0, 0, 0 },
  45.         {                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  46.         { 16, 17, 15, 15, 12,                   0, 0, 0, 0, 0, 0 },
  47.         { 31, 31, 31, 31, 32, 12,                  0, 0, 0, 0, 0 },
  48.         {  4, 34,  3,  5,                    0, 0, 0, 0, 0, 0, 0 }
  49. };
  50.  
  51. JE_byte verticalHeight = 7;
  52. JE_byte helpBoxColor = 12;
  53. JE_byte helpBoxBrightness = 1;
  54. JE_byte helpBoxShadeType = FULL_SHADE;
  55.  
  56. char helpTxt[39][231];                                                   /* [1..39] of string [230] */
  57. char pName[21][16];                                                      /* [1..21] of string [15] */
  58. char miscText[HELPTEXT_MISCTEXT_COUNT][42];                              /* [1..68] of string [41] */
  59. char miscTextB[HELPTEXT_MISCTEXTB_COUNT][HELPTEXT_MISCTEXTB_SIZE];       /* [1..5] of string [10] */
  60. char keyName[8][18];                                                     /* [1..8] of string [17] */
  61. char menuText[7][HELPTEXT_MENUTEXT_SIZE];                                /* [1..7] of string [20] */
  62. char outputs[9][31];                                                     /* [1..9] of string [30] */
  63. char topicName[6][21];                                                   /* [1..6] of string [20] */
  64. char mainMenuHelp[HELPTEXT_MAINMENUHELP_COUNT][66];                      /* [1..34] of string [65] */
  65. char inGameText[6][21];                                                  /* [1..6] of string [20] */
  66. char detailLevel[6][13];                                                 /* [1..6] of string [12] */
  67. char gameSpeedText[5][13];                                               /* [1..5] of string [12] */
  68. char inputDevices[3][13];                                                /* [1..3] of string [12] */
  69. char networkText[HELPTEXT_NETWORKTEXT_COUNT][HELPTEXT_NETWORKTEXT_SIZE]; /* [1..4] of string [20] */
  70. char difficultyNameB[11][21];                                            /* [0..9] of string [20] */
  71. char joyButtonNames[5][21];                                              /* [1..5] of string [20] */
  72. char superShips[HELPTEXT_SUPERSHIPS_COUNT][26];                          /* [0..10] of string [25] */
  73. char specialName[HELPTEXT_SPECIALNAME_COUNT][10];                        /* [1..9] of string [9] */
  74. char destructHelp[25][22];                                               /* [1..25] of string [21] */
  75. char weaponNames[17][17];                                                /* [1..17] of string [16] */
  76. char destructModeName[DESTRUCT_MODES][13];                               /* [1..destructmodes] of string [12] */
  77. char shipInfo[HELPTEXT_SHIPINFO_COUNT][2][256];                          /* [1..13, 1..2] of string */
  78. char menuInt[MENU_MAX+1][11][18];                                        /* [0..14, 1..11] of string [17] */
  79.  
  80.  
  81. void decrypt_pascal_string( char *s, int len )
  82. {
  83.         static const unsigned char crypt_key[] = { 204, 129, 63, 255, 71, 19, 25, 62, 1, 99 };
  84.  
  85.         for (int i = len - 1; i >= 0; --i)
  86.         {
  87.                 s[i] ^= crypt_key[i % sizeof(crypt_key)];
  88.                 if (i > 0)
  89.                         s[i] ^= s[i - 1];
  90.         }
  91. }
  92.  
  93. void read_encrypted_pascal_string( char *s, int size, FILE *f )
  94. {
  95.         int len = getc(f);
  96.         if (len != EOF)
  97.         {
  98.                 int skip = MAX((len + 1) - size, 0);
  99.                 assert(skip == 0);
  100.  
  101.                 len -= skip;
  102.                 efread(s, 1, len, f);
  103.                 if (size > 0)
  104.                         s[len] = '\0';
  105.                 fseek(f, skip, SEEK_CUR);
  106.  
  107.                 decrypt_pascal_string(s, len);
  108.         }
  109. }
  110.  
  111. void skip_pascal_string( FILE *f )
  112. {
  113.         int len = getc(f);
  114.         fseek(f, len, SEEK_CUR);
  115. }
  116.  
  117. void JE_helpBox( SDL_Surface *screen,  int x, int y, const char *message, unsigned int boxwidth )
  118. {
  119.         JE_byte startpos, endpos, pos;
  120.         JE_boolean endstring;
  121.  
  122.         char substring[256];
  123.  
  124.         if (strlen(message) == 0)
  125.         {
  126.                 return;
  127.         }
  128.  
  129.         pos = 1;
  130.         endpos = 0;
  131.         endstring = false;
  132.  
  133.         do
  134.         {
  135.                 startpos = endpos + 1;
  136.  
  137.                 do
  138.                 {
  139.                         endpos = pos;
  140.                         do
  141.                         {
  142.                                 pos++;
  143.                                 if (pos == strlen(message))
  144.                                 {
  145.                                         endstring = true;
  146.                                         if ((unsigned)(pos - startpos) < boxwidth)
  147.                                         {
  148.                                                 endpos = pos + 1;
  149.                                         }
  150.                                 }
  151.  
  152.                         } while (!(message[pos-1] == ' ' || endstring));
  153.  
  154.                 } while (!((unsigned)(pos - startpos) > boxwidth || endstring));
  155.  
  156.                 SDL_strlcpy(substring, message + startpos - 1, MIN((size_t)(endpos - startpos + 1), sizeof(substring)));
  157.                 JE_textShade(screen, x, y, substring, helpBoxColor, helpBoxBrightness, helpBoxShadeType);
  158.  
  159.                 y += verticalHeight;
  160.  
  161.         } while (!endstring);
  162.  
  163.         if (endpos != pos + 1)
  164.         {
  165.                 JE_textShade(screen, x, y, message + endpos, helpBoxColor, helpBoxBrightness, helpBoxShadeType);
  166.         }
  167.  
  168.         helpBoxColor = 12;
  169.         helpBoxShadeType = FULL_SHADE;
  170. }
  171.  
  172. void JE_HBox( SDL_Surface *screen, int x, int y, unsigned int  messagenum, unsigned int boxwidth )
  173. {
  174.         JE_helpBox(screen, x, y, helpTxt[messagenum-1], boxwidth);
  175. }
  176.  
  177. void JE_loadHelpText( void )
  178. {
  179.         const unsigned int menuInt_entries[MENU_MAX + 1] = { -1, 7, 9, 8, -1, -1, 11, -1, -1, -1, 6, 4, 6, 7, 5 };
  180.        
  181.         FILE *f = dir_fopen_die(data_dir(), "tyrian.hdt", "rb");
  182.         efread(&episode1DataLoc, sizeof(JE_longint), 1, f);
  183.  
  184.         /*Online Help*/
  185.         skip_pascal_string(f);
  186.         for (unsigned int i = 0; i < COUNTOF(helpTxt); ++i)
  187.                 read_encrypted_pascal_string(helpTxt[i], sizeof(helpTxt[i]), f);
  188.         skip_pascal_string(f);
  189.  
  190.         /*Planet names*/
  191.         skip_pascal_string(f);
  192.         for (unsigned int i = 0; i < COUNTOF(pName); ++i)
  193.                 read_encrypted_pascal_string(pName[i], sizeof(pName[i]), f);
  194.         skip_pascal_string(f);
  195.  
  196.         /*Miscellaneous text*/
  197.         skip_pascal_string(f);
  198.         for (unsigned int i = 0; i < COUNTOF(miscText); ++i)
  199.                 read_encrypted_pascal_string(miscText[i], sizeof(miscText[i]), f);
  200.         skip_pascal_string(f);
  201.  
  202.         /*Little Miscellaneous text*/
  203.         skip_pascal_string(f);
  204.         for (unsigned int i = 0; i < COUNTOF(miscTextB); ++i)
  205.                 read_encrypted_pascal_string(miscTextB[i], sizeof(miscTextB[i]), f);
  206.         skip_pascal_string(f);
  207.  
  208.         /*Key names*/
  209.         skip_pascal_string(f);
  210.         for (unsigned int i = 0; i < menuInt_entries[6]; ++i)
  211.                 read_encrypted_pascal_string(menuInt[6][i], sizeof(menuInt[6][i]), f);
  212.         skip_pascal_string(f);
  213.  
  214.         /*Main Menu*/
  215.         skip_pascal_string(f);
  216.         for (unsigned int i = 0; i < COUNTOF(menuText); ++i)
  217.                 read_encrypted_pascal_string(menuText[i], sizeof(menuText[i]), f);
  218.         skip_pascal_string(f);
  219.  
  220.         /*Event text*/
  221.         skip_pascal_string(f);
  222.         for (unsigned int i = 0; i < COUNTOF(outputs); ++i)
  223.                 read_encrypted_pascal_string(outputs[i], sizeof(outputs[i]), f);
  224.         skip_pascal_string(f);
  225.  
  226.         /*Help topics*/
  227.         skip_pascal_string(f);
  228.         for (unsigned int i = 0; i < COUNTOF(topicName); ++i)
  229.                 read_encrypted_pascal_string(topicName[i], sizeof(topicName[i]), f);
  230.         skip_pascal_string(f);
  231.  
  232.         /*Main Menu Help*/
  233.         skip_pascal_string(f);
  234.         for (unsigned int i = 0; i < COUNTOF(mainMenuHelp); ++i)
  235.                 read_encrypted_pascal_string(mainMenuHelp[i], sizeof(mainMenuHelp[i]), f);
  236.         skip_pascal_string(f);
  237.  
  238.         /*Menu 1 - Main*/
  239.         skip_pascal_string(f);
  240.         for (unsigned int i = 0; i < menuInt_entries[1]; ++i)
  241.                 read_encrypted_pascal_string(menuInt[1][i], sizeof(menuInt[1][i]), f);
  242.         skip_pascal_string(f);
  243.  
  244.         /*Menu 2 - Items*/
  245.         skip_pascal_string(f);
  246.         for (unsigned int i = 0; i < menuInt_entries[2]; ++i)
  247.                 read_encrypted_pascal_string(menuInt[2][i], sizeof(menuInt[2][i]), f);
  248.         skip_pascal_string(f);
  249.  
  250.         /*Menu 3 - Options*/
  251.         skip_pascal_string(f);
  252.         for (unsigned int i = 0; i < menuInt_entries[3]; ++i)
  253.                 read_encrypted_pascal_string(menuInt[3][i], sizeof(menuInt[3][i]), f);
  254.         skip_pascal_string(f);
  255.  
  256.         /*InGame Menu*/
  257.         skip_pascal_string(f);
  258.         for (unsigned int i = 0; i < COUNTOF(inGameText); ++i)
  259.                 read_encrypted_pascal_string(inGameText[i], sizeof(inGameText[i]), f);
  260.         skip_pascal_string(f);
  261.  
  262.         /*Detail Level*/
  263.         skip_pascal_string(f);
  264.         for (unsigned int i = 0; i < COUNTOF(detailLevel); ++i)
  265.                 read_encrypted_pascal_string(detailLevel[i], sizeof(detailLevel[i]), f);
  266.         skip_pascal_string(f);
  267.  
  268.         /*Game speed text*/
  269.         skip_pascal_string(f);
  270.         for (unsigned int i = 0; i < COUNTOF(gameSpeedText); ++i)
  271.                 read_encrypted_pascal_string(gameSpeedText[i], sizeof(gameSpeedText[i]), f);
  272.         skip_pascal_string(f);
  273.  
  274.         // episode names
  275.         skip_pascal_string(f);
  276.         for (unsigned int i = 0; i < COUNTOF(episode_name); ++i)
  277.                 read_encrypted_pascal_string(episode_name[i], sizeof(episode_name[i]), f);
  278.         skip_pascal_string(f);
  279.  
  280.         // difficulty names
  281.         skip_pascal_string(f);
  282.         for (unsigned int i = 0; i < COUNTOF(difficulty_name); ++i)
  283.                 read_encrypted_pascal_string(difficulty_name[i], sizeof(difficulty_name[i]), f);
  284.         skip_pascal_string(f);
  285.  
  286.         // gameplay mode names
  287.         skip_pascal_string(f);
  288.         for (unsigned int i = 0; i < COUNTOF(gameplay_name); ++i)
  289.                 read_encrypted_pascal_string(gameplay_name[i], sizeof(gameplay_name[i]), f);
  290.         skip_pascal_string(f);
  291.  
  292.         /*Menu 10 - 2Player Main*/
  293.         skip_pascal_string(f);
  294.         for (unsigned int i = 0; i < menuInt_entries[10]; ++i)
  295.                 read_encrypted_pascal_string(menuInt[10][i], sizeof(menuInt[10][i]), f);
  296.         skip_pascal_string(f);
  297.  
  298.         /*Input Devices*/
  299.         skip_pascal_string(f);
  300.         for (unsigned int i = 0; i < COUNTOF(inputDevices); ++i)
  301.                 read_encrypted_pascal_string(inputDevices[i], sizeof(inputDevices[i]), f);
  302.         skip_pascal_string(f);
  303.  
  304.         /*Network text*/
  305.         skip_pascal_string(f);
  306.         for (unsigned int i = 0; i < COUNTOF(networkText); ++i)
  307.                 read_encrypted_pascal_string(networkText[i], sizeof(networkText[i]), f);
  308.         skip_pascal_string(f);
  309.  
  310.         /*Menu 11 - 2Player Network*/
  311.         skip_pascal_string(f);
  312.         for (unsigned int i = 0; i < menuInt_entries[11]; ++i)
  313.                 read_encrypted_pascal_string(menuInt[11][i], sizeof(menuInt[11][i]), f);
  314.         skip_pascal_string(f);
  315.  
  316.         /*HighScore Difficulty Names*/
  317.         skip_pascal_string(f);
  318.         for (unsigned int i = 0; i < COUNTOF(difficultyNameB); ++i)
  319.                 read_encrypted_pascal_string(difficultyNameB[i], sizeof(difficultyNameB[i]), f);
  320.         skip_pascal_string(f);
  321.  
  322.         /*Menu 12 - Network Options*/
  323.         skip_pascal_string(f);
  324.         for (unsigned int i = 0; i < menuInt_entries[12]; ++i)
  325.                 read_encrypted_pascal_string(menuInt[12][i], sizeof(menuInt[12][i]), f);
  326.         skip_pascal_string(f);
  327.  
  328.         /*Menu 13 - Joystick*/
  329.         skip_pascal_string(f);
  330.         for (unsigned int i = 0; i < menuInt_entries[13]; ++i)
  331.                 read_encrypted_pascal_string(menuInt[13][i], sizeof(menuInt[13][i]), f);
  332.         skip_pascal_string(f);
  333.  
  334.         /*Joystick Button Assignments*/
  335.         skip_pascal_string(f);
  336.         for (unsigned int i = 0; i < COUNTOF(joyButtonNames); ++i)
  337.                 read_encrypted_pascal_string(joyButtonNames[i], sizeof(joyButtonNames[i]), f);
  338.         skip_pascal_string(f);
  339.  
  340.         /*SuperShips - For Super Arcade Mode*/
  341.         skip_pascal_string(f);
  342.         for (unsigned int i = 0; i < COUNTOF(superShips); ++i)
  343.                 read_encrypted_pascal_string(superShips[i], sizeof(superShips[i]), f);
  344.         skip_pascal_string(f);
  345.  
  346.         /*SuperShips - For Super Arcade Mode*/
  347.         skip_pascal_string(f);
  348.         for (unsigned int i = 0; i < COUNTOF(specialName); ++i)
  349.                 read_encrypted_pascal_string(specialName[i], sizeof(specialName[i]), f);
  350.         skip_pascal_string(f);
  351.  
  352.         /*Secret DESTRUCT game*/
  353.         skip_pascal_string(f);
  354.         for (unsigned int i = 0; i < COUNTOF(destructHelp); ++i)
  355.                 read_encrypted_pascal_string(destructHelp[i], sizeof(destructHelp[i]), f);
  356.         skip_pascal_string(f);
  357.  
  358.         /*Secret DESTRUCT weapons*/
  359.         skip_pascal_string(f);
  360.         for (unsigned int i = 0; i < COUNTOF(weaponNames); ++i)
  361.                 read_encrypted_pascal_string(weaponNames[i], sizeof(weaponNames[i]), f);
  362.         skip_pascal_string(f);
  363.  
  364.         /*Secret DESTRUCT modes*/
  365.         skip_pascal_string(f);
  366.         for (unsigned int i = 0; i < COUNTOF(destructModeName); ++i)
  367.                 read_encrypted_pascal_string(destructModeName[i], sizeof(destructModeName[i]), f);
  368.         skip_pascal_string(f);
  369.  
  370.         /*NEW: Ship Info*/
  371.         skip_pascal_string(f);
  372.         for (unsigned int i = 0; i < COUNTOF(shipInfo); ++i)
  373.         {
  374.                 read_encrypted_pascal_string(shipInfo[i][0], sizeof(shipInfo[i][0]), f);
  375.                 read_encrypted_pascal_string(shipInfo[i][1], sizeof(shipInfo[i][1]), f);
  376.         }
  377.         skip_pascal_string(f);
  378.        
  379.         fclose(f);
  380. }
  381.  
  382.