Gut most of the old skin code.

Custom skins are smashed on most targets. Player colors don't work, etc.
However, this will let me do a much cleaner implementation.
This commit is contained in:
Bill Currie 2012-01-23 16:16:30 +09:00
parent 61c127abc0
commit 7bfddd7ffe
36 changed files with 207 additions and 1264 deletions

View file

@ -77,7 +77,6 @@ typedef struct entity_s {
vec_t full_transform[4 * 4];
struct model_s *model; // NULL = no model
int frame;
byte *colormap;
int skinnum; // for Alias models
struct skin_s *skin;

View file

@ -30,6 +30,7 @@
#define _SKIN_H
#include "QF/qtypes.h"
#include "QF/vid.h"
#include "QF/zone.h"
#define MAX_CACHED_SKINS 128
@ -38,18 +39,23 @@
#define RSSHOT_WIDTH 320
#define RSSHOT_HEIGHT 200
typedef struct translation_s {
byte top[VID_GRADES][16];
byte bottom[VID_GRADES][16];
} translation_t;
typedef struct skin_s {
char name[MAX_SKIN_LENGTH];
qboolean failedload; // the name isn't a valid skin
union {
cache_user_t cache;
struct tex_s *texels;
} data;
int texture;
int fb_texture;
int numfb;
const char *name;
qboolean valid; // the skin was found
struct tex_s *texels;
byte *colormap;
int texnum;
int auxtex;
} skin_t;
skin_t *Skin_SetColormap (skin_t *skin, int cmap);
void Skin_SetTranslation (int cmap, int top, int bottom);
extern byte player_8bit_texels[640 * 400];
extern skin_t skin_cache[MAX_CACHED_SKINS];
extern int skin_textures;
@ -68,7 +74,7 @@ int Skin_Init_Textures (int base);
void Skin_Init (void);
void Skin_Init_Cvars (void);
void Skin_Init_Translation (void);
void Skin_Set_Translate (int top, int bottom, void *_dest);
void Skin_Set_Translate (int top, int bottom, translation_t *trans);
void Skin_Do_Translation (skin_t *player_skin, int slot, skin_t *skin);
void Skin_Do_Translation_Model (struct model_s *model, int skinnum,
int slot, skin_t *skin);

View file

@ -89,6 +89,7 @@ void Sys_MaskPrintf (int mask, const char *fmt, ...) __attribute__((format(print
#define SYS_SND (1|512)
#define SYS_GLT (1|1024)
#define SYS_GLSL (1|2048)
#define SYS_SKIN (1|4096)
int Sys_CheckInput (int idle, int net_socket);
const char *Sys_ConsoleInput (void);

View file

@ -7,7 +7,7 @@ INCLUDES= -I$(top_srcdir)/include
lib_LTLIBRARIES= libQFmodels.la @VID_MODEL_TARGETS@
EXTRA_LTLIBRARIES= libQFmodels_gl.la libQFmodels_glsl.la libQFmodels_sw.la
models_sources = clip_hull.c model.c portal.c trace.c winding.c
models_sources = clip_hull.c model.c portal.c skin.c trace.c winding.c
libQFmodels_la_LDFLAGS= -version-info $(QUAKE_LIBRARY_VERSION_INFO) -no-undefined
libQFmodels_la_LIBADD= brush/libbrush.la $(top_builddir)/libs/util/libQFutil.la

102
libs/models/skin.c Normal file
View file

@ -0,0 +1,102 @@
/*
skin.c
Skin support
Copyright (C) 2012 Bill Currie <bill@taniwha.org>
Author: Bill Currie <bill@taniwha.org>
Date: 2012/1/23
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
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
static __attribute__ ((used)) const char rcsid[] = "$Id$";
#ifdef HAVE_STRING_H
# include "string.h"
#endif
#ifdef HAVE_STRINGS_H
# include "strings.h"
#endif
#include <stdlib.h>
#include "QF/image.h"
#include "QF/model.h"
#include "QF/skin.h"
#include "QF/sys.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
static byte translations[MAX_TRANSLATIONS][VID_GRADES * 256];
static skin_t *
new_skin (void)
{
return calloc (1, sizeof (skin_t));
}
VISIBLE void
Skin_SetTranslation (int cmap, int top, int bottom)
{
#if 0
int i, j;
byte *source;
top = bound (0, top, 13) * 16;
bottom = bound (0, bottom, 13) * 16;
source = vid.colormap8;
for (i = 0; i < VID_GRADES; i++, source += 256) {
if (top < 128) // the artists made some backwards ranges.
memcpy (trans->top[i], source + top, 16);
else
for (j = 0; j < 16; j++)
trans->top[i][j] = source[top + 15 - j];
if (bottom < 128)
memcpy (trans->bottom[i], source + bottom, 16);
else
for (j = 0; j < 16; j++)
trans->bottom[i][j] = source[bottom + 15 - j];
}
#endif
}
skin_t *
Skin_SetColormap (skin_t *skin, int cmap)
{
if (!skin)
skin = new_skin ();
skin->colormap = 0;
if (cmap < 0 || cmap > MAX_TRANSLATIONS)
Sys_MaskPrintf (SYS_SKIN, "invalid skin slot: %d\n", cmap);
if (cmap > 0 && cmap <= MAX_TRANSLATIONS)
skin->colormap = translations[cmap - 1];
return skin;
}

View file

@ -12,7 +12,7 @@ endif
gl_src = \
gl_draw.c gl_dyn_lights.c gl_dyn_part.c gl_dyn_textures.c \
gl_fog.c gl_graph.c gl_lightmap.c gl_mod_alias.c gl_mod_sprite.c \
gl_rmain.c gl_rmisc.c gl_rsurf.c gl_screen.c gl_skin.c gl_sky.c \
gl_rmain.c gl_rmisc.c gl_rsurf.c gl_screen.c gl_sky.c \
gl_sky_clip.c gl_textures.c gl_warp.c
libgl_la_SOURCES= $(gl_src)

View file

@ -522,12 +522,12 @@ R_DrawAliasModel (entity_t *e)
// if the model has a colorised/external skin, use it, otherwise use
// the skin embedded in the model data
if (e->skin && !gl_nocolors->int_val) {
if (e->skin && e->skin->texnum && !gl_nocolors->int_val) {
skin_t *skin = e->skin;
texture = skin->texture;
texture = skin->texnum;
if (gl_fb_models->int_val) {
fb_texture = skin->fb_texture;
fb_texture = skin->auxtex;
}
} else {
maliasskindesc_t *skindesc;

View file

@ -152,7 +152,7 @@ R_Init (void)
texture_extension_number = R_InitGraphTextures (texture_extension_number);
texture_extension_number = Skin_Init_Textures (texture_extension_number);
//FIXME texture_extension_number = Skin_Init_Textures (texture_extension_number);
r_init = 1;
R_InitParticles ();

View file

@ -1,282 +0,0 @@
/*
gl_skin.c
(description)
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:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
static __attribute__ ((used)) const char rcsid[] =
"$Id$";
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include "QF/cvar.h"
#include "QF/image.h"
#include "QF/render.h"
#include "QF/skin.h"
#include "QF/sys.h"
#include "QF/GL/defines.h"
#include "QF/GL/funcs.h"
#include "QF/GL/qf_textures.h"
#include "compat.h"
#include "r_cvar.h"
static byte translate[256];
static unsigned int translate32[256];
static int player_width = 296;
static int player_height = 194;
VISIBLE void
Skin_Set_Translate (int top, int bottom, void *_dest)
{
int i;
top = bound (0, top, 13) << 4;
bottom = bound (0, bottom, 13) << 4;
if (VID_Is8bit ()) { // 8bit texture upload
for (i = 0; i < 16; i++) {
// the artists made some backwards ranges. sigh.
if (top < 128)
translate[TOP_RANGE + i] = top + i;
else
translate[TOP_RANGE + i] = top + 15 - i;
if (bottom < 128)
translate[BOTTOM_RANGE + i] = bottom + i;
else
translate[BOTTOM_RANGE + i] = bottom + 15 - i;
}
} else {
if (top < 128)
memcpy (translate32 + TOP_RANGE, d_8to24table + top,
16 * sizeof (unsigned int));
else
for (i = 0; i < 16; i++)
translate32[TOP_RANGE + i] = d_8to24table[top + 15 - i];
if (bottom < 128)
memcpy (translate32 + BOTTOM_RANGE, d_8to24table + bottom,
16 * sizeof (unsigned int));
else
for (i = 0; i < 16; i++)
translate32[BOTTOM_RANGE + i] = d_8to24table[bottom + 15 - i];
}
}
static void
build_skin_8 (byte * original, int tinwidth, int tinheight,
unsigned int scaled_width, unsigned int scaled_height,
int inwidth, qboolean alpha)
{
// Improvements should be mirrored in GL_ResampleTexture in gl_textures.c
byte *inrow;
byte pixels[512 * 256], *out;
unsigned int i, j;
unsigned int frac, fracstep;
out = pixels;
memset (pixels, 0, sizeof (pixels));
fracstep = tinwidth * 0x10000 / scaled_width;
for (i = 0; i < scaled_height; i++, out += scaled_width) {
inrow = original + inwidth * (i * tinheight / scaled_height);
frac = fracstep >> 1;
for (j = 0; j < scaled_width; j++) {
out[j] = translate[inrow[frac >> 16]];
frac += fracstep;
}
}
GL_Upload8_EXT ((byte *) pixels, scaled_width, scaled_height, false,
alpha);
}
static void
build_skin_32 (byte * original, int tinwidth, int tinheight,
unsigned int scaled_width, unsigned int scaled_height,
int inwidth, qboolean alpha)
{
// Improvements should be mirrored in GL_ResampleTexture in gl_textures.c
byte *inrow;
unsigned int i, j;
int samples = alpha ? gl_alpha_format : gl_solid_format;
unsigned int frac, fracstep;
unsigned int pixels[512 * 256], *out;
out = pixels;
memset (pixels, 0, sizeof (pixels));
fracstep = tinwidth * 0x10000 / scaled_width;
for (i = 0; i < scaled_height; i++, out += scaled_width) {
inrow = original + inwidth * (i * tinheight / scaled_height);
frac = fracstep >> 1;
for (j = 0; j < scaled_width; j++) {
out[j] = translate32[inrow[frac >> 16]];
frac += fracstep;
}
}
qfglTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, pixels);
qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if (Anisotropy)
qfglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT,
aniso);
}
static void
build_skin (int texnum, byte *ptexels, int width, int height,
int owidth, int oheight, qboolean alpha)
{
unsigned int scaled_width, scaled_height;
// because this happens during gameplay, do it fast
// instead of sending it through GL_Upload8()
qfglBindTexture (GL_TEXTURE_2D, texnum);
// FIXME deek: This 512x256 limit sucks!
scaled_width = min (gl_max_size->int_val, 512);
scaled_height = min (gl_max_size->int_val, 256);
// allow users to crunch sizes down even more if they want
scaled_width >>= gl_playermip->int_val;
scaled_height >>= gl_playermip->int_val;
if (VID_Is8bit ()) { // 8bit texture upload
build_skin_8 (ptexels, owidth, oheight, scaled_width, scaled_height,
width, alpha);
} else {
build_skin_32 (ptexels, owidth, oheight, scaled_width, scaled_height,
width, alpha);
}
}
VISIBLE void
Skin_Do_Translation (skin_t *player_skin, int slot, skin_t *skin)
{
byte *original;
int inwidth, inheight;
int texnum = skin->texture;
tex_t *skin_texels;
if ((skin_texels = (tex_t *) Skin_Cache (player_skin)) != NULL) {
// skin data width
inwidth = 320;
inheight = 200;
original = skin_texels->data;
} else {
original = player_8bit_texels;
inwidth = player_width;
inheight = player_height;
}
build_skin (texnum, original, inwidth, inheight,
player_width, player_height, false);
}
VISIBLE void
Skin_Do_Translation_Model (model_t *model, int skinnum, int slot, skin_t *skin)
{
byte *original;
int inwidth, inheight;
int texnum = skin->texture;
aliashdr_t *paliashdr;
maliasskindesc_t *pskindesc;
if (!model) // player doesn't have a model yet
return;
if (model->type != mod_alias) // translate skins only on alias models
return;
paliashdr = Cache_Get (&model->cache);
if (skinnum < 0
|| skinnum >= paliashdr->mdl.numskins) {
Sys_MaskPrintf (SYS_DEV, "(%d): Invalid player skin #%d\n", slot,
skinnum);
skinnum = 0;
}
pskindesc = ((maliasskindesc_t *)
((byte *) paliashdr + paliashdr->skindesc)) + skinnum;
//FIXME: broken for skin groups
original = (byte *) paliashdr + pskindesc->skin;
inwidth = paliashdr->mdl.skinwidth;
inheight = paliashdr->mdl.skinheight;
build_skin (texnum, original, inwidth, inheight, inwidth, inheight, false);
Cache_Release (&model->cache);
}
VISIBLE void
Skin_Player_Model (model_t *model)
{
aliashdr_t *paliashdr;
player_width = 296;
player_height = 194;
if (!model) // player doesn't have a model yet
return;
if (model->type != mod_alias) // translate skins only on alias models
return;
paliashdr = Cache_Get (&model->cache);
player_width = paliashdr->mdl.skinwidth;
player_height = paliashdr->mdl.skinheight;
Cache_Release (&model->cache);
}
VISIBLE void
Skin_Init_Translation (void)
{
int i;
for (i = 0; i < 256; i++) {
translate[i] = i;
translate32[i] = d_8to24table[i];
}
}
VISIBLE void
Skin_Process (skin_t *skin, tex_t *tex)
{
int pixels = tex->width * tex->height;
byte *ptexels = Hunk_TempAlloc (pixels);
skin->fb_texture = 0;
if (Mod_CalcFullbright (tex->data, ptexels, pixels)) {
skin->fb_texture = skin_fb_textures + (skin - skin_cache);
build_skin (skin->fb_texture, ptexels, tex->width, tex->height,
296, 194, true);
}
}

View file

@ -15,7 +15,7 @@ shader_gen= \
glsl_src = \
glsl_alias.c glsl_bsp.c glsl_draw.c glsl_lightmap.c glsl_main.c \
glsl_particles.c glsl_screen.c glsl_skin.c glsl_sprite.c glsl_textures.c
glsl_particles.c glsl_screen.c glsl_sprite.c glsl_textures.c
if BUILD_GLSL
noinst_LTLIBRARIES= libglsl.la

View file

@ -228,7 +228,7 @@ R_DrawAlias (void)
if (ent->skin) {
skin_t *skin = ent->skin;
skin_tex = skin->texture;
skin_tex = skin->texnum;
} else {
maliasskindesc_t *skindesc;
skindesc = R_AliasGetSkindesc (ent->skinnum, hdr);

View file

@ -1,70 +0,0 @@
/*
glsl_skin.c
GLSL rendering
Copyright (C) 2012 Bill Currie <bill@taniwha.org>
Author: Bill Currie <bill@taniwha.org>
Date: 2012/1/13
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
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
static __attribute__ ((used)) const char rcsid[] = "$Id$";
#include "QF/image.h"
#include "QF/model.h"
#include "QF/skin.h"
VISIBLE void
Skin_Player_Model (model_t *model)
{
}
VISIBLE void
Skin_Set_Translate (int top, int bottom, void *_dest)
{
}
VISIBLE void
Skin_Do_Translation (skin_t *player_skin, int slot, skin_t *skin)
{
}
VISIBLE void
Skin_Do_Translation_Model (model_t *model, int skinnum, int slot,
skin_t *skin)
{
}
VISIBLE void
Skin_Process (skin_t *skin, tex_t *tex)
{
}
VISIBLE void
Skin_Init_Translation (void)
{
}

View file

@ -26,7 +26,7 @@ sw_src= \
d_sky.c d_sprite.c d_surf.c d_vars.c d_zpoint.c draw.c fpu.c nonintel.c \
screen.c sw_fog.c sw_graph.c sw_raclip.c sw_ralias.c sw_rbsp.c sw_rdraw.c \
sw_redge.c sw_rmain.c sw_rmisc.c sw_rpart.c sw_rsky.c sw_rsprite.c \
sw_rsurf.c sw_skin.c
sw_rsurf.c
libasm_la_LDFLAGS= @STATIC@
libasm_la_SOURCES= $(asm_src)

View file

@ -568,15 +568,17 @@ R_AliasSetupSkin (void)
r_affinetridesc.seamfixupX16 = (a_skinwidth >> 1) << 16;
r_affinetridesc.skinheight = pmdl->skinheight;
acolormap = vid.colormap8;
if (currententity->skin) {
tex_t *base;
base = currententity->skin->data.texels;
base = currententity->skin->texels;
if (base) {
r_affinetridesc.pskin = base->data;
r_affinetridesc.skinwidth = base->width;
r_affinetridesc.skinheight = base->height;
}
acolormap = currententity->skin->colormap;
}
}
@ -653,9 +655,6 @@ R_AliasDrawModel (alight_t *plighting)
R_AliasSetupLighting (plighting);
R_AliasSetupFrame ();
if (!currententity->colormap)
Sys_Error ("R_AliasDrawModel: !currententity->colormap");
r_affinetridesc.drawtype = (currententity->trivial_accept == 3) &&
r_recursiveaffinetriangles;
@ -667,7 +666,8 @@ R_AliasDrawModel (alight_t *plighting)
#endif
}
acolormap = currententity->colormap;
if (!acolormap)
acolormap = vid.colormap8;
if (currententity != r_view_model)
ziscale = (float) 0x8000 *(float) 0x10000;

View file

@ -1,106 +0,0 @@
/*
sw_skin.c
(description)
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:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
static __attribute__ ((used)) const char rcsid[] =
"$Id$";
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include "QF/model.h"
#include "QF/render.h"
#include "QF/skin.h"
#include "compat.h"
void
Skin_Set_Translate (int top, int bottom, void *_dest)
{
int i, j;
byte *source;
byte *dest = (byte *) _dest;
top = bound (0, top, 13) * 16;
bottom = bound (0, bottom, 13) * 16;
source = vid.colormap8;
memcpy (dest, vid.colormap8, VID_GRADES*256);
for (i = 0; i < VID_GRADES; i++, dest += 256, source += 256) {
if (top < 128) // the artists made some backwards
// ranges. sigh.
memcpy (dest + TOP_RANGE, source + top, 16);
else
for (j = 0; j < 16; j++)
dest[TOP_RANGE + j] = source[top + 15 - j];
if (bottom < 128)
memcpy (dest + BOTTOM_RANGE, source + bottom, 16);
else
for (j = 0; j < 16; j++)
dest[BOTTOM_RANGE + j] = source[bottom + 15 - j];
}
}
void
Skin_Do_Translation (skin_t *player_skin, int slot, skin_t *skin)
{
}
void
Skin_Do_Translation_Model (model_t *model, int skinnum, int slot, skin_t *skin)
{
}
void
Skin_Player_Model (model_t *model)
{
}
void
Skin_Init_Translation (void)
{
}
void
Skin_Process (skin_t *skin, struct tex_s *tex)
{
}

View file

@ -14,7 +14,7 @@ sw32_src= \
d_sky.c d_sprite.c d_surf.c d_vars.c d_zpoint.c draw.c screen.c \
sw32_fog.c sw32_graph.c sw32_raclip.c sw32_ralias.c sw32_rbsp.c \
sw32_rdraw.c sw32_redge.c sw32_rmain.c sw32_rmisc.c sw32_rpart.c \
sw32_rsky.c sw32_rsprite.c sw32_rsurf.c sw32_skin.c
sw32_rsky.c sw32_rsprite.c sw32_rsurf.c
libsw32_la_SOURCES= $(sw32_src)

View file

@ -561,15 +561,17 @@ R_AliasSetupSkin (void)
r_affinetridesc.seamfixupX16 = (a_skinwidth >> 1) << 16;
r_affinetridesc.skinheight = pmdl->skinheight;
acolormap = vid.colormap8;
if (currententity->skin) {
tex_t *base;
base = currententity->skin->data.texels;
base = currententity->skin->texels;
if (base) {
r_affinetridesc.pskin = base->data;
r_affinetridesc.skinwidth = base->width;
r_affinetridesc.skinheight = base->height;
}
acolormap = currententity->skin->colormap;
}
}
@ -646,10 +648,8 @@ R_AliasDrawModel (alight_t *plighting)
R_AliasSetupLighting (plighting);
R_AliasSetupFrame ();
if (!currententity->colormap)
Sys_Error ("R_AliasDrawModel: !currententity->colormap");
acolormap = currententity->colormap;
if (!acolormap)
acolormap = vid.colormap8;
if (acolormap == &vid.colormap8 && r_pixbytes != 1)
{
if (r_pixbytes == 2)

View file

@ -1,201 +0,0 @@
/*
sw32_skin.c
(description)
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:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
static __attribute__ ((used)) const char rcsid[] =
"$Id$";
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include "QF/model.h"
#include "QF/render.h"
#include "QF/skin.h"
#include "QF/sys.h"
#include "compat.h"
#include "d_iface.h"
VISIBLE void
Skin_Set_Translate (int top, int bottom, void *_dest)
{
int i, j;
top = bound (0, top, 13) * 16;
bottom = bound (0, bottom, 13) * 16;
switch(r_pixbytes) {
case 1:
{
byte *source;
byte *dest = (byte *) _dest;
source = vid.colormap8;
memcpy (dest, vid.colormap8, VID_GRADES * 256);
for (i = 0; i < VID_GRADES; i++, dest += 256, source += 256) {
if (top < 128) // the artists made some backwards ranges.
memcpy (dest + TOP_RANGE, source + top, 16);
else
for (j = 0; j < 16; j++)
dest[TOP_RANGE + j] = source[top + 15 - j];
if (bottom < 128)
memcpy (dest + BOTTOM_RANGE, source + bottom, 16);
else
for (j = 0; j < 16; j++)
dest[BOTTOM_RANGE + j] = source[bottom + 15 - j];
}
}
break;
case 2:
{
unsigned short *source;
unsigned short *dest = (unsigned short *) _dest;
source = vid.colormap16;
memcpy (dest, vid.colormap16, 2 * VID_GRADES * 256);
for (i = 0; i < VID_GRADES; i++, dest += 256, source += 256) {
if (top < 128)
{
for (j = 0; j < 16; j++)
dest[TOP_RANGE + j] = source[top + j];
}
else
{
for (j = 0; j < 16; j++)
dest[TOP_RANGE + j] = source[top + 15 - j];
}
if (bottom < 128)
{
for (j = 0; j < 16; j++)
dest[BOTTOM_RANGE + j] = source[bottom + j];
}
else
{
for (j = 0; j < 16; j++)
dest[BOTTOM_RANGE + j] = source[bottom + 15 - j];
}
}
}
break;
case 4:
{
unsigned int *source;
unsigned int *dest = (unsigned int *) _dest;
source = vid.colormap32;
memcpy (dest, vid.colormap32, 4 * VID_GRADES * 256);
for (i = 0; i < VID_GRADES; i++, dest += 256, source += 256) {
if (top < 128)
{
for (j = 0; j < 16; j++)
dest[TOP_RANGE + j] = source[top + j];
}
else
{
for (j = 0; j < 16; j++)
dest[TOP_RANGE + j] = source[top + 15 - j];
}
if (bottom < 128)
{
for (j = 0; j < 16; j++)
dest[BOTTOM_RANGE + j] = source[bottom + j];
}
else
{
for (j = 0; j < 16; j++)
dest[BOTTOM_RANGE + j] = source[bottom + 15 - j];
}
}
}
break;
default:
Sys_Error("Skin_Set_Translate: unsupported r_pixbytes %i",
r_pixbytes);
}
/*
dest2 = (byte *) _dest;
for (j = 0;j < 256;j++)
dest2[j] = d_8to24table[j];
if (top < 128) {
for (j = 0;j < 16;j++)
dest2[TOP_RANGE + j] = d_8to24table[top + j];
} else {
for (j = 0; j < 16; j++)
dest2[TOP_RANGE + j] = d_8to24table[top + 15 - j];
}
if (bottom < 128) {
for (j = 0;j < 16;j++)
dest2[BOTTOM_RANGE + j] = d_8to24table[bottom + j];
} else {
for (j = 0; j < 16; j++)
dest2[BOTTOM_RANGE + j] = d_8to24table[bottom + 15 - j];
}
*/
}
VISIBLE void
Skin_Do_Translation (skin_t *player_skin, int slot, skin_t *skin)
{
}
VISIBLE void
Skin_Do_Translation_Model (model_t *model, int skinnum, int slot, skin_t *skin)
{
}
VISIBLE void
Skin_Player_Model (model_t *model)
{
}
VISIBLE void
Skin_Init_Translation (void)
{
}
VISIBLE void
Skin_Process (skin_t *skin, struct tex_s *tex)
{
}

View file

@ -61,7 +61,6 @@ typedef struct
int frags;
int colors; // two 4 bit fields
int _colors;
byte translations[4*VID_GRADES*256]; // space for colormap32
} scoreboard_t;
#define NAME_LENGTH 64

View file

@ -77,8 +77,7 @@ server_LIB_DEPS=$(server_LIBFILES) $(common_LIBFILES)
libnq_client_a_SOURCES= \
cl_cam.c cl_cmd.c cl_demo.c cl_ents.c cl_input.c cl_main.c \
cl_screen.c cl_parse.c cl_skin.c cl_tent.c cl_view.c skin.c \
sbar.c
cl_screen.c cl_parse.c cl_tent.c cl_view.c sbar.c
libnq_server_a_SOURCES= \
host.c host_cmd.c sv_cl_phys.c sv_cvar.c sv_main.c \

View file

@ -64,6 +64,7 @@ byte *vid_colormap;
// these two are not intended to be set directly
cvar_t *cl_name;
cvar_t *cl_color;
cvar_t *cl_writecfg;
@ -131,7 +132,6 @@ void
CL_InitCvars (void)
{
Chase_Init_Cvars ();
CL_Skin_Init_Cvars ();
IN_Init_Cvars ();
VID_Init_Cvars ();
S_Init_Cvars ();
@ -212,8 +212,6 @@ CL_ClearState (void)
SZ_Clear (&cls.message);
Skin_ClearTempSkins ();
CL_ClearTEnts ();
R_ClearState ();
@ -529,7 +527,6 @@ CL_Init (cbuf_t *cbuf)
IN_Init ();
CL_SetState (ca_disconnected);
CL_Skin_Init ();
SZ_Alloc (&cls.message, 1024);
CL_Input_Init ();

View file

@ -155,7 +155,6 @@ CL_EntityNum (int num)
while (cl.num_entities <= num) {
cl_baselines[cl.num_entities].ent =
&cl_entities[cl.num_entities];
cl_entities[cl.num_entities].colormap = vid.colormap8;
cl.num_entities++;
}
}
@ -523,13 +522,9 @@ CL_ParseUpdate (int bits)
i = MSG_ReadByte (net_message);
else
i = state->baseline.colormap;
if (!i)
ent->colormap = vid.colormap8;
else {
if (i > cl.maxclients)
Sys_Error ("i >= cl.maxclients");
ent->colormap = cl.scores[i - 1].translations;
}
if (i > cl.maxclients)
Sys_Error ("i > cl.maxclients");
ent->skin = Skin_SetColormap (ent->skin, i);
if (bits & U_SKIN)
skin = MSG_ReadByte (net_message);
@ -537,11 +532,10 @@ CL_ParseUpdate (int bits)
skin = state->baseline.skin;
if (skin != ent->skinnum) {
ent->skinnum = skin;
if (num > 0 && num <= cl.maxclients) {
if (!ent->skin)
ent->skin = Skin_NewTempSkin ();
if (ent->skin)
CL_NewTranslation (num - 1, ent->skin);
if (num <= cl.maxclients) {
ent->skin = Skin_SetColormap (ent->skin, num);
Skin_SetTranslation (num, cl.scores[num].colors >> 4,
cl.scores[num].colors & 0xf);
}
}
@ -617,10 +611,9 @@ CL_ParseUpdate (int bits)
} else
forcelink = true; // hack to make null model players work
if (num > 0 && num <= cl.maxclients) {
if (!ent->skin)
ent->skin = Skin_NewTempSkin ();
if (ent->skin)
CL_NewTranslation (num - 1, ent->skin);
ent->skin = Skin_SetColormap (ent->skin, num);
Skin_SetTranslation (num, cl.scores[num].colors >> 4,
cl.scores[num].colors & 0xf);
}
}
@ -824,7 +817,7 @@ CL_ParseStatic (int version)
//FIXME alpha & lerp
ent->model = cl.model_precache[state.baseline.modelindex];
ent->frame = state.baseline.frame;
ent->colormap = vid.colormap8;
ent->skin = 0;
ent->skinnum = state.baseline.skin;
if (state.baseline.colormod == 255) {
ent->colormod[0] = ent->colormod[1] = ent->colormod[2] = 1.0;
@ -1028,10 +1021,9 @@ CL_ParseServerMessage (void)
} else {
entity_t *ent = &cl_entities[i+1];
cl.scores[i].colors = MSG_ReadByte (net_message);
if (!ent->skin)
ent->skin = Skin_NewTempSkin ();
if (ent->skin)
CL_NewTranslation (i, ent->skin);
ent->skin = Skin_SetColormap (ent->skin, i);
Skin_SetTranslation (i, cl.scores[i].colors >> 4,
cl.scores[i].colors & 0xf);
}
break;

View file

@ -1,162 +0,0 @@
/*
skin.c
(description)
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:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
static __attribute__ ((used)) const char rcsid[] =
"$Id$";
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include "QF/cmd.h"
#include "QF/cvar.h"
#include "QF/msg.h"
#include "QF/screen.h"
#include "QF/skin.h"
#include "QF/sys.h"
#include "QF/va.h"
#include "compat.h"
#include "cl_skin.h"
#include "client.h"
#include "server.h"
cvar_t *noskins; //XXX FIXME
cvar_t *skin;
cvar_t *topcolor;
cvar_t *bottomcolor;
cvar_t *cl_color;
static void
CL_Color_f (void)
{
int top, bottom;
char playercolor;
if (Cmd_Argc () == 1) {
Sys_Printf ("\"color\" is \"%d %d\"\n", (cl_color->int_val) >> 4,
(cl_color->int_val) & 0x0f);
Sys_Printf ("color <0-13> [0-13]\n");
return;
}
if (Cmd_Argc () == 2)
top = bottom = atoi (Cmd_Argv (1));
else {
top = atoi (Cmd_Argv (1));
bottom = atoi (Cmd_Argv (2));
}
top = min (top & 15, 13);
bottom = min (bottom & 15, 13);
playercolor = top * 16 + bottom;
if (cmd_source == src_command) {
Cvar_SetValue (cl_color, playercolor);
if (cls.state == ca_connected)
CL_Cmd_ForwardToServer ();
return;
}
host_client->colors = playercolor;
SVfloat (host_client->edict, team) = bottom + 1;
// send notification to all clients
MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
MSG_WriteByte (&sv.reliable_datagram, host_client - svs.clients);
MSG_WriteByte (&sv.reliable_datagram, host_client->colors);
}
void
CL_Skin_Init (void)
{
Skin_Init ();
Cmd_AddCommand ("color", CL_Color_f, "The pant and shirt color (color "
"shirt pants) Note that if only shirt color is given, "
"pants will match");
}
void
CL_Skin_Init_Cvars (void)
{
Skin_Init_Cvars ();
cl_color = Cvar_Get ("_cl_color", "0", CVAR_ARCHIVE, NULL, "Player color");
}
void
CL_NewTranslation (int slot, skin_t *skin)
{
scoreboard_t *player;
int top, bottom;
byte *dest;
model_t *model;
cl_entity_state_t *state;
int skinnum;
if (slot > cl.maxclients)
Sys_Error ("CL_NewTranslation: slot > cl.maxclients");
player = &cl.scores[slot];
dest = player->translations;
top = (player->colors & 0xf0) >> 4;
bottom = player->colors & 15;
state = &cl_baselines[1 + slot];
model = state->ent->model;
skinnum = state->ent->skinnum;
memset (skin, 0, sizeof (*skin)); //XXX external skins not yet supported
if (!model)
return;
skin->texture = skin_textures + slot; //FIXME
skin->data.texels = 0; //FIXME
if (player->colors == player->_colors
&& model == state->model
&& skinnum == state->skinnum)
return;
player->_colors = player->colors;
state->model = model;
state->skinnum = skinnum;
Skin_Set_Translate (top, bottom, dest);
Skin_Do_Translation_Model (model, skinnum, slot, skin);
}

View file

@ -135,7 +135,7 @@ CL_Init_Entity (entity_t *ent)
{
memset (ent, 0, sizeof (*ent));
ent->colormap = vid.colormap8;
ent->skin = 0;
QuatSet (1.0, 1.0, 1.0, 1.0, ent->colormod);
ent->scale = 1.0;
ent->pose1 = ent->pose2 = -1;

View file

@ -666,7 +666,7 @@ V_CalcRefdef (void)
view->model = cl.model_precache[cl.stats[STAT_WEAPON]];
view->frame = cl.stats[STAT_WEAPONFRAME];
view->colormap = vid.colormap8;
view->skin = 0;
// set up the refresh position
VectorAdd (r_refdef.viewangles, cl.punchangle, r_refdef.viewangles);

View file

@ -26,16 +26,10 @@
$Id$
*/
#ifndef _CL_SKIN_H
#define _CL_SKIN_H
#ifndef __cl_skin_h
#define __cl_skin_h
#include "QF/qtypes.h"
#include "QF/skin.h"
void CL_Skins_f (void);
void CL_AllSkins_f (void);
void Skin_NextDownload (void);
void CL_Skin_Init (void);
void CL_Skin_Init_Cvars (void);
#endif
#endif//__cl_skin_h

View file

@ -86,9 +86,6 @@ typedef struct player_info_s
int _bottomcolor;
int spectator;
byte translations[4*VID_GRADES*256]; // space for colormap32
int translationcolor[256];
struct skin_s *skin;
int stats[MAX_CL_STATS]; // health, etc
int prevcount;
} player_info_t;

