123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 |
- /*
- Copyright (C) 1996-1997 Id Software, Inc.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
- #include "quakedef.h"
- cvar_t baseskin = {"baseskin", "base"};
- cvar_t noskins = {"noskins", "0"};
- char allskins[128];
- #define MAX_CACHED_SKINS 128
- skin_t skins[MAX_CACHED_SKINS];
- int numskins;
- /*
- ================
- Skin_Find
- Determines the best skin for the given scoreboard
- slot, and sets scoreboard->skin
- ================
- */
- void Skin_Find (player_info_t *sc)
- {
- skin_t *skin;
- int i;
- char name[128], *s;
- if (allskins[0])
- strcpy (name, allskins);
- else
- {
- s = Info_ValueForKey (sc->userinfo, "skin");
- if (s && s[0])
- strcpy (name, s);
- else
- strcpy (name, baseskin.string);
- }
- if (strstr (name, "..") || *name == '.')
- strcpy (name, "base");
- COM_StripExtension (name, name);
- for (i=0 ; i<numskins ; i++)
- {
- if (!strcmp (name, skins[i].name))
- {
- sc->skin = &skins[i];
- Skin_Cache (sc->skin);
- return;
- }
- }
- if (numskins == MAX_CACHED_SKINS)
- { // ran out of spots, so flush everything
- Skin_Skins_f ();
- return;
- }
- skin = &skins[numskins];
- sc->skin = skin;
- numskins++;
- memset (skin, 0, sizeof(*skin));
- strncpy(skin->name, name, sizeof(skin->name) - 1);
- }
- /*
- ==========
- Skin_Cache
- Returns a pointer to the skin bitmap, or NULL to use the default
- ==========
- */
- byte *Skin_Cache (skin_t *skin)
- {
- char name[1024];
- byte *raw;
- byte *out, *pix;
- pcx_t *pcx;
- int x, y;
- int dataByte;
- int runLength;
- if (cls.downloadtype == dl_skin)
- return NULL; // use base until downloaded
- if (noskins.value==1) // JACK: So NOSKINS > 1 will show skins, but
- return NULL; // not download new ones.
- if (skin->failedload)
- return NULL;
- out = Cache_Check (&skin->cache);
- if (out)
- return out;
- //
- // load the pic from disk
- //
- sprintf (name, "skins/%s.pcx", skin->name);
- raw = COM_LoadTempFile (name);
- if (!raw)
- {
- Con_Printf ("Couldn't load skin %s\n", name);
- sprintf (name, "skins/%s.pcx", baseskin.string);
- raw = COM_LoadTempFile (name);
- if (!raw)
- {
- skin->failedload = true;
- return NULL;
- }
- }
- //
- // parse the PCX file
- //
- pcx = (pcx_t *)raw;
- raw = &pcx->data;
- if (pcx->manufacturer != 0x0a
- || pcx->version != 5
- || pcx->encoding != 1
- || pcx->bits_per_pixel != 8
- || pcx->xmax >= 320
- || pcx->ymax >= 200)
- {
- skin->failedload = true;
- Con_Printf ("Bad skin %s\n", name);
- return NULL;
- }
-
- out = Cache_Alloc (&skin->cache, 320*200, skin->name);
- if (!out)
- Sys_Error ("Skin_Cache: couldn't allocate");
- pix = out;
- memset (out, 0, 320*200);
- for (y=0 ; y<pcx->ymax ; y++, pix += 320)
- {
- for (x=0 ; x<=pcx->xmax ; )
- {
- if (raw - (byte*)pcx > com_filesize)
- {
- Cache_Free (&skin->cache);
- skin->failedload = true;
- Con_Printf ("Skin %s was malformed. You should delete it.\n", name);
- return NULL;
- }
- dataByte = *raw++;
- if((dataByte & 0xC0) == 0xC0)
- {
- runLength = dataByte & 0x3F;
- if (raw - (byte*)pcx > com_filesize)
- {
- Cache_Free (&skin->cache);
- skin->failedload = true;
- Con_Printf ("Skin %s was malformed. You should delete it.\n", name);
- return NULL;
- }
- dataByte = *raw++;
- }
- else
- runLength = 1;
- // skin sanity check
- if (runLength + x > pcx->xmax + 2) {
- Cache_Free (&skin->cache);
- skin->failedload = true;
- Con_Printf ("Skin %s was malformed. You should delete it.\n", name);
- return NULL;
- }
- while(runLength-- > 0)
- pix[x++] = dataByte;
- }
- }
- if ( raw - (byte *)pcx > com_filesize)
- {
- Cache_Free (&skin->cache);
- skin->failedload = true;
- Con_Printf ("Skin %s was malformed. You should delete it.\n", name);
- return NULL;
- }
- skin->failedload = false;
- return out;
- }
- /*
- =================
- Skin_NextDownload
- =================
- */
- void Skin_NextDownload (void)
- {
- player_info_t *sc;
- int i;
- if (cls.downloadnumber == 0)
- Con_Printf ("Checking skins...\n");
- cls.downloadtype = dl_skin;
- for (
- ; cls.downloadnumber != MAX_CLIENTS
- ; cls.downloadnumber++)
- {
- sc = &cl.players[cls.downloadnumber];
- if (!sc->name[0])
- continue;
- Skin_Find (sc);
- if (noskins.value)
- continue;
- if (!CL_CheckOrDownloadFile(va("skins/%s.pcx", sc->skin->name)))
- return; // started a download
- }
- cls.downloadtype = dl_none;
- // now load them in for real
- for (i=0 ; i<MAX_CLIENTS ; i++)
- {
- sc = &cl.players[i];
- if (!sc->name[0])
- continue;
- Skin_Cache (sc->skin);
- #ifdef GLQUAKE
- sc->skin = NULL;
- #endif
- }
- if (cls.state != ca_active)
- { // get next signon phase
- MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
- MSG_WriteString (&cls.netchan.message,
- va("begin %i", cl.servercount));
- Cache_Report (); // print remaining memory
- }
- }
- /*
- ==========
- Skin_Skins_f
- Refind all skins, downloading if needed.
- ==========
- */
- void Skin_Skins_f (void)
- {
- int i;
- for (i=0 ; i<numskins ; i++)
- {
- if (skins[i].cache.data)
- Cache_Free (&skins[i].cache);
- }
- numskins = 0;
- cls.downloadnumber = 0;
- cls.downloadtype = dl_skin;
- Skin_NextDownload ();
- }
- /*
- ==========
- Skin_AllSkins_f
- Sets all skins to one specific one
- ==========
- */
- void Skin_AllSkins_f (void)
- {
- strcpy (allskins, Cmd_Argv(1));
- Skin_Skins_f ();
- }
|