|
|
1.1 ! root 1: /* ! 2: Copyright (C) 1996-1997 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: */ ! 20: ! 21: #include "quakedef.h" ! 22: ! 23: cvar_t baseskin = {"baseskin", "base"}; ! 24: cvar_t noskins = {"noskins", "0"}; ! 25: ! 26: char allskins[128]; ! 27: #define MAX_CACHED_SKINS 128 ! 28: skin_t skins[MAX_CACHED_SKINS]; ! 29: int numskins; ! 30: ! 31: /* ! 32: ================ ! 33: Skin_Find ! 34: ! 35: Determines the best skin for the given scoreboard ! 36: slot, and sets scoreboard->skin ! 37: ! 38: ================ ! 39: */ ! 40: void Skin_Find (player_info_t *sc) ! 41: { ! 42: skin_t *skin; ! 43: int i; ! 44: char name[128], *s; ! 45: ! 46: if (allskins[0]) ! 47: strcpy (name, allskins); ! 48: else ! 49: { ! 50: s = Info_ValueForKey (sc->userinfo, "skin"); ! 51: if (s && s[0]) ! 52: strcpy (name, s); ! 53: else ! 54: strcpy (name, baseskin.string); ! 55: } ! 56: ! 57: if (strstr (name, "..") || *name == '.') ! 58: strcpy (name, "base"); ! 59: ! 60: COM_StripExtension (name, name); ! 61: ! 62: for (i=0 ; i<numskins ; i++) ! 63: { ! 64: if (!strcmp (name, skins[i].name)) ! 65: { ! 66: sc->skin = &skins[i]; ! 67: Skin_Cache (sc->skin); ! 68: return; ! 69: } ! 70: } ! 71: ! 72: if (numskins == MAX_CACHED_SKINS) ! 73: { // ran out of spots, so flush everything ! 74: Skin_Skins_f (); ! 75: return; ! 76: } ! 77: ! 78: skin = &skins[numskins]; ! 79: sc->skin = skin; ! 80: numskins++; ! 81: ! 82: memset (skin, 0, sizeof(*skin)); ! 83: strncpy(skin->name, name, sizeof(skin->name) - 1); ! 84: } ! 85: ! 86: ! 87: /* ! 88: ========== ! 89: Skin_Cache ! 90: ! 91: Returns a pointer to the skin bitmap, or NULL to use the default ! 92: ========== ! 93: */ ! 94: byte *Skin_Cache (skin_t *skin) ! 95: { ! 96: char name[1024]; ! 97: byte *raw; ! 98: byte *out, *pix; ! 99: pcx_t *pcx; ! 100: int x, y; ! 101: int dataByte; ! 102: int runLength; ! 103: ! 104: if (cls.downloadtype == dl_skin) ! 105: return NULL; // use base until downloaded ! 106: ! 107: if (noskins.value==1) // JACK: So NOSKINS > 1 will show skins, but ! 108: return NULL; // not download new ones. ! 109: ! 110: if (skin->failedload) ! 111: return NULL; ! 112: ! 113: out = Cache_Check (&skin->cache); ! 114: if (out) ! 115: return out; ! 116: ! 117: // ! 118: // load the pic from disk ! 119: // ! 120: sprintf (name, "skins/%s.pcx", skin->name); ! 121: raw = COM_LoadTempFile (name); ! 122: if (!raw) ! 123: { ! 124: Con_Printf ("Couldn't load skin %s\n", name); ! 125: sprintf (name, "skins/%s.pcx", baseskin.string); ! 126: raw = COM_LoadTempFile (name); ! 127: if (!raw) ! 128: { ! 129: skin->failedload = true; ! 130: return NULL; ! 131: } ! 132: } ! 133: ! 134: // ! 135: // parse the PCX file ! 136: // ! 137: pcx = (pcx_t *)raw; ! 138: raw = &pcx->data; ! 139: ! 140: if (pcx->manufacturer != 0x0a ! 141: || pcx->version != 5 ! 142: || pcx->encoding != 1 ! 143: || pcx->bits_per_pixel != 8 ! 144: || pcx->xmax >= 320 ! 145: || pcx->ymax >= 200) ! 146: { ! 147: skin->failedload = true; ! 148: Con_Printf ("Bad skin %s\n", name); ! 149: return NULL; ! 150: } ! 151: ! 152: out = Cache_Alloc (&skin->cache, 320*200, skin->name); ! 153: if (!out) ! 154: Sys_Error ("Skin_Cache: couldn't allocate"); ! 155: ! 156: pix = out; ! 157: memset (out, 0, 320*200); ! 158: ! 159: for (y=0 ; y<pcx->ymax ; y++, pix += 320) ! 160: { ! 161: for (x=0 ; x<=pcx->xmax ; ) ! 162: { ! 163: if (raw - (byte*)pcx > com_filesize) ! 164: { ! 165: Cache_Free (&skin->cache); ! 166: skin->failedload = true; ! 167: Con_Printf ("Skin %s was malformed. You should delete it.\n", name); ! 168: return NULL; ! 169: } ! 170: dataByte = *raw++; ! 171: ! 172: if((dataByte & 0xC0) == 0xC0) ! 173: { ! 174: runLength = dataByte & 0x3F; ! 175: if (raw - (byte*)pcx > com_filesize) ! 176: { ! 177: Cache_Free (&skin->cache); ! 178: skin->failedload = true; ! 179: Con_Printf ("Skin %s was malformed. You should delete it.\n", name); ! 180: return NULL; ! 181: } ! 182: dataByte = *raw++; ! 183: } ! 184: else ! 185: runLength = 1; ! 186: ! 187: // skin sanity check ! 188: if (runLength + x > pcx->xmax + 2) { ! 189: Cache_Free (&skin->cache); ! 190: skin->failedload = true; ! 191: Con_Printf ("Skin %s was malformed. You should delete it.\n", name); ! 192: return NULL; ! 193: } ! 194: while(runLength-- > 0) ! 195: pix[x++] = dataByte; ! 196: } ! 197: ! 198: } ! 199: ! 200: if ( raw - (byte *)pcx > com_filesize) ! 201: { ! 202: Cache_Free (&skin->cache); ! 203: skin->failedload = true; ! 204: Con_Printf ("Skin %s was malformed. You should delete it.\n", name); ! 205: return NULL; ! 206: } ! 207: ! 208: skin->failedload = false; ! 209: ! 210: return out; ! 211: } ! 212: ! 213: ! 214: /* ! 215: ================= ! 216: Skin_NextDownload ! 217: ================= ! 218: */ ! 219: void Skin_NextDownload (void) ! 220: { ! 221: player_info_t *sc; ! 222: int i; ! 223: ! 224: if (cls.downloadnumber == 0) ! 225: Con_Printf ("Checking skins...\n"); ! 226: cls.downloadtype = dl_skin; ! 227: ! 228: for ( ! 229: ; cls.downloadnumber != MAX_CLIENTS ! 230: ; cls.downloadnumber++) ! 231: { ! 232: sc = &cl.players[cls.downloadnumber]; ! 233: if (!sc->name[0]) ! 234: continue; ! 235: Skin_Find (sc); ! 236: if (noskins.value) ! 237: continue; ! 238: if (!CL_CheckOrDownloadFile(va("skins/%s.pcx", sc->skin->name))) ! 239: return; // started a download ! 240: } ! 241: ! 242: cls.downloadtype = dl_none; ! 243: ! 244: // now load them in for real ! 245: for (i=0 ; i<MAX_CLIENTS ; i++) ! 246: { ! 247: sc = &cl.players[i]; ! 248: if (!sc->name[0]) ! 249: continue; ! 250: Skin_Cache (sc->skin); ! 251: #ifdef GLQUAKE ! 252: sc->skin = NULL; ! 253: #endif ! 254: } ! 255: ! 256: if (cls.state != ca_active) ! 257: { // get next signon phase ! 258: MSG_WriteByte (&cls.netchan.message, clc_stringcmd); ! 259: MSG_WriteString (&cls.netchan.message, ! 260: va("begin %i", cl.servercount)); ! 261: Cache_Report (); // print remaining memory ! 262: } ! 263: } ! 264: ! 265: ! 266: /* ! 267: ========== ! 268: Skin_Skins_f ! 269: ! 270: Refind all skins, downloading if needed. ! 271: ========== ! 272: */ ! 273: void Skin_Skins_f (void) ! 274: { ! 275: int i; ! 276: ! 277: for (i=0 ; i<numskins ; i++) ! 278: { ! 279: if (skins[i].cache.data) ! 280: Cache_Free (&skins[i].cache); ! 281: } ! 282: numskins = 0; ! 283: ! 284: cls.downloadnumber = 0; ! 285: cls.downloadtype = dl_skin; ! 286: Skin_NextDownload (); ! 287: } ! 288: ! 289: ! 290: /* ! 291: ========== ! 292: Skin_AllSkins_f ! 293: ! 294: Sets all skins to one specific one ! 295: ========== ! 296: */ ! 297: void Skin_AllSkins_f (void) ! 298: { ! 299: strcpy (allskins, Cmd_Argv(1)); ! 300: Skin_Skins_f (); ! 301: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.