Annotation of quakeworld/client/skin.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

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