Changeset 20

Show
Ignore:
Timestamp:
03/28/07 12:14:46 (2 years ago)
Author:
pmac
Message:

Eliminated "get_player_choice" in birth.c
Cleaned up bugs found in ui.c as result.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/birth.c

    r11 r20  
    614614#define CLASS_AUX_COL   50 
    615615 
    616  
    617 typedef struct birth_menu birth_menu; 
    618  
    619  
    620 /* 
    621  * A structure to hold the menus 
    622  */ 
    623 struct birth_menu 
    624 { 
    625         bool grayed; 
    626         cptr name; 
    627 }; 
    628  
    629  
    630616/* 
    631617 * Clear the previous question 
     
    641627        } 
    642628} 
    643  
    644  
    645 /* 
    646  * Generic "get choice from menu" function 
    647  */ 
    648 static int get_player_choice(birth_menu *choices, int num, int def, 
    649                              int col, int wid, byte *select, 
    650                              cptr helpfile, void (*hook)(birth_menu)) 
    651 
    652         int top = 0, cur = def; 
    653         int i, dir; 
    654         char c; 
    655         char buf[80]; 
    656         bool done = FALSE; 
    657         int hgt; 
    658         byte attr; 
    659  
    660         /* Autoselect if able */ 
    661         if (num == 1) done = TRUE; 
    662  
    663         /* Clear */ 
    664         for (i = TABLE_ROW; i < Term->hgt; i++) 
    665         { 
    666                 /* Clear */ 
    667                 Term_erase(col, i, Term->wid - wid); 
    668         } 
    669  
    670         /* Choose */ 
    671         while (TRUE) 
    672         { 
    673                 hgt = Term->hgt - TABLE_ROW - 1; 
    674  
    675                 /* Redraw the list */ 
    676                 for (i = 0; ((i + top < num) && (i <= hgt)); i++) 
    677                 { 
    678                         if (i + top < 26) 
    679                         { 
    680                                 strnfmt(buf, sizeof(buf), "%c) %s", I2A(i + top), 
    681                                         choices[i + top].name); 
    682                         } 
    683                         else 
    684                         { 
    685                                 /* ToDo: Fix the ASCII dependency */ 
    686                                 strnfmt(buf, sizeof(buf), "%c) %s", 'A' + (i + top - 26), 
    687                                         choices[i + top].name); 
    688                         } 
    689  
    690                         /* Clear */ 
    691                         Term_erase(col, i + TABLE_ROW, wid); 
    692  
    693                         /* Display */ 
    694                         if (i == (cur - top)) 
    695                         { 
    696                                 /* Highlight the current selection */ 
    697                                 if (choices[i + top].grayed) attr = TERM_BLUE; 
    698                                 else attr = TERM_L_BLUE; 
    699                         } 
    700                         else 
    701                         { 
    702                                 if (choices[i + top].grayed) attr = TERM_SLATE; 
    703                                 else attr = TERM_WHITE; 
    704                         } 
    705  
    706                         Term_putstr(col, i + TABLE_ROW, wid, attr, buf); 
    707                 } 
    708  
    709                 if (done) 
    710                 { 
    711                         /* Set the value */ 
    712                         *select = cur; 
    713  
    714                         /* Success */ 
    715                         return BIRTH_SUCCESS; 
    716                 } 
    717  
    718                 /* Display auxiliary information if any is available. */ 
    719                 if (hook) hook(choices[cur]); 
    720  
    721                 /* Move the cursor */ 
    722                 put_str("", TABLE_ROW + cur - top, col); 
    723  
    724                 c = inkey(); 
    725  
    726                 /* Exit the game */ 
    727                 if (c == KTRL('X')) quit(NULL); 
    728  
    729                 /* Make a choice */ 
    730                 if ((c == '\n') || (c == '\r')) 
    731                 { 
    732                         /* Set the value */ 
    733                         *select = cur; 
    734  
    735                         /* Success */ 
    736                         return BIRTH_SUCCESS; 
    737                 } 
    738  
    739                 /* Random choice */ 
    740                 if (c == '*') 
    741                 { 
    742                         /* Ensure legal choice */ 
    743                         do { cur = rand_int(num); } while (choices[cur].grayed); 
    744  
    745                         /* Done */ 
    746                         done = TRUE; 
    747                 } 
    748  
    749                 /* Alphabetic choice */ 
    750                 else if (isalpha((unsigned char)c)) 
    751                 { 
    752                         int choice; 
    753  
    754                         if (islower((unsigned char)c)) choice = A2I(c); 
    755                         else choice = c - 'A' + 26; 
    756  
    757                         /* Validate input */ 
    758                         if ((choice > -1) && (choice < num)) 
    759                         { 
    760                                 cur = choice; 
    761  
    762                                 /* Done */ 
    763                                 done = TRUE; 
    764                         } 
    765                         else 
    766                         { 
    767                                 bell("Illegal response to question!"); 
    768                         } 
    769                 } 
    770  
    771                 /* Move */ 
    772                 else if (isdigit((unsigned char)c) || isarrow(c)) 
    773                 { 
    774                         /* Get a direction from the key */ 
    775                         dir = target_dir(c); 
    776  
    777                         /* Going up? */ 
    778                         if (dir == 8) 
    779                         { 
    780                                 /* Move selection */ 
    781                                 if (cur != 0) cur--; 
    782  
    783                                 /* Scroll up */ 
    784                                 if ((top > 0) && ((cur - top) < 4)) top--; 
    785                         } 
    786  
    787                         /* Going down? */ 
    788                         else if (dir == 2) 
    789                         { 
    790                                 /* Move selection */ 
    791                                 if (cur != (num - 1)) cur++; 
    792  
    793                                 /* Scroll down */ 
    794                                 if ((top + hgt < (num - 1)) && ((top + hgt - cur) < 4)) top++; 
    795                         } 
    796  
    797                         /* Going back? */ 
    798                         else if (dir == 4) 
    799                         { 
    800                                 /* Save the current value (for later) */ 
    801                                 *select = cur; 
    802  
    803                                 /* Return */ 
    804                                 return BIRTH_BACK; 
    805                         } 
    806  
    807                         /* Going forward acts as pressing enter */ 
    808                         else if (dir == 6) 
    809                         { 
    810                                 /* Set the value */ 
    811                                 *select = cur; 
    812  
    813                                 /* Success */ 
    814                                 return BIRTH_SUCCESS; 
    815                         } 
    816                 } 
    817  
    818                 /* Hack - go back */ 
    819                 else if (c == ESCAPE) return BIRTH_RESTART; 
    820  
    821                 /* Help */ 
    822                 else if (c == '?') 
    823                 { 
    824                         strnfmt(buf, sizeof(buf), "%s#%s", helpfile, choices[cur].name); 
    825  
    826                         screen_save(); 
    827                         (void)show_file(buf, NULL, 0, 0); 
    828                         screen_load(); 
    829                 } 
    830  
    831                 /* Options */ 
    832                 else if (c == '=') 
    833                 { 
    834                         do_cmd_options(); 
    835                 } 
    836  
    837                 /* Invalid input */ 
    838                 else bell("Illegal response to question!"); 
    839  
    840                 /* If choice is off screen, move it to the top */ 
    841                 if ((cur < top) || (cur > top + hgt)) top = cur; 
    842         } 
    843 
    844  
     629/* =================================================== */ 
     630 
     631/* gender/race/classs menu selector */ 
    845632 
    846633/* 
    847634 * Display additional information about each race during the selection. 
    848635 */ 
    849 static void race_aux_hook(birth_menu r_str
    850 { 
    851         int race, i; 
     636static void race_aux_hook(int race, const region *reg
     637{ 
     638        int i; 
    852639        char s[50]; 
    853  
    854         /* Extract the proper race index from the string. */ 
    855         for (race = 0; race < z_info->p_max; race++) 
    856         { 
    857                 if (!strcmp(r_str.name, p_name + p_info[race].name)) break; 
    858         } 
    859640 
    860641        if (race == z_info->p_max) return; 
     
    878659 
    879660/* 
    880  * Player race 
    881  */ 
    882 static bool get_player_race(void) 
    883 { 
    884         int i, res; 
    885         birth_menu *races; 
    886  
    887         C_MAKE(races, z_info->p_max, birth_menu); 
    888  
    889         /* Extra info */ 
    890         Term_putstr(QUESTION_COL, QUESTION_ROW, -1, TERM_YELLOW, 
    891                     "Your 'race' determines various intrinsic factors and bonuses."); 
    892  
    893         /* Tabulate races */ 
    894         for (i = 0; i < z_info->p_max; i++) 
    895         { 
    896                 races[i].name = p_name + p_info[i].name; 
    897                 races[i].grayed = FALSE; 
    898         } 
    899  
    900         res = get_player_choice(races, z_info->p_max, p_ptr->prace, 
    901                                          RACE_COL, 15, &p_ptr->prace, 
    902                                          "birth.txt", race_aux_hook); 
    903  
    904         /* Free memory */ 
    905         FREE(races); 
    906  
    907         /* No selection? */ 
    908         if (res < 0) return (res); 
    909  
    910         /* Save the race pointer */ 
    911         rp_ptr = &p_info[p_ptr->prace]; 
    912  
    913         /* Success */ 
    914         return (TRUE); 
    915 } 
    916  
    917  
    918 /* 
    919661 * Display additional information about each class during the selection. 
    920662 */ 
    921 static void class_aux_hook(birth_menu c_str
    922 { 
    923         int class_idx, i; 
     663static void class_aux_hook(int class_idx, const region *loc
     664{ 
     665        int i; 
    924666        char s[128]; 
    925  
    926         /* Extract the proper class index from the string. */ 
    927         for (class_idx = 0; class_idx < z_info->c_max; class_idx++) 
    928         { 
    929                 if (!strcmp(c_str.name, c_name + c_info[class_idx].name)) break; 
    930         } 
    931667 
    932668        if (class_idx == z_info->c_max) return; 
     
    947683 
    948684 
    949 /* 
    950  * Player class 
    951  */ 
    952 static bool get_player_class(void) 
    953 
    954         int i, res; 
    955         birth_menu *classes; 
    956  
    957         C_MAKE(classes, z_info->c_max, birth_menu); 
    958  
    959         /* Extra info */ 
    960         Term_putstr(QUESTION_COL, QUESTION_ROW, -1, TERM_YELLOW, 
    961                     "Your 'class' determines various intrinsic abilities and bonuses."); 
    962         Term_putstr(QUESTION_COL, QUESTION_ROW + 1, -1, TERM_YELLOW, 
    963                     "Any greyed-out entries should only be used by advanced players."); 
    964  
    965         /* Tabulate classes */ 
    966         for (i = 0; i < z_info->c_max; i++) 
    967         { 
    968                 /* Analyze */ 
    969                 if (!(rp_ptr->choice & (1L << i))) classes[i].grayed = TRUE; 
    970                 else classes[i].grayed = FALSE; 
    971  
    972                 /* Save the string */ 
    973                 classes[i].name = c_name + c_info[i].name; 
    974         } 
    975  
    976         res = get_player_choice(classes, z_info->c_max, p_ptr->pclass, 
    977                                           CLASS_COL, 20, &p_ptr->pclass, 
    978                                           "birth.txt", class_aux_hook); 
    979  
    980         /* Free memory */ 
    981         FREE(classes); 
    982  
    983         /* No selection? */ 
    984         if (res < 0) return (res); 
    985  
    986         /* Set class */ 
    987         cp_ptr = &c_info[p_ptr->pclass]; 
    988         mp_ptr = &cp_ptr->spells; 
    989  
    990         return (TRUE); 
    991 
    992  
    993  
    994 /* 
    995  * Player sex 
    996  */ 
    997 static bool get_player_sex(void) 
    998 
    999         int i, res; 
    1000         birth_menu genders[MAX_SEXES]; 
    1001  
    1002         /* Extra info */ 
    1003         Term_putstr(QUESTION_COL, QUESTION_ROW, -1, TERM_YELLOW, 
    1004                     "Your 'sex' does not have any significant gameplay effects."); 
    1005  
    1006         /* Tabulate genders */ 
    1007         for (i = 0; i < MAX_SEXES; i++) 
    1008         { 
    1009                 genders[i].name = sex_info[i].title; 
    1010                 genders[i].grayed = FALSE; 
    1011         } 
    1012  
    1013         res = get_player_choice(genders, MAX_SEXES, p_ptr->psex, 
    1014                                         SEX_COL, 15, &p_ptr->psex, 
    1015                                         "birth.txt", NULL); 
    1016  
    1017         /* No selection? */ 
    1018         if (res < 0) return (res); 
    1019  
    1020         /* Save the sex pointer */ 
    1021         sp_ptr = &sex_info[p_ptr->psex]; 
    1022  
    1023         return (TRUE); 
     685static region gender_region = {SEX_COL, TABLE_ROW, 15, -2}; 
     686static region race_region = {RACE_COL, TABLE_ROW, 15, -2}; 
     687static region class_region = {CLASS_COL, TABLE_ROW, 15, -2}; 
     688 
     689static void show_help(cptr helpfile, cptr topic) { 
     690        char buf[80]; 
     691        strnfmt(buf, sizeof(buf), "%s#%s", helpfile, topic); 
     692        screen_save(); 
     693        show_file(buf, NULL, 0, 0); 
     694        screen_load(); 
     695
     696 
     697/* GENDER */ 
     698/* Could make a general purpose display, but see no point. */ 
     699static void display_gender(menu_type *menu, int oid, bool cursor, 
     700                                                        int row, int col, int width) 
     701
     702        byte attr = curs_attrs[CURS_KNOWN][0 != cursor]; 
     703        c_prt(attr, sex_info[oid].title, row, col); 
     704
     705 
     706/* Not worth writing a general purpose handler */ 
     707static bool gender_handler(char cmd, void *db, int oid) 
     708
     709        if(cmd == '\xff') { 
     710                p_ptr->psex = oid; 
     711                sp_ptr = &sex_info[p_ptr->psex]; 
     712        } 
     713        else if(cmd == '*') { 
     714                p_ptr->prace = rand_int(SEX_MALE); 
     715                sp_ptr = &sex_info[p_ptr->psex]; 
     716        } 
     717        else if(cmd == KTRL('X')) quit(NULL); 
     718        else if(cmd == '?')  show_help("birth.txt", sex_info[oid].title); 
     719        else return FALSE; 
     720        return TRUE; 
     721
     722 
     723/* RACE */ 
     724static void display_race(menu_type *menu, int oid, bool cursor, 
     725                                                int row, int col, int width) 
     726
     727        byte attr = curs_attrs[CURS_KNOWN][0 != cursor]; 
     728        c_prt(attr, p_name + p_info[oid].name, row, col); 
     729
     730 
     731static bool race_handler(char cmd, void *db, int oid) 
     732
     733        if(cmd == '\xff') { 
     734                p_ptr->prace = oid; 
     735                rp_ptr = &p_info[p_ptr->prace]; 
     736        } 
     737        else if(cmd == '*') { 
     738                p_ptr->prace = rand_int(z_info->p_max); 
     739                rp_ptr = &p_info[p_ptr->prace]; 
     740        } 
     741        else if(cmd == KTRL('X')) quit(NULL); 
     742        else if(cmd == '?')  show_help("birth.txt", p_name+p_info[oid].name); 
     743        else return FALSE; 
     744        return TRUE; 
     745
     746 
     747 
     748/* CLASS */ 
     749static void display_class(menu_type *menu, int oid, bool cursor, 
     750                                                        int row, int col, int width) 
     751
     752        byte attr = curs_attrs[0 != (rp_ptr->choice & (1L << oid))][0 != cursor]; 
     753        c_prt(attr, c_name + c_info[oid].name, row, col); 
     754
     755 
     756static bool class_handler(char cmd, void *db, int oid) 
     757
     758        if(cmd == '\xff') { 
     759                p_ptr->pclass = oid; 
     760                cp_ptr = &c_info[p_ptr->pclass]; 
     761                mp_ptr = &cp_ptr->spells; 
     762        } 
     763        else if(cmd == '*') { 
     764                for(;;) { 
     765                        p_ptr->pclass = rand_int(z_info->c_max); 
     766                        cp_ptr = &c_info[p_ptr->pclass]; 
     767                        mp_ptr = &cp_ptr->spells; 
     768                        if((rp_ptr->choice & (1L << oid))) 
     769                                break; 
     770                } 
     771        } 
     772        else if(cmd == KTRL('X')) quit(NULL); 
     773        else if(cmd == '?') show_help("birth.txt", c_name+c_info[oid].name); 
     774        else return FALSE; 
     775        return TRUE; 
     776
     777 
     778 
     779static const menu_class menu_defs[] = { 
     780        {0, 0, 0, display_gender, gender_handler }, 
     781        {0, 0, 0, display_race, race_handler }, 
     782        {0, 0, 0, display_class, class_handler }, 
     783}; 
     784 
     785/* Menu display and selector */ 
     786 
     787static void choose_character() 
     788
     789        int i; 
     790 
     791        const region *regions [] = {&gender_region, &race_region, &class_region}; 
     792        byte *values [] = {&p_ptr->psex, &p_ptr->prace, &p_ptr->pclass}; 
     793        int limits [] = {SEX_MALE+1, z_info->p_max, z_info->c_max}; 
     794        const char *hints [] = { 
     795                "Your 'sex' does not have any significant gameplay effects.", 
     796                "Your 'race' determines various intrinsic factors and bonuses.", 
     797                "Your 'class' determines various intrinsic abilities and bonuses" }; 
     798         
     799        typedef void (*browse_f) (int oid, const region *loc); 
     800        browse_f browse [] = {NULL, race_aux_hook, class_aux_hook }; 
     801        menu_type menu; 
     802        WIPE(&menu, menu); 
     803        menu.cmd_keys = "?*"; 
     804 
     805        for(i = 0; i < N_ELEMENTS(menu_defs); i++) 
     806        { 
     807                key_event cx; 
     808                int cursor = *values[i]; 
     809                clear_question(); 
     810        Term_putstr(QUESTION_COL, QUESTION_ROW, -1, TERM_YELLOW, hints[i]); 
     811                menu.count = limits[i]; 
     812                menu.flags = MN_NO_TAGS | MN_DBL_TAP; 
     813                menu_init(&menu); 
     814                menu_set_class(&menu, &menu_defs[i]); 
     815                menu.browse_hook = browse[i]; 
     816 
     817                cx = menu_select(&menu, 0, menu.count, &cursor, *regions[i]); 
     818                if(cx.key == ESCAPE) { 
     819                        i = 0; /* restart */ 
     820                } 
     821                else if(cx.type == EVT_BACK) { 
     822                        i--; 
     823                } 
     824        } 
     825 
    1024826} 
    1025827 
     
    1033835static bool player_birth_aux_1(void) 
    1034836{ 
    1035         int i, res, cur
     837        int i
    1036838 
    1037839        /*** Instructions ***/ 
     
    1069871        text_out_indent = 0; 
    1070872 
    1071         /* Prepare for user selection */ 
    1072         cur = 0; 
    1073         res = 0; 
    1074  
    1075         /* Get user choices */ 
    1076         while (cur < 3) 
    1077         { 
    1078                 /* Get the player's choice */ 
    1079                 switch (cur) 
    1080                 { 
    1081                         case 0: res = get_player_sex(); break; 
    1082                         case 1: res = get_player_race(); break; 
    1083                         case 2: res = get_player_class(); break; 
    1084                 } 
    1085  
    1086                 /* Clean up */ 
    1087                 clear_question(); 
    1088  
    1089                 /* Act on the result */ 
    1090                 if (res == BIRTH_RESTART) return (FALSE); 
    1091  
    1092                 /* Work out where we are on the menu system now */ 
    1093                 if ((res == BIRTH_BACK) && (cur > 0)) cur--; 
    1094                 else cur++; 
    1095         } 
     873        choose_character(); 
     874 
    1096875 
    1097876        /* Set adult options from birth options */ 
     
    1127906} 
    1128907 
     908/* =================================================== */ 
    1129909 
    1130910/* 
  • trunk/src/ui.c

    r16 r20  
    6262        if(cmd == '\xff' && evt->action) { 
    6363                evt->action(evt->data, evt->name); 
     64        } 
     65        else if(cmd == '\xff') 
    6466                return TRUE; 
    65         } 
    66         return FALSE; 
    6767} 
    6868 
     
    299299        if(menu->handler) 
    300300                return menu->handler(cmd, menu->menu_data, oid); 
    301         return TRUE; 
     301        return FALSE; 
    302302} 
    303303 
     
    481481                 
    482482                menu->skin->display_list(menu, object_list, n, *cursor, &top, &active); 
     483                /* if(menu->flags & MN_DISPLAY_ONLY) 
     484                        return; 
     485                */ 
    483486                if(menu->browse_hook) { 
    484487                        menu->browse_hook(oid, &loc); 
     
    495498                        case EVT_MOVE: 
    496499                                continue; 
     500                        case EVT_SELECT: 
     501                                if(oid != *cursor) /* refresh */ 
     502                                        menu->skin->display_list(menu, object_list, n, *cursor, &top, &active); 
    497503                } 
    498504                if(menu->flags & MN_NO_ACT) 
    499505                        return ke; 
    500506 
    501                 if(!handle_menu_key(ke.key, menu, *cursor)) 
     507                if(handle_menu_key(ke.key, menu, *cursor)) 
    502508                        return ke; 
    503509        } 
     
    522528}; 
    523529 
     530void menu_set_class(menu_type *menu, const menu_class *def) 
     531{ 
     532        menu->flags |= def->flag; 
     533        menu->get_tag = def->get_tag; 
     534        menu->valid_row = def->valid_row; 
     535        menu->handler = def->handler; 
     536        menu->display_label = def->display_row; 
     537} 
    524538 
    525539bool menu_init(menu_type *menu) 
     
    539553        { 
    540554                if(menu_class_reg[i]->flag == classID) { 
    541                         menu->handler = menu_class_reg[i]->handler; 
    542                         menu->display_label = menu_class_reg[i]->display_row; 
    543                         menu->valid_row = menu_class_reg[i]->valid_row; 
    544                         menu->get_tag = menu_class_reg[i]->get_tag; 
     555                        menu_set_class(menu, menu_class_reg[i]); 
    545556                } 
    546557        } 
     
    553564        return TRUE; 
    554565} 
     566 
  • trunk/src/ui.h

    r17 r20  
    204204        bool (*handler)(char cmd, void *db, int oid); 
    205205 
    206         int (*browse_hook)(int oid, region *loc);  /* auxiliary browser help function */ 
     206        void (*browse_hook)(int oid, const region *loc);  /* auxiliary browser help function */ 
    207207 
    208208        /* These are "protected" - not visible for canned menu classes, */ 
     
    261261/* Set up structures for canned menu actions */ 
    262262bool menu_init(menu_type *menu); 
     263void menu_set_class(menu_type *menu, const menu_class *class_def); 
    263264 
    264265