|
|
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.