diff options
author | dshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573> | 2006-09-27 17:27:53 +0000 |
---|---|---|
committer | dshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573> | 2006-09-27 17:27:53 +0000 |
commit | 9848ee54a552f599675e119e5af3d4fda821eca2 (patch) | |
tree | f6115aab7c0b50f0278a73b99555e02ea3712656 /crawl-ref/source | |
parent | a1d56f9b8defcfbf9eef15dca800ee6241127a46 (diff) | |
download | crawl-ref-9848ee54a552f599675e119e5af3d4fda821eca2.tar.gz crawl-ref-9848ee54a552f599675e119e5af3d4fda821eca2.zip |
Added Elethiomel's superior command-help.
Added -Werror to DOS and Windows makefiles.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/branches/stone_soup@155 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source')
-rw-r--r-- | crawl-ref/source/command.cc | 329 | ||||
-rw-r--r-- | crawl-ref/source/externs.h | 11 | ||||
-rw-r--r-- | crawl-ref/source/initfile.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/initfile.h | 1 | ||||
-rw-r--r-- | crawl-ref/source/invent.cc | 197 | ||||
-rw-r--r-- | crawl-ref/source/libutil.cc | 123 | ||||
-rw-r--r-- | crawl-ref/source/libutil.h | 6 | ||||
-rw-r--r-- | crawl-ref/source/makefile.dos | 2 | ||||
-rw-r--r-- | crawl-ref/source/makefile.mgw | 1 | ||||
-rw-r--r-- | crawl-ref/source/menu.cc | 163 | ||||
-rw-r--r-- | crawl-ref/source/menu.h | 43 |
11 files changed, 596 insertions, 282 deletions
diff --git a/crawl-ref/source/command.cc b/crawl-ref/source/command.cc index 489a7f23b0..efb32faef9 100644 --- a/crawl-ref/source/command.cc +++ b/crawl-ref/source/command.cc @@ -27,17 +27,24 @@ #include "itemname.h" #include "item_use.h" #include "items.h" +#include "libutil.h" #include "menu.h" #include "ouch.h" #include "spl-cast.h" #include "spl-util.h" #include "stuff.h" #include "version.h" +#include "view.h" #include "wpn-misc.h" static void adjust_item(void); static void adjust_spells(void); static void adjust_ability(void); +static void list_wizard_commands(); +#ifdef OBSOLETE_COMMAND_HELP +static const char *command_string( int i ); +#endif +static const char *wizard_string( int i ); void quit_game(void) { @@ -553,3 +560,325 @@ void list_weapons(void) mpr( info, MSGCH_EQUIPMENT, menu_colour(info) ); } // end list_weapons() + +static void cmdhelp_showline(int index, const MenuEntry *me) +{ + static_cast<formatted_string *>(me->data)->display(); +} + +static int cmdhelp_keyfilter(int keyin) +{ + switch (keyin) + { + case CK_DOWN: + case '+': + case '=': + return ('>'); + case CK_UP: + case '-': + case '_': + return ('<'); + case 'x': + return (CK_ESCAPE); + default: + return (keyin); + } +} + +static bool cmdhelp_textfilter(const std::string &tag) +{ +#ifdef STASH_TRACKING + if (tag == "s") + return (true); +#endif +#ifdef WIZARD + if (tag == "wiz") + return (true); +#endif + return (false); +} + +void list_commands(bool wizard) +{ + if (wizard) + { + list_wizard_commands(); + return; + } + + static const char *command_template = + "<h>Movement: Extended Movement:\n" + "To move in a direction, use either Ctrl-G : Interlevel travel\n" + "of these control schema: Ctrl-O : Auto-explore\n" + "7 8 9 y k u Ctrl-W : Mark waypoint\n" + " \\|/ \\|/ Shift-Dir.: Long walk\n" + "4-5-6 h-.-l / Dir. : Long walk\n" + " /|\\ /|\\ Shift-5 : Rest 100 turns\n" + "7 8 9 b j n\n" + " <?s><h>Stash Management Commands:\n" + "\"Center\" buttons (5/./Del) will <?s>Ctrl-S : Mark stash\n" + "rest one turn. <?s>Ctrl-E : Forget stash\n" + " <?s>Ctrl-F : Search stashes\n" + "\n" + "<h>Dungeon Interaction and Information: Player Character Information:\n" + "o/c: Open/Close Door @ : Display character Status\n" + "Ctrl-Dir. : Door o/c, Untrap, Attack ] : Display worn armour\n" + "* Direction: Door o/c, Untrap, Attack \" : Display worn jewellery\n" + "</>: Ascend/Descend a staircase C : Display experience info\n" + "s : Search adjacent tiles ^ : Show religion screen\n" + "; : Examine occupied tile A : Show abilities/mutations\n" + "x : Examine visible surroundings \\ : Show item knowlede\n" + "X : Examine level map m : Show skill screen\n" + "+/-: Scroll up/down on level map i : Show inventory list\n" + "O : Show dungeon overview % : Show resistances\n" + "\n" + "<h>Item Interaction (inventory): Other Actions:\n" + "v : View item description a : Use special ability\n" + "z : Zap a wand p : Pray\n" + "t : throw/shoot an item Z : Cast a spell\n" + "f : fire first available missile ! : Shout or command allies\n" + "q : Quaff a potion Ctrl-A: Toggle autopickup\n" + "e : eat food (also see below)\n" + "r : Read a scroll or book <h>Game saving and exiting:\n" + "M : Memorise a spell from a book S : Save game and exit\n" + "w : Wield an item ( - for none) Ctrl-X:Save game without query\n" + "' : Wield item a, or switch to b Q : Quit without saving\n" + "E : Evoke power of wielded item\n" + "W : Wear armour <h>Non-gameplay Commands / Info\n" + "T : Take off armour V : Version Information\n" + "P : Put on jewellery Ctrl-P: See old messages\n" + "R : Remove jewellery Ctrl-R: Redraw screen\n" + "d(#): Drop (exact quantity of) items # : Dump character to file\n" + "= : Reassign inventory/spell letters ` : Add macro\n" + " ~ : Save macros\n" + "<h>Item Interaction (floor):</h> <?wiz>& : Wizard-mode commands\n" + "D : Dissect a corpse\n" + "e : eat food (also see above)\n" + ",/g: pick up items\n"; + std::vector<std::string> lines = + split_string("\n", command_template, false, true); + + Menu cmd_help; + + // Set flags, and don't use easy exit. + cmd_help.set_flags( + MF_NOSELECT | MF_ALWAYS_SHOW_MORE | MF_NOWRAP, + false); + cmd_help.set_more( + formatted_string::parse_string( + "<cyan>[ + : Page down. - : Page up." + " Esc/x exits.]")); + cmd_help.f_drawitem = cmdhelp_showline; + cmd_help.f_keyfilter = cmdhelp_keyfilter; + + std::vector<MenuEntry*> entries; + + for (unsigned i = 0, size = lines.size(); i < size; ++i) + { + MenuEntry *me = new MenuEntry; + me->data = new formatted_string( + formatted_string::parse_string( + lines[i], + true, + cmdhelp_textfilter) ); + entries.push_back(me); + + cmd_help.add_entry(me); + } + + cmd_help.show(); + + for (unsigned i = 0, size = entries.size(); i < size; ++i) + delete static_cast<formatted_string*>( entries[i]->data ); +} + +static void list_wizard_commands() +{ + const char *line; + int j = 0; + +#ifdef DOS_TERM + char buffer[4800]; + + window(1, 1, 80, 25); + gettext(1, 1, 80, 25, buffer); +#endif + + clrscr(); + + // BCR - Set to screen length - 1 to display the "more" string + int moreLength = (get_number_of_lines() - 1) * 2; + + for (int i = 0; i < 500; i++) + { + line = wizard_string( i ); + + if (strlen( line ) != 0) + { + // BCR - If we've reached the end of the screen, clear + if (j == moreLength) + { + gotoxy(2, j / 2 + 1); + cprintf("More..."); + getch(); + clrscr(); + j = 0; + } + + gotoxy( ((j % 2) ? 40 : 2), ((j / 2) + 1) ); + cprintf( line ); + + j++; + } + } + + getch(); + +#ifdef DOS_TERM + puttext(1, 1, 80, 25, buffer); +#endif + + return; +} // end list_commands() + +static const char *wizard_string( int i ) +{ + UNUSED( i ); + +#ifdef WIZARD + return((i == 10) ? "a : acquirement" : + (i == 13) ? "A : set all skills to level" : + (i == 15) ? "b : controlled blink" : + (i == 20) ? "B : banish yourself to the Abyss" : + (i == 30) ? "g : add a skill" : + (i == 35) ? "G : remove all monsters" : + (i == 40) ? "h/H : heal yourself (super-Heal)" : + (i == 50) ? "i/I : identify/unidentify inventory": + (i == 70) ? "l : make entrance to labyrinth" : + (i == 80) ? "m/M : create monster by number/name": + (i == 90) ? "o/%% : create an object" : + (i == 100) ? "p : make entrance to pandemonium" : + (i == 110) ? "x : gain an experience level" : + (i == 115) ? "r : change character's species" : + (i == 120) ? "s : gain 20000 skill points" : + (i == 130) ? "S : set skill to level" : + (i == 140) ? "t : tweak object properties" : + (i == 150) ? "X : Receive a gift from Xom" : + (i == 160) ? "z/Z : cast any spell by number/name": + (i == 200) ? "$ : get 1000 gold" : + (i == 210) ? "</> : create up/down staircase" : + (i == 220) ? "u/d : shift up/down one level" : + (i == 230) ? "~/\" : goto a level" : + (i == 240) ? "( : create a feature" : + (i == 250) ? "] : get a mutation" : + (i == 260) ? "[ : get a demonspawn mutation" : + (i == 270) ? ": : find branch" : + (i == 280) ? "{ : magic mapping" : + (i == 290) ? "^ : gain piety" : + (i == 300) ? "_ : gain religion" : + (i == 310) ? "\' : list items" : + (i == 320) ? "? : list wizard commands" : + (i == 330) ? "| : acquire all unrand artefacts" : + (i == 340) ? "+ : turn item into random artefact" : + (i == 350) ? "= : sum skill points" + : ""); + +#else + return (""); +#endif +} // end wizard_string() + +#ifdef OBSOLETE_COMMAND_HELP +static const char *command_string( int i ) +{ + /* + * BCR - Command printing, case statement + * Note: The numbers in this case indicate the order in which the + * commands will be printed out. Make sure none of these + * numbers is greater than 500, because that is the limit. + * + * Arranged alpha lower, alpha upper, punctuation, ctrl. + * + */ + + return((i == 10) ? "a : use special ability" : + (i == 20) ? "d(#) : drop (exact quantity of) items" : + (i == 30) ? "e : eat food" : + (i == 40) ? "f : fire first available missile" : + (i == 50) ? "i : inventory listing" : + (i == 55) ? "m : check skills" : + (i == 60) ? "o/c : open / close a door" : + (i == 65) ? "p : pray" : + (i == 70) ? "q : quaff a potion" : + (i == 80) ? "r : read a scroll or book" : + (i == 90) ? "s : search adjacent tiles" : + (i == 100) ? "t : throw/shoot an item" : + (i == 110) ? "v : view item description" : + (i == 120) ? "w : wield an item" : + (i == 130) ? "x : examine visible surroundings" : + (i == 135) ? "z : zap a wand" : + (i == 140) ? "A : list abilities/mutations" : + (i == 141) ? "C : check experience" : + (i == 142) ? "D : dissect a corpse" : + (i == 145) ? "E : evoke power of wielded item" : + (i == 150) ? "M : memorise a spell" : + (i == 155) ? "O : overview of the dungeon" : + (i == 160) ? "P/R : put on / remove jewellery" : + (i == 165) ? "Q : quit without saving" : + (i == 168) ? "S : save game and exit" : + (i == 179) ? "V : version information" : + (i == 200) ? "W/T : wear / take off armour" : + (i == 210) ? "X : examine level map" : + (i == 220) ? "Z : cast a spell" : + (i == 240) ? ",/g : pick up items" : + (i == 242) ? "./del: rest one turn" : + (i == 250) ? "</> : ascend / descend a staircase" : + (i == 270) ? "; : examine occupied tile" : + (i == 280) ? "\\ : check item knowledge" : +#ifdef WIZARD + (i == 290) ? "& : invoke your Wizardly powers" : +#endif + (i == 300) ? "+/- : scroll up/down [level map only]" : + (i == 310) ? "! : shout or command allies" : + (i == 325) ? "^ : describe religion" : + (i == 337) ? "@ : status" : + (i == 340) ? "# : dump character to file" : + (i == 350) ? "= : reassign inventory/spell letters" : + (i == 360) ? "\' : wield item a, or switch to b" : + (i == 370) ? ": : make a note" : +#ifdef USE_MACROS + (i == 380) ? "` : add macro" : + (i == 390) ? "~ : save macros" : +#endif + (i == 400) ? "] : display worn armour" : + (i == 410) ? "\" : display worn jewellery" : + (i == 415) ? "{ : inscribe an item" : + (i == 420) ? "Ctrl-P : see old messages" : +#ifdef PLAIN_TERM + (i == 430) ? "Ctrl-R : Redraw screen" : +#endif + (i == 440) ? "Ctrl-A : toggle autopickup" : + (i == 445) ? "Ctrl-M : toggle autoprayer" : + (i == 447) ? "Ctrl-T : toggle fizzle" : + (i == 450) ? "Ctrl-X : Save game without query" : + +#ifdef ALLOW_DESTROY_ITEM_COMMAND + (i == 451) ? "Ctrl-D : Destroy inventory item" : +#endif + (i == 453) ? "Ctrl-G : interlevel travel" : + (i == 455) ? "Ctrl-O : explore" : + +#ifdef STASH_TRACKING + (i == 456) ? "Ctrl-S : mark stash" : + (i == 457) ? "Ctrl-E : forget stash" : + (i == 458) ? "Ctrl-F : search stashes" : +#endif + + (i == 460) ? "Shift & DIR : long walk" : + (i == 465) ? "/ DIR : long walk" : + (i == 470) ? "Ctrl & DIR : door; untrap; attack" : + (i == 475) ? "* DIR : door; untrap; attack" : + (i == 478) ? "Shift & 5 on keypad : rest 100 turns" + : ""); +} // end command_string() +#endif // OBSOLETE_COMMAND_HELP diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h index 0dbe078a58..67b65d21b9 100644 --- a/crawl-ref/source/externs.h +++ b/crawl-ref/source/externs.h @@ -608,7 +608,7 @@ class formatted_string { public: formatted_string() : ops() { } - formatted_string(const std::string &s); + formatted_string(const std::string &s, bool init_style = false); operator std::string() const; void display(int start = 0, int end = -1) const; @@ -619,6 +619,12 @@ public: void gotoxy(int x, int y); void textcolor(int color); +public: + static formatted_string parse_string( + const std::string &s, + bool eol_ends_format = true, + bool (*process_tag)(const std::string &tag) = NULL ); + private: enum fs_op_type { @@ -627,6 +633,9 @@ private: FSOP_TEXT }; + static int get_colour(const std::string &tag); + +private: struct fs_op { fs_op_type type; diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc index cf7e57f116..aee7d96933 100644 --- a/crawl-ref/source/initfile.cc +++ b/crawl-ref/source/initfile.cc @@ -62,7 +62,7 @@ template<class A, class B> void append_vector( } // returns -1 if unmatched else returns 0-15 -static short str_to_colour( const std::string &str ) +short str_to_colour( const std::string &str ) { int ret; diff --git a/crawl-ref/source/initfile.h b/crawl-ref/source/initfile.h index 1cd2ce0560..921a72cb3d 100644 --- a/crawl-ref/source/initfile.h +++ b/crawl-ref/source/initfile.h @@ -18,6 +18,7 @@ #include <cstdio> std::string & trim_string( std::string &str ); +short str_to_colour( const std::string &str ); // last updated 12may2000 {dlb} /* *********************************************************************** diff --git a/crawl-ref/source/invent.cc b/crawl-ref/source/invent.cc index c77c14e098..009e59b64d 100644 --- a/crawl-ref/source/invent.cc +++ b/crawl-ref/source/invent.cc @@ -37,9 +37,6 @@ #include "view.h" #include "menu.h" -const char *command_string( int i ); -const char *wizard_string( int i ); - struct InvTitle : public MenuEntry { Menu *m; @@ -474,7 +471,7 @@ unsigned char invent_select( { InvMenu menu; - menu.selitem_text = selitemfn; + menu.f_selitem = selitemfn; if (filter) menu.set_select_filter( *filter ); @@ -933,195 +930,3 @@ int prompt_invent_item( const char *prompt, int type_expect, return (ret); } - -void list_commands(bool wizard) -{ - const char *line; - int j = 0; - -#ifdef DOS_TERM - char buffer[4800]; - - window(1, 1, 80, 25); - gettext(1, 1, 80, 25, buffer); -#endif - - clrscr(); - - // BCR - Set to screen length - 1 to display the "more" string - int moreLength = (get_number_of_lines() - 1) * 2; - - for (int i = 0; i < 500; i++) - { - if (wizard) - line = wizard_string( i ); - else - line = command_string( i ); - - if (strlen( line ) != 0) - { - // BCR - If we've reached the end of the screen, clear - if (j == moreLength) - { - gotoxy(2, j / 2 + 1); - cprintf("More..."); - getch(); - clrscr(); - j = 0; - } - - gotoxy( ((j % 2) ? 40 : 2), ((j / 2) + 1) ); - cprintf( line ); - - j++; - } - } - - getch(); - -#ifdef DOS_TERM - puttext(1, 1, 80, 25, buffer); -#endif - - return; -} // end list_commands() - -const char *wizard_string( int i ) -{ - UNUSED( i ); - -#ifdef WIZARD - return((i == 10) ? "a : acquirement" : - (i == 13) ? "A : set all skills to level" : - (i == 15) ? "b : controlled blink" : - (i == 20) ? "B : banish yourself to the Abyss" : - (i == 30) ? "g : add a skill" : - (i == 35) ? "G : remove all monsters" : - (i == 40) ? "h/H : heal yourself (super-Heal)" : - (i == 50) ? "i/I : identify/unidentify inventory": - (i == 70) ? "l : make entrance to labyrinth" : - (i == 80) ? "m/M : create monster by number/name": - (i == 90) ? "o/%% : create an object" : - (i == 100) ? "p : make entrance to pandemonium" : - (i == 110) ? "x : gain an experience level" : - (i == 115) ? "r : change character's species" : - (i == 120) ? "s : gain 20000 skill points" : - (i == 130) ? "S : set skill to level" : - (i == 140) ? "t : tweak object properties" : - (i == 150) ? "X : Receive a gift from Xom" : - (i == 160) ? "z/Z : cast any spell by number/name": - (i == 200) ? "$ : get 1000 gold" : - (i == 210) ? "</> : create up/down staircase" : - (i == 220) ? "u/d : shift up/down one level" : - (i == 230) ? "~/\" : goto a level" : - (i == 240) ? "( : create a feature" : - (i == 250) ? "] : get a mutation" : - (i == 260) ? "[ : get a demonspawn mutation" : - (i == 270) ? ": : find branch" : - (i == 280) ? "{ : magic mapping" : - (i == 290) ? "^ : gain piety" : - (i == 300) ? "_ : gain religion" : - (i == 310) ? "\' : list items" : - (i == 320) ? "? : list wizard commands" : - (i == 330) ? "| : acquire all unrand artefacts" : - (i == 340) ? "+ : turn item into random artefact" : - (i == 350) ? "= : sum skill points" - : ""); - -#else - return (""); -#endif -} // end wizard_string() - -const char *command_string( int i ) -{ - /* - * BCR - Command printing, case statement - * Note: The numbers in this case indicate the order in which the - * commands will be printed out. Make sure none of these - * numbers is greater than 500, because that is the limit. - * - * Arranged alpha lower, alpha upper, punctuation, ctrl. - * - */ - - return((i == 10) ? "a : use special ability" : - (i == 20) ? "d(#) : drop (exact quantity of) items" : - (i == 30) ? "e : eat food" : - (i == 40) ? "f : fire first available missile" : - (i == 50) ? "i : inventory listing" : - (i == 55) ? "m : check skills" : - (i == 60) ? "o/c : open / close a door" : - (i == 65) ? "p : pray" : - (i == 70) ? "q : quaff a potion" : - (i == 80) ? "r : read a scroll or book" : - (i == 90) ? "s : search adjacent tiles" : - (i == 100) ? "t : throw/shoot an item" : - (i == 110) ? "v : view item description" : - (i == 120) ? "w : wield an item" : - (i == 130) ? "x : examine visible surroundings" : - (i == 135) ? "z : zap a wand" : - (i == 140) ? "A : list abilities/mutations" : - (i == 141) ? "C : check experience" : - (i == 142) ? "D : dissect a corpse" : - (i == 145) ? "E : evoke power of wielded item" : - (i == 150) ? "M : memorise a spell" : - (i == 155) ? "O : overview of the dungeon" : - (i == 160) ? "P/R : put on / remove jewellery" : - (i == 165) ? "Q : quit without saving" : - (i == 168) ? "S : save game and exit" : - (i == 179) ? "V : version information" : - (i == 200) ? "W/T : wear / take off armour" : - (i == 210) ? "X : examine level map" : - (i == 220) ? "Z : cast a spell" : - (i == 240) ? ",/g : pick up items" : - (i == 242) ? "./del: rest one turn" : - (i == 250) ? "</> : ascend / descend a staircase" : - (i == 270) ? "; : examine occupied tile" : - (i == 280) ? "\\ : check item knowledge" : -#ifdef WIZARD - (i == 290) ? "& : invoke your Wizardly powers" : -#endif - (i == 300) ? "+/- : scroll up/down [level map only]" : - (i == 310) ? "! : shout or command allies" : - (i == 325) ? "^ : describe religion" : - (i == 337) ? "@ : status" : - (i == 340) ? "# : dump character to file" : - (i == 350) ? "= : reassign inventory/spell letters" : - (i == 360) ? "\' : wield item a, or switch to b" : - (i == 370) ? ": : make a note" : -#ifdef USE_MACROS - (i == 380) ? "` : add macro" : - (i == 390) ? "~ : save macros" : -#endif - (i == 400) ? "] : display worn armour" : - (i == 410) ? "\" : display worn jewellery" : - (i == 415) ? "{ : inscribe an item" : - (i == 420) ? "Ctrl-P : see old messages" : -#ifdef PLAIN_TERM - (i == 430) ? "Ctrl-R : Redraw screen" : -#endif - (i == 440) ? "Ctrl-A : toggle autopickup" : - (i == 445) ? "Ctrl-M : toggle autoprayer" : - (i == 447) ? "Ctrl-T : toggle fizzle" : - (i == 450) ? "Ctrl-X : Save game without query" : - -#ifdef ALLOW_DESTROY_ITEM_COMMAND - (i == 451) ? "Ctrl-D : Destroy inventory item" : -#endif - (i == 453) ? "Ctrl-G : interlevel travel" : - (i == 455) ? "Ctrl-O : explore" : - -#ifdef STASH_TRACKING - (i == 456) ? "Ctrl-S : mark stash" : - (i == 457) ? "Ctrl-E : forget stash" : - (i == 458) ? "Ctrl-F : search stashes" : -#endif - - (i == 460) ? "Shift & DIR : long walk" : - (i == 465) ? "/ DIR : long walk" : - (i == 470) ? "Ctrl & DIR : door; untrap; attack" : - (i == 475) ? "* DIR : door; untrap; attack" : - (i == 478) ? "Shift & 5 on keypad : rest 100 turns" - : ""); -} // end command_string() diff --git a/crawl-ref/source/libutil.cc b/crawl-ref/source/libutil.cc index e03ddc1e78..ff0f00abc9 100644 --- a/crawl-ref/source/libutil.cc +++ b/crawl-ref/source/libutil.cc @@ -13,6 +13,7 @@ #include "AppHdr.h" #include "defines.h" +#include "initfile.h" #include "libutil.h" #include "externs.h" #include <stdio.h> @@ -348,21 +349,29 @@ std::string & trim_string( std::string &str ) return (str); } -std::vector<std::string> split_string(const char *sep, std::string s) +std::vector<std::string> split_string( + const char *sep, + std::string s, + bool trim_segments, + bool accept_empty_segments) { std::vector<std::string> segments; + int separator_length = strlen(sep); std::string::size_type pos; while ((pos = s.find(sep, 0)) != std::string::npos) { - if (pos > 0) + if (pos > 0 || accept_empty_segments) segments.push_back(s.substr(0, pos)); - s.erase(0, pos + 1); + s.erase(0, pos + separator_length); } if (s.length() > 0) segments.push_back(s); - for (int i = 0, count = segments.size(); i < count; ++i) - trim_string(segments[i]); + if (trim_segments) + { + for (int i = 0, count = segments.size(); i < count; ++i) + trim_string(segments[i]); + } return segments; } @@ -583,10 +592,110 @@ bool pattern_match(void *compiled_pattern, const char *text, int length) // formatted_string // -formatted_string::formatted_string(const std::string &s) +formatted_string::formatted_string(const std::string &s, bool init_style) : ops() { - ops.push_back( s ); + if (init_style) + ops.push_back(LIGHTGREY); + ops.push_back(s); +} + +int formatted_string::get_colour(const std::string &tag) +{ + if (tag == "h") + return (YELLOW); + + const int colour = str_to_colour(tag); + return (colour != -1? colour : LIGHTGREY); +} + +formatted_string formatted_string::parse_string( + const std::string &s, + bool eol_ends_format, + bool (*process)(const std::string &tag)) +{ + // FIXME This is a lame mess, just good enough for the task on hand + // (keyboard help). + formatted_string fs; + std::string::size_type tag = std::string::npos; + std::string::size_type length = s.length(); + + std::string currs; + int curr_colour = LIGHTGREY; + bool masked = false; + + for (tag = 0; tag < length; ++tag) + { + bool invert_colour = false; + std::string::size_type endpos = std::string::npos; + + if (s[tag] != '<' || tag >= length - 2) + { + if (!masked) + currs += s[tag]; + continue; + } + + // Is this a << escape? + if (s[tag + 1] == '<') + { + if (!masked) + currs += s[tag]; + tag++; + continue; + } + + endpos = s.find('>', tag + 1); + // No closing >? + if (endpos == std::string::npos) + { + if (!masked) + currs += s[tag]; + continue; + } + + std::string tagtext = s.substr(tag + 1, endpos - tag - 1); + if (tagtext.empty() || tagtext == "/") + { + if (!masked) + currs += s[tag]; + continue; + } + + if (tagtext[0] == '/') + { + invert_colour = true; + tagtext = tagtext.substr(1); + tag++; + } + + if (tagtext[0] == '?') + { + if (tagtext.length() == 1) + masked = false; + else if (process && !process(tagtext.substr(1))) + masked = true; + + tag += tagtext.length() + 1; + continue; + } + + const int new_colour = invert_colour? LIGHTGREY : get_colour(tagtext); + if (new_colour != curr_colour) + { + fs.cprintf(currs); + currs.clear(); + fs.textcolor( curr_colour = new_colour ); + } + tag += tagtext.length() + 1; + } + if (currs.length()) + fs.cprintf(currs); + + if (eol_ends_format && curr_colour != LIGHTGREY) + fs.textcolor(LIGHTGREY); + + return (fs); } formatted_string::operator std::string() const diff --git a/crawl-ref/source/libutil.h b/crawl-ref/source/libutil.h index 3ddbc998d4..ea97b2fcf8 100644 --- a/crawl-ref/source/libutil.h +++ b/crawl-ref/source/libutil.h @@ -35,7 +35,11 @@ bool cancelable_get_line( char *buf, int len, int wrapcol = 80, input_history *mh = NULL ); std::string & trim_string( std::string &str ); -std::vector<std::string> split_string(const char *sep, std::string s); +std::vector<std::string> split_string( + const char *sep, + std::string s, + bool trim = true, + bool accept_empties = false); #ifdef NEED_USLEEP void usleep( unsigned long time ); diff --git a/crawl-ref/source/makefile.dos b/crawl-ref/source/makefile.dos index b037bbe7da..458b168bb3 100644 --- a/crawl-ref/source/makefile.dos +++ b/crawl-ref/source/makefile.dos @@ -12,7 +12,7 @@ CXX = gxx DELETE = del COPY = copy OS_TYPE = DOS -CFLAGS = -D$(OS_TYPE) $(EXTRA_FLAGS) -Wshadow -fsigned-char -pedantic +CFLAGS = -D$(OS_TYPE) $(EXTRA_FLAGS) -Wshadow -Werror -fsigned-char -pedantic LDFLAGS = LIB = # LIB = -lcurso -lpano diff --git a/crawl-ref/source/makefile.mgw b/crawl-ref/source/makefile.mgw index e49be0967c..3a6da80ebb 100644 --- a/crawl-ref/source/makefile.mgw +++ b/crawl-ref/source/makefile.mgw @@ -19,6 +19,7 @@ OS_TYPE = WIN32CONSOLE CFLAGS = -Wall -Wwrite-strings -Wstrict-prototypes \ -Wmissing-prototypes -Wmissing-declarations \ -Wshadow \ + -Werror \ -fsigned-char \ -pedantic \ -D$(OS_TYPE) $(EXTRA_FLAGS) \ diff --git a/crawl-ref/source/menu.cc b/crawl-ref/source/menu.cc index bdf4beb817..da821e7c2f 100644 --- a/crawl-ref/source/menu.cc +++ b/crawl-ref/source/menu.cc @@ -8,12 +8,15 @@ #include "view.h" Menu::Menu( int _flags ) - : selitem_text(NULL), + : f_selitem(NULL), + f_drawitem(NULL), + f_keyfilter(NULL), title(NULL), flags(_flags), first_entry(0), y_offset(0), pagesize(0), + more("-more-", true), items(), sel(NULL), select_filter(), @@ -22,6 +25,7 @@ Menu::Menu( int _flags ) lastch(0), alive(false) { + set_flags(flags); } Menu::~Menu() @@ -32,6 +36,21 @@ Menu::~Menu() delete highlighter; } +void Menu::set_flags(int new_flags, bool use_options) +{ + flags = new_flags; + if (use_options) + { + if (Options.easy_exit_menu) + flags |= MF_EASY_EXIT; + } +} + +void Menu::set_more(const formatted_string &fs) +{ + more = fs; +} + void Menu::set_highlighter( MenuHighlighter *mh ) { if (highlighter != mh) @@ -65,7 +84,7 @@ std::vector<MenuEntry *> Menu::show() deselect_all(false); // Lose lines for the title + room for more. - pagesize = get_number_of_lines() - 2; + pagesize = get_number_of_lines() - !!title - 1; #ifdef DOS_TERM char buffer[4600]; @@ -100,8 +119,6 @@ void Menu::do_menu( std::vector<MenuEntry*> *selected ) bool Menu::is_set(int flag) const { - if (flag == MF_EASY_EXIT && Options.easy_exit_menu) - return true; return (flags & flag) == flag; } @@ -111,60 +128,66 @@ bool Menu::process_key( int keyin ) return false; bool nav = false, repaint = false; + + if (f_keyfilter) + keyin = (*f_keyfilter)(keyin); + switch (keyin) { - case CK_ENTER: + case 0: + return true; + case CK_ENTER: + return false; + case CK_ESCAPE: + sel->clear(); + lastch = keyin; + return false; + case ' ': case CK_PGDN: case '>': case '\'': + nav = true; + repaint = page_down(); + if (!repaint && !is_set(MF_EASY_EXIT) && !is_set(MF_NOWRAP)) + { + repaint = first_entry != 0; + first_entry = 0; + } + break; + case CK_PGUP: case '<': case ';': + nav = true; + repaint = page_up(); + break; + case CK_UP: + nav = true; + repaint = line_up(); + break; + case CK_DOWN: + nav = true; + repaint = line_down(); + break; + default: + lastch = keyin; + + // If no selection at all is allowed, exit now. + if (!(flags & (MF_SINGLESELECT | MF_MULTISELECT))) return false; - case CK_ESCAPE: - sel->clear(); - lastch = keyin; + + if (!is_set(MF_NO_SELECT_QTY) && isdigit( keyin )) + { + if (num > 999) + num = -1; + num = (num == -1)? keyin - '0' : + num * 10 + keyin - '0'; + } + + select_items( keyin, num ); + get_selected( sel ); + if (sel->size() == 1 && (flags & MF_SINGLESELECT)) return false; - case ' ': case CK_PGDN: case '>': case '\'': - nav = true; - repaint = page_down(); - if (!repaint && flags && !is_set(MF_EASY_EXIT)) - { - repaint = first_entry != 0; - first_entry = 0; - } - break; - case CK_PGUP: case '<': case ';': - nav = true; - repaint = page_up(); - break; - case CK_UP: - nav = true; - repaint = line_up(); - break; - case CK_DOWN: - nav = true; - repaint = line_down(); - break; - default: - lastch = keyin; - - // If no selection at all is allowed, exit now. - if (!(flags & (MF_SINGLESELECT | MF_MULTISELECT))) - return false; - - if (!is_set(MF_NO_SELECT_QTY) && isdigit( keyin )) - { - if (num > 999) - num = -1; - num = (num == -1)? keyin - '0' : - num * 10 + keyin - '0'; - } - - select_items( keyin, num ); - get_selected( sel ); - if (sel->size() == 1 && (flags & MF_SINGLESELECT)) - return false; - draw_select_count( sel->size() ); + draw_select_count( sel->size() ); - if (flags & MF_ANYPRINTABLE && !isdigit( keyin )) - return false; + if (flags & MF_ANYPRINTABLE && !isdigit( keyin )) + return false; - break; + break; } if (!isdigit( keyin )) @@ -175,7 +198,7 @@ bool Menu::process_key( int keyin ) if (repaint) draw_menu( sel ); // Easy exit should not kill the menu if there are selected items. - else if (sel->empty() && (!flags || is_set(MF_EASY_EXIT))) + else if (sel->empty() && is_set(MF_EASY_EXIT)) { sel->clear(); return false; @@ -215,9 +238,9 @@ void Menu::draw_select_count( int count ) if (!is_set(MF_MULTISELECT)) return; - if (selitem_text) + if (f_selitem) { - draw_title_suffix( selitem_text( sel ) ); + draw_title_suffix( f_selitem( sel ) ); } else { @@ -381,7 +404,7 @@ void Menu::draw_menu( std::vector< MenuEntry* > *selected ) draw_title(); draw_select_count( selected->size() ); - y_offset = 2; + y_offset = 1 + !!title; int end = first_entry + pagesize; if (end > (int) items.size()) end = items.size(); @@ -390,11 +413,10 @@ void Menu::draw_menu( std::vector< MenuEntry* > *selected ) { draw_item( i ); } - if (end < (int) items.size()) + if (end < (int) items.size() || is_set(MF_ALWAYS_SHOW_MORE)) { gotoxy( 1, y_offset + pagesize ); - textcolor( LIGHTGREY ); - cprintf("-more-"); + more.display(); } } @@ -424,14 +446,29 @@ void Menu::draw_title() } } +bool Menu::in_page(int index) const +{ + return (index >= first_entry && index < first_entry + pagesize); +} + void Menu::draw_item( int index ) const { - if (index < first_entry || index >= first_entry + pagesize) + if (!in_page(index)) return; - gotoxy( 1, y_offset + index - first_entry ); - textcolor( item_colour(items[index]) ); - cprintf( "%s", items[index]->get_text().c_str() ); + + draw_item(index, items[index]); +} + +void Menu::draw_item(int index, const MenuEntry *me) const +{ + if (f_drawitem) + (*f_drawitem)(index, me); + else + { + textcolor( item_colour(items[index]) ); + cprintf( "%s", items[index]->get_text().c_str() ); + } } bool Menu::page_down() diff --git a/crawl-ref/source/menu.h b/crawl-ref/source/menu.h index a788b92ebc..57b90b33b0 100644 --- a/crawl-ref/source/menu.h +++ b/crawl-ref/source/menu.h @@ -5,6 +5,7 @@ #include <vector> #include <algorithm> #include "AppHdr.h" +#include "externs.h" #include "defines.h" #include "libutil.h" @@ -123,15 +124,18 @@ public: enum MenuFlag { - MF_NOSELECT = 0, // No selection is permitted - MF_SINGLESELECT = 1, // Select just one item - MF_MULTISELECT = 2, // Select multiple items - MF_NO_SELECT_QTY = 4, // Disallow partial selections - MF_ANYPRINTABLE = 8, // Any printable character is valid, and - // closes the menu. - MF_SELECT_ANY_PAGE = 16, // Allow selections to occur on any page. - - MF_EASY_EXIT = 64 + MF_NOSELECT = 0x0000, // No selection is permitted + MF_SINGLESELECT = 0x0001, // Select just one item + MF_MULTISELECT = 0x0002, // Select multiple items + MF_NO_SELECT_QTY = 0x0004, // Disallow partial selections + MF_ANYPRINTABLE = 0x0008, // Any printable character is valid, and + // closes the menu. + MF_SELECT_ANY_PAGE = 0x0010, // Allow selections to occur on any page. + + MF_ALWAYS_SHOW_MORE = 0x0020, // Always show the -more- footer + MF_NOWRAP = 0x0040, // Paging past the end will not wrap back. + + MF_EASY_EXIT = 0x1000 }; /////////////////////////////////////////////////////////////////////// @@ -147,12 +151,17 @@ public: Menu( int flags = MF_MULTISELECT ); virtual ~Menu(); - void set_flags( int new_flags ) { this->flags = new_flags; } + // Sets menu flags to new_flags. If use_options is true, game options may + // override options. + void set_flags(int new_flags, bool use_options = true); int get_flags() const { return flags; } bool is_set( int flag ) const; bool draw_title_suffix( const std::string &s, bool titlefirst = true ); void update_title(); + + // Sets a replacement for the --more-- string. + void set_more(const formatted_string &more); void set_highlighter( MenuHighlighter *h ); void set_title( MenuEntry *e ); @@ -171,8 +180,12 @@ public: public: typedef std::string (*selitem_tfn)( const std::vector<MenuEntry*> *sel ); + typedef void (*drawitem_tfn)(int index, const MenuEntry *me); + typedef int (*keyfilter_tfn)(int keyin); - selitem_tfn selitem_text; + selitem_tfn f_selitem; + drawitem_tfn f_drawitem; + keyfilter_tfn f_keyfilter; protected: MenuEntry *title; @@ -181,6 +194,8 @@ protected: int first_entry, y_offset; int pagesize; + formatted_string more; + std::vector<MenuEntry*> items; std::vector<MenuEntry*> *sel; std::vector<text_pattern> select_filter; @@ -196,7 +211,9 @@ protected: void do_menu( std::vector<MenuEntry*> *selected ); virtual void draw_select_count( int count ); - void draw_item( int index ) const; + virtual void draw_item( int index ) const; + virtual void draw_item(int index, const MenuEntry *me) const; + virtual void draw_title(); void draw_menu( std::vector<MenuEntry*> *selected ); bool page_down(); @@ -204,6 +221,8 @@ protected: bool page_up(); bool line_up(); + bool in_page(int index) const; + void deselect_all(bool update_view = true); void select_items( int key, int qty = -1 ); void select_index( int index, int qty = -1 ); |