| Here's a replacement Menu routine for Hugo 2.1 that allows for multiple | |
| and nested menus. You can use it either as an #include'd header or | |
| cut and paste it directly into your source file. Since it is already set | |
| up to handle two menus of my own design, I'm including the code for the | |
| routines which call them for the sake of illustration. | |
| !---------------------------------------------------------------------------- | |
| ! x = Menu(menu_type) | |
| ! | |
| ! The Menu routine expects the array menuitem[] to hold a series of | |
| ! dictionary entries representing the list of possible choices, with the | |
| ! title of the menu contained in menuitem[0]. It returns the number chosen, | |
| ! or 0 if none is selected. | |
| ! | |
| ! The argument <menu_type> specifies which menu you want to display. You'll | |
| ! need to remember which type is which for when you make the call to Menu(). | |
| ! For instance, you'll need to remember that type 1 is the main menu, and | |
| ! type 2 the color menu and so on. This way of doing it allows you to add | |
| ! more menus to your game fairly easily. You just need to add a new | |
| ! initialization block to Menu() corresponding to your new menu type. | |
| ! | |
| ! Values *must* be given for <num> and <width> in the variable initialization | |
| ! blocks, since they're expected by the code which follows. Actually, you | |
| ! can get by with not specifying <width>, but <num> is mandatory. I've chosen | |
| ! the length of the longest string in each list for the widths, but there's | |
| ! nothing to prevent you from choosing another. | |
| #ifclear NO_MENUS | |
| #ifset NO_STRING_ARRAYS | |
| array _temp_string[256] | |
| #endif | |
| replace Menu(menu_type) | |
| { | |
| local a, i, column, olda, width, num | |
| if menu_type = 1 | |
| { menuitem[0]="Main Menu" | |
| menuitem[1]="Help" | |
| menuitem[2]="About" | |
| menuitem[3]="Legal" | |
| menuitem[4]="Credits" | |
| menuitem[5]="Color" | |
| num=5 ! number of choices in menu | |
| width=6 ! longest stg len (excluding title) | |
| } | |
| elseif menu_type = 2 | |
| { menuitem[0]="Choose Status Line Color" | |
| menuitem[1]="Black" | |
| menuitem[2]="Blue" | |
| menuitem[3]="Green" | |
| menuitem[4]="Cyan" | |
| menuitem[5]="Red" | |
| menuitem[6]="Magenta" | |
| menuitem[7]="Brown" | |
| menuitem[8]="White" | |
| num=8 ! number of choices in menu | |
| width=6 ! longest stg len (excluding title) | |
| } | |
| else | |
| { "Menu type not specified or doesn't exist. Can't display.\n" | |
| return true | |
| } | |
| if num = 0 | |
| { "Number of menu choices not defined. Can't display.\n" | |
| return true | |
| } | |
| if MENU_TEXTCOLOR=0 and MENU_BGCOLOR=0 ! must not have been set | |
| {MENU_TEXTCOLOR = TEXTCOLOR | |
| MENU_BGCOLOR = BGCOLOR | |
| MENU_SELECTCOLOR = SL_TEXTCOLOR | |
| MENU_SELECTBGCOLOR = SL_BGCOLOR} | |
| else | |
| {MENU_SELECTCOLOR = SL_TEXTCOLOR | |
| MENU_SELECTBGCOLOR = SL_BGCOLOR} | |
| if width = 0: width = 20 | |
| for (i=1; i<=num; i=i+1) ! determine appropriate width | |
| #ifclear NO_AUX_MATH | |
| width = higher(width, string(_temp_string, menuitem[i])) | |
| #endif | |
| #ifset NO_AUX_MATH | |
| {a = string(_temp_string, menuitem[i]) | |
| if a > width: width = a} | |
| #endif | |
| column = MAX_LINE/2 - width/2 | |
| color TEXTCOLOR, BGCOLOR | |
| cls | |
| window ! print title of menu | |
| { | |
| color MENU_SELECTCOLOR, MENU_SELECTBGCOLOR | |
| print to (MAX_LINE/2-string(_temp_string, menuitem[0])/2-1); | |
| print menuitem[0]; | |
| print to MAX_LINE | |
| color MENU_TEXTCOLOR, MENU_BGCOLOR | |
| } | |
| locate 1, 1 ! print commands | |
| print "[N]ext item"; to (MAX_LINE - 11); "[Q]uit menu" | |
| print "[P]revious item"; to (MAX_LINE - 17); "[Enter] to select" | |
| for (i=1; i<=num; i=i+1) ! print menu choices | |
| { | |
| color MENU_TEXTCOLOR, MENU_BGCOLOR | |
| locate column, (3+i) | |
| print menuitem[i]; to (column+width) | |
| } | |
| color TEXTCOLOR, BGCOLOR | |
| a = 1 | |
| while true ! continuous loop | |
| { | |
| if a ~= olda | |
| { | |
| if olda ~= 0 | |
| {locate column, (3+olda) | |
| color MENU_TEXTCOLOR, MENU_BGCOLOR | |
| print menuitem[olda]; to (column+width)} | |
| color MENU_SELECTCOLOR, MENU_SELECTBGCOLOR | |
| locate column, (3+a) | |
| print menuitem[a]; to (column+width) | |
| color TEXTCOLOR, BGCOLOR | |
| } | |
| locate column, (3+a) | |
| olda = a | |
| pause | |
| select word[0] | |
| case 'N', 'n', DOWN_ARROW, RIGHT_ARROW | |
| { | |
| a = a + 1 | |
| if a > num: a = 1 | |
| } | |
| case 'P', 'p', UP_ARROW, LEFT_ARROW | |
| { | |
| a = a - 1 | |
| if a = 0: a = num | |
| } | |
| case 'Q', 'q', ESCAPE_KEY | |
| { | |
| window: print to MAX_LINE | |
| cls | |
| return 0 | |
| } | |
| case ENTER_KEY | |
| { | |
| window: print to MAX_LINE | |
| cls | |
| return a | |
| } | |
| if word[0] >= '0' and word[0] <= '9' | |
| { | |
| a = word[0] - '0' | |
| if a = 0: a = 10 | |
| if a > num: a = olda | |
| } | |
| } | |
| } | |
| #endif ! ifclear NO_MENUS | |
| !---------------------------------------------------------------------------- | |
| ! The verb defs I'm using to allow the player to access my two menus from | |
| ! the command line: | |
| xverb "color" | |
| * DoColorMenu | |
| xverb "help", "menu" | |
| * DoHelpMenu | |
| ! A recommendation on style: | |
| ! | |
| ! I also place a call to DoColorMenu() right before the prompt = ">" line | |
| ! in my init() routines so the player can choose the status line color at | |
| ! the start of the game. Why? Two reasons: one, it breaks up the intro | |
| ! and makes the game start less abrupt, the way title and credit sequences | |
| ! do for movies, and two, it signals the player that menus are available in | |
| ! the game. | |
| !---------------------------------------------------------------------------- | |
| ! Here are the verbroutines that are called by "help," "menu," and "color" | |
| ! (as well as directly as just described above). Note the call to DoColorMenu | |
| ! when the player makes selection 5 ("Color") in the help menu; this is an | |
| ! example of a nested menu. Note that the remainder of the help menu code | |
| ! has been omitted for the sake of clarity (it works, but it only responds | |
| ! to selection 5). | |
| routine DoColorMenu | |
| { | |
| local a | |
| a = Menu(2) | |
| SL_BGCOLOR = a - 1 ! because color 0 = menuitem[1], etc. | |
| if SL_BGCOLOR = 2 or SL_BGCOLOR = 3 | |
| SL_TEXTCOLOR = 0 ! black text for light backgrounds | |
| elseif SL_BGCOLOR = 6 or SL_BGCOLOR = 7 | |
| SL_TEXTCOLOR = 0 | |
| else : SL_TEXTCOLOR = 15 ! bright white text for darker bkgrds | |
| PrintStatusLine ! redisplay everything for the player | |
| DescribePlace(location) | |
| return true | |
| } | |
| routine DoHelpMenu | |
| { | |
| local a | |
| a = Menu(1) ! call with menu type | |
| if a = 5 | |
| { DoColorMenu | |
| return true ! to avoid duplication of room desc | |
| } | |
| PrintStatusLine ! redisplay everything for the player | |
| DescribePlace(location) | |
| return true | |
| } | |
| !---------------------------------------------------------------------------- | |
| Enjoy! | |
| This document is provided as-is, with no warranty whatsoever express or | |
| implied, by Cardinal Teulbachs, Archbishop of Frith. | |
Xet Storage Details
- Size:
- 7.24 kB
- Xet hash:
- fc162068867fb5ca6c37d7baf2820b0d9052af8699a091caf297029ad7942921
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.