mirror of
https://git.code.sf.net/p/quake/newtree
synced 2024-11-21 19:51:18 +00:00
skin.c:
Rip out the pcx loading code and use LoadPCX instead. pcx.h: remove the data field from pcx_t: it was messing with gcc's idea of the structure size. also, update LoadPCX's prototype pcx.c: change LoadPCX to return tex_t (new type in texture.h) and take a new param: convert. LoadPCX will now wither load raw 8 bit or convert to rgba on loading depending on convert. Also, make LoadPCX WORK and use Hunk_TempAlloc to store the resulting texture. texture.h: define tex_t. defines an in-memory texture (either 8 or 32 bit, depending on the presense of a palette). Data comes immediately after the sturcture. eg tex_t *tex = Hunk_TempAlloc (sizeof (tex_t) + count)
This commit is contained in:
parent
6aecae38e6
commit
fc70d429bb
4 changed files with 129 additions and 122 deletions
|
@ -45,12 +45,11 @@ typedef struct
|
|||
unsigned short bytes_per_line;
|
||||
unsigned short palette_type;
|
||||
char filler[58];
|
||||
unsigned char data; // unbounded
|
||||
} pcx_t;
|
||||
|
||||
void WritePCXfile (char *filename, byte * data, int width, int height,
|
||||
int rowbytes, byte * palette, qboolean upload,
|
||||
qboolean flip);
|
||||
void LoadPCX (QFile *f);
|
||||
struct tex_s *LoadPCX (QFile *f, int convert); // tex is from Hunk_TempAlloc
|
||||
|
||||
#endif // __pcx_h
|
||||
|
|
47
include/texture.h
Normal file
47
include/texture.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
texture.h
|
||||
|
||||
texture definition
|
||||
|
||||
Copyright (C) 2000 Bill Currie
|
||||
|
||||
Author: Bill Currie
|
||||
Date: 2000-01-18
|
||||
|
||||
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:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifndef __texture_h
|
||||
#define __texture_h
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
// could not use texture_t as that is used for models.
|
||||
typedef struct tex_s {
|
||||
int width;
|
||||
int height;
|
||||
unsigned char *palette; // 0 = 32 bit, otherise 8
|
||||
unsigned char data[ZERO_LENGTH_ARRAY];
|
||||
} tex_t;
|
||||
|
||||
#endif // __texture_h
|
84
source/pcx.c
84
source/pcx.c
|
@ -39,26 +39,27 @@
|
|||
|
||||
#include "cl_parse.h"
|
||||
#include "console.h"
|
||||
#include "host.h"
|
||||
#include "pcx.h"
|
||||
#include "qendian.h"
|
||||
#include "qtypes.h"
|
||||
#include "quakefs.h"
|
||||
#include "texture.h"
|
||||
#include "zone.h"
|
||||
|
||||
byte *pcx_rgb;
|
||||
|
||||
/*
|
||||
LoadPCX
|
||||
*/
|
||||
void
|
||||
LoadPCX (QFile *f)
|
||||
tex_t *
|
||||
LoadPCX (QFile *f, int convert)
|
||||
{
|
||||
pcx_t *pcx, pcxbuf;
|
||||
byte palette[768];
|
||||
byte *pix;
|
||||
int x, y;
|
||||
int dataByte, runLength;
|
||||
int dataByte, runLength = 1;
|
||||
int count;
|
||||
tex_t *tex;
|
||||
|
||||
//
|
||||
// parse the PCX file
|
||||
|
@ -81,39 +82,74 @@ LoadPCX (QFile *f)
|
|||
|| pcx->encoding != 1
|
||||
|| pcx->bits_per_pixel != 8 || pcx->xmax >= 320 || pcx->ymax >= 256) {
|
||||
Con_Printf ("Bad pcx file\n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
// seek to palette
|
||||
Qseek (f, -768, SEEK_END);
|
||||
Qread (f, palette, 768);
|
||||
|
||||
Qseek (f, sizeof (pcxbuf) - 4, SEEK_SET);
|
||||
if (convert) {
|
||||
// seek to palette
|
||||
Qseek (f, -768, SEEK_END);
|
||||
Qread (f, palette, 768);
|
||||
}
|
||||
|
||||
Qseek (f, sizeof (pcxbuf), SEEK_SET);
|
||||
|
||||
count = (pcx->xmax + 1) * (pcx->ymax + 1);
|
||||
pcx_rgb = malloc (count * 4);
|
||||
if (convert)
|
||||
count *= 4;
|
||||
tex = Hunk_TempAlloc (sizeof (tex_t) + count);
|
||||
tex->width = pcx->xmax + 1;
|
||||
tex->height = pcx->ymax + 1;
|
||||
if (convert) {
|
||||
tex->palette = 0;
|
||||
} else {
|
||||
tex->palette = host_basepal;
|
||||
}
|
||||
pix = tex->data;
|
||||
|
||||
for (y = 0; y <= pcx->ymax; y++) {
|
||||
pix = pcx_rgb + 4 * y * (pcx->xmax + 1);
|
||||
for (x = 0; x <= pcx->ymax;) {
|
||||
for (y = 0; y < tex->height; y++) {
|
||||
for (x = 0; x < tex->width;) {
|
||||
runLength = 1;
|
||||
dataByte = Qgetc (f);
|
||||
if (dataByte == EOF)
|
||||
break;
|
||||
|
||||
if ((dataByte & 0xC0) == 0xC0) {
|
||||
runLength = dataByte & 0x3F;
|
||||
dataByte = Qgetc (f);
|
||||
} else {
|
||||
runLength = 1;
|
||||
if (dataByte == EOF)
|
||||
break;
|
||||
}
|
||||
|
||||
while (runLength-- > 0) {
|
||||
pix[0] = palette[dataByte * 3];
|
||||
pix[1] = palette[dataByte * 3 + 1];
|
||||
pix[2] = palette[dataByte * 3 + 2];
|
||||
pix[3] = 255;
|
||||
pix += 4;
|
||||
x++;
|
||||
if (convert) {
|
||||
while (count && runLength > 0) {
|
||||
pix[0] = palette[dataByte * 3];
|
||||
pix[1] = palette[dataByte * 3 + 1];
|
||||
pix[2] = palette[dataByte * 3 + 2];
|
||||
pix[3] = 255;
|
||||
pix += 4;
|
||||
count -= 4;
|
||||
runLength--;
|
||||
x++;
|
||||
}
|
||||
} else {
|
||||
while (count && runLength > 0) {
|
||||
*pix++ = dataByte;
|
||||
count--;
|
||||
runLength--;
|
||||
x++;
|
||||
}
|
||||
}
|
||||
if (runLength)
|
||||
break;
|
||||
}
|
||||
if (runLength)
|
||||
break;
|
||||
}
|
||||
if (count || runLength) {
|
||||
Con_Printf ("PCX was malformed. You should delete it.\n");
|
||||
return 0;
|
||||
}
|
||||
return tex;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -150,7 +186,7 @@ WritePCXfile (char *filename, byte * data, int width, int height,
|
|||
memset (pcx->filler, 0, sizeof (pcx->filler));
|
||||
|
||||
// pack the image
|
||||
pack = &pcx->data;
|
||||
pack = (byte*)&pcx[1];
|
||||
|
||||
if (flip)
|
||||
data += rowbytes * (height - 1);
|
||||
|
|
117
source/skin.c
117
source/skin.c
|
@ -47,6 +47,7 @@
|
|||
#include "screen.h"
|
||||
#include "skin.h"
|
||||
#include "sys.h"
|
||||
#include "texture.h"
|
||||
#include "va.h"
|
||||
|
||||
cvar_t *baseskin;
|
||||
|
@ -62,13 +63,10 @@ skin_t skins[MAX_CACHED_SKINS];
|
|||
int numskins;
|
||||
|
||||
/*
|
||||
================
|
||||
Skin_Find
|
||||
Skin_Find
|
||||
|
||||
Determines the best skin for the given scoreboard
|
||||
slot, and sets scoreboard->skin
|
||||
|
||||
================
|
||||
Determines the best skin for the given scoreboard
|
||||
slot, and sets scoreboard->skin
|
||||
*/
|
||||
void
|
||||
Skin_Find (player_info_t *sc)
|
||||
|
@ -116,22 +114,17 @@ Skin_Find (player_info_t *sc)
|
|||
|
||||
|
||||
/*
|
||||
==========
|
||||
Skin_Cache
|
||||
Skin_Cache
|
||||
|
||||
Returns a pointer to the skin bitmap, or NULL to use the default
|
||||
==========
|
||||
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;
|
||||
byte *out;
|
||||
QFile *file;
|
||||
tex_t *tex;
|
||||
|
||||
if (cls.downloadtype == dl_skin)
|
||||
return NULL; // use base until downloaded
|
||||
|
@ -149,34 +142,19 @@ Skin_Cache (skin_t *skin)
|
|||
|
||||
// load the pic from disk
|
||||
snprintf (name, sizeof (name), "skins/%s.pcx", skin->name);
|
||||
raw = COM_LoadTempFile (name);
|
||||
if (!raw) {
|
||||
COM_FOpenFile (name, &file);
|
||||
if (!file) {
|
||||
Con_Printf ("Couldn't load skin %s\n", name);
|
||||
snprintf (name, sizeof (name), "skins/%s.pcx", baseskin->string);
|
||||
raw = COM_LoadTempFile (name);
|
||||
if (!raw) {
|
||||
COM_FOpenFile (name, &file);
|
||||
if (!file) {
|
||||
skin->failedload = true;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
tex = LoadPCX (file, 0);
|
||||
|
||||
// parse the PCX file
|
||||
pcx = (pcx_t *) raw;
|
||||
raw = &pcx->data;
|
||||
|
||||
pcx->xmax = LittleShort (pcx->xmax);
|
||||
pcx->xmin = LittleShort (pcx->xmin);
|
||||
pcx->ymax = LittleShort (pcx->ymax);
|
||||
pcx->ymin = LittleShort (pcx->ymin);
|
||||
pcx->hres = LittleShort (pcx->hres);
|
||||
pcx->vres = LittleShort (pcx->vres);
|
||||
pcx->bytes_per_line = LittleShort (pcx->bytes_per_line);
|
||||
pcx->palette_type = LittleShort (pcx->palette_type);
|
||||
|
||||
if (pcx->manufacturer != 0x0a
|
||||
|| pcx->version != 5
|
||||
|| pcx->encoding != 1
|
||||
|| pcx->bits_per_pixel != 8 || pcx->xmax >= 320 || pcx->ymax >= 200) {
|
||||
if (!tex || tex->width > 320 || tex->height > 200) {
|
||||
skin->failedload = true;
|
||||
Con_Printf ("Bad skin %s\n", name);
|
||||
return NULL;
|
||||
|
@ -186,54 +164,7 @@ Skin_Cache (skin_t *skin)
|
|||
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;
|
||||
}
|
||||
memcpy (out, tex->data, tex->width * tex->height);
|
||||
|
||||
skin->failedload = false;
|
||||
|
||||
|
@ -242,9 +173,7 @@ Skin_Cache (skin_t *skin)
|
|||
|
||||
|
||||
/*
|
||||
=================
|
||||
Skin_NextDownload
|
||||
=================
|
||||
Skin_NextDownload
|
||||
*/
|
||||
void
|
||||
Skin_NextDownload (void)
|
||||
|
@ -289,11 +218,9 @@ Skin_NextDownload (void)
|
|||
|
||||
|
||||
/*
|
||||
==========
|
||||
Skin_Skins_f
|
||||
Skin_Skins_f
|
||||
|
||||
Refind all skins, downloading if needed.
|
||||
==========
|
||||
Refind all skins, downloading if needed.
|
||||
*/
|
||||
void
|
||||
Skin_Skins_f (void)
|
||||
|
@ -313,11 +240,9 @@ Skin_Skins_f (void)
|
|||
|
||||
|
||||
/*
|
||||
==========
|
||||
Skin_AllSkins_f
|
||||
Skin_AllSkins_f
|
||||
|
||||
Sets all skins to one specific one
|
||||
==========
|
||||
Sets all skins to one specific one
|
||||
*/
|
||||
void
|
||||
Skin_AllSkins_f (void)
|
||||
|
|
Loading…
Reference in a new issue