home *** CD-ROM | disk | FTP | other *** search
/ GameStar Special 2004 August / GSSH0804.iso / Rollenspiele / SwordOfFargoal / fargoal20030731b.exe / fargoal / src / menu.c < prev    next >
C/C++ Source or Header  |  2003-07-31  |  18KB  |  918 lines

  1. #include "main.h"
  2. #include "menu.h"
  3. #include "game.h"
  4. #include "gfx.h"
  5. #include "map.h"
  6. #include "scroller.h"
  7. #include "credits.h"
  8.  
  9. int menu_active = 1;
  10.  
  11. static int update_main = 0;
  12. static int update_top = 0;
  13. static int update_bottom = 0;
  14.  
  15. static int menu_selected = 0;
  16. char const **menu_text;
  17. void (*menu) (int);
  18.  
  19. int menu_sub_selection[100];
  20. int menu_sub_highlight = 0;
  21. int ugly_hacking = 0;
  22.  
  23. static void menu_main (int);
  24. char const *menu_main_text[] =
  25. {
  26.     "Start/Continue quest",
  27.     " ",
  28.     "Continue current quest",
  29.     " ",
  30.     "Delete a quest",
  31.     " ",
  32.     "Settings",
  33.     " ",
  34.     "Exit",
  35.     NULL
  36. };
  37.  
  38. static int selected_quest;
  39. static int rolled_health, rolled_skill;
  40. static char quest_string[256];
  41. static char health_string[256];
  42. static char skill_string[256];
  43. static void menu_quest (int);
  44. char const *menu_quest_text[] =
  45. {
  46.     " New quest ",
  47.     " ",
  48.     " Health ",
  49.     " Skill ",
  50.     " ",
  51.     "Roll again, please",
  52.     " ",
  53.     "Begin quest: The Sword of Fargoal",
  54. //    "Enhanced quest 1: The Helmet of Fargoal",
  55. //    "Enhanced quest 2: Beyond the Dungeons of Fargoal ",
  56.     " ",
  57.     "Back",
  58.     NULL
  59. };
  60.  
  61.  
  62. char savenames[9][100];
  63.  
  64. static void menu_new (int);
  65. char const *menu_new_text[14];
  66.  
  67. static void menu_delete (int);
  68. char const *menu_delete_text[14];
  69.  
  70. static void menu_settings (int);
  71. char const *menu_settings_text[] =
  72. {
  73.     " Settings ",
  74.     " ",
  75.     "Display",
  76.     " ",
  77.     "Gameplay",
  78.     " ",
  79.     "Graphics style",
  80.     " ",
  81.     "Back",
  82.     NULL
  83. };
  84.  
  85. static void menu_display (int);
  86. char const *menu_display_text[] =
  87. {
  88.     " Display Settings ",
  89.     " ",
  90.     "^Windowed^Fullscreen",
  91.     " ",
  92.     " Color depth ",
  93.     "^8^15^16^24^32",
  94.     " ",
  95.     "Back",
  96.     NULL
  97. };
  98.  
  99. static void menu_gameplay (int);
  100. char const *menu_gameplay_text[] =
  101. {
  102.     " Gameplay settings ",
  103.     " ",
  104.     "^Monster Movement:^Classic^Free",
  105.     "^Monster Behavior:^Classic^Enhanced",
  106.     "^Skill/HP balance:^Classic^Enhanced",
  107.     "^Play Controls:^Classic^Enhanced",
  108.     "^Fighting:^Classic^Adjacent",
  109.     "^Dungeons:^Classic^Enhanced",
  110.     "^Speed:^Classic^Enhanced",
  111.     " ",
  112.     "Back",
  113.     NULL
  114. };
  115.  
  116. static void menu_graphics (int);
  117. char const *menu_graphics_text[] =
  118. {
  119.     " Graphics style ",
  120.     " ",
  121.     "Choose different scheme",
  122.     "Toggle big sprites",
  123.     "Custom configuration",
  124.     " ",
  125.     "Back",
  126.     NULL
  127. };
  128.  
  129. static void menu_customize (int);
  130. char const *menu_customize_text[] =
  131. {
  132.     " Custom Configuration ",
  133.     " ",
  134.     "Different Layout",
  135.     "Different Tileset",
  136.     "Different Spriteset",
  137.     " ",
  138.     "Back",
  139.     NULL
  140. };
  141.  
  142. void
  143. menu_alt_tab (void)
  144. {
  145.     update_top = 1;
  146.     update_main = 1;
  147.     update_bottom = 1;
  148. }
  149.  
  150. static void
  151. menu_selection (int dir)
  152. {
  153.     int os = menu_selected;
  154.     if (dir == 1 || dir == -1)
  155.     {
  156.         do
  157.         {
  158.             menu_selected += dir;
  159.             if (menu_selected < 0)
  160.             {
  161.                 int i;
  162.                 for (i = 0; menu_text[i + 1]; i++);
  163.                 menu_selected = i;
  164.             }
  165.             if (!menu_text[menu_selected])
  166.                 menu_selected = 0;
  167.         } while (menu_text[menu_selected][0] == ' ' && os != menu_selected);
  168.     }
  169.  
  170.     if (menu_selected != os)
  171.     {
  172.         update_main = 1;
  173.         if (!ugly_hacking)
  174.             play_sample (step, 250, 128, 1000, 0);
  175.     }
  176.     menu_sub_highlight = 0;
  177. }
  178.  
  179. static void
  180. change_menu (void (*func) (int), char const **text)
  181. {
  182.     int t;
  183.     menu = func;
  184.     menu_text = text;
  185.     update_main = 1;
  186.     menu_selected = -1;
  187.     menu_sub_highlight = 0;
  188.     ugly_hacking = 1;
  189.     for (t = 0; ; t++)
  190.     {
  191.         int o = menu_selected;
  192.         menu(1);
  193.         if (menu_selected < o)
  194.             break;
  195.     }
  196.     ugly_hacking = 0;
  197.  
  198.     play_sample (human[1], 250, 128, 1000, 0);
  199. }
  200.  
  201. static void
  202. menu_main (int dir)
  203. {
  204.     if (dir)
  205.     {
  206.         menu_selection (dir);
  207.         return;
  208.     }
  209.     switch (menu_selected)
  210.     {
  211.         case 0:
  212.             change_menu (menu_new, menu_new_text);
  213.             break;
  214.         case 2:
  215.             if (!notrunning)
  216.             {
  217.                 game_continue ();
  218.                 menu_active = 0;
  219.                 break;
  220.             }
  221.             /* Fall through! */        
  222.         case 4:
  223.             change_menu (menu_delete, menu_delete_text);
  224.             break;
  225.         case 6:
  226.             change_menu (menu_settings, menu_settings_text);
  227.             break;
  228.         case 8:
  229.             run_exit ();
  230.             break;
  231.     }
  232. }
  233.  
  234. static void
  235. roll (void)
  236. {    
  237.     player_roll (&rolled_health, &rolled_skill);
  238.     sprintf (health_string, " Health: %i ", rolled_health);
  239.     menu_quest_text[2] = health_string;
  240.     sprintf (skill_string, " Skill: %i ", rolled_skill);
  241.     menu_quest_text[3] = skill_string;
  242.     
  243.     update_main = 1;
  244. }
  245.  
  246. static void
  247. menu_quest (int dir)
  248. {
  249.     if (dir)
  250.     {
  251.         menu_selection (dir);
  252.         return;
  253.     }
  254.     switch (menu_selected)
  255.     {
  256.         case 5:
  257.             roll ();
  258.             break;
  259.         case 7:
  260.         {            
  261.             char str[100];
  262.             char entry[100];
  263.  
  264.             quest_number = selected_quest;
  265.                     
  266.             message (FPS / 2, NULL, "Quest %i selected!!", menu_selected - 1);
  267.  
  268.             set_config_file ("data/settings.cfg");
  269.             sprintf (str, "data/save%i.dat", quest_number);
  270.             sprintf (entry, "Beginning");
  271.  
  272.             set_config_string ("SOF", str, entry);
  273.             sprintf (savenames[quest_number - 1], "%i: %s", quest_number, entry);
  274.             update_main = 1;
  275.             
  276.             sprintf (quest_string, " New quest: %s ", entry);
  277.             menu_quest_text[0] = quest_string;
  278.             
  279.             game_original (rolled_health, rolled_skill);
  280.             menu_active = 0;
  281.             break;
  282.         }
  283.         /*case 8:
  284.             game_original ();
  285.             menu_active = 0;
  286.         break;
  287.         case 9:
  288.             game_original ();
  289.             menu_active = 0;
  290.         break;*/
  291.         case 9:
  292.             change_menu (menu_main, menu_main_text);
  293.         break;
  294.     }
  295. }
  296.  
  297. static void
  298. menu_new (int dir)
  299. {
  300.     if (dir)
  301.     {
  302.         menu_selection (dir);
  303.         return;
  304.     }
  305.     if (menu_selected >= 2 && menu_selected <= 10)
  306.     {
  307.         char str[100];
  308.         set_config_file ("data/settings.cfg");
  309.         sprintf (str, "data/save%i.dat",    menu_selected - 1);
  310.         
  311.         if (!get_config_string ("SOF", str, NULL))
  312.         {
  313.             roll ();
  314.             selected_quest = menu_selected - 1;
  315.             change_menu (menu_quest, menu_quest_text);
  316.             menu_selected = 7;
  317.         }
  318.         else
  319.         {
  320.             if (game_load (menu_selected - 1))
  321.             {
  322.                 quest_number = menu_selected - 1;
  323.                 message (FPS / 2, NULL, "Quest %i loaded!!", menu_selected - 1);
  324.                 game_continue ();
  325.                 menu_active = 0;
  326.             }
  327.             else
  328.                 message (FPS / 2, NULL, "Could not load!!");
  329.         }
  330.     }
  331.     else
  332.     {
  333.         change_menu (menu_main, menu_main_text);
  334.         menu_selected = 2;
  335.     }
  336. }
  337.  
  338. static void
  339. menu_delete (int dir)
  340. {
  341.     if (dir)
  342.     {
  343.         menu_selection (dir);
  344.         return;
  345.     }
  346.     if (menu_selected >= 2 && menu_selected <= 10)
  347.     {
  348.         char str[100];
  349.         set_config_file ("data/settings.cfg");
  350.         sprintf (str, "data/save%i.dat", menu_selected - 1);
  351.         if (game_delete (menu_selected - 1) ||
  352.             get_config_string ("SOF", str, NULL))
  353.         {
  354.             message (FPS / 2, NULL, "Quest %i removed!!", menu_selected - 1);
  355.             sprintf (savenames[menu_selected - 2], "%i: empty", menu_selected - 1);
  356.             set_config_string ("SOF", str, NULL);
  357.             update_main = 1;
  358.         }
  359.         else
  360.         {
  361.             message (FPS / 2, NULL, "Nothing to remove!!");
  362.         }
  363.         
  364.     }
  365.     else
  366.     {
  367.         change_menu (menu_main, menu_main_text);
  368.         menu_selected = 2;
  369.     }
  370. }
  371.  
  372. static int
  373. get_cd_num (int cd)
  374. {
  375.     return cd / 8 - (cd == 8);
  376. }
  377.  
  378. static void
  379. menu_settings (int dir)
  380. {
  381.     if (dir)
  382.     {
  383.         menu_selection (dir);
  384.         return;
  385.     }
  386.     if (menu_selected == 2)
  387.     {
  388.         change_menu (menu_display, menu_display_text);
  389.         return;
  390.     }
  391.     if (menu_selected == 4)
  392.     {
  393.         change_menu (menu_gameplay, menu_gameplay_text);
  394.         return;
  395.     }
  396.     if (menu_selected == 6)
  397.     {
  398.         change_menu (menu_graphics, menu_graphics_text);
  399.         return;
  400.     }
  401.     change_menu (menu_main, menu_main_text);
  402.     menu_selected = 2;
  403. }
  404.  
  405. static void
  406. menu_gameplay (int dir)
  407. {
  408.     int *vars[] =
  409.     {
  410.         &extensions_nomonsterpause,
  411.         &extensions_monsteraction,
  412.         &extensions_balance,
  413.         &extensions_controls,
  414.         &extensions_overlapfight,
  415.         &extensions_dungeons,
  416.         &extensions_speed
  417.     };
  418.     if (dir == 1 || dir == -1)
  419.     {
  420.         menu_selection (dir);
  421.         if (menu_selected != 10)
  422.             menu_sub_highlight = 1 + *vars[menu_selected - 2];
  423.         menu_sub_selection[menu_selected] = menu_sub_highlight;
  424.         return;
  425.     }
  426.     if (menu_selected != 10)
  427.     {
  428.         *vars[menu_selected - 2] = !*vars[menu_selected - 2];
  429.         menu_sub_selection[menu_selected] = 1 + *vars[menu_selected - 2];
  430.         update_main = 1;
  431.         message (FPS / 2, NULL, "Gameplay settings changed");
  432.         menu_sub_highlight = menu_sub_selection[menu_selected];
  433.         return;
  434.     }
  435.     if (!dir)
  436.     {
  437.         change_menu (menu_settings, menu_settings_text);
  438.         menu_selected = 4;
  439.     }
  440. }
  441.  
  442.  
  443. static void
  444. menu_display (int dir)
  445. {
  446.     if (dir == 1 || dir == -1)
  447.     {
  448.         menu_selection (dir);
  449.         if (menu_selected == 5)
  450.             menu_sub_highlight = get_cd_num (colordepth);
  451.         if (menu_selected == 2)
  452.             menu_sub_highlight = fullscreen;
  453.         menu_sub_selection[menu_selected] = menu_sub_highlight;
  454.         return;
  455.     }
  456.     if (menu_selected == 2)
  457.     {
  458.         if (dir)
  459.         {
  460.             menu_sub_highlight = (menu_sub_highlight + dir / 2) & 1;
  461.             update_main = 1;
  462.             return;
  463.         }
  464.         if (set_gfx_mode (menu_sub_highlight ? GFX_AUTODETECT_FULLSCREEN : GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0))
  465.         {
  466.             set_gfx_mode (fullscreen ? GFX_AUTODETECT_FULLSCREEN : GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
  467.             message (FPS / 2, NULL, "Cannot use %s mode with the current color depth", menu_sub_selection[menu_selected] ? "fullscreen" : "windowed");            
  468.         }
  469.         else
  470.         {
  471.             message (FPS / 2, NULL, "Changed to %s", fullscreen ? "fullscreen" : "windowed");
  472.             menu_sub_selection[menu_selected] = menu_sub_highlight;
  473.             fullscreen = menu_sub_selection[menu_selected];
  474.         }
  475.         fix_alt_tab ();
  476.         {
  477.             if (colordepth == 8)
  478.             {
  479.                 PALETTE pal;
  480.                 generate_332_palette (pal);
  481.                 memset (&pal[0], 0, sizeof pal[0]);
  482.                 set_palette (pal);
  483.             }
  484.             update_top = 1;
  485.             update_main = 1;
  486.             update_bottom = 1;
  487.         }
  488.         return;
  489.     }
  490.     if (menu_selected == 5)
  491.     {
  492.         if (dir)
  493.         {
  494.             menu_sub_highlight = MAX (0, MIN (4, menu_sub_highlight + dir / 2));
  495.             update_main = 1;
  496.         }
  497.         else
  498.         {
  499.             int cds[] = {8, 15, 16, 24, 32};
  500.             int cd = cds[menu_sub_highlight];
  501.             set_color_depth (cd);
  502.             if (set_gfx_mode (fullscreen ? GFX_AUTODETECT_FULLSCREEN : GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0))
  503.             {
  504.                 set_color_depth (colordepth);
  505.                 set_gfx_mode (fullscreen ? GFX_AUTODETECT_FULLSCREEN : GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
  506.                 message (FPS / 2, NULL, "Cannot use color depth %i in %s mode", cd,
  507.                     fullscreen ? "fullscreen" : "windowed");
  508.             }
  509.             else
  510.             {
  511.                 menu_sub_selection[menu_selected] = menu_sub_highlight;
  512.                 colordepth = cd;
  513.                 message (FPS / 2, NULL, "Colordepth set to %i", cd);
  514.             }
  515.             fix_alt_tab ();
  516.             if (cd == 8)
  517.             {
  518.                 PALETTE pal;
  519.                 generate_332_palette (pal);
  520.                 memset (&pal[0], 0, sizeof pal[0]);
  521.                 set_palette (pal);
  522.             }
  523.             update_top = 1;
  524.             update_main = 1;
  525.             update_bottom = 1;
  526.             graphics_init ();
  527.             destroy_bitmap (page);
  528.             page = create_bitmap (SCREEN_W, SCREEN_H);
  529.         }
  530.         return;
  531.     }
  532.     if (dir == 0)
  533.     {
  534.         change_menu (menu_settings, menu_settings_text);
  535.         menu_selected = 2;
  536.     }
  537. }
  538.  
  539. static void
  540. scheme_selection (int dir, int *s, char const *str)
  541. {
  542.     char section[256];
  543.     *s += dir == -2 ? -1 : 1;
  544.     set_config_file ("data/sof.cfg");
  545.     if (*s < 0)
  546.     {
  547.         for (*s = 1; ; (*s)++)
  548.         {
  549.             sprintf (section, "scheme%i", *s);
  550.             if (!get_config_string (section, str, NULL))
  551.             {
  552.                 (*s)--;
  553.                 break;
  554.             }
  555.         }
  556.     }
  557.     sprintf (section, "scheme%i", *s);
  558.     if (!get_config_string (section, str, NULL))
  559.     {
  560.         *s = 0;
  561.     }
  562. }
  563.  
  564. static void
  565. menu_graphics (int dir)
  566. {
  567.     if (dir == 1 || dir == -1)
  568.     {
  569.         menu_selection (dir);
  570.         return;
  571.     }
  572.     if (menu_selected == 2)
  573.     {
  574.         scheme_selection (dir, &scheme, "name");
  575.         charset = scheme;
  576.         tileset = scheme;
  577.         layout = scheme;
  578.         update_top = 1;
  579.         update_main = 1;
  580.         update_bottom = 1;
  581.         graphics_init ();
  582.         message (FPS / 2, 0, "Scheme %i", scheme);
  583.         return;
  584.     }
  585.     if (menu_selected == 3)
  586.     {
  587.         doublesize = !doublesize;
  588.         update_main = 1;
  589.         graphics_init ();
  590.         message (FPS / 2, 0, "Switched big sprites %s",
  591.             doublesize ? "on" : "off");
  592.         return;
  593.     }
  594.     if (menu_selected == 4)
  595.     {
  596.         if (dir == 0)
  597.             change_menu (menu_customize, menu_customize_text);
  598.         return;
  599.     }
  600.     if (!dir)
  601.     {
  602.         change_menu (menu_settings, menu_settings_text);
  603.         menu_selected = 6;
  604.     }
  605. }
  606.  
  607. static void
  608. menu_customize (int dir)
  609. {
  610.     if (dir == 1 || dir == -1)
  611.     {
  612.         menu_selection (dir);
  613.         return;
  614.     }
  615.  
  616.     if (menu_selected == 4)
  617.     {
  618.         scheme_selection (dir, &charset, "sprites");
  619.         graphics_init();
  620.         message (FPS / 2, 0, "Sprites %i", charset);
  621.         update_main = 1;
  622.         return;
  623.     }
  624.     if (menu_selected == 3)
  625.     {
  626.         scheme_selection (dir, &tileset, "tileset");
  627.         graphics_init();
  628.         message (FPS / 2, 0, "Tileset %i", tileset);
  629.         update_main = 1;
  630.         return;
  631.     }
  632.     if (menu_selected == 2)
  633.     {
  634.         update_top = 1;
  635.         update_main = 1;
  636.         update_bottom = 1;
  637.         scheme_selection (dir, &layout, "layout");
  638.         graphics_init();
  639.         message (FPS / 2, 0, "Layout %i", layout);
  640.         return;
  641.     }
  642.  
  643.     if (!dir)
  644.     {
  645.         change_menu (menu_settings, menu_settings_text);
  646.         menu_selected = 6;
  647.     }
  648. }
  649.  
  650. void
  651. menu_init (void)
  652. {
  653.     int i;
  654.     char str[100];
  655.  
  656.     set_config_file ("data/settings.cfg");
  657.     
  658.     if (!notrunning)
  659.     {
  660.         char entry[100];
  661.         sprintf (entry, "Dungeon %i, Level %i, %s",
  662.             list[1].current_level, list[1].lev,
  663.             won ? "won" : gameover ? "dead" : swordrun ? "running out of time" : "alive");
  664.         game_save (quest_number);
  665.         sprintf (str, "data/save%i.dat", quest_number);
  666.         set_config_string ("SOF", str, entry);
  667.     }
  668.  
  669.     for (i = 0; i < 9; i++)
  670.     {
  671.         char const *entry;
  672.         sprintf (str, "data/save%i.dat",    i + 1);
  673.         entry = get_config_string ("SOF", str, "empty");
  674.         sprintf (savenames[i], "%i: %s", i + 1, entry);
  675.         menu_delete_text[2 + i] = savenames[i];
  676.         menu_new_text[2 + i] = savenames[i];
  677.     }
  678.     menu_delete_text[0] = " Delete Quest ";
  679.     menu_delete_text[1] = " ";
  680.     menu_delete_text[11] = " ";
  681.     menu_delete_text[12] = "Back";
  682.     menu_delete_text[13] = NULL;
  683.         
  684.     menu_new_text[0] = " Select a spot ";
  685.     menu_new_text[1] = " ";
  686.     menu_new_text[11] = " ";
  687.     menu_new_text[12] = "Back";
  688.     menu_new_text[13] = NULL;
  689.     
  690.     update_top = 1;
  691.     update_main = 1;
  692.     update_bottom = 1;
  693.     menu_text = menu_main_text;
  694.     menu = menu_main;
  695.     menu_selected = 0;
  696.     
  697.     credits_init ();
  698.     
  699.     if (!notrunning && !won && !gameover)
  700.     {
  701.         menu_selected = 2;
  702.         message (FPS / 2, NULL, "Thy quest is interrupted!!");
  703.     }
  704.     else
  705.     {
  706.         /* Need something for the initial DR. */
  707.         if (won)
  708.         {
  709.             message (FPS / 2, NULL, "You won!!");
  710.         }
  711.         else
  712.         if (gameover)
  713.         {
  714.             message (FPS / 2, NULL, "You lost!!");
  715.         }
  716.         else
  717.         message (FPS / 2, NULL, "Welcome!");
  718.     }
  719. }
  720.  
  721. void
  722. menu_run (void)
  723. {
  724.     if (check_key (KEY_ENTER) || check_key (KEY_LCONTROL))
  725.     {
  726.         menu (0);    
  727.     }
  728.     if (check_key (KEY_LEFT))
  729.     {
  730.         menu (-2);
  731.     }
  732.     if (check_key (KEY_RIGHT))
  733.     {
  734.         menu (2);
  735.     }
  736.     if (check_key (KEY_DOWN))
  737.     {
  738.         menu (1);
  739.     }
  740.     if (check_key (KEY_UP))
  741.     {
  742.         menu (-1);
  743.     }
  744.     messages_update ();
  745.     if (credits_scroll ())
  746.         update_top = 1;
  747. }
  748.  
  749.  
  750.  
  751. void
  752. menu_render (void)
  753. {
  754.     messages_render ();
  755.     
  756.     if (update_top)
  757.     {
  758.         blit (title, page, 0, 18, 0, 18, SCREEN_W, 72);
  759.         credits_render ();
  760.     }
  761.     
  762.     if (update_main)
  763.     {
  764.         int i;
  765.         int x = 0, y = 0;
  766.         blit (title, page, 0, 90, 0, 90, SCREEN_W, 300);
  767.         text_mode (-1);
  768.         for (i = 0; menu_text[i]; i++)
  769.         {
  770.             int w;
  771.             char const *ptr = menu_text[i];
  772.             int show_selection = 0;
  773.             int j;
  774.             int img = 0;
  775.             if (*ptr >= '1' && *ptr <= '9')
  776.             {
  777.                 img = *ptr - '0';
  778.             }
  779.             if (*ptr == '^')
  780.             {
  781.                 show_selection = 1;
  782.                 ptr++;
  783.             }
  784.             w = text_length (font, ptr);
  785.             x = (SCREEN_W - w) / 2;
  786.             if (img)
  787.             {
  788.                 draw_sprite (page, anims[img], x - 10 - sprite_w,
  789.                     120 + y + text_height (font) / 2 - sprite_h / 2);
  790.             }
  791.             for (j = 0; ; j++)
  792.             {
  793.                 char str[256];
  794.                 int color;
  795.                 char *next = strchr (ptr + 1, '^');
  796.                 if (next)
  797.                     ustrzncpy (str, 256, ptr, next - ptr);
  798.                 else
  799.                     ustrzcpy (str, 256, ptr);
  800.                 
  801.                 if (menu_text[i][0] == ' ')
  802.                     color = layout_color (LC_TITLE);
  803.                 else
  804.                     color = menu_selected == i && menu_sub_highlight == j ?
  805.                     layout_color (LC_HIGHLIGHT) : show_selection &&
  806.                     menu_sub_selection[i] == j ? layout_color (LC_SELECTED) :
  807.                     layout_color (LC_MENU);
  808.                 
  809.                 textprintf (page, font, x, 120 + y,    color, "%s", str);
  810.                 x += text_length (font, str) + text_length (font, "^");
  811.                 if (next)
  812.                     ptr = next + 1;
  813.                 else
  814.                     break;
  815.             }
  816.             
  817.             y += 20;
  818.         }
  819.         if (menu == menu_graphics || menu == menu_customize)
  820.         {
  821.             int xp = SCREEN_W / 2 - 7 * tw / 2;
  822.             int yp = 300;
  823.             // Draw small sample
  824.             for (y = 0; y < 7; y++)
  825.             {
  826.                 for (x = 0; x < 7; x++)
  827.                 {
  828.                     // This kind of code drives me insane - PP
  829.                     masked_blit (tileset_bmp, page,
  830.                         x > 0 && y > 0 && x < 6 && y < 6 ?
  831.                         x > 1 && y > 1 && x < 5 && y < 5 ?
  832.                         tw : tw * 2 : tw,
  833.                         0, xp + x * tw, yp + y * th - th, tw, th * 2);
  834.                 }
  835.             }
  836.  
  837.             masked_blit (charset_bmp, page, 0, 0, xp + tw * 7 / 2 - sprite_w / 2,
  838.                 yp + 4 * th - sprite_h, sprite_w, sprite_h);
  839.             
  840.             if (menu == menu_graphics)
  841.             {
  842.                 textprintf_centre (page, font, SCREEN_W / 2, 276,
  843.                     layout_color (LC_HELP),    "\"%s\"%s", scheme_name,
  844.                         doublesize ? " (2 x)" : "");
  845.             }
  846.             else
  847.             {
  848.                 textprintf_centre (page, font, SCREEN_W / 2, 276,
  849.                     layout_color (LC_HELP),    
  850.                         (menu_selected>=2&&menu_selected<=4)?
  851.                         "\"%s\"%s":"%s%s",
  852.                         menu_selected == 4 ? charset_name :
  853.                         menu_selected == 3 ? tileset_name :
  854.                         menu_selected == 2 ? layout_name : "",
  855.                         menu_selected == 4 && doublesize ? " (2x)" : "");
  856.  
  857.             }
  858.         }
  859.         if (menu == menu_display)
  860.         {
  861.             if (menu_selected == 5)
  862.                 textprintf_centre (page, font, SCREEN_W / 2, 300, layout_color (LC_HELP),
  863.                     "Current depth: %i", colordepth);
  864.             if (menu_selected == 2)
  865.                 textprintf_centre (page, font, SCREEN_W / 2, 300, layout_color (LC_HELP),
  866.                     "Currently: %s mode", fullscreen ? "fullscreen" : "windowed");
  867.         }
  868.         if (menu == menu_gameplay)
  869.         {
  870.             textprintf_centre (page, font, SCREEN_W / 2, 350,
  871.                 layout_color (LC_HELP),    "%s",            
  872.                 menu_selected == 2 ? "Paused or unpaused monster turns" :
  873.                 menu_selected == 3 ? "whether mages/demons disappear, and monsters move when not near" :
  874.                 menu_selected == 4 ? "Random or monster-skill based skill advancement/and more HP" :
  875.                 menu_selected == 5 ? "Fargoal or Roguelike controls" :
  876.                 menu_selected == 6 ? "Overlapped fights, or not" :
  877.                 menu_selected == 7 ? "Allow check for getting stuck, and custom levels" :
  878.                 menu_selected == 8 ? "Original or fast movement speed" :
  879.                 "");
  880.         }
  881.  
  882.     }
  883.     
  884.     if (update_bottom)
  885.     {
  886.         blit (title, page, 0, SCREEN_H - 90, 0, SCREEN_H - 90, SCREEN_W, 90);
  887.         textprintf_right (page, font, SCREEN_W - 5, SCREEN_H - 5 - 8,
  888.             layout_color (LC_HELP), "remakes.org");
  889.     }
  890.     
  891.     if (USE_DRS)
  892.     {
  893.         if (messages_updated ())
  894.         {
  895.             blit (page, screen, 0, 0, 0, 0, SCREEN_W, 18);
  896.         }
  897.         if (update_top)
  898.         {
  899.             blit (page, screen, 0, 18, 0, 18, SCREEN_W, 72);
  900.             update_top =0 ;
  901.         }
  902.         if (update_main)
  903.         {
  904.             blit (page, screen, 0, 90, 0, 90, SCREEN_W, 300);
  905.             update_main = 0;
  906.         }
  907.         if (update_bottom)
  908.         {
  909.             blit (page, screen, 0, SCREEN_H - 90, 0, SCREEN_H - 90, SCREEN_W, 90);
  910.             update_bottom =0 ;
  911.         }
  912.     }
  913.     else
  914.     {
  915.         blit (page, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
  916.     }
  917. }
  918.