Annotation of quakeworld/client/skin.c, revision 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.