View file

@ -110,7 +110,7 @@ libqw_client_a_SOURCES= \
cl_cam.c cl_chat.c cl_cmd.c cl_cvar.c cl_demo.c cl_entparse.c \
cl_ents.c cl_http.c cl_input.c cl_main.c cl_ngraph.c cl_parse.c \
cl_pred.c cl_screen.c cl_skin.c cl_slist.c cl_tent.c cl_view.c \
locs.c sbar.c skin.c teamplay.c
locs.c sbar.c teamplay.c
# Software-rendering clients

View file

@ -202,13 +202,13 @@ CL_TransformEntity (entity_t *ent, const vec3_t angles, qboolean force)
static void
CL_LinkPacketEntities (void)
{
int pnum, i;
int pnum;
dlight_t *dl;
entity_t *ent;
entity_state_t *s1;
model_t *model;
packet_entities_t *pack;
player_info_t *info;
//player_info_t *info;
pack = &cl.frames[cls.netchan.incoming_sequence &
UPDATE_MASK].packet_entities;
@ -246,25 +246,24 @@ CL_LinkPacketEntities (void)
if (s1->colormap && (s1->colormap <= MAX_CLIENTS)
&& cl.players[s1->colormap - 1].name[0]
&& !strcmp (ent->model->name, "progs/player.mdl")) {
ent->colormap = cl.players[s1->colormap - 1].translations;
info = &cl.players[s1->colormap - 1];
ent->skin = Skin_SetColormap (ent->skin, s1->colormap);
//info = &cl.players[s1->colormap - 1];
} else {
ent->colormap = vid.colormap8;
info = NULL;
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) {
i = s1->colormap - 1;
CL_NewTranslation (i, 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
@ -485,7 +484,7 @@ CL_LinkPlayers (void)
ent->model = cl.model_precache[state->pls.modelindex];
ent->frame = state->pls.frame;
ent->colormap = info->translations;
ent->skin = Skin_SetColormap (ent->skin, j + 1);
ent->skinnum = state->pls.skinnum;
CL_TransformEntity (ent, ang, false);
@ -495,6 +494,7 @@ 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) {
@ -505,7 +505,7 @@ CL_LinkPlayers (void)
} else {
ent->skin = NULL;
}
#endif
ent->min_light = min (cl.fbskins, cl_fb_players->value);
if (ent->min_light >= 1.0)
@ -539,8 +539,6 @@ CL_EmitEntities (void)
if (!cl.validsequence)
return;
Skin_ClearTempSkins ();
CL_LinkPlayers ();
CL_LinkPacketEntities ();
CL_UpdateTEnts ();

View file

@ -1741,7 +1741,6 @@ Host_Init (void)
CL_Cam_Init_Cvars ();
CL_Input_Init_Cvars ();
CL_Skin_Init_Cvars ();
CL_Init_Cvars ();
CL_Prediction_Init_Cvars ();
Game_Init_Cvars ();

View file

@ -59,6 +59,7 @@ static __attribute__ ((used)) const char rcsid[] =
#include "QF/qfplist.h"
#include "QF/quakeio.h"
#include "QF/screen.h"
#include "QF/skin.h"
#include "QF/sound.h"
#include "QF/sys.h"
#include "QF/teamplay.h"
@ -365,7 +366,7 @@ Model_NextDownload (void)
if (strequal (cl.model_name[i], "progs/player.mdl")
&& cl.model_precache[i]->type == mod_alias) {
info_key = pmodel_name;
Skin_Player_Model (cl.model_precache[i]);
//XXX Skin_Player_Model (cl.model_precache[i]);
}
if (strequal (cl.model_name[i], "progs/eyes.mdl")
&& cl.model_precache[i]->type == mod_alias)
@ -1111,8 +1112,8 @@ CL_ProcessUserInfo (int slot, player_info_t *player)
else
player->spectator = false;
if (cls.state == ca_active)
Skin_Find (player);
//XXX if (cls.state == ca_active)
//XXX Skin_Find (player);
Sbar_Changed ();
}

View file

@ -76,11 +76,11 @@ Skin_NextDownload (void)
sc = &cl.players[cls.downloadnumber];
if (!sc->name[0])
continue;
Skin_Find (sc);
//XXX Skin_Find (sc);
if (noskins->int_val) //XXX FIXME
continue;
if (!CL_CheckOrDownloadFile (va ("skins/%s.pcx", sc->skin->name)))
return; // started a download
//XXX if (!CL_CheckOrDownloadFile (va ("skins/%s.pcx", sc->skin->name)))
//XXX return; // started a download
}
cls.downloadtype = dl_none;
@ -90,9 +90,9 @@ Skin_NextDownload (void)
sc = &cl.players[i];
if (!sc->name[0])
continue;
Skin_Find (sc);
Skin_Cache (sc->skin);
sc->skin = NULL;
//XXX Skin_Find (sc);
//XXX Skin_Cache (sc->skin);
//XXX sc->skin = NULL;
}
if (cls.state != ca_active) {
@ -112,10 +112,10 @@ Skin_NextDownload (void)
Refind all skins, downloading if needed.
*/
void
static void
CL_Skins_f (void)
{
Skin_Flush ();
//XXX Skin_Flush ();
if (cls.state == ca_disconnected)
return;
@ -130,14 +130,14 @@ CL_Skins_f (void)
Sets all skins to one specific one
*/
void
static void
CL_AllSkins_f (void)
{
if (Cmd_Argc () == 2) {
strcpy (allskins, Cmd_Argv (1));
//XXX strcpy (allskins, Cmd_Argv (1));
} else if (Cmd_Argc () == 1) {
Sys_Printf ("clearing allskins\n");
allskins[0] = 0;
//XXX allskins[0] = 0;
} else {
Sys_Printf ("Usage: allskins [name]\n");
return;
@ -180,19 +180,6 @@ CL_Color_f (void)
Cvar_Set (bottomcolor, num);
}
void
CL_Skin_Init (void)
{
Skin_Init ();
Cmd_AddCommand ("skins", CL_Skins_f, "Download all skins that are "
"currently in use");
Cmd_AddCommand ("allskins", CL_AllSkins_f, "Force all player skins to "
"one skin");
Cmd_AddCommand ("color", CL_Color_f, "The pant and shirt color (color "
"shirt pants) Note that if only shirt color is given, "
"pants will match");
}
static void
skin_f (cvar_t *var)
{
@ -203,9 +190,18 @@ skin_f (cvar_t *var)
}
void
CL_Skin_Init_Cvars (void)
CL_Skin_Init (void)
{
Skin_Init_Cvars ();
//Skin_Init ();
//Skin_Init_Cvars ();
Cmd_AddCommand ("skins", CL_Skins_f, "Download all skins that are "
"currently in use");
Cmd_AddCommand ("allskins", CL_AllSkins_f, "Force all player skins to "
"one skin");
Cmd_AddCommand ("color", CL_Color_f, "The pant and shirt color (color "
"shirt pants) Note that if only shirt color is given, "
"pants will match");
noskins = Cvar_Get ("noskins", "0", CVAR_ARCHIVE, NULL, //XXX FIXME
"set to 1 to not download new skins");
skin = Cvar_Get ("skin", "", CVAR_ARCHIVE | CVAR_USERINFO, skin_f,
@ -215,39 +211,3 @@ CL_Skin_Init_Cvars (void)
bottomcolor = Cvar_Get ("bottomcolor", "0", CVAR_ARCHIVE | CVAR_USERINFO,
Cvar_Info, "Players color on bottom");
}
void
CL_NewTranslation (int slot, skin_t *skin)
{
player_info_t *player;
if (slot > MAX_CLIENTS)
Host_Error ("CL_NewTranslation: slot > MAX_CLIENTS");
player = &cl.players[slot];
if (!player->name[0])
return;
if (player->skin && !strequal (player->skinname->value, player->skin->name))
player->skin = NULL;
if (player->_topcolor != player->topcolor ||
player->_bottomcolor != player->bottomcolor || !player->skin) {
player->_topcolor = player->topcolor;
player->_bottomcolor = player->bottomcolor;
Skin_Set_Translate (player->topcolor, player->bottomcolor,
player->translations);
if (!player->skin)
Skin_Find (player);
memcpy (skin, player->skin, sizeof (*skin));
skin->texture = skin_textures + slot; // FIXME
skin->data.texels = Skin_Cache (player->skin);
// FIXME: breaks cache ownership
Skin_Do_Translation (player->skin, slot, skin);
} else {
memcpy (skin, player->skin, sizeof (*skin));
skin->texture = skin_textures + slot; // FIXME
skin->data.texels = Skin_Cache (player->skin);
// FIXME: breaks cache ownership
}
}

View file

@ -141,7 +141,7 @@ CL_Init_Entity (entity_t *ent)
{
memset (ent, 0, sizeof (*ent));
ent->colormap = vid.colormap8;
ent->skin = 0;
QuatSet (1.0, 1.0, 1.0, 1.0, ent->colormod);
ent->scale = 1.0;
ent->pose1 = ent->pose2 = -1;
@ -642,7 +642,7 @@ CL_ParseProjectiles (qboolean nail2)
pr = &tent->ent;
pr->model = cl.model_precache[cl_spikeindex];
pr->colormap = vid.colormap8;
pr->skin = 0;
pr->origin[0] = ((bits[0] + ((bits[1] & 15) << 8)) << 1) - 4096;
pr->origin[1] = (((bits[1] >> 4) + (bits[2] << 4)) << 1) - 4096;
pr->origin[2] = ((bits[3] + ((bits[4] & 15) << 8)) << 1) - 4096;

View file

@ -671,7 +671,7 @@ V_CalcRefdef (void)
else
view->model = cl.model_precache[cl.stats[STAT_WEAPON]];
view->frame = view_message->pls.weaponframe;
view->colormap = vid.colormap8;
view->skin = 0;
// set up the refresh position
r_refdef.viewangles[PITCH] += cl.punchangle;

View file

@ -1,283 +0,0 @@
/*
skin.c
(description)
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:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
static __attribute__ ((used)) const char rcsid[] =
"$Id$";
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include "QF/cvar.h"
#include "QF/hash.h"
#include "QF/image.h"
#include "QF/pcx.h"
#include "QF/quakefs.h"
#include "QF/skin.h"
#include "QF/sys.h"
#include "client.h"
#include "compat.h"
#include "skin_stencil.h"
#define MAX_TEMP_SKINS 64 //XXX dynamic?
extern cvar_t *noskins; //FIXME shouldn't be here
cvar_t *baseskin;
char allskins[128];
skin_t skin_cache[MAX_CACHED_SKINS];
static hashtab_t *skin_hash;
static int numskins;
static skin_t temp_skins[MAX_TEMP_SKINS];
static int num_temp_skins;
static int fullfb;
int skin_textures;
int skin_fb_textures;
static const char *
skin_get_key (void *_skin, void *unused)
{
skin_t *skin = (skin_t*)_skin;
return skin->name;
}
/*
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;
char name[128];
const char *s = NULL;
if (allskins[0]) {
strncpy (name, allskins, sizeof (name));
} else {
if ((s = sc->skinname->value) && s[0])
strncpy (name, s, sizeof (name));
else
strncpy (name, baseskin->string, sizeof (name));
}
if (strstr (name, "..") || *name == '.')
strcpy (name, "base");
if (!allskins[0] && (!s || !strcaseequal (name, s)))
Info_SetValueForKey (sc->userinfo, "skin", name, 1);
QFS_StripExtension (name, name);
skin = Hash_Find (skin_hash, name);
if (skin) {
sc->skin = skin;
Skin_Cache (sc->skin);
return;
}
if (numskins == MAX_CACHED_SKINS) {
// ran out of spots, so flush everything
Skin_Flush ();
return;
}
skin = &skin_cache[numskins];
sc->skin = skin;
numskins++;
memset (skin, 0, sizeof (*skin));
strncpy (skin->name, name, sizeof (skin->name) - 1);
Hash_Add (skin_hash, skin);
}
/*
Skin_Cache
Returns a pointer to the skin bitmap, or NULL to use the default
*/
tex_t *
Skin_Cache (skin_t *skin)
{
char name[1024];
tex_t *out;
QFile *file;
tex_t *tex;
int pixels;
byte *ipix, *opix;
int i, numfb;
if (cls.downloadtype == dl_skin) // use base until downloaded
return NULL;
// NOSKINS > 1 will show skins, but not download new ones.
if (noskins->int_val == 1) //XXX FIXME
return NULL;
if (skin->failedload)
return NULL;
out = Cache_Check (&skin->data.cache);
if (out)
return out;
// load the pic from disk
snprintf (name, sizeof (name), "skins/%s.pcx", skin->name);
QFS_FOpenFile (name, &file);
if (!file) {
Sys_Printf ("Couldn't load skin %s\n", name);
snprintf (name, sizeof (name), "skins/%s.pcx", baseskin->string);
QFS_FOpenFile (name, &file);
if (!file) {
skin->failedload = true;
return NULL;
}
}
pixels = 320 * 200;
out = Cache_Alloc (&skin->data.cache, field_offset (tex_t, data[pixels]),
skin->name);
if (!out)
Sys_Error ("Skin_Cache: couldn't allocate");
tex = LoadPCX (file, 0, vid.palette);
Qclose (file);
if (!tex || tex->width > 320 || tex->height > 200) {
skin->failedload = true;
Sys_Printf ("Bad skin %s\n", name);
return NULL;
}
opix = out->data;
out->width = 320;
out->height = 200;
out->palette = tex->palette; //FIXME assumes 0 or vid.palette
memset (opix, 0, pixels);
for (i = 0, ipix = tex->data; i < tex->height;
i++, opix += 320, ipix += tex->width)
memcpy (opix, ipix, tex->width);
Skin_Process (skin, out);
skin->failedload = false;
for (i = 0,numfb = 0; i < 320*200; i++)
if (skin_stencil[i] && out->data[i] >= 256 - 32)
numfb++;
skin->numfb = numfb;
return out;
}
void
Skin_Flush (void)
{
int i;
for (i = 0; i < numskins; i++) {
if (skin_cache[i].data.cache.data)
Cache_Free (&skin_cache[i].data.cache);
}
numskins = 0;
Hash_FlushTable (skin_hash);
}
skin_t *
Skin_NewTempSkin (void)
{
if (num_temp_skins == MAX_TEMP_SKINS)
return 0; // ran out
return &temp_skins[num_temp_skins++];
}
void
Skin_ClearTempSkins (void)
{
num_temp_skins = 0;
}
int
Skin_Init_Textures (int base)
{
skin_textures = base;
base += MAX_TEMP_SKINS;
skin_fb_textures = base;
base += MAX_TEMP_SKINS;
return base;
}
void
Skin_Init (void)
{
int i;
skin_hash = Hash_NewTable (1021, skin_get_key, 0, 0);
Skin_Init_Translation ();
for (i = 0, fullfb = 0; i < 320*200; i++)
fullfb += skin_stencil[i];
}
void
Skin_Init_Cvars (void)
{
baseskin = Cvar_Get ("baseskin", "base", CVAR_NONE, NULL,
"default base skin name");
}
int
Skin_FbPercent (const char *skin_name)
{
int i, totalfb = 0;
skin_t *skin = 0;
if (skin_name) {
skin = Hash_Find (skin_hash, skin_name);
if (skin)
return skin->numfb * 1000 / fullfb;
return -1;
}
for (i = 0; i < numskins; i++)
totalfb += skin_cache[i].numfb;
return totalfb * 1000 / (numskins * fullfb);
}

View file

@ -160,6 +160,7 @@ Team_ParseSay (const char *s)
case 'S':
bracket = 0;
t1 = skin->string;
t1 = "FIXME";
break;
case 'd':
bracket = 0;
@ -451,13 +452,15 @@ Team_F_Skins (char *args)
for (l = 0; args[l] && !isspace ((byte) args[l]); l++);
if (l == 0) {
totalfb = Skin_FbPercent (0);
//XXXtotalfb = Skin_FbPercent (0);
totalfb = 0;
return va ("say Player models have %f%% brightness\n"
"say Average percent fullbright for all loaded skins is "
"%d.%d%%", allfb * 100, totalfb / 10, totalfb % 10);
}
totalfb = Skin_FbPercent (args);
//XXX totalfb = Skin_FbPercent (args);
totalfb = 0;
if (totalfb >= 0)
return va ("say \"Skin %s is %d.%d%% fullbright\"", args, totalfb / 10,