From d7d167c1e9f44e34cee9298673e1f5cb582c8ca9 Mon Sep 17 00:00:00 2001 From: Shpoike Date: Sat, 11 Sep 2021 04:07:03 +0100 Subject: [PATCH] Fix corrupted player skins. Fix player colours not always applying properly. Allow richer player colours. --- Quake/cl_demo.c | 9 +++- Quake/cl_main.c | 56 ++++++++++++++++++++- Quake/cl_parse.c | 9 ++-- Quake/client.h | 4 +- Quake/draw.h | 14 +++++- Quake/gl_draw.c | 33 ++++++++++-- Quake/gl_model.c | 7 +++ Quake/gl_rmisc.c | 7 +-- Quake/gl_texmgr.c | 126 +++++++++++++++++++++++++++------------------- Quake/gl_texmgr.h | 6 +-- Quake/host_cmd.c | 2 +- Quake/image.c | 18 ++----- Quake/image.h | 5 +- Quake/menu.c | 56 +++++++++++---------- Quake/pr_ext.c | 24 +++++---- Quake/sbar.c | 77 ++++------------------------ 16 files changed, 260 insertions(+), 193 deletions(-) diff --git a/Quake/cl_demo.c b/Quake/cl_demo.c index 7866052f..1e1990a6 100644 --- a/Quake/cl_demo.c +++ b/Quake/cl_demo.c @@ -329,7 +329,7 @@ void CL_Record_Prespawn(void) void CL_Record_Spawn(void) { const char *cmd; - int i; + int i, c; // player names, colors, and frag counts for (i = 0; i < cl.maxclients; i++) @@ -342,7 +342,12 @@ void CL_Record_Spawn(void) MSG_WriteShort (&net_message, cl.scores[i].frags); MSG_WriteByte (&net_message, svc_updatecolors); MSG_WriteByte (&net_message, i); - MSG_WriteByte (&net_message, cl.scores[i].colors); + c = 0; + if (cl.scores[i].shirt.type == 1) + c |= (cl.scores[i].shirt.rgb[0]<<4)&0xf; + if (cl.scores[i].pants.type == 1) + c |= (cl.scores[i].pants.rgb[0]<<0)&0xf; + MSG_WriteByte (&net_message, c); } // send all current light styles diff --git a/Quake/cl_main.c b/Quake/cl_main.c index c3cc9105..73d9a0dd 100644 --- a/Quake/cl_main.c +++ b/Quake/cl_main.c @@ -1382,15 +1382,67 @@ static void CL_ServerExtension_ServerinfoUpdate_f(void) Info_SetKey(cl.serverinfo, sizeof(cl.serverinfo), newserverkey, newservervalue); } +int Sbar_ColorForMap (int m); +byte *CL_PLColours_ToRGB(plcolour_t *c) +{ + if (c->type == 2) + return c->rgb; + else if (c->type == 1) + return (byte *)(d_8to24table + (c->basic<<4)+8); + else + return (byte*)&d_8to24table[15]; +} +char *CL_PLColours_ToString(plcolour_t c) +{ + if (c.type == 2) + return va("0x%02x%02x%02x", c.rgb[0], c.rgb[1], c.rgb[2]); + else if (c.type == 1) + return va("%i", c.basic); + return "0"; +} + +plcolour_t CL_PLColours_Parse(const char *s) +{ + plcolour_t c; + unsigned int v = strtoul(s, NULL, 0); + if (!strncmp(s, "0x", 2)) + { + c.type = 2; + c.basic = 0; + c.rgb[0] = 0xff&(v>>16); + c.rgb[1] = 0xff&(v>>8); + c.rgb[2] = 0xff&(v>>0); + } + else if (*s) + { + c.type = 1; + c.basic = v; + c.rgb[0] = c.rgb[1] = c.rgb[2] = v&0xf; + } + else + { + c.type = 0; + c.rgb[0] = c.rgb[1] = c.rgb[2] = 0; + } + return c; +} static void CL_UserinfoChanged(scoreboard_t *sb) { char tmp[64]; + plcolour_t top, bot; Info_GetKey(sb->userinfo, "name", sb->name, sizeof(sb->name)); Info_GetKey(sb->userinfo, "topcolor", tmp, sizeof(tmp)); - sb->colors = (atoi(tmp)&15)<<4; + top = CL_PLColours_Parse(tmp); Info_GetKey(sb->userinfo, "bottomcolor", tmp, sizeof(tmp)); - sb->colors |= (atoi(tmp)&15); + bot = CL_PLColours_Parse(tmp); + + if (!CL_PLColours_Equals(top, sb->shirt) || !CL_PLColours_Equals(bot, sb->pants)) + { + sb->shirt = top; + sb->pants = bot; + R_TranslateNewPlayerSkin (sb-cl.scores); + } } static void CL_ServerExtension_FullUserinfo_f(void) { diff --git a/Quake/cl_parse.c b/Quake/cl_parse.c index 734697b6..5690e295 100644 --- a/Quake/cl_parse.c +++ b/Quake/cl_parse.c @@ -1972,10 +1972,14 @@ static void CL_ParseClientdata (void) CL_NewTranslation ===================== */ -static void CL_NewTranslation (int slot) +static void CL_NewTranslation (int slot, int vanillacolour) { if (slot > cl.maxclients) Sys_Error ("CL_NewTranslation: slot > cl.maxclients"); + + //clumsy, but ensures its initialised properly. + cl.scores[slot].shirt = CL_PLColours_Parse(va("%i", (vanillacolour>>4)&0xf)); + cl.scores[slot].pants = CL_PLColours_Parse(va("%i", (vanillacolour>>0)&0xf)); R_TranslatePlayerSkin (slot); } @@ -2586,8 +2590,7 @@ void CL_ParseServerMessage (void) i = MSG_ReadByte (); if (i >= cl.maxclients) Host_Error ("CL_ParseServerMessage: svc_updatecolors > MAX_SCOREBOARD"); - cl.scores[i].colors = MSG_ReadByte (); - CL_NewTranslation (i); + CL_NewTranslation (i, MSG_ReadByte()); break; case svc_particle: diff --git a/Quake/client.h b/Quake/client.h index ca1a4c1f..d92e87c6 100644 --- a/Quake/client.h +++ b/Quake/client.h @@ -38,9 +38,9 @@ typedef struct char name[MAX_SCOREBOARDNAME]; float entertime; int frags; - int colors; // two 4 bit fields + plcolour_t shirt; + plcolour_t pants; int ping; - byte translations[VID_GRADES*256]; char userinfo[8192]; } scoreboard_t; diff --git a/Quake/draw.h b/Quake/draw.h index 131954d1..77d2cb6e 100644 --- a/Quake/draw.h +++ b/Quake/draw.h @@ -26,6 +26,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // draw.h -- these are the only functions outside the refresh allowed // to touch the vid buffer +typedef struct +{ + byte type; //0 for none, 1 for legacy colours, 2 for rgb. + byte basic; + byte rgb[3]; +} plcolour_t; +plcolour_t CL_PLColours_Parse(const char *s); +char *CL_PLColours_ToString(plcolour_t c); +byte *CL_PLColours_ToRGB(plcolour_t *c); +#define CL_PLColours_Equals(a,b) (!memcmp(&a,&b, sizeof(plcolour_t))) + extern qpic_t *draw_disc; // also used on sbar void Draw_Init (void); @@ -33,10 +44,11 @@ void Draw_Character (int x, int y, int num); void Draw_DebugChar (char num); void Draw_Pic (int x, int y, qpic_t *pic); void Draw_SubPic (float x, float y, float w, float h, qpic_t *pic, float s1, float t1, float s2, float t2); -void Draw_TransPicTranslate (int x, int y, qpic_t *pic, int top, int bottom); //johnfitz -- more parameters +void Draw_TransPicTranslate (int x, int y, qpic_t *pic, plcolour_t top, plcolour_t bottom); //johnfitz -- more parameters void Draw_ConsoleBackground (void); //johnfitz -- removed parameter int lines void Draw_TileClear (int x, int y, int w, int h); void Draw_Fill (int x, int y, int w, int h, int c, float alpha); //johnfitz -- added alpha +void Draw_FillPlayer (int x, int y, int w, int h, plcolour_t c, float alpha); //Spike - for richer player colours. void Draw_FadeScreen (void); void Draw_String (int x, int y, const char *str); qpic_t *Draw_PicFromWad2 (const char *name, unsigned int texflags); diff --git a/Quake/gl_draw.c b/Quake/gl_draw.c index d45276f0..bd45bd70 100644 --- a/Quake/gl_draw.c +++ b/Quake/gl_draw.c @@ -705,12 +705,12 @@ Draw_TransPicTranslate -- johnfitz -- rewritten to use texmgr to do translation Only used for the player color selection menu ============= */ -void Draw_TransPicTranslate (int x, int y, qpic_t *pic, int top, int bottom) +void Draw_TransPicTranslate (int x, int y, qpic_t *pic, plcolour_t top, plcolour_t bottom) { - static int oldtop = -2; - static int oldbottom = -2; + static plcolour_t oldtop = {-2}; + static plcolour_t oldbottom = {-2}; - if (top != oldtop || bottom != oldbottom) + if (!CL_PLColours_Equals(top, oldtop) || !CL_PLColours_Equals(bottom, oldbottom)) { glpic_t *p = (glpic_t *)pic->data; gltexture_t *glt = p->gltexture; @@ -827,6 +827,31 @@ void Draw_Fill (int x, int y, int w, int h, int c, float alpha) //johnfitz -- ad glEnable (GL_ALPHA_TEST); //johnfitz -- for alpha glEnable (GL_TEXTURE_2D); } +void Draw_FillPlayer (int x, int y, int w, int h, plcolour_t c, float alpha) +{ + glDisable (GL_TEXTURE_2D); + glEnable (GL_BLEND); //johnfitz -- for alpha + glDisable (GL_ALPHA_TEST); //johnfitz -- for alpha + if (c.type == 2) + glColor4f (c.rgb[0]/255.0, c.rgb[1]/255.0, c.rgb[2]/255.0, alpha); //johnfitz -- added alpha + else + { + byte *pal = (byte *)&d_8to24table[(c.basic<<4) + 8]; //johnfitz -- use d_8to24table instead of host_basepal + glColor4f (pal[0]/255.0, pal[1]/255.0, pal[2]/255.0, alpha); //johnfitz -- added alpha + } + + glBegin (GL_QUADS); + glVertex2f (x,y); + glVertex2f (x+w, y); + glVertex2f (x+w, y+h); + glVertex2f (x, y+h); + glEnd (); + + glColor3f (1,1,1); + glDisable (GL_BLEND); //johnfitz -- for alpha + glEnable (GL_ALPHA_TEST); //johnfitz -- for alpha + glEnable (GL_TEXTURE_2D); +} /* ================ diff --git a/Quake/gl_model.c b/Quake/gl_model.c index 3360c4c2..c9d4c632 100644 --- a/Quake/gl_model.c +++ b/Quake/gl_model.c @@ -26,6 +26,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" +extern gltexture_t *playertextures[MAX_SCOREBOARD]; //spike - to ensure skins don't get screwed randomly. + qmodel_t *loadmodel; char loadname[32]; // for hunk tags @@ -324,6 +326,7 @@ qmodel_t *Mod_LoadModel (qmodel_t *mod, qboolean crash) byte *buf; byte stackbuf[1024]; // avoid dirtying the cache heap int mod_type; + int i; if (!mod->needload) { @@ -457,6 +460,10 @@ qmodel_t *Mod_LoadModel (qmodel_t *mod, qboolean crash) Mod_SetExtraFlags (mod); //johnfitz. spike -- moved this to be generic, because most of the flags are anyway. + for (i = 0; i < countof(playertextures); i++) + if (playertextures[i] && playertextures[i]->owner == mod) + R_TranslateNewPlayerSkin(i); + return mod; } diff --git a/Quake/gl_rmisc.c b/Quake/gl_rmisc.c index 80ba6089..fb03f304 100644 --- a/Quake/gl_rmisc.c +++ b/Quake/gl_rmisc.c @@ -254,15 +254,10 @@ R_TranslatePlayerSkin -- johnfitz -- rewritten. also, only handles new colors, */ void R_TranslatePlayerSkin (int playernum) { - int top, bottom; - - top = (cl.scores[playernum].colors & 0xf0)>>4; - bottom = cl.scores[playernum].colors &15; - //FIXME: if gl_nocolors is on, then turned off, the textures may be out of sync with the scoreboard colors. if (!gl_nocolors.value) if (playertextures[playernum]) - TexMgr_ReloadImage (playertextures[playernum], top, bottom); + TexMgr_ReloadImage (playertextures[playernum], cl.scores[playernum].shirt, cl.scores[playernum].pants); } /* diff --git a/Quake/gl_texmgr.c b/Quake/gl_texmgr.c index 3eb0f505..6cfe500b 100644 --- a/Quake/gl_texmgr.c +++ b/Quake/gl_texmgr.c @@ -37,6 +37,8 @@ static int numgltextures; static gltexture_t *active_gltextures, *free_gltextures; gltexture_t *notexture, *nulltexture; +plcolour_t plcolour_none = {0}; + unsigned int d_8to24table[256]; unsigned int d_8to24table_fbright[256]; unsigned int d_8to24table_fbright_fence[256]; @@ -1321,7 +1323,7 @@ static void TexMgr_LoadImage8 (gltexture_t *glt, byte *data) extern cvar_t gl_fullbrights; qboolean padw = false, padh = false; byte padbyte; - unsigned int *usepal; + unsigned int *usepal, translation[256]; int i; // HACK HACK HACK -- taken from tomazquake @@ -1373,6 +1375,68 @@ static void TexMgr_LoadImage8 (gltexture_t *glt, byte *data) padbyte = 255; } + if (glt->shirt.type || glt->pants.type) + { + int shirt, pants, m; + //create new translation table + for (i = 0; i < 256; i++) + translation[i] = usepal[i]; + + if (glt->shirt.type == 2) + { + for (i = 0; i < 16; i++) + { + m = i|(i<<4); + ((byte *) &translation[TOP_RANGE+i])[0] = (m * glt->shirt.rgb[0])>>8; + ((byte *) &translation[TOP_RANGE+i])[1] = (m * glt->shirt.rgb[1])>>8; + ((byte *) &translation[TOP_RANGE+i])[2] = (m * glt->shirt.rgb[2])>>8; + ((byte *) &translation[TOP_RANGE+i])[3] = 255; + } + } + else if (glt->shirt.type == 1) + { + shirt = glt->shirt.rgb[0] * 16; + if (shirt < 128) + { + for (i = 0; i < 16; i++) + translation[TOP_RANGE+i] = usepal[shirt + i]; + } + else + { + for (i = 0; i < 16; i++) + translation[TOP_RANGE+i] = usepal[shirt+15-i]; + } + } + + if (glt->pants.type == 2) + { + for (i = 0; i < 16; i++) + { + m = i|(i<<4); + ((byte *) &translation[BOTTOM_RANGE+i])[0] = (m * glt->pants.rgb[0])>>8; + ((byte *) &translation[BOTTOM_RANGE+i])[1] = (m * glt->pants.rgb[1])>>8; + ((byte *) &translation[BOTTOM_RANGE+i])[2] = (m * glt->pants.rgb[2])>>8; + ((byte *) &translation[BOTTOM_RANGE+i])[3] = 255; + } + } + else if (glt->pants.type == 1) + { + pants = glt->pants.rgb[0] * 16; + if (pants < 128) + { + for (i = 0; i < 16; i++) + translation[BOTTOM_RANGE+i] = usepal[pants + i]; + } + else + { + for (i = 0; i < 16; i++) + translation[BOTTOM_RANGE+i] = usepal[pants+15-i]; + } + } + + usepal = translation; + } + // pad each dimention, but only if it's not going to be downsampled later if (glt->flags & TEXPREF_PAD) { @@ -1467,8 +1531,8 @@ gltexture_t *TexMgr_LoadImage (qmodel_t *owner, const char *name, int width, int glt->width = width; glt->height = height; glt->flags = flags; - glt->shirt = -1; - glt->pants = -1; + glt->shirt.type = 0; + glt->pants.type = 0; q_strlcpy (glt->source_file, source_file, sizeof(glt->source_file)); glt->source_offset = source_offset; glt->source_format = format; @@ -1539,11 +1603,10 @@ gltexture_t *TexMgr_LoadImage (qmodel_t *owner, const char *name, int width, int TexMgr_ReloadImage -- reloads a texture, and colormaps it if needed ================ */ -void TexMgr_ReloadImage (gltexture_t *glt, int shirt, int pants) +void TexMgr_ReloadImage (gltexture_t *glt, plcolour_t shirt, plcolour_t pants) { - byte translation[256]; - byte *src, *dst, *data = NULL, *translated; - int mark, size, i; + byte *data = NULL; + int mark, size; qboolean malloced = false; enum srcformat fmt = glt->source_format; // @@ -1584,9 +1647,9 @@ invalid: Con_Printf ("TexMgr_ReloadImage: invalid source for %s\n", glt->name); // // if shirt and pants are -1,-1, use existing shirt and pants colors // if existing shirt and pants colors are -1,-1, don't bother colormapping - if (shirt > -1 && pants > -1) + if (shirt.type || pants.type) { - if (glt->source_format == SRC_INDEXED) + if (fmt == SRC_INDEXED) { glt->shirt = shirt; glt->pants = pants; @@ -1594,50 +1657,11 @@ invalid: Con_Printf ("TexMgr_ReloadImage: invalid source for %s\n", glt->name); else Con_Printf ("TexMgr_ReloadImage: can't colormap a non SRC_INDEXED texture: %s\n", glt->name); } - if (glt->shirt > -1 && glt->pants > -1) - { - //create new translation table - for (i = 0; i < 256; i++) - translation[i] = i; - shirt = glt->shirt * 16; - if (shirt < 128) - { - for (i = 0; i < 16; i++) - translation[TOP_RANGE+i] = shirt + i; - } - else - { - for (i = 0; i < 16; i++) - translation[TOP_RANGE+i] = shirt+15-i; - } - - pants = glt->pants * 16; - if (pants < 128) - { - for (i = 0; i < 16; i++) - translation[BOTTOM_RANGE+i] = pants + i; - } - else - { - for (i = 0; i < 16; i++) - translation[BOTTOM_RANGE+i] = pants+15-i; - } - - //translate texture - size = glt->width * glt->height; - dst = translated = (byte *) Hunk_Alloc (size); - src = data; - - for (i = 0; i < size; i++) - *dst++ = translation[*src++]; - - data = translated; - } // // upload it // - switch (glt->source_format) + switch (fmt) { case SRC_INDEXED: TexMgr_LoadImage8 (glt, data); @@ -1681,7 +1705,7 @@ void TexMgr_ReloadImages (void) for (glt = active_gltextures; glt; glt = glt->next) { glGenTextures(1, &glt->texnum); - TexMgr_ReloadImage (glt, -1, -1); + TexMgr_ReloadImage (glt, plcolour_none, plcolour_none); } in_reload_images = false; @@ -1698,7 +1722,7 @@ void TexMgr_ReloadNobrightImages (void) for (glt = active_gltextures; glt; glt = glt->next) if (glt->flags & TEXPREF_NOBRIGHT) - TexMgr_ReloadImage(glt, -1, -1); + TexMgr_ReloadImage(glt, plcolour_none, plcolour_none); } /* diff --git a/Quake/gl_texmgr.h b/Quake/gl_texmgr.h index 106f26d1..fed37893 100644 --- a/Quake/gl_texmgr.h +++ b/Quake/gl_texmgr.h @@ -62,8 +62,8 @@ typedef struct gltexture_s { unsigned int source_width; //size of image in source data unsigned int source_height; //size of image in source data unsigned short source_crc; //generated by source data before modifications - signed char shirt; //0-13 shirt color, or -1 if never colormapped - signed char pants; //0-13 pants color, or -1 if never colormapped + plcolour_t shirt; + plcolour_t pants; //used for rendering int visframe; //matches r_framecount if texture was bound this frame } gltexture_t; @@ -98,7 +98,7 @@ void TexMgr_BlockSize (enum srcformat format, int *bytes, int *width, int *heigh // IMAGE LOADING gltexture_t *TexMgr_LoadImage (qmodel_t *owner, const char *name, int width, int height, enum srcformat format, byte *data, const char *source_file, src_offset_t source_offset, unsigned flags); -void TexMgr_ReloadImage (gltexture_t *glt, int shirt, int pants); +void TexMgr_ReloadImage (gltexture_t *glt, plcolour_t shirt, plcolour_t pants); void TexMgr_ReloadImages (void); void TexMgr_ReloadNobrightImages (void); diff --git a/Quake/host_cmd.c b/Quake/host_cmd.c index cd5b6489..7415e6e9 100644 --- a/Quake/host_cmd.c +++ b/Quake/host_cmd.c @@ -1671,7 +1671,7 @@ void Host_Color_f(void) if (Cmd_Argc() == 1) { - Con_Printf ("\"%s\" is \"%i %i\"\n", Cmd_Argv(0), ((int)cl_topcolor.value), ((int)cl_bottomcolor.value)); + Con_Printf ("\"%s\" is \"%s %s\"\n", Cmd_Argv(0), CL_PLColours_ToString(CL_PLColours_Parse(cl_topcolor.string)), CL_PLColours_ToString(CL_PLColours_Parse(cl_bottomcolor.string))); Con_Printf ("color <0-13> [0-13]\n"); return; } diff --git a/Quake/image.c b/Quake/image.c index 184ff37f..07deeeff 100644 --- a/Quake/image.c +++ b/Quake/image.c @@ -569,7 +569,7 @@ byte *Image_LoadImage (const char *name, int *width, int *height, enum srcformat q_snprintf (loadfilename, sizeof(loadfilename), "%s%s.lmp", "", name); COM_FOpenFile (loadfilename, &f, NULL); if (f) - return Image_LoadLMP (f, width, height); + return Image_LoadLMP (f, width, height, fmt); return NULL; } @@ -1011,13 +1011,11 @@ typedef struct Image_LoadLMP ============ */ -byte *Image_LoadLMP (FILE *f, int *width, int *height) +byte *Image_LoadLMP (FILE *f, int *width, int *height, enum srcformat *fmt) { lmpheader_t qpic; size_t pix; void *data; - byte *src; - unsigned int *dest; fread(&qpic, sizeof(qpic), 1, f); qpic.width = LittleLong (qpic.width); @@ -1031,19 +1029,13 @@ byte *Image_LoadLMP (FILE *f, int *width, int *height) return NULL; } - data = (byte *) Hunk_Alloc(pix*4); //+1 to allow reading padding byte on last line - dest = data; - src = (byte *)data + pix*(4-1); - - fread(src, 1, pix, f); - - while(pix --> 0) - *dest++ = d_8to24table[*src++]; - + data = (byte *) Hunk_Alloc(pix); //+1 to allow reading padding byte on last line + fread(data, 1, pix, f); fclose(f); *width = qpic.width; *height = qpic.height; + *fmt = SRC_INDEXED; return data; } diff --git a/Quake/image.h b/Quake/image.h index 84d9fcab..52f188c1 100644 --- a/Quake/image.h +++ b/Quake/image.h @@ -25,11 +25,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //image.h -- image reading / writing +enum srcformat; + //be sure to free the hunk after using these loading functions byte *Image_LoadTGA (FILE *f, int *width, int *height); byte *Image_LoadPCX (FILE *f, int *width, int *height); -byte *Image_LoadLMP (FILE *f, int *width, int *height); -enum srcformat; +byte *Image_LoadLMP (FILE *f, int *width, int *height, enum srcformat *fmt); byte *Image_LoadImage (const char *name, int *width, int *height, enum srcformat *fmt, qboolean *malloced); qboolean Image_WriteTGA (const char *name, byte *data, int width, int height, int bpp, qboolean upsidedown); diff --git a/Quake/menu.c b/Quake/menu.c index bc31084b..11940a7e 100644 --- a/Quake/menu.c +++ b/Quake/menu.c @@ -138,7 +138,7 @@ void M_DrawPic (int x, int y, qpic_t *pic) Draw_Pic (x, y, pic); //johnfitz -- simplified becuase centering is handled elsewhere } -void M_DrawTransPicTranslate (int x, int y, qpic_t *pic, int top, int bottom) //johnfitz -- more parameters +void M_DrawTransPicTranslate (int x, int y, qpic_t *pic, plcolour_t top, plcolour_t bottom) //johnfitz -- more parameters { Draw_TransPicTranslate (x, y, pic, top, bottom); //johnfitz -- simplified becuase centering is handled elsewhere } @@ -653,15 +653,28 @@ void M_MultiPlayer_Key (int key) //============================================================================= /* SETUP MENU */ -int setup_cursor = 4; -int setup_cursor_table[] = {40, 56, 80, 104, 140}; +static int setup_cursor = 4; +static int setup_cursor_table[] = {40, 56, 80, 104, 140}; -char setup_hostname[16]; -char setup_myname[16]; -int setup_oldtop; -int setup_oldbottom; -int setup_top; -int setup_bottom; +static char setup_hostname[16]; +static char setup_myname[16]; +static plcolour_t setup_oldtop; +static plcolour_t setup_oldbottom; +static plcolour_t setup_top; +static plcolour_t setup_bottom; + +void M_AdjustColour(plcolour_t *tr, int dir) +{ + { + tr->type = 1; + if (tr->basic+dir < 0) + tr->basic = 13; + else if (tr->basic+dir > 13) + tr->basic = 0; + else + tr->basic += dir; + } +} #define NUM_SETUP_CMDS 5 @@ -672,8 +685,8 @@ void M_Menu_Setup_f (void) m_entersound = true; Q_strcpy(setup_myname, cl_name.string); Q_strcpy(setup_hostname, hostname.string); - setup_top = setup_oldtop = ((int)cl_topcolor.value) >> 4; - setup_bottom = setup_oldbottom = ((int)cl_bottomcolor.value) & 15; + setup_top = setup_oldtop = CL_PLColours_Parse(cl_topcolor.string); + setup_bottom = setup_oldbottom = CL_PLColours_Parse(cl_bottomcolor.string); IN_UpdateGrabs(); } @@ -744,9 +757,9 @@ void M_Setup_Key (int k) return; S_LocalSound ("misc/menu3.wav"); if (setup_cursor == 2) - setup_top = setup_top - 1; + M_AdjustColour(&setup_top, -1); if (setup_cursor == 3) - setup_bottom = setup_bottom - 1; + M_AdjustColour(&setup_bottom, -1); break; case K_RIGHTARROW: if (setup_cursor < 2) @@ -754,9 +767,9 @@ void M_Setup_Key (int k) forward: S_LocalSound ("misc/menu3.wav"); if (setup_cursor == 2) - setup_top = setup_top + 1; + M_AdjustColour(&setup_top, +1); if (setup_cursor == 3) - setup_bottom = setup_bottom + 1; + M_AdjustColour(&setup_bottom, +1); break; case K_ENTER: @@ -773,8 +786,8 @@ forward: Cbuf_AddText ( va ("name \"%s\"\n", setup_myname) ); if (Q_strcmp(hostname.string, setup_hostname) != 0) Cvar_Set("hostname", setup_hostname); - if (setup_top != setup_oldtop || setup_bottom != setup_oldbottom) - Cbuf_AddText( va ("color %i %i\n", setup_top, setup_bottom) ); + if (!CL_PLColours_Equals(setup_top, setup_oldtop) || !CL_PLColours_Equals(setup_bottom, setup_oldbottom)) + Cbuf_AddText( va ("color %s %s\n", CL_PLColours_ToString(setup_top), CL_PLColours_ToString(setup_bottom)) ); m_entersound = true; M_Menu_MultiPlayer_f (); break; @@ -793,15 +806,6 @@ forward: } break; } - - if (setup_top > 13) - setup_top = 0; - if (setup_top < 0) - setup_top = 13; - if (setup_bottom > 13) - setup_bottom = 0; - if (setup_bottom < 0) - setup_bottom = 13; } diff --git a/Quake/pr_ext.c b/Quake/pr_ext.c index 61d41efb..a5d07153 100644 --- a/Quake/pr_ext.c +++ b/Quake/pr_ext.c @@ -5435,20 +5435,20 @@ void PF_cl_playerkey_internal(int player, const char *key, qboolean retfloat) q_snprintf(buf, sizeof(buf), "%g", cl.scores[player].entertime); else if (!strcmp(key, "topcolor_rgb")) { - byte *pal = (byte *)d_8to24table + 4*Sbar_ColorForMap((cl.scores[player].colors)&0xf0); //johnfitz -- use d_8to24table instead of host_basepal + byte *pal = CL_PLColours_ToRGB(&cl.scores[player].shirt); q_snprintf(buf, sizeof(buf), "%g %g %g", pal[0]/255.0, pal[1]/255.0, pal[2]/255.0); } else if (!strcmp(key, "bottomcolor_rgb")) { - byte *pal = (byte *)d_8to24table + 4*Sbar_ColorForMap((cl.scores[player].colors<<4)&0xf0); //johnfitz -- use d_8to24table instead of host_basepal + byte *pal = CL_PLColours_ToRGB(&cl.scores[player].pants); q_snprintf(buf, sizeof(buf), "%g %g %g", pal[0]/255.0, pal[1]/255.0, pal[2]/255.0); } else if (!strcmp(key, "topcolor")) - q_snprintf(buf, sizeof(buf), "%i", (cl.scores[player].colors>>4)&0xf); + ret = CL_PLColours_ToString(cl.scores[player].shirt); else if (!strcmp(key, "bottomcolor")) - q_snprintf(buf, sizeof(buf), "%i", cl.scores[player].colors&0xf); + ret = CL_PLColours_ToString(cl.scores[player].pants); else if (!strcmp(key, "team")) //quakeworld uses team infokeys to decide teams (instead of colours). but NQ never did, so that's fun. Lets allow mods to use either so that they can favour QW and let the engine hide differences . - q_snprintf(buf, sizeof(buf), "%i", (cl.scores[player].colors&0xf)+1); + q_snprintf(buf, sizeof(buf), "%i", (cl.scores[player].pants.basic)+1); else if (!strcmp(key, "userid")) ret = NULL; //unknown // else if (!strcmp(key, "vignored")) //checks to see this player's voicechat is ignored. @@ -6941,9 +6941,10 @@ static void PF_cl_getrenderentity(void) { int palidx = cl.entities[entnum].netstate.colormap; byte *pal; - if (!(cl.entities[entnum].netstate.eflags & EFLAGS_COLOURMAPPED)) - palidx = cl.scores[palidx].colors; - pal = (byte *)d_8to24table + 4*Sbar_ColorForMap(palidx&0x0f); + if ((cl.entities[entnum].netstate.eflags & EFLAGS_COLOURMAPPED) || palidx >= cl.maxclients) + pal = (byte *)d_8to24table + 4*Sbar_ColorForMap(palidx&0x0f); + else + pal = CL_PLColours_ToRGB(&cl.scores[palidx].pants); G_FLOAT(OFS_RETURN+0) = pal[0] / 255.0; G_FLOAT(OFS_RETURN+1) = pal[1] / 255.0; G_FLOAT(OFS_RETURN+2) = pal[2] / 255.0; @@ -6953,9 +6954,10 @@ static void PF_cl_getrenderentity(void) { int palidx = cl.entities[entnum].netstate.colormap; byte *pal; - if (!(cl.entities[entnum].netstate.eflags & EFLAGS_COLOURMAPPED)) - palidx = cl.scores[palidx].colors; - pal = (byte *)d_8to24table + 4*Sbar_ColorForMap(palidx&0xf0); + if ((cl.entities[entnum].netstate.eflags & EFLAGS_COLOURMAPPED) || palidx >= cl.maxclients) + pal = (byte *)d_8to24table + 4*Sbar_ColorForMap(palidx&0xf0); + else + pal = CL_PLColours_ToRGB(&cl.scores[palidx].shirt); G_FLOAT(OFS_RETURN+0) = pal[0] / 255.0; G_FLOAT(OFS_RETURN+1) = pal[1] / 255.0; G_FLOAT(OFS_RETURN+2) = pal[2] / 255.0; diff --git a/Quake/sbar.c b/Quake/sbar.c index 0a25246e..d01ac03e 100644 --- a/Quake/sbar.c +++ b/Quake/sbar.c @@ -464,11 +464,6 @@ void Sbar_DrawNum (int x, int y, int num, int digits, int color) //============================================================================= int fragsort[MAX_SCOREBOARD]; - -char scoreboardtext[MAX_SCOREBOARD][20]; -int scoreboardtop[MAX_SCOREBOARD]; -int scoreboardbottom[MAX_SCOREBOARD]; -int scoreboardcount[MAX_SCOREBOARD]; int scoreboardlines; /* @@ -510,35 +505,6 @@ int Sbar_ColorForMap (int m) return m < 128 ? m + 8 : m + 8; } -/* -=============== -Sbar_UpdateScoreboard -=============== -*/ -void Sbar_UpdateScoreboard (void) -{ - int i, k; - int top, bottom; - scoreboard_t *s; - - Sbar_SortFrags (); - -// draw the text - memset (scoreboardtext, 0, sizeof(scoreboardtext)); - - for (i = 0; i < scoreboardlines; i++) - { - k = fragsort[i]; - s = &cl.scores[k]; - sprintf (&scoreboardtext[i][1], "%3i %s", s->frags, s->name); - - top = s->colors & 0xf0; - bottom = (s->colors & 15) <<4; - scoreboardtop[i] = Sbar_ColorForMap (top); - scoreboardbottom[i] = Sbar_ColorForMap (bottom); - } -} - /* =============== Sbar_SoloScoreboard -- johnfitz -- new layout @@ -829,7 +795,7 @@ Sbar_DrawFrags -- johnfitz -- heavy revision */ void Sbar_DrawFrags (void) { - int numscores, i, x, color; + int numscores, i, x; char num[12]; scoreboard_t *s; @@ -845,14 +811,10 @@ void Sbar_DrawFrags (void) continue; // top color - color = s->colors & 0xf0; - color = Sbar_ColorForMap (color); - Draw_Fill (x + 10, 1, 28, 4, color, 1); + Draw_FillPlayer (x + 10, 1, 28, 4, s->shirt, 1); // bottom color - color = (s->colors & 15)<<4; - color = Sbar_ColorForMap (color); - Draw_Fill (x + 10, 5, 28, 3, color, 1); + Draw_FillPlayer (x + 10, 5, 28, 3, s->pants, 1); // number sprintf (num, "%3i", s->frags); @@ -885,32 +847,26 @@ void Sbar_DrawFace (void) // PGM 03/02/97 - fixed so color swatch only appears in CTF modes if (rogue && (cl.maxclients != 1) && (teamplay.value>3) && (teamplay.value<7)) { - int top, bottom; int xofs; char num[12]; scoreboard_t *s; s = &cl.scores[cl.viewentity - 1]; // draw background - top = s->colors & 0xf0; - bottom = (s->colors & 15)<<4; - top = Sbar_ColorForMap (top); - bottom = Sbar_ColorForMap (bottom); - if (cl.gametype == GAME_DEATHMATCH) xofs = 113; else xofs = ((vid.width - 320)>>1) + 113; Sbar_DrawPic (112, 0, rsb_teambord); - Draw_Fill (xofs, /*vid.height-*/24+3, 22, 9, top, 1); //johnfitz -- sbar coords are now relative - Draw_Fill (xofs, /*vid.height-*/24+12, 22, 9, bottom, 1); //johnfitz -- sbar coords are now relative + Draw_FillPlayer (xofs, /*vid.height-*/24+3, 22, 9, s->shirt, 1); //johnfitz -- sbar coords are now relative + Draw_FillPlayer (xofs, /*vid.height-*/24+12, 22, 9, s->pants, 1); //johnfitz -- sbar coords are now relative // draw number f = s->frags; sprintf (num, "%3i",f); - if (top == 8) + if (s->shirt.type == 1 && s->shirt.basic == 0) //white team. FIXME: vanilla says top, but I suspect it should be the lower colour, as that's the actual team nq sees. { if (num[0] != ' ') Sbar_DrawCharacter(113, 3, 18 + num[0] - '0'); @@ -1240,7 +1196,6 @@ void Sbar_DeathmatchOverlay (void) { qpic_t *pic; int i, k, l; - int top, bottom; int x, y, f; char num[12]; scoreboard_t *s; @@ -1266,16 +1221,11 @@ void Sbar_DeathmatchOverlay (void) continue; // draw background - top = s->colors & 0xf0; - bottom = (s->colors & 15)<<4; - top = Sbar_ColorForMap (top); - bottom = Sbar_ColorForMap (bottom); - if (S_Voip_Speaking(k)) //spike -- display an underlay for people who are speaking Draw_Fill ( x, y, 320-x*2, 8, ((k+1)==cl.viewentity)?75:73, 1); - Draw_Fill ( x, y, 40, 4, top, 1); //johnfitz -- stretched overlays - Draw_Fill ( x, y+4, 40, 4, bottom, 1); //johnfitz -- stretched overlays + Draw_FillPlayer ( x, y, 40, 4, s->shirt, 1); //johnfitz -- stretched overlays + Draw_FillPlayer ( x, y+4, 40, 4, s->pants, 1); //johnfitz -- stretched overlays // draw number f = s->frags; @@ -1332,7 +1282,7 @@ Sbar_MiniDeathmatchOverlay */ void Sbar_MiniDeathmatchOverlay (void) { - int i, k, top, bottom, x, y, f, numlines; + int i, k, x, y, f, numlines; char num[12]; float scale; //johnfitz scoreboard_t *s; @@ -1372,13 +1322,8 @@ void Sbar_MiniDeathmatchOverlay (void) continue; // colors - top = s->colors & 0xf0; - bottom = (s->colors & 15)<<4; - top = Sbar_ColorForMap (top); - bottom = Sbar_ColorForMap (bottom); - - Draw_Fill (x, y+1, 40, 4, top, 1); - Draw_Fill (x, y+5, 40, 3, bottom, 1); + Draw_FillPlayer (x, y+1, 40, 4, s->shirt, 1); + Draw_FillPlayer (x, y+5, 40, 3, s->pants, 1); // number f = s->frags;