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

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

unix.superglobalmegacorp.com

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