attempt to fix autoid revealing spies in TF.
fix issues with converted qizmo demos that appear to contain connectionless packets. clarify some spam a little. made demos menu re-open in the same path as before, with the same demo selected. still no mouse. attempt to cope with gles2's potential lower attribute limit. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4939 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
b247f3e076
commit
89a33f317a
12 changed files with 186 additions and 99 deletions
|
@ -862,6 +862,7 @@ readit:
|
|||
|
||||
olddemotime = demotime;
|
||||
|
||||
net_from.type = NA_INVALID;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -2263,11 +2263,15 @@ void CL_Packet_f (void)
|
|||
|
||||
if (Cmd_FromGamecode()) //some mvd servers stuffcmd a packet command which lets them know which ip the client is from.
|
||||
{ //unfortunatly, 50% of servers are badly configured.
|
||||
if (cls.demoplayback)
|
||||
{
|
||||
Con_DPrintf ("Not sending realip packet from demo\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (adr.type == NA_IP)
|
||||
if (adr.address.ip[0] == 127)
|
||||
if (adr.address.ip[1] == 0)
|
||||
if (adr.address.ip[2] == 0)
|
||||
if (adr.address.ip[3] == 1)
|
||||
if ((adr.address.ip[0] == 127 && adr.address.ip[1] == 0 && adr.address.ip[2] == 0 && adr.address.ip[3] == 1) ||
|
||||
(adr.address.ip[0] == 0 && adr.address.ip[1] == 0 && adr.address.ip[2] == 0 && adr.address.ip[3] == 0))
|
||||
{
|
||||
adr.address.ip[0] = cls.netchan.remote_address.address.ip[0];
|
||||
adr.address.ip[1] = cls.netchan.remote_address.address.ip[1];
|
||||
|
@ -2613,32 +2617,36 @@ void CL_ConnectionlessPacket (void)
|
|||
Con_TPrintf ("redirect to %s\n", data);
|
||||
NET_StringToAdr(data, PORT_QWSERVER, &adr);
|
||||
data = "\xff\xff\xff\xffgetchallenge\n";
|
||||
connectinfo.istransfer = true;
|
||||
connectinfo.adr = adr;
|
||||
NET_SendPacket (NS_CLIENT, strlen(data), data, &adr);
|
||||
|
||||
if (NET_CompareAdr(&connectinfo.adr, &net_from))
|
||||
{
|
||||
connectinfo.istransfer = true;
|
||||
connectinfo.adr = adr;
|
||||
NET_SendPacket (NS_CLIENT, strlen(data), data, &adr);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (!strcmp(s, "reject"))
|
||||
{ //generic rejection. stop trying.
|
||||
char *data = MSG_ReadStringLine();
|
||||
Con_Printf ("reject\n%s\n", data);
|
||||
connectinfo.trying = false;
|
||||
if (NET_CompareAdr(&connectinfo.adr, &net_from))
|
||||
connectinfo.trying = false;
|
||||
return;
|
||||
}
|
||||
else if (!strcmp(s, "badname"))
|
||||
{ //rejected purely because of player name
|
||||
Con_Printf ("f%s\n", s);
|
||||
connectinfo.trying = false;
|
||||
return;
|
||||
if (NET_CompareAdr(&connectinfo.adr, &net_from))
|
||||
connectinfo.trying = false;
|
||||
}
|
||||
else if (!strcmp(s, "badaccount"))
|
||||
{ //rejected because username or password is wrong
|
||||
Con_Printf ("f%s\n", s);
|
||||
connectinfo.trying = false;
|
||||
return;
|
||||
if (NET_CompareAdr(&connectinfo.adr, &net_from))
|
||||
connectinfo.trying = false;
|
||||
}
|
||||
else
|
||||
Con_Printf ("f%s", s);
|
||||
|
||||
Con_Printf ("f%s\n", s);
|
||||
return;
|
||||
}
|
||||
|
||||
if (c == S2C_CHALLENGE)
|
||||
|
@ -2916,6 +2924,8 @@ void CL_ConnectionlessPacket (void)
|
|||
#ifdef Q2CLIENT
|
||||
client_connect: //fixme: make function
|
||||
#endif
|
||||
if (net_from.type == NA_INVALID)
|
||||
return; //I've found a qizmo demo that contains one of these. its best left ignored.
|
||||
|
||||
if (!NET_CompareAdr(&connectinfo.adr, &net_from))
|
||||
{
|
||||
|
@ -2980,7 +2990,7 @@ client_connect: //fixme: make function
|
|||
{
|
||||
char cmdtext[2048];
|
||||
|
||||
if (net_from.type != net_local_cl_ipadr.type || net_from.type != NA_IP
|
||||
if (net_from.type == NA_INVALID || net_from.type != net_local_cl_ipadr.type || net_from.type != NA_IP
|
||||
|| ((*(unsigned *)net_from.address.ip != *(unsigned *)net_local_cl_ipadr.address.ip) && (*(unsigned *)net_from.address.ip != htonl(INADDR_LOOPBACK))))
|
||||
{
|
||||
Con_TPrintf ("Command packet from remote host. Ignored.\n");
|
||||
|
@ -3047,7 +3057,7 @@ client_connect: //fixme: make function
|
|||
}
|
||||
|
||||
//happens in demos
|
||||
if (c == svc_disconnect && cls.demoplayback != DPB_NONE)
|
||||
if (c == svc_disconnect && cls.demoplayback != DPB_NONE && net_from.type == NA_INVALID)
|
||||
{
|
||||
Host_EndGame ("End of Demo");
|
||||
return;
|
||||
|
|
|
@ -383,9 +383,9 @@ void CL_PredictUsercmd (int pnum, int entnum, player_state_t *from, player_state
|
|||
VectorCopy (from->velocity, pmove.velocity);
|
||||
VectorCopy (from->gravitydir, pmove.gravitydir);
|
||||
|
||||
if (!(pmove.velocity[0] == 0) && !(pmove.velocity[0] != 0))
|
||||
if (IS_NAN(pmove.velocity[0]))
|
||||
{
|
||||
Con_Printf("nan velocity!\n");
|
||||
Con_DPrintf("nan velocity!\n");
|
||||
pmove.velocity[0] = 0;
|
||||
pmove.velocity[1] = 0;
|
||||
pmove.velocity[2] = 0;
|
||||
|
|
|
@ -445,14 +445,19 @@ typedef struct demoitem_s {
|
|||
char name[1];
|
||||
} demoitem_t;
|
||||
|
||||
typedef struct {
|
||||
int fsroot; //FS_SYSTEM, FS_GAME, FS_GAMEONLY. if FS_SYSTEM, executed command will have a leading #
|
||||
char path[MAX_OSPATH];
|
||||
char selname[MAX_OSPATH];
|
||||
} demoloc_t;
|
||||
|
||||
typedef struct {
|
||||
menucustom_t *list;
|
||||
demoitem_t *selected;
|
||||
demoitem_t *firstitem;
|
||||
|
||||
demoloc_t *fs;
|
||||
int pathlen;
|
||||
char path[MAX_OSPATH];
|
||||
int fsroot; //FS_SYSTEM, FS_GAME, FS_GAMEONLY. if FS_SYSTEM, executed command will have a leading #
|
||||
|
||||
char *command[64]; //these let the menu be used for nearly any sort of file browser.
|
||||
char *ext[64];
|
||||
|
@ -524,34 +529,34 @@ static qboolean M_DemoKey(menucustom_t *control, menu_t *menu, int key, unsigned
|
|||
case K_UPARROW:
|
||||
if (info->selected && info->selected->prev)
|
||||
info->selected = info->selected->prev;
|
||||
return true;
|
||||
break;
|
||||
case K_MWHEELDOWN:
|
||||
case K_DOWNARROW:
|
||||
if (info->selected && info->selected->next)
|
||||
info->selected = info->selected->next;
|
||||
return true;
|
||||
break;
|
||||
case K_HOME:
|
||||
info->selected = info->items;
|
||||
return true;
|
||||
break;
|
||||
case K_END:
|
||||
info->selected = info->items;
|
||||
while(info->selected->next)
|
||||
info->selected = info->selected->next;
|
||||
return true;
|
||||
break;
|
||||
case K_PGUP:
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
if (info->selected && info->selected->prev)
|
||||
info->selected = info->selected->prev;
|
||||
}
|
||||
return true;
|
||||
break;
|
||||
case K_PGDN:
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
if (info->selected && info->selected->next)
|
||||
info->selected = info->selected->next;
|
||||
}
|
||||
return true;
|
||||
break;
|
||||
case K_ENTER:
|
||||
case K_KP_ENTER:
|
||||
if (info->selected)
|
||||
|
@ -568,13 +573,20 @@ static qboolean M_DemoKey(menucustom_t *control, menu_t *menu, int key, unsigned
|
|||
if (extnum == info->numext) //wasn't on our list of extensions.
|
||||
extnum = 0;
|
||||
|
||||
Cbuf_AddText(va("%s \"%s%s\"\n", info->command[extnum], (info->fsroot==FS_SYSTEM)?"#":"", info->selected->name), RESTRICT_LOCAL);
|
||||
M_RemoveMenu(menu);
|
||||
Cbuf_AddText(va("%s \"%s%s\"\n", info->command[extnum], (info->fs->fsroot==FS_SYSTEM)?"#":"", info->selected->name), RESTRICT_LOCAL);
|
||||
M_RemoveMenu(menu);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
if (info->selected)
|
||||
Q_strncpyz(info->fs->selname, info->selected->name, sizeof(info->fs->selname));
|
||||
else
|
||||
Q_strncpyz(info->fs->selname, "", sizeof(info->fs->selname));
|
||||
return true;
|
||||
}
|
||||
|
||||
static int QDECL DemoAddItem(const char *filename, qofs_t size, time_t modified, void *parm, searchpathfuncs_t *spath)
|
||||
|
@ -730,23 +742,27 @@ static void ShowDemoMenu (menu_t *menu, const char *path)
|
|||
char *s;
|
||||
char match[256];
|
||||
|
||||
if (*path == '/')
|
||||
path++;
|
||||
Q_strncpyz(info->path, path, sizeof(info->path));
|
||||
if (info->fsroot == FS_GAME)
|
||||
if (path != info->fs->path)
|
||||
{
|
||||
if (*path == '/')
|
||||
path++;
|
||||
Q_strncpyz(info->fs->path, path, sizeof(info->fs->path));
|
||||
}
|
||||
|
||||
if (info->fs->fsroot == FS_GAME)
|
||||
{
|
||||
if (!strcmp(path, "../"))
|
||||
{
|
||||
FS_NativePath("", FS_ROOT, info->path, sizeof(info->path));
|
||||
info->fsroot = FS_SYSTEM;
|
||||
while((s = strchr(info->path, '\\')))
|
||||
FS_NativePath("", FS_ROOT, info->fs->path, sizeof(info->fs->path));
|
||||
info->fs->fsroot = FS_SYSTEM;
|
||||
while((s = strchr(info->fs->path, '\\')))
|
||||
*s = '/';
|
||||
}
|
||||
}
|
||||
while (!strcmp(info->path+strlen(info->path)-3, "../"))
|
||||
while (!strcmp(info->fs->path+strlen(info->fs->path)-3, "../"))
|
||||
{
|
||||
c = 0;
|
||||
for (s = info->path+strlen(info->path)-3; s >= info->path; s--)
|
||||
for (s = info->fs->path+strlen(info->fs->path)-3; s >= info->fs->path; s--)
|
||||
{
|
||||
if (*s == '/')
|
||||
{
|
||||
|
@ -757,71 +773,85 @@ static void ShowDemoMenu (menu_t *menu, const char *path)
|
|||
}
|
||||
}
|
||||
if (c<2)
|
||||
*info->path = '\0';
|
||||
*info->fs->path = '\0';
|
||||
}
|
||||
info->selected = NULL;
|
||||
info->pathlen = strlen(info->path);
|
||||
info->pathlen = strlen(info->fs->path);
|
||||
|
||||
M_Demo_Flush(menu->data);
|
||||
if (info->fsroot == FS_SYSTEM)
|
||||
if (info->fs->fsroot == FS_SYSTEM)
|
||||
{
|
||||
s = strchr(info->path, '/');
|
||||
s = strchr(info->fs->path, '/');
|
||||
if (s && strchr(s+1, '/'))
|
||||
{
|
||||
Q_snprintfz(match, sizeof(match), "%s../", info->path);
|
||||
Q_snprintfz(match, sizeof(match), "%s../", info->fs->path);
|
||||
DemoAddItem(match, 0, 0, info, NULL);
|
||||
}
|
||||
}
|
||||
else if (*info->path)
|
||||
else if (*info->fs->path)
|
||||
{
|
||||
Q_snprintfz(match, sizeof(match), "%s../", info->path);
|
||||
Q_snprintfz(match, sizeof(match), "%s../", info->fs->path);
|
||||
DemoAddItem(match, 0, 0, info, NULL);
|
||||
}
|
||||
else if (info->fsroot == FS_GAME)
|
||||
else if (info->fs->fsroot == FS_GAME)
|
||||
{
|
||||
Q_snprintfz(match, sizeof(match), "../");
|
||||
DemoAddItem(match, 0, 0, info, NULL);
|
||||
}
|
||||
if (info->fsroot == FS_SYSTEM)
|
||||
if (info->fs->fsroot == FS_SYSTEM)
|
||||
{
|
||||
if (info->path)
|
||||
Q_snprintfz(match, sizeof(match), "%s*", info->path);
|
||||
if (info->fs->path)
|
||||
Q_snprintfz(match, sizeof(match), "%s*", info->fs->path);
|
||||
else
|
||||
Q_snprintfz(match, sizeof(match), "/*");
|
||||
Sys_EnumerateFiles("", match, DemoAddItem, info, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_snprintfz(match, sizeof(match), "%s*", info->path);
|
||||
Q_snprintfz(match, sizeof(match), "%s*", info->fs->path);
|
||||
COM_EnumerateFiles(match, DemoAddItem, info);
|
||||
}
|
||||
M_Demo_Flatten(info);
|
||||
}
|
||||
void M_Demo_Reselect(demomenu_t *info, const char *name)
|
||||
{
|
||||
demoitem_t *item;
|
||||
for(item = info->items; item; item = item->next)
|
||||
{
|
||||
if (!strcmp(item->name, name))
|
||||
{
|
||||
info->selected = item;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void M_Menu_Demos_f (void)
|
||||
{
|
||||
demomenu_t *info;
|
||||
menu_t *menu;
|
||||
menu_t *menu;
|
||||
static demoloc_t mediareenterloc = {FS_GAME};
|
||||
|
||||
Key_Dest_Add(kdm_menu);
|
||||
Key_Dest_Remove(kdm_console);
|
||||
m_state = m_complex;
|
||||
|
||||
menu = M_CreateMenu(sizeof(demomenu_t));
|
||||
menu->remove = M_Demo_Remove;
|
||||
info = menu->data;
|
||||
|
||||
info->fsroot = FS_GAME;
|
||||
info->fs = &mediareenterloc;
|
||||
|
||||
info->numext = 0;
|
||||
info->command[info->numext] = "playdemo";
|
||||
info->command[info->numext] = "closemenu;playdemo";
|
||||
info->ext[info->numext++] = ".qwd";
|
||||
info->command[info->numext] = "playdemo";
|
||||
info->command[info->numext] = "closemenu;playdemo";
|
||||
info->ext[info->numext++] = ".dem";
|
||||
info->command[info->numext] = "playdemo";
|
||||
info->command[info->numext] = "closemenu;playdemo";
|
||||
info->ext[info->numext++] = ".dm2";
|
||||
info->command[info->numext] = "playdemo";
|
||||
info->command[info->numext] = "closemenu;playdemo";
|
||||
info->ext[info->numext++] = ".mvd";
|
||||
info->command[info->numext] = "playdemo";
|
||||
info->command[info->numext] = "closemenu;playdemo";
|
||||
info->ext[info->numext++] = ".mvd.gz";
|
||||
//there are also qizmo demos (.qwz) out there...
|
||||
//we don't support them, but if we were to ask quizmo to decode them for us, we could do.
|
||||
|
@ -845,13 +875,15 @@ void M_Menu_Demos_f (void)
|
|||
|
||||
menu->selecteditem = (menuoption_t*)info->list;
|
||||
|
||||
ShowDemoMenu(menu, "");
|
||||
ShowDemoMenu(menu, info->fs->path);
|
||||
M_Demo_Reselect(info, info->fs->selname);
|
||||
}
|
||||
|
||||
void M_Menu_MediaFiles_f (void)
|
||||
{
|
||||
demomenu_t *info;
|
||||
menu_t *menu;
|
||||
menu_t *menu;
|
||||
static demoloc_t mediareenterloc = {FS_GAME};
|
||||
|
||||
Key_Dest_Add(kdm_menu);
|
||||
m_state = m_complex;
|
||||
|
@ -860,7 +892,7 @@ void M_Menu_MediaFiles_f (void)
|
|||
menu->remove = M_Demo_Remove;
|
||||
info = menu->data;
|
||||
|
||||
info->fsroot = FS_GAME;
|
||||
info->fs = &mediareenterloc;
|
||||
|
||||
info->ext[0] = ".m3u";
|
||||
info->command[0] = "mediaplaylist";
|
||||
|
@ -889,6 +921,7 @@ void M_Menu_MediaFiles_f (void)
|
|||
|
||||
menu->selecteditem = (menuoption_t*)info->list;
|
||||
|
||||
ShowDemoMenu(menu, "");
|
||||
ShowDemoMenu(menu, info->fs->path);
|
||||
M_Demo_Reselect(info, info->fs->selname);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -80,23 +80,25 @@ typedef unsigned int skinid_t; //skin 0 is 'unused'
|
|||
struct dlight_s;
|
||||
typedef struct entity_s
|
||||
{
|
||||
//FIXME: instancing somehow. separate visentity+visinstance. only viable with full glsl though.
|
||||
//will need to generate a vbo somehow for the instances.
|
||||
|
||||
int keynum; // for matching entities in different frames
|
||||
vec3_t origin;
|
||||
vec3_t angles;
|
||||
vec3_t angles; // fixme: should be redundant.
|
||||
vec3_t axis[3];
|
||||
|
||||
vec4_t shaderRGBAf; /*colormod+alpha, available for shaders to mix*/
|
||||
float shaderTime; /*timestamp, for syncing shader times to spawns*/
|
||||
vec3_t glowmod; /*meant to be a multiplier for the fullbrights*/
|
||||
|
||||
int light_known; /*bsp lighting has been caled*/
|
||||
int light_known; /*bsp lighting has been calced*/
|
||||
vec3_t light_avg; /*midpoint level*/
|
||||
vec3_t light_range; /*avg + this = max, avg - this = min*/
|
||||
vec3_t light_dir;
|
||||
|
||||
vec3_t oldorigin;
|
||||
vec3_t oldangles;
|
||||
|
||||
vec3_t oldorigin; /*for q2/q3 beams*/
|
||||
|
||||
struct model_s *model; // NULL = no model
|
||||
int skinnum; // for Alias models
|
||||
skinid_t customskin; // quake3 style skins
|
||||
|
|
|
@ -389,6 +389,7 @@ rulesetrule_t rulesetrules_strict[] = {
|
|||
{"r_shadow_realtime_world", "0"}, /*static lighting can be used to cast shadows around corners*/
|
||||
{"ruleset_allow_in", "0"},
|
||||
{"r_projection", "0"},
|
||||
{"gl_shadeq1_name", "*"},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
|
@ -408,6 +409,7 @@ rulesetrule_t rulesetrules_nqr[] = {
|
|||
{"sbar_teamstatus", "0"},
|
||||
{"ruleset_allow_in", "0"},
|
||||
{"r_projection", "0"},
|
||||
{"gl_shadeq1_name", "*"},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
|
|
|
@ -1540,6 +1540,7 @@ static void SCR_DrawAutoID(vec3_t org, player_info_t *pl, qboolean isteam)
|
|||
qboolean haveinfo;
|
||||
unsigned int textflags;
|
||||
int h;
|
||||
char *pname;
|
||||
|
||||
static vec4_t healthcolours[] =
|
||||
{
|
||||
|
@ -1600,6 +1601,7 @@ static void SCR_DrawAutoID(vec3_t org, player_info_t *pl, qboolean isteam)
|
|||
health = pl->statsf[STAT_HEALTH];
|
||||
armour = pl->statsf[STAT_ARMOR];
|
||||
items = pl->stats[STAT_ITEMS];
|
||||
pname = pl->name;
|
||||
haveinfo = true;
|
||||
}
|
||||
else
|
||||
|
@ -1607,12 +1609,16 @@ static void SCR_DrawAutoID(vec3_t org, player_info_t *pl, qboolean isteam)
|
|||
health = pl->tinfo.health;
|
||||
armour = pl->tinfo.armour;
|
||||
items = pl->tinfo.items;
|
||||
pname = ((*pl->tinfo.nick)?pl->tinfo.nick:(cl.teamfortress?"-":pl->name));
|
||||
haveinfo = pl->tinfo.time > cl.time;
|
||||
}
|
||||
|
||||
y -= 8;
|
||||
len = COM_ParseFunString(textflags, pl->name, buffer, sizeof(buffer), false) - buffer;
|
||||
Draw_ExpandedString(x - len*4, y, buffer);
|
||||
if (strcmp(pname, "-")) //a tinfo nick of - hides names. this can be used for TF to hide names for spies.
|
||||
{
|
||||
y -= 8;
|
||||
len = COM_ParseFunString(textflags, pname, buffer, sizeof(buffer), false) - buffer;
|
||||
Draw_ExpandedString(x - len*4, y, buffer);
|
||||
}
|
||||
|
||||
if (!haveinfo)
|
||||
return; //we don't trust the info that we have, so no ids.
|
||||
|
@ -1705,6 +1711,7 @@ void R_DrawNameTags(void)
|
|||
lerpents_t *le;
|
||||
qboolean isteam;
|
||||
char *ourteam;
|
||||
int ourcolour;
|
||||
|
||||
extern cvar_t r_showfields, r_projection;
|
||||
|
||||
|
@ -1791,9 +1798,15 @@ void R_DrawNameTags(void)
|
|||
return;
|
||||
|
||||
if (r_refdef.playerview->cam_state != CAM_FREECAM && r_refdef.playerview->cam_spec_track >= 0)
|
||||
{
|
||||
ourteam = cl.players[r_refdef.playerview->cam_spec_track].team;
|
||||
ourcolour = cl.players[r_refdef.playerview->cam_spec_track].rbottomcolor;
|
||||
}
|
||||
else
|
||||
{
|
||||
ourteam = cl.players[r_refdef.playerview->playernum].team;
|
||||
ourcolour = cl.players[r_refdef.playerview->playernum].rbottomcolor;
|
||||
}
|
||||
|
||||
for (i = 0; i < cl.allocated_client_slots; i++)
|
||||
{
|
||||
|
@ -1826,14 +1839,16 @@ void R_DrawNameTags(void)
|
|||
if (i == Cam_TrackNum(r_refdef.playerview)) //no tag for the player that you're tracking, either.
|
||||
continue;
|
||||
|
||||
if (!cl.teamplay || !scr_autoid_team.ival || strcmp(cl.players[i].team, ourteam))
|
||||
{
|
||||
if (!cl.teamplay || !scr_autoid_team.ival)
|
||||
isteam = false;
|
||||
else if (cl.teamfortress && !cl.spectator) //teamfortress should go by their colours instead, because spies. primarily this is to allow enemy spies to appear through walls as well as your own team (note that the qc will also need tinfo stuff for tf, to avoid issues with just checking player names).
|
||||
isteam = cl.players[i].rbottomcolor == ourcolour;
|
||||
else
|
||||
isteam = !strcmp(cl.players[i].team, ourteam);
|
||||
|
||||
if (!isteam)
|
||||
if (!cl.spectator && !cls.demoplayback || !scr_autoid.ival)
|
||||
continue; //only show our team when playing, too cheaty otherwise.
|
||||
isteam = false;
|
||||
}
|
||||
else
|
||||
isteam = true;
|
||||
|
||||
SCR_DrawAutoID(nametagorg[i], &cl.players[i], isteam);
|
||||
}
|
||||
|
|
|
@ -313,10 +313,10 @@ qboolean NET_CompareAdr (netadr_t *a, netadr_t *b)
|
|||
}
|
||||
#endif
|
||||
|
||||
Sys_Error("NET_CompareAdr: Bad address type");
|
||||
Con_Printf("NET_CompareAdr: Bad address type\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===================
|
||||
NET_CompareBaseAdr
|
||||
|
|
|
@ -932,6 +932,9 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
|
|||
|
||||
Con_DPrintf("GLSL available\n");
|
||||
}
|
||||
|
||||
if (gl_config.arb_shader_objects)
|
||||
qglGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &gl_config.maxattribs);
|
||||
#endif
|
||||
|
||||
qglGetProgramBinary = NULL;
|
||||
|
@ -1999,25 +2002,35 @@ GLhandleARB GLSlang_CreateProgramObject (const char *name, GLhandleARB vert, GLh
|
|||
|
||||
qglBindAttribLocationARB(program, VATTR_VERTEX1, "v_position1");
|
||||
qglBindAttribLocationARB(program, VATTR_COLOUR, "v_colour");
|
||||
#if MAXRLIGHTMAPS > 1
|
||||
qglBindAttribLocationARB(program, VATTR_COLOUR2, "v_colour2");
|
||||
qglBindAttribLocationARB(program, VATTR_COLOUR3, "v_colour3");
|
||||
qglBindAttribLocationARB(program, VATTR_COLOUR4, "v_colour4");
|
||||
#endif
|
||||
qglBindAttribLocationARB(program, VATTR_TEXCOORD, "v_texcoord");
|
||||
qglBindAttribLocationARB(program, VATTR_LMCOORD, "v_lmcoord");
|
||||
#if MAXRLIGHTMAPS > 1
|
||||
qglBindAttribLocationARB(program, VATTR_LMCOORD2, "v_lmcoord2");
|
||||
qglBindAttribLocationARB(program, VATTR_LMCOORD3, "v_lmcoord3");
|
||||
qglBindAttribLocationARB(program, VATTR_LMCOORD4, "v_lmcoord4");
|
||||
#endif
|
||||
qglBindAttribLocationARB(program, VATTR_NORMALS, "v_normal");
|
||||
qglBindAttribLocationARB(program, VATTR_SNORMALS, "v_svector");
|
||||
qglBindAttribLocationARB(program, VATTR_TNORMALS, "v_tvector");
|
||||
qglBindAttribLocationARB(program, VATTR_BONENUMS, "v_bone");
|
||||
qglBindAttribLocationARB(program, VATTR_BONEWEIGHTS, "v_weight");
|
||||
qglBindAttribLocationARB(program, VATTR_VERTEX2, "v_position2");
|
||||
|
||||
//the following MAY not be valid in gles2.
|
||||
if (gl_config.maxattribs > VATTR_BONENUMS)
|
||||
qglBindAttribLocationARB(program, VATTR_BONENUMS, "v_bone");
|
||||
if (gl_config.maxattribs > VATTR_BONEWEIGHTS)
|
||||
qglBindAttribLocationARB(program, VATTR_BONEWEIGHTS, "v_weight");
|
||||
#if MAXRLIGHTMAPS > 1
|
||||
if (gl_config.maxattribs > VATTR_COLOUR2)
|
||||
qglBindAttribLocationARB(program, VATTR_COLOUR2, "v_colour2");
|
||||
if (gl_config.maxattribs > VATTR_COLOUR3)
|
||||
qglBindAttribLocationARB(program, VATTR_COLOUR3, "v_colour3");
|
||||
if (gl_config.maxattribs > VATTR_COLOUR4)
|
||||
qglBindAttribLocationARB(program, VATTR_COLOUR4, "v_colour4");
|
||||
#endif
|
||||
#if MAXRLIGHTMAPS > 1
|
||||
if (gl_config.maxattribs > VATTR_LMCOORD2)
|
||||
qglBindAttribLocationARB(program, VATTR_LMCOORD2, "v_lmcoord2");
|
||||
if (gl_config.maxattribs > VATTR_LMCOORD3)
|
||||
qglBindAttribLocationARB(program, VATTR_LMCOORD3, "v_lmcoord3");
|
||||
if (gl_config.maxattribs > VATTR_LMCOORD4)
|
||||
qglBindAttribLocationARB(program, VATTR_LMCOORD4, "v_lmcoord4");
|
||||
#endif
|
||||
|
||||
qglLinkProgramARB(program);
|
||||
return program;
|
||||
}
|
||||
|
@ -2170,6 +2183,13 @@ qboolean GLSlang_CreateProgramPermu(program_t *prog, const char *name, unsigned
|
|||
ver = 120;
|
||||
#endif
|
||||
}
|
||||
if ((permu & PERMUTATION_SKELETAL) && gl_config.maxattribs < 10)
|
||||
return false; //can happen in gles2
|
||||
#if MAXRLIGHTMAPS > 1
|
||||
if ((permu & PERMUTATION_LIGHTSTYLES) && gl_config.maxattribs < 16)
|
||||
return false; //can happen in gles2
|
||||
#endif
|
||||
|
||||
prog->permu[permu].handle = GLSlang_CreateProgram(name, ver, precompilerconstants, vert, tcs, tes, geom, frag, noerrors, blobfile);
|
||||
if (prog->permu[permu].handle.glsl.handle)
|
||||
return true;
|
||||
|
|
|
@ -220,6 +220,7 @@ qboolean GL_CheckExtension(char *extname);
|
|||
typedef struct {
|
||||
float glversion;
|
||||
int maxglslversion;
|
||||
int maxattribs; //max generic attributes. probably only 16 on nvidia.
|
||||
qboolean nofixedfunc;
|
||||
qboolean gles;
|
||||
qboolean webgl_ie; //workaround ie webgl bugs/omissions.
|
||||
|
|
|
@ -315,21 +315,24 @@ typedef struct
|
|||
|
||||
enum{
|
||||
PERMUTATION_GENERIC = 0,
|
||||
PERMUTATION_BUMPMAP = 1,
|
||||
PERMUTATION_FULLBRIGHT = 2,
|
||||
PERMUTATION_UPPERLOWER = 4,
|
||||
PERMUTATION_REFLECTCUBEMASK = 8,
|
||||
PERMUTATION_BUMPMAP = 1, //FIXME: make argument somehow
|
||||
PERMUTATION_FULLBRIGHT = 2, //FIXME: make argument somehow
|
||||
PERMUTATION_UPPERLOWER = 4, //FIXME: make argument somehow
|
||||
PERMUTATION_REFLECTCUBEMASK = 8, //FIXME: make argument somehow
|
||||
PERMUTATION_SKELETAL = 16,
|
||||
PERMUTATION_FOG = 32,
|
||||
PERMUTATION_FOG = 32, //FIXME: remove.
|
||||
PERMUTATION_FRAMEBLEND = 64,
|
||||
#if MAXRLIGHTMAPS > 1
|
||||
PERMUTATION_LIGHTSTYLES = 128,
|
||||
PERMUTATION_LIGHTSTYLES = 128, //FIXME: make argument
|
||||
#endif
|
||||
PERMUTATIONS = 256
|
||||
};
|
||||
|
||||
enum shaderattribs_e
|
||||
{
|
||||
//GLES2 has a limit of 8.
|
||||
//GL2 has a limit of 16.
|
||||
//vendors may provide more.
|
||||
VATTR_VERTEX1=0, //NOTE: read the comment about VATTR_LEG_VERTEX
|
||||
VATTR_VERTEX2=1,
|
||||
VATTR_COLOUR=2,
|
||||
|
|
|
@ -9768,7 +9768,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"con_printf", PF_Fixme, 0, 0, 0, 392, D("void(string conname, string messagefmt, ...)", "Prints onto a named console.")},
|
||||
{"con_draw", PF_Fixme, 0, 0, 0, 393, D("void(string conname, vector pos, vector size, float fontsize)", "Draws the named console.")},
|
||||
{"con_input", PF_Fixme, 0, 0, 0, 394, D("float(string conname, float inevtype, float parama, float paramb, float paramc)", "Forwards input events to the named console. Mouse updates should be absolute only.")},
|
||||
{"cvar_unsaved", PF_Fixme, 0, 0, 0, 0, D("float()", "Returns true if any archived cvar has an unsaved value.")},
|
||||
{"cvars_haveunsaved",PF_Fixme, 0, 0, 0, 0, D("float()", "Returns true if any archived cvar has an unsaved value.")},
|
||||
//end fte extras
|
||||
|
||||
//DP extras
|
||||
|
|
Loading…
Reference in a new issue