Annotation of quake2/ctf/p_menu.c, revision 1.1.1.1

1.1       root        1: #include "g_local.h"
                      2: 
                      3: // Note that the pmenu entries are duplicated
                      4: // this is so that a static set of pmenu entries can be used
                      5: // for multiple clients and changed without interference
                      6: // note that arg will be freed when the menu is closed, it must be allocated memory
                      7: pmenuhnd_t *PMenu_Open(edict_t *ent, pmenu_t *entries, int cur, int num, void *arg)
                      8: {
                      9:        pmenuhnd_t *hnd;
                     10:        pmenu_t *p;
                     11:        int i;
                     12: 
                     13:        if (!ent->client)
                     14:                return NULL;
                     15: 
                     16:        if (ent->client->menu) {
                     17:                gi.dprintf("warning, ent already has a menu\n");
                     18:                PMenu_Close(ent);
                     19:        }
                     20: 
                     21:        hnd = malloc(sizeof(*hnd));
                     22: 
                     23:        hnd->arg = arg;
                     24:        hnd->entries = malloc(sizeof(pmenu_t) * num);
                     25:        memcpy(hnd->entries, entries, sizeof(pmenu_t) * num);
                     26:        // duplicate the strings since they may be from static memory
                     27:        for (i = 0; i < num; i++)
                     28:                if (entries[i].text)
                     29:                        hnd->entries[i].text = strdup(entries[i].text);
                     30: 
                     31:        hnd->num = num;
                     32: 
                     33:        if (cur < 0 || !entries[cur].SelectFunc) {
                     34:                for (i = 0, p = entries; i < num; i++, p++)
                     35:                        if (p->SelectFunc)
                     36:                                break;
                     37:        } else
                     38:                i = cur;
                     39: 
                     40:        if (i >= num)
                     41:                hnd->cur = -1;
                     42:        else
                     43:                hnd->cur = i;
                     44: 
                     45:        ent->client->showscores = true;
                     46:        ent->client->inmenu = true;
                     47:        ent->client->menu = hnd;
                     48: 
                     49:        PMenu_Do_Update(ent);
                     50:        gi.unicast (ent, true);
                     51: 
                     52:        return hnd;
                     53: }
                     54: 
                     55: void PMenu_Close(edict_t *ent)
                     56: {
                     57:        int i;
                     58:        pmenuhnd_t *hnd;
                     59: 
                     60:        if (!ent->client->menu)
                     61:                return;
                     62: 
                     63:        hnd = ent->client->menu;
                     64:        for (i = 0; i < hnd->num; i++)
                     65:                if (hnd->entries[i].text)
                     66:                        free(hnd->entries[i].text);
                     67:        free(hnd->entries);
                     68:        if (hnd->arg)
                     69:                free(hnd->arg);
                     70:        free(hnd);
                     71:        ent->client->menu = NULL;
                     72:        ent->client->showscores = false;
                     73: }
                     74: 
                     75: // only use on pmenu's that have been called with PMenu_Open
                     76: void PMenu_UpdateEntry(pmenu_t *entry, const char *text, int align, SelectFunc_t SelectFunc)
                     77: {
                     78:        if (entry->text)
                     79:                free(entry->text);
                     80:        entry->text = strdup(text);
                     81:        entry->align = align;
                     82:        entry->SelectFunc = SelectFunc;
                     83: }
                     84: 
                     85: void PMenu_Do_Update(edict_t *ent)
                     86: {
                     87:        char string[1400];
                     88:        int i;
                     89:        pmenu_t *p;
                     90:        int x;
                     91:        pmenuhnd_t *hnd;
                     92:        char *t;
                     93:        qboolean alt = false;
                     94: 
                     95:        if (!ent->client->menu) {
                     96:                gi.dprintf("warning:  ent has no menu\n");
                     97:                return;
                     98:        }
                     99: 
                    100:        hnd = ent->client->menu;
                    101: 
                    102:        strcpy(string, "xv 32 yv 8 picn inventory ");
                    103: 
                    104:        for (i = 0, p = hnd->entries; i < hnd->num; i++, p++) {
                    105:                if (!p->text || !*(p->text))
                    106:                        continue; // blank line
                    107:                t = p->text;
                    108:                if (*t == '*') {
                    109:                        alt = true;
                    110:                        t++;
                    111:                }
                    112:                sprintf(string + strlen(string), "yv %d ", 32 + i * 8);
                    113:                if (p->align == PMENU_ALIGN_CENTER)
                    114:                        x = 196/2 - strlen(t)*4 + 64;
                    115:                else if (p->align == PMENU_ALIGN_RIGHT)
                    116:                        x = 64 + (196 - strlen(t)*8);
                    117:                else
                    118:                        x = 64;
                    119: 
                    120:                sprintf(string + strlen(string), "xv %d ",
                    121:                        x - ((hnd->cur == i) ? 8 : 0));
                    122: 
                    123:                if (hnd->cur == i)
                    124:                        sprintf(string + strlen(string), "string2 \"\x0d%s\" ", t);
                    125:                else if (alt)
                    126:                        sprintf(string + strlen(string), "string2 \"%s\" ", t);
                    127:                else
                    128:                        sprintf(string + strlen(string), "string \"%s\" ", t);
                    129:                alt = false;
                    130:        }
                    131: 
                    132:        gi.WriteByte (svc_layout);
                    133:        gi.WriteString (string);
                    134: }
                    135: 
                    136: void PMenu_Update(edict_t *ent)
                    137: {
                    138:        if (!ent->client->menu) {
                    139:                gi.dprintf("warning:  ent has no menu\n");
                    140:                return;
                    141:        }
                    142: 
                    143:        if (level.time - ent->client->menutime >= 1.0) {
                    144:                // been a second or more since last update, update now
                    145:                PMenu_Do_Update(ent);
                    146:                gi.unicast (ent, true);
                    147:                ent->client->menutime = level.time;
                    148:                ent->client->menudirty = false;
                    149:        }
                    150:        ent->client->menutime = level.time + 0.2;
                    151:        ent->client->menudirty = true;
                    152: }
                    153: 
                    154: void PMenu_Next(edict_t *ent)
                    155: {
                    156:        pmenuhnd_t *hnd;
                    157:        int i;
                    158:        pmenu_t *p;
                    159: 
                    160:        if (!ent->client->menu) {
                    161:                gi.dprintf("warning:  ent has no menu\n");
                    162:                return;
                    163:        }
                    164: 
                    165:        hnd = ent->client->menu;
                    166: 
                    167:        if (hnd->cur < 0)
                    168:                return; // no selectable entries
                    169: 
                    170:        i = hnd->cur;
                    171:        p = hnd->entries + hnd->cur;
                    172:        do {
                    173:                i++, p++;
                    174:                if (i == hnd->num)
                    175:                        i = 0, p = hnd->entries;
                    176:                if (p->SelectFunc)
                    177:                        break;
                    178:        } while (i != hnd->cur);
                    179: 
                    180:        hnd->cur = i;
                    181: 
                    182:        PMenu_Update(ent);
                    183: }
                    184: 
                    185: void PMenu_Prev(edict_t *ent)
                    186: {
                    187:        pmenuhnd_t *hnd;
                    188:        int i;
                    189:        pmenu_t *p;
                    190: 
                    191:        if (!ent->client->menu) {
                    192:                gi.dprintf("warning:  ent has no menu\n");
                    193:                return;
                    194:        }
                    195: 
                    196:        hnd = ent->client->menu;
                    197: 
                    198:        if (hnd->cur < 0)
                    199:                return; // no selectable entries
                    200: 
                    201:        i = hnd->cur;
                    202:        p = hnd->entries + hnd->cur;
                    203:        do {
                    204:                if (i == 0) {
                    205:                        i = hnd->num - 1;
                    206:                        p = hnd->entries + i;
                    207:                } else
                    208:                        i--, p--;
                    209:                if (p->SelectFunc)
                    210:                        break;
                    211:        } while (i != hnd->cur);
                    212: 
                    213:        hnd->cur = i;
                    214: 
                    215:        PMenu_Update(ent);
                    216: }
                    217: 
                    218: void PMenu_Select(edict_t *ent)
                    219: {
                    220:        pmenuhnd_t *hnd;
                    221:        pmenu_t *p;
                    222: 
                    223:        if (!ent->client->menu) {
                    224:                gi.dprintf("warning:  ent has no menu\n");
                    225:                return;
                    226:        }
                    227: 
                    228:        hnd = ent->client->menu;
                    229: 
                    230:        if (hnd->cur < 0)
                    231:                return; // no selectable entries
                    232: 
                    233:        p = hnd->entries + hnd->cur;
                    234: 
                    235:        if (p->SelectFunc)
                    236:                p->SelectFunc(ent, hnd);
                    237: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.