|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.