mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-18 15:01:41 +00:00
Fix custom player skins for the sw renderers.
This commit is contained in:
parent
1f3eaaf2e0
commit
19dc579a5a
3 changed files with 126 additions and 33 deletions
|
@ -42,6 +42,13 @@
|
|||
#define RSSHOT_WIDTH 320
|
||||
#define RSSHOT_HEIGHT 200
|
||||
|
||||
// if more than 32 clients are to be supported, then this will need to be
|
||||
// updated
|
||||
#define MAX_TRANSLATIONS 32
|
||||
|
||||
#define PLAYER_WIDTH 296
|
||||
#define PLAYER_HEIGHT 194
|
||||
|
||||
typedef struct skin_s {
|
||||
const char *name;
|
||||
qboolean valid; // the skin was found
|
||||
|
@ -52,6 +59,7 @@ typedef struct skin_s {
|
|||
} skin_t;
|
||||
|
||||
skin_t *Skin_SetColormap (skin_t *skin, int cmap);
|
||||
skin_t *Skin_SetSkin (skin_t *skin, int cmap, const char *skinname);
|
||||
void Skin_SetupSkin (skin_t *skin, int cmap);
|
||||
void Skin_SetTranslation (int cmap, int top, int bottom);
|
||||
void Skin_ProcessTranslation (int cmap, const byte *translation);
|
||||
|
|
|
@ -42,17 +42,25 @@ static __attribute__ ((used)) const char rcsid[] = "$Id$";
|
|||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "QF/hash.h"
|
||||
#include "QF/image.h"
|
||||
#include "QF/model.h"
|
||||
#include "QF/pcx.h"
|
||||
#include "QF/quakefs.h"
|
||||
#include "QF/skin.h"
|
||||
#include "QF/sys.h"
|
||||
#include "QF/va.h"
|
||||
|
||||
#include "QF/GLSL/funcs.h"
|
||||
|
||||
// if more than 32 clients are to be supported, then this will need to be
|
||||
// updated
|
||||
#define MAX_TRANSLATIONS 32
|
||||
typedef struct skinbank_s {
|
||||
char *name;
|
||||
tex_t *texels;
|
||||
int users;
|
||||
} skinbank_t;
|
||||
|
||||
static byte translations[MAX_TRANSLATIONS][VID_GRADES * 256];
|
||||
static hashtab_t *skin_cache;
|
||||
|
||||
static skin_t *
|
||||
new_skin (void)
|
||||
|
@ -113,8 +121,110 @@ Skin_SetColormap (skin_t *skin, int cmap)
|
|||
return skin;
|
||||
}
|
||||
|
||||
skin_t *
|
||||
Skin_SetSkin (skin_t *skin, int cmap, const char *skinname)
|
||||
{
|
||||
char *name = 0;
|
||||
skinbank_t *sb = 0;
|
||||
tex_t *tex = 0;
|
||||
|
||||
if (skinname) {
|
||||
name = QFS_CompressPath (skinname);
|
||||
QFS_StripExtension (name, name);
|
||||
if (strchr (name, '.') || strchr (name, '/')) {
|
||||
Sys_Printf ("Bad skin name: '%s'\n", skinname);
|
||||
free (name);
|
||||
name = 0;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
QFile *file;
|
||||
byte *ipix, *opix;
|
||||
int i;
|
||||
tex_t *out;
|
||||
|
||||
if (!name)
|
||||
break;
|
||||
sb = Hash_Find (skin_cache, name);
|
||||
if (sb) {
|
||||
sb->users++;
|
||||
tex = sb->texels;
|
||||
break;
|
||||
}
|
||||
|
||||
if (Hash_NumElements (skin_cache) >= MAX_CACHED_SKINS) {
|
||||
Sys_Printf ("Too many skins\n");
|
||||
free (name);
|
||||
name = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
QFS_FOpenFile (va ("skins/%s.pcx", name), &file);
|
||||
if (!file) {
|
||||
Sys_Printf ("Couldn't load skin %s\n", name);
|
||||
free (name);
|
||||
name = 0;
|
||||
break;
|
||||
}
|
||||
tex = LoadPCX (file, 0, vid.palette);
|
||||
Qclose (file);
|
||||
if (!tex || tex->width > 320 || tex->height > 200) {
|
||||
Sys_Printf ("Bad skin %s\n", name);
|
||||
free (name);
|
||||
name = 0;
|
||||
tex = 0;
|
||||
break;
|
||||
}
|
||||
out = malloc (field_offset (tex_t, data[PLAYER_WIDTH*PLAYER_HEIGHT]));
|
||||
out->width = PLAYER_WIDTH;
|
||||
out->height = PLAYER_HEIGHT;
|
||||
out->format = tex_palette;
|
||||
out->palette = vid.palette;
|
||||
memset (out->data, 0, PLAYER_WIDTH * PLAYER_HEIGHT);
|
||||
opix = out->data;
|
||||
ipix = tex->data;
|
||||
for (i = 0; i < out->height; i++) {
|
||||
memcpy (opix, ipix, min (tex->width, out->width));
|
||||
ipix += tex->width;
|
||||
opix += out->width;
|
||||
}
|
||||
tex = out;
|
||||
|
||||
sb = malloc (sizeof (skinbank_t));
|
||||
sb->texels = tex;
|
||||
sb->name = name;
|
||||
sb->users = 1;
|
||||
Hash_Add (skin_cache, sb);
|
||||
} while (0);
|
||||
|
||||
if (!skin)
|
||||
skin = new_skin ();
|
||||
skin->texels = tex;
|
||||
skin->name = name;
|
||||
Skin_SetupSkin (skin, cmap);
|
||||
return skin;
|
||||
}
|
||||
|
||||
static const char *
|
||||
skin_getkey (void *sb, void *unused)
|
||||
{
|
||||
return ((skinbank_t *) sb)->name;
|
||||
}
|
||||
|
||||
static void
|
||||
skin_free (void *_sb, void *unused)
|
||||
{
|
||||
skinbank_t *sb = (skinbank_t *) _sb;
|
||||
|
||||
free (sb->name);
|
||||
free (sb->texels);
|
||||
free (sb);
|
||||
}
|
||||
|
||||
void
|
||||
Skin_Init (void)
|
||||
{
|
||||
skin_cache = Hash_NewTable (127, skin_getkey, skin_free, 0);
|
||||
Skin_InitTranslations ();
|
||||
}
|
||||
|
|
|
@ -208,7 +208,6 @@ CL_LinkPacketEntities (void)
|
|||
entity_state_t *s1;
|
||||
model_t *model;
|
||||
packet_entities_t *pack;
|
||||
//player_info_t *info;
|
||||
|
||||
pack = &cl.frames[cls.netchan.incoming_sequence &
|
||||
UPDATE_MASK].packet_entities;
|
||||
|
@ -244,26 +243,12 @@ CL_LinkPacketEntities (void)
|
|||
|
||||
// set colormap
|
||||
if (s1->colormap && (s1->colormap <= MAX_CLIENTS)
|
||||
&& cl.players[s1->colormap - 1].name[0]
|
||||
&& !strcmp (ent->model->name, "progs/player.mdl")) {
|
||||
&& cl.players[s1->colormap - 1].name[0]) {
|
||||
ent->skin = Skin_SetColormap (ent->skin, s1->colormap);
|
||||
//info = &cl.players[s1->colormap - 1];
|
||||
} else {
|
||||
ent->skin = Skin_SetColormap (ent->skin, 0);
|
||||
//info = NULL;
|
||||
}
|
||||
#if 0 //XXX
|
||||
if (info && info->skinname && !info->skin)
|
||||
Skin_Find (info);
|
||||
if (info && info->skin) {
|
||||
ent->skin = Skin_NewTempSkin ();
|
||||
if (ent->skin) {
|
||||
CL_NewTranslation (s1->colormap - 1, ent->skin);
|
||||
}
|
||||
} else {
|
||||
ent->skin = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
// LordHavoc: cleaned up Endy's coding style, and fixed Endy's bugs
|
||||
// Ender: Extend (Colormod) [QSG - Begin]
|
||||
// N.B: All messy code below is the sole fault of LordHavoc and
|
||||
|
@ -494,24 +479,14 @@ CL_LinkPlayers (void)
|
|||
|
||||
if (state->pls.modelindex == cl_playerindex) { //XXX
|
||||
// use custom skin
|
||||
#if 0
|
||||
if (!info->skin)
|
||||
Skin_Find (info);
|
||||
if (info && info->skin) {
|
||||
ent->skin = Skin_NewTempSkin ();
|
||||
if (ent->skin) {
|
||||
CL_NewTranslation (j, ent->skin);
|
||||
}
|
||||
} else {
|
||||
ent->skin = NULL;
|
||||
}
|
||||
#endif
|
||||
Skin_SetSkin (ent->skin, j + 1, info->skinname->value);
|
||||
|
||||
ent->min_light = min (cl.fbskins, cl_fb_players->value);
|
||||
|
||||
if (ent->min_light >= 1.0)
|
||||
ent->fullbright = 1;
|
||||
} else {
|
||||
ent->skin = NULL;
|
||||
Skin_SetSkin (ent->skin, j + 1, 0);
|
||||
}
|
||||
|
||||
// stuff entity in map
|
||||
|
|
Loading…
Reference in a new issue