mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-22 03:51:32 +00:00
add geometry shader support. because why not.
bind command now makes it a bit easier to edit the binding. and any alias. autoid tweaks. slightly better q1qvm/ktx support. extend the api a little. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4927 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
6515417cd6
commit
667e8dec10
26 changed files with 1408 additions and 795 deletions
|
@ -896,10 +896,11 @@ void CL_PredictMovePNum (int seat)
|
|||
|
||||
pv->nolocalplayer = !!(cls.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) || (cls.protocol != CP_QUAKEWORLD);
|
||||
|
||||
if (!cl.spectator) //just in case
|
||||
if (!cl.spectator && (pv->cam_state != CAM_FREECAM || pv->cam_spec_track != -1)) //just in case
|
||||
{
|
||||
pv->cam_state = CAM_FREECAM;
|
||||
pv->cam_spec_track = -1;
|
||||
pv->viewentity = (cls.demoplayback)?0:(pv->playernum+1);
|
||||
}
|
||||
|
||||
#ifdef Q2CLIENT
|
||||
|
|
|
@ -2279,6 +2279,7 @@ static void Image_LoadTexture_Failed(void *ctx, void *data, size_t a, size_t b)
|
|||
}
|
||||
static void Image_LoadTextureMips(void *ctx, void *data, size_t a, size_t b)
|
||||
{
|
||||
int i;
|
||||
texid_t tex = ctx;
|
||||
struct pendingtextureinfo *mips = data;
|
||||
|
||||
|
@ -2288,6 +2289,12 @@ static void Image_LoadTextureMips(void *ctx, void *data, size_t a, size_t b)
|
|||
tex->status = TEX_LOADED;
|
||||
else
|
||||
tex->status = TEX_FAILED;
|
||||
|
||||
for (i = 0; i < mips->mipcount; i++)
|
||||
if (mips->mip[i].needfree)
|
||||
BZ_Free(mips->mip[i].data);
|
||||
if (mips->extrafree)
|
||||
BZ_Free(mips->extrafree);
|
||||
BZ_Free(mips);
|
||||
|
||||
if (!strncmp(tex->ident, "gfx/", 4))
|
||||
|
|
|
@ -601,6 +601,15 @@ void Key_ConsoleInsert(char *instext)
|
|||
}
|
||||
key_linepos += len;
|
||||
}
|
||||
void Key_ConsoleReplace(char *instext)
|
||||
{
|
||||
if (!*instext)
|
||||
return;
|
||||
|
||||
key_linepos = 1;
|
||||
key_lines[edit_line][key_linepos] = 0;
|
||||
Key_ConsoleInsert(instext);
|
||||
}
|
||||
|
||||
void Key_DefaultLinkClicked(console_t *con, char *text, char *info)
|
||||
{
|
||||
|
@ -792,6 +801,12 @@ void Key_DefaultLinkClicked(console_t *con, char *text, char *info)
|
|||
Cbuf_AddText(va("\nmap %s\n", c), RESTRICT_LOCAL);
|
||||
return;
|
||||
}
|
||||
c = Info_ValueForKey(info, "type");
|
||||
if (*c)
|
||||
{
|
||||
Key_ConsoleReplace(c);
|
||||
return;
|
||||
}
|
||||
c = Info_ValueForKey(info, "cmd");
|
||||
if (*c && !strchr(c, ';') && !strchr(c, '\n'))
|
||||
{
|
||||
|
@ -1716,6 +1731,18 @@ void Key_Unbindall_f (void)
|
|||
Key_SetBinding (i, ~0, NULL, Cmd_ExecLevel);
|
||||
}
|
||||
|
||||
void Key_AliasEdit_f (void)
|
||||
{
|
||||
char *alias = Cmd_AliasExist(Cmd_Argv(1), RESTRICT_LOCAL);
|
||||
char quotedalias[2048];
|
||||
if (alias)
|
||||
{
|
||||
COM_QuotedString(alias, quotedalias, sizeof(quotedalias), false);
|
||||
Key_ConsoleReplace(va("alias %s %s", Cmd_Argv(1), quotedalias));
|
||||
}
|
||||
else
|
||||
Con_Printf("Not an alias\n");
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
|
@ -1747,7 +1774,19 @@ void Key_Bind_f (void)
|
|||
if (modifier == ~0) //modifier unspecified. default to no modifier
|
||||
modifier = 0;
|
||||
if (keybindings[b][modifier])
|
||||
Con_Printf ("\"%s\" = \"%s\"\n", Cmd_Argv(1), keybindings[b][modifier] );
|
||||
{
|
||||
char *alias = Cmd_AliasExist(keybindings[b][modifier], RESTRICT_LOCAL);
|
||||
char quotedbind[2048];
|
||||
char quotedalias[2048];
|
||||
COM_QuotedString(keybindings[b][modifier], quotedbind, sizeof(quotedbind), false);
|
||||
if (alias)
|
||||
{
|
||||
COM_QuotedString(alias, quotedalias, sizeof(quotedalias), false);
|
||||
Con_Printf ("^[\"%s\"\\type\\bind %s %s^] = ^[\"%s\"\\type\\alias %s %s^]\n", Cmd_Argv(1), Cmd_Argv(1), quotedbind, keybindings[b][modifier], keybindings[b][modifier], quotedalias);
|
||||
}
|
||||
else
|
||||
Con_Printf ("^[\"%s\"\\type\\bind %s %s^] = \"%s\"\n", Cmd_Argv(1), keybindings[b][modifier], Cmd_Argv(1), keybindings[b][modifier] );
|
||||
}
|
||||
else
|
||||
Con_Printf ("\"%s\" is not bound\n", Cmd_Argv(1) );
|
||||
return;
|
||||
|
@ -1976,6 +2015,7 @@ void Key_Init (void)
|
|||
Cmd_AddCommand ("bindlevel",Key_BindLevel_f);
|
||||
Cmd_AddCommand ("unbind",Key_Unbind_f);
|
||||
Cmd_AddCommand ("unbindall",Key_Unbindall_f);
|
||||
Cmd_AddCommand ("aliasedit",Key_AliasEdit_f);
|
||||
|
||||
Cvar_Register (&con_selectioncolour, "Console variables");
|
||||
Cvar_Register (&con_echochat, "Console variables");
|
||||
|
|
|
@ -1537,6 +1537,7 @@ static void SCR_DrawAutoID(vec3_t org, player_info_t *pl, qboolean isteam)
|
|||
float barwidth;
|
||||
qboolean haveinfo;
|
||||
unsigned int textflags;
|
||||
int h;
|
||||
|
||||
static vec4_t healthcolours[] =
|
||||
{
|
||||
|
@ -1614,6 +1615,8 @@ static void SCR_DrawAutoID(vec3_t org, player_info_t *pl, qboolean isteam)
|
|||
if (!haveinfo)
|
||||
return; //we don't trust the info that we have, so no ids.
|
||||
|
||||
h = 0;
|
||||
|
||||
//display health bar
|
||||
if (scr_autoid_health.ival)
|
||||
{
|
||||
|
@ -1627,6 +1630,7 @@ static void SCR_DrawAutoID(vec3_t org, player_info_t *pl, qboolean isteam)
|
|||
health = 100;
|
||||
}
|
||||
barwidth = 32;
|
||||
h += 8;
|
||||
y -= 8;
|
||||
R2D_ImageColours(healthcolours[r][0], healthcolours[r][1], healthcolours[r][2], healthcolours[r][3]*alpha);
|
||||
R2D_FillBlock(x - barwidth*0.5 + barwidth * health/100.0, y, barwidth * (100-health)/100.0, 8);
|
||||
|
@ -1647,6 +1651,7 @@ static void SCR_DrawAutoID(vec3_t org, player_info_t *pl, qboolean isteam)
|
|||
else r = -1;
|
||||
if (r >= 0)
|
||||
{
|
||||
h += 8;
|
||||
y -= 8;
|
||||
armour = bound(0, armour, health);
|
||||
barwidth = 32;
|
||||
|
@ -1660,10 +1665,9 @@ static void SCR_DrawAutoID(vec3_t org, player_info_t *pl, qboolean isteam)
|
|||
|
||||
if (scr_autoid_weapon.ival)
|
||||
{
|
||||
if (scr_autoid_armour.ival && scr_autoid_health.ival)
|
||||
y += 4;
|
||||
else if (!scr_autoid_armour.ival && !scr_autoid_health.ival)
|
||||
y -= 8;
|
||||
if (h < 8)
|
||||
h = 8;
|
||||
y += (h-8)/2;
|
||||
|
||||
for (r = 7; r>=0; r--)
|
||||
if (items & (1<<r))
|
||||
|
@ -1672,7 +1676,19 @@ static void SCR_DrawAutoID(vec3_t org, player_info_t *pl, qboolean isteam)
|
|||
if (r >= 0)
|
||||
{
|
||||
len = COM_ParseFunString(textflags, wbitnames[r]->string, buffer, sizeof(buffer), false) - buffer;
|
||||
Draw_ExpandedString(x + barwidth*0.5 + 4, y, buffer);
|
||||
if (textflags & CON_HALFALPHA)
|
||||
{
|
||||
for (r = 0; r < len; r++)
|
||||
if (!(buffer[r] & CON_RICHFORECOLOUR))
|
||||
buffer[r] |= CON_HALFALPHA;
|
||||
}
|
||||
if (len && (buffer[0] & CON_CHARMASK) == '{' && (buffer[len-1] & CON_CHARMASK) == '}')
|
||||
{ //these are often surrounded by {} to make them white in chat messages, and recoloured.
|
||||
buffer[len-1] = 0;
|
||||
Draw_ExpandedString(x + barwidth*0.5 + 4, y, buffer+1);
|
||||
}
|
||||
else
|
||||
Draw_ExpandedString(x + barwidth*0.5 + 4, y, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2165,6 +2165,8 @@ void Cmd_ExecuteString (char *text, int level)
|
|||
|
||||
Cmd_ExpandStringArguments (a->value, dest, sizeof(dest));
|
||||
Cbuf_InsertText (dest, execlevel, false);
|
||||
|
||||
Con_DPrintf("Execing alias %s:\n%s\n", a->name, a->value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -2806,7 +2808,7 @@ void Cmd_set_f(void)
|
|||
|
||||
if (Cmd_Argc()<3)
|
||||
{
|
||||
Con_TPrintf("set <var> <equation>\n");
|
||||
Con_TPrintf("%s %s <equation>\n", Cmd_Argv(0), *Cmd_Argv(1)?Cmd_Argv(1):"<var>");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -3962,7 +3962,7 @@ static void PR_uri_get_callback(struct dl_download *dl)
|
|||
int selfnum = dl->user_num;
|
||||
func_t func;
|
||||
|
||||
if (!prinst)
|
||||
if (!prinst || dl->user_sequence != svs.spawncount)
|
||||
return;
|
||||
|
||||
func = PR_FindFunction(prinst, "URI_Get_Callback", PR_ANY);
|
||||
|
@ -4048,6 +4048,7 @@ void QCBUILTIN PF_uri_get (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
|
|||
dl->user_ctx = w;
|
||||
dl->user_float = id;
|
||||
dl->user_num = *w->g.self;
|
||||
dl->user_sequence = svs.spawncount;
|
||||
dl->isquery = true;
|
||||
G_FLOAT(OFS_RETURN) = 1;
|
||||
}
|
||||
|
|
|
@ -483,11 +483,11 @@ void QCBUILTIN PF_setspawnparms (pubprogfuncs_t *prinst, struct globalvars_s *pr
|
|||
void QCBUILTIN PF_precache_vwep_model(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
int PF_ForceInfoKey_Internal(unsigned int entnum, const char *key, const char *value);
|
||||
int PF_checkclient_Internal (pubprogfuncs_t *prinst);
|
||||
void PF_precache_sound_Internal (pubprogfuncs_t *prinst, const char *s);
|
||||
int PF_precache_sound_Internal (pubprogfuncs_t *prinst, const char *s);
|
||||
int PF_precache_model_Internal (pubprogfuncs_t *prinst, const char *s, qboolean queryonly);
|
||||
void PF_setmodel_Internal (pubprogfuncs_t *prinst, edict_t *e, const char *m);
|
||||
char *PF_infokey_Internal (int entnum, const char *value);
|
||||
void PF_stuffcmd_Internal(int entnum, const char *str);
|
||||
void PF_stuffcmd_Internal(int entnum, const char *str, unsigned int flags);
|
||||
void PF_centerprint_Internal (int entnum, qboolean plaque, const char *s);
|
||||
void PF_WriteString_Internal (int target, const char *str);
|
||||
pbool QDECL ED_CanFree (edict_t *ed);
|
||||
|
|
|
@ -99,12 +99,29 @@ dllhandle_t *QVM_LoadDLL(const char *name, qboolean binroot, void **vmMain, sys_
|
|||
hVM = Sys_LoadLibrary(fname, funcs);
|
||||
if (!hVM && FS_NativePath(dllname_anycpu, FS_BINARYPATH, fname, sizeof(fname)))
|
||||
hVM = Sys_LoadLibrary(fname, funcs);
|
||||
|
||||
// run through the search paths
|
||||
iterator = NULL;
|
||||
while (!hVM && COM_IteratePaths(&iterator, NULL, 0, gpath, sizeof(gpath)))
|
||||
{
|
||||
if (!hVM && FS_NativePath(va("%s_%s_"ARCH_CPU_POSTFIX ARCH_DL_POSTFIX, name, gpath), FS_BINARYPATH, fname, sizeof(fname)))
|
||||
{
|
||||
Con_DPrintf("Loading native: %s\n", fname);
|
||||
hVM = Sys_LoadLibrary(fname, funcs);
|
||||
}
|
||||
|
||||
if (!hVM && FS_NativePath(va("%s_%s"ARCH_DL_POSTFIX, name, gpath), FS_BINARYPATH, fname, sizeof(fname)))
|
||||
{
|
||||
Con_DPrintf("Loading native: %s\n", fname);
|
||||
hVM = Sys_LoadLibrary(fname, funcs);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// run through the search paths
|
||||
iterator = NULL;
|
||||
while (!hVM && COM_IteratePaths(&iterator, gpath, sizeof(gpath), NULL, false))
|
||||
while (!hVM && COM_IteratePaths(&iterator, gpath, sizeof(gpath), NULL, 0))
|
||||
{
|
||||
if (!hVM)
|
||||
{
|
||||
|
|
|
@ -1893,12 +1893,14 @@ static void BE_ApplyUniforms(program_t *prog, int permu)
|
|||
ID3D11DeviceContext_VSSetShader(d3ddevctx, prog->permu[permu].handle.hlsl.vert, NULL, 0);
|
||||
ID3D11DeviceContext_HSSetShader(d3ddevctx, prog->permu[permu].handle.hlsl.hull, NULL, 0);
|
||||
ID3D11DeviceContext_DSSetShader(d3ddevctx, prog->permu[permu].handle.hlsl.domain, NULL, 0);
|
||||
ID3D11DeviceContext_GSSetShader(d3ddevctx, prog->permu[permu].handle.hlsl.geom, NULL, 0);
|
||||
ID3D11DeviceContext_PSSetShader(d3ddevctx, prog->permu[permu].handle.hlsl.frag, NULL, 0);
|
||||
ID3D11DeviceContext_IASetPrimitiveTopology(d3ddevctx, prog->permu[permu].handle.hlsl.topology);
|
||||
|
||||
ID3D11DeviceContext_VSSetConstantBuffers(d3ddevctx, 0, 3, cbuf);
|
||||
ID3D11DeviceContext_HSSetConstantBuffers(d3ddevctx, 0, 3, cbuf);
|
||||
ID3D11DeviceContext_DSSetConstantBuffers(d3ddevctx, 0, 3, cbuf);
|
||||
ID3D11DeviceContext_GSSetConstantBuffers(d3ddevctx, 0, 3, cbuf);
|
||||
ID3D11DeviceContext_PSSetConstantBuffers(d3ddevctx, 0, 3, cbuf);
|
||||
}
|
||||
|
||||
|
|
|
@ -246,14 +246,6 @@ qboolean D3D11_LoadTextureMips(image_t *tex, struct pendingtextureinfo *mips)
|
|||
D3D11_DestroyTexture(tex);
|
||||
hr = ID3D11Device_CreateTexture2D(pD3DDev11, &tdesc, (mips->mip[0].data?subresdesc:NULL), (ID3D11Texture2D**)&tex->ptr);
|
||||
|
||||
for (i = 0; i < mips->mipcount; i++)
|
||||
{
|
||||
if (mips->mip[i].needfree)
|
||||
BZ_Free(mips->mip[i].data);
|
||||
}
|
||||
if (mips->extrafree)
|
||||
BZ_Free(mips->extrafree);
|
||||
|
||||
return !FAILED(hr);
|
||||
}
|
||||
void D3D11_UploadLightmap(lightmapinfo_t *lm)
|
||||
|
|
|
@ -236,6 +236,7 @@ static qboolean D3D11Shader_CreateShaders(program_t *prog, const char *name, int
|
|||
void *vblob, size_t vsize,
|
||||
void *hblob, size_t hsize,
|
||||
void *dblob, size_t dsize,
|
||||
void *gblob, size_t gsize,
|
||||
void *fblob, size_t fsize)
|
||||
{
|
||||
qboolean success = true;
|
||||
|
@ -255,6 +256,9 @@ static qboolean D3D11Shader_CreateShaders(program_t *prog, const char *name, int
|
|||
else
|
||||
prog->permu[permu].handle.hlsl.topology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
|
||||
|
||||
if (gblob && FAILED(ID3D11Device_CreateGeometryShader(pD3DDev11, gblob, gsize, NULL, (ID3D11GeometryShader**)&prog->permu[permu].handle.hlsl.geom)))
|
||||
success = false;
|
||||
|
||||
if (FAILED(ID3D11Device_CreatePixelShader(pD3DDev11, fblob, fsize, NULL, (ID3D11PixelShader**)&prog->permu[permu].handle.hlsl.frag)))
|
||||
success = false;
|
||||
|
||||
|
@ -358,8 +362,8 @@ static qboolean D3D11Shader_CreateShaders(program_t *prog, const char *name, int
|
|||
static qboolean D3D11Shader_LoadBlob(program_t *prog, const char *name, unsigned int permu, vfsfile_t *blobfile)
|
||||
{
|
||||
qboolean success;
|
||||
char *vblob, *hblob, *dblob, *fblob;
|
||||
unsigned int vsz, hsz, dsz, fsz;
|
||||
char *vblob, *hblob, *dblob, *gblob, *fblob;
|
||||
unsigned int vsz, hsz, dsz, gsz, fsz;
|
||||
|
||||
VFS_READ(blobfile, &vsz, sizeof(vsz));
|
||||
vblob = Z_Malloc(vsz);
|
||||
|
@ -383,20 +387,30 @@ static qboolean D3D11Shader_LoadBlob(program_t *prog, const char *name, unsigned
|
|||
else
|
||||
dblob = NULL;
|
||||
|
||||
VFS_READ(blobfile, &gsz, sizeof(gsz));
|
||||
if (dsz != ~0u)
|
||||
{
|
||||
gblob = Z_Malloc(gsz);
|
||||
VFS_READ(blobfile, gblob, gsz);
|
||||
}
|
||||
else
|
||||
gblob = NULL;
|
||||
|
||||
VFS_READ(blobfile, &fsz, sizeof(fsz));
|
||||
fblob = Z_Malloc(fsz);
|
||||
VFS_READ(blobfile, fblob, fsz);
|
||||
|
||||
|
||||
success = D3D11Shader_CreateShaders(prog, name, permu, vblob, vsz, hblob, hsz, dblob, dsz, fblob, fsz);
|
||||
success = D3D11Shader_CreateShaders(prog, name, permu, vblob, vsz, hblob, hsz, dblob, dsz, gblob, gsz, fblob, fsz);
|
||||
Z_Free(vblob);
|
||||
Z_Free(hblob);
|
||||
Z_Free(dblob);
|
||||
Z_Free(gblob);
|
||||
Z_Free(fblob);
|
||||
return success;
|
||||
}
|
||||
|
||||
qboolean D3D11Shader_CreateProgram (program_t *prog, const char *name, unsigned int permu, int ver, const char **precompilerconstants, const char *vert, const char *hull, const char *domain, const char *frag, qboolean silenterrors, vfsfile_t *blobfile)
|
||||
qboolean D3D11Shader_CreateProgram (program_t *prog, const char *name, unsigned int permu, int ver, const char **precompilerconstants, const char *vert, const char *hull, const char *domain, const char *geom, const char *frag, qboolean silenterrors, vfsfile_t *blobfile)
|
||||
{
|
||||
static const char *defaultsamplers[] =
|
||||
{
|
||||
|
@ -427,8 +441,9 @@ qboolean D3D11Shader_CreateProgram (program_t *prog, const char *name, unsigned
|
|||
char *hsformat = NULL;
|
||||
char *dsformat = NULL;
|
||||
char *fsformat;
|
||||
char *gsformat = NULL;
|
||||
D3D_SHADER_MACRO defines[64];
|
||||
ID3DBlob *vcode = NULL, *hcode = NULL, *dcode = NULL, *fcode = NULL, *errors = NULL;
|
||||
ID3DBlob *vcode = NULL, *hcode = NULL, *dcode = NULL, *gcode = NULL, *fcode = NULL, *errors = NULL;
|
||||
qboolean success = false;
|
||||
ID3D11ShaderReflection *freflect;
|
||||
int i;
|
||||
|
@ -438,16 +453,19 @@ qboolean D3D11Shader_CreateProgram (program_t *prog, const char *name, unsigned
|
|||
vsformat = "vs_5_0";
|
||||
hsformat = "hs_5_0";
|
||||
dsformat = "ds_5_0";
|
||||
gsformat = "gs_5_0";
|
||||
fsformat = "ps_5_0";
|
||||
}
|
||||
else if (d3dfeaturelevel >= D3D_FEATURE_LEVEL_10_1)
|
||||
{
|
||||
vsformat = "vs_4_1";
|
||||
gsformat = "gs_4_1";
|
||||
fsformat = "ps_4_1";
|
||||
}
|
||||
else if (d3dfeaturelevel >= D3D_FEATURE_LEVEL_10_0)
|
||||
{
|
||||
vsformat = "vs_4_0";
|
||||
gsformat = "gs_4_0";
|
||||
fsformat = "ps_4_0";
|
||||
}
|
||||
else if (d3dfeaturelevel >= D3D_FEATURE_LEVEL_9_3)
|
||||
|
@ -463,6 +481,9 @@ qboolean D3D11Shader_CreateProgram (program_t *prog, const char *name, unsigned
|
|||
|
||||
prog->permu[permu].handle.hlsl.vert = NULL;
|
||||
prog->permu[permu].handle.hlsl.frag = NULL;
|
||||
prog->permu[permu].handle.hlsl.hull = NULL;
|
||||
prog->permu[permu].handle.hlsl.domain = NULL;
|
||||
prog->permu[permu].handle.hlsl.geom = NULL;
|
||||
prog->permu[permu].handle.hlsl.layout = NULL;
|
||||
|
||||
if (pD3DCompile)
|
||||
|
@ -547,6 +568,24 @@ qboolean D3D11Shader_CreateProgram (program_t *prog, const char *name, unsigned
|
|||
}
|
||||
}
|
||||
|
||||
if (geom)
|
||||
{
|
||||
if (!dsformat)
|
||||
success = false;
|
||||
else
|
||||
{
|
||||
defines[0].Name = "GEOMETRY_SHADER";
|
||||
if (FAILED(pD3DCompile(domain, strlen(domain), name, defines, &myd3dinclude, "main", gsformat, 0, 0, &gcode, &errors)))
|
||||
success = false;
|
||||
if (errors && !silenterrors)
|
||||
{
|
||||
char *messages = ID3DBlob_GetBufferPointer(errors);
|
||||
Con_Printf("geometry shader %s:\n%s", name, messages);
|
||||
ID3DBlob_Release(errors);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defines[0].Name = "FRAGMENT_SHADER";
|
||||
if (FAILED(pD3DCompile(frag, strlen(frag), name, defines, &myd3dinclude, "main", fsformat, 0, 0, &fcode, &errors)))
|
||||
success = false;
|
||||
|
@ -568,6 +607,7 @@ qboolean D3D11Shader_CreateProgram (program_t *prog, const char *name, unsigned
|
|||
ID3DBlob_GetBufferPointer(vcode), ID3DBlob_GetBufferSize(vcode),
|
||||
hcode?ID3DBlob_GetBufferPointer(hcode):NULL, hcode?ID3DBlob_GetBufferSize(hcode):0,
|
||||
dcode?ID3DBlob_GetBufferPointer(dcode):NULL, dcode?ID3DBlob_GetBufferSize(dcode):0,
|
||||
gcode?ID3DBlob_GetBufferPointer(gcode):NULL, gcode?ID3DBlob_GetBufferSize(gcode):0,
|
||||
ID3DBlob_GetBufferPointer(fcode), ID3DBlob_GetBufferSize(fcode));
|
||||
|
||||
if (success && blobfile)
|
||||
|
@ -601,6 +641,18 @@ qboolean D3D11Shader_CreateProgram (program_t *prog, const char *name, unsigned
|
|||
VFS_WRITE(blobfile, ID3DBlob_GetBufferPointer(dcode), sz);
|
||||
}
|
||||
|
||||
if (!gcode)
|
||||
{
|
||||
sz = ~0u;
|
||||
VFS_WRITE(blobfile, &sz, sizeof(sz));
|
||||
}
|
||||
else
|
||||
{
|
||||
sz = ID3DBlob_GetBufferSize(gcode);
|
||||
VFS_WRITE(blobfile, &sz, sizeof(sz));
|
||||
VFS_WRITE(blobfile, ID3DBlob_GetBufferPointer(gcode), sz);
|
||||
}
|
||||
|
||||
sz = ID3DBlob_GetBufferSize(fcode);
|
||||
VFS_WRITE(blobfile, &sz, sizeof(sz));
|
||||
VFS_WRITE(blobfile, ID3DBlob_GetBufferPointer(fcode), sz);
|
||||
|
@ -641,6 +693,8 @@ qboolean D3D11Shader_CreateProgram (program_t *prog, const char *name, unsigned
|
|||
ID3DBlob_Release(hcode);
|
||||
if (dcode)
|
||||
ID3DBlob_Release(dcode);
|
||||
if (gcode)
|
||||
ID3DBlob_Release(gcode);
|
||||
if (fcode)
|
||||
ID3DBlob_Release(fcode);
|
||||
}
|
||||
|
|
|
@ -84,6 +84,8 @@ qboolean D3D9_LoadTextureMips(image_t *tex, struct pendingtextureinfo *mips)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!pD3DDev9)
|
||||
return false; //can happen on errors
|
||||
if (FAILED(IDirect3DDevice9_CreateTexture(pD3DDev9, mips->mip[0].width, mips->mip[0].height, mips->mipcount, 0, fmt, D3DPOOL_MANAGED, &dt, NULL)))
|
||||
return false;
|
||||
|
||||
|
|
|
@ -141,12 +141,18 @@ static dllhandle_t *shaderlib;
|
|||
(This)->lpVtbl -> Release(This)
|
||||
#endif
|
||||
|
||||
static qboolean D3D9Shader_CreateProgram (program_t *prog, const char *sname, unsigned int permu, int ver, const char **precompilerconstants, const char *vert, const char *tcs, const char *tes, const char *frag, qboolean silent, vfsfile_t *blobfile)
|
||||
static qboolean D3D9Shader_CreateProgram (program_t *prog, const char *sname, unsigned int permu, int ver, const char **precompilerconstants, const char *vert, const char *tcs, const char *tes, const char *geom, const char *frag, qboolean silent, vfsfile_t *blobfile)
|
||||
{
|
||||
D3DXMACRO defines[64];
|
||||
LPD3DXBUFFER code = NULL, errors = NULL;
|
||||
qboolean success = false;
|
||||
|
||||
if (geom || tcs || tes)
|
||||
{
|
||||
Con_Printf("geometry and tessellation shaders are not availale in d3d9 (%s)\n", sname);
|
||||
return false;
|
||||
}
|
||||
|
||||
prog->permu[permu].handle.hlsl.vert = NULL;
|
||||
prog->permu[permu].handle.hlsl.frag = NULL;
|
||||
|
||||
|
|
|
@ -3508,7 +3508,7 @@ void GLBE_SelectMode(backendmode_t mode)
|
|||
if (!shaderstate.allblackshader.glsl.handle)
|
||||
{
|
||||
const char *defs[] = {NULL};
|
||||
shaderstate.allblackshader = GLSlang_CreateProgram("allblackprogram", gl_config_gles?100:110, defs, "#include \"sys/skeletal.h\"\nvoid main(){gl_Position = skeletaltransform();}", NULL, NULL, "void main(){gl_FragColor=vec4(0.0,0.0,0.0,1.0);}", false, NULL);
|
||||
shaderstate.allblackshader = GLSlang_CreateProgram("allblackprogram", gl_config_gles?100:110, defs, "#include \"sys/skeletal.h\"\nvoid main(){gl_Position = skeletaltransform();}", NULL, NULL, NULL, "void main(){gl_FragColor=vec4(0.0,0.0,0.0,1.0);}", false, NULL);
|
||||
shaderstate.allblack_mvp = qglGetUniformLocationARB(shaderstate.allblackshader.glsl.handle, "m_modelviewprojection");
|
||||
}
|
||||
/*BEM_DEPTHONLY does support mesh writing, but its not the only way its used... FIXME!*/
|
||||
|
@ -3533,7 +3533,7 @@ void GLBE_SelectMode(backendmode_t mode)
|
|||
if (gl_config_nofixedfunc && !shaderstate.allblackshader.glsl.handle)
|
||||
{
|
||||
const char *defs[] = {NULL};
|
||||
shaderstate.allblackshader = GLSlang_CreateProgram("allblackprogram", gl_config_gles?100:110, defs, "#include \"sys/skeletal.h\"\nvoid main(){gl_Position = skeletaltransform();}", NULL, NULL, "void main(){gl_FragColor=vec4(0.0,0.0,0.0,1.0);}", false, NULL);
|
||||
shaderstate.allblackshader = GLSlang_CreateProgram("allblackprogram", gl_config_gles?100:110, defs, "#include \"sys/skeletal.h\"\nvoid main(){gl_Position = skeletaltransform();}", NULL, NULL, NULL, "void main(){gl_FragColor=vec4(0.0,0.0,0.0,1.0);}", false, NULL);
|
||||
shaderstate.allblack_mvp = qglGetUniformLocationARB(shaderstate.allblackshader.glsl.handle, "m_modelviewprojection");
|
||||
}
|
||||
|
||||
|
@ -4058,7 +4058,7 @@ static void DrawMeshes(void)
|
|||
if (!shaderstate.allblackshader.glsl.handle)
|
||||
{
|
||||
const char *defs[] = {NULL};
|
||||
shaderstate.allblackshader = GLSlang_CreateProgram("allblackprogram", gl_config_gles?100:110, defs, "#include \"sys/skeletal.h\"\nvoid main(){gl_Position = skeletaltransform();}", NULL, NULL, "void main(){gl_FragColor=vec4(0.0,0.0,0.0,1.0);}", false, NULL);
|
||||
shaderstate.allblackshader = GLSlang_CreateProgram("allblackprogram", gl_config_gles?100:110, defs, "#include \"sys/skeletal.h\"\nvoid main(){gl_Position = skeletaltransform();}", NULL, NULL, NULL, "void main(){gl_FragColor=vec4(0.0,0.0,0.0,1.0);}", false, NULL);
|
||||
shaderstate.allblack_mvp = qglGetUniformLocationARB(shaderstate.allblackshader.glsl.handle, "m_modelviewprojection");
|
||||
}
|
||||
|
||||
|
|
|
@ -376,9 +376,6 @@ qboolean GL_LoadTextureMips(texid_t tex, struct pendingtextureinfo *mips)
|
|||
qglTexImage3D(targface, i, GL_RGB, size, size, size, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, mips->mip[i].data);
|
||||
break;
|
||||
}
|
||||
|
||||
if (mips->mip[i].needfree)
|
||||
Z_Free(mips->mip[i].data);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -466,13 +463,9 @@ qboolean GL_LoadTextureMips(texid_t tex, struct pendingtextureinfo *mips)
|
|||
qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data);
|
||||
break;
|
||||
}
|
||||
if (mips->mip[i].needfree)
|
||||
Z_Free(mips->mip[i].data);
|
||||
}
|
||||
}
|
||||
|
||||
if (mips->extrafree)
|
||||
Z_Free(mips->extrafree);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -983,6 +983,7 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
|
|||
unsigned int permuoffsets[PERMUTATIONS], initoffset=0;
|
||||
unsigned int blobheaderoffset=0;
|
||||
qboolean blobadded;
|
||||
qboolean geom = false;
|
||||
qboolean tess = false;
|
||||
|
||||
char *cvarnames[64];
|
||||
|
@ -1014,6 +1015,11 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
|
|||
prog->nofixedcompat = false;
|
||||
script += 7;
|
||||
}
|
||||
else if (!strncmp(script, "!!geom", 6))
|
||||
{
|
||||
geom = true;
|
||||
script += 6;
|
||||
}
|
||||
else if (!strncmp(script, "!!tess", 6))
|
||||
{
|
||||
tess = true;
|
||||
|
@ -1334,7 +1340,7 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
|
|||
initoffset = VFS_GETLEN(blobfile);
|
||||
VFS_SEEK(blobfile, initoffset);
|
||||
}
|
||||
if (!sh_config.pCreateProgram(prog, name, p, ver, permutationdefines, script, tess?script:NULL, tess?script:NULL, script, (p & PERMUTATION_SKELETAL)?true:onefailed, sh_config.pValidateProgram?NULL:blobfile))
|
||||
if (!sh_config.pCreateProgram(prog, name, p, ver, permutationdefines, script, tess?script:NULL, tess?script:NULL, geom?script:NULL, script, (p & PERMUTATION_SKELETAL)?true:onefailed, sh_config.pValidateProgram?NULL:blobfile))
|
||||
{
|
||||
if (!(p & PERMUTATION_SKELETAL))
|
||||
onefailed = true; //don't flag it if skeletal failed.
|
||||
|
|
|
@ -1005,6 +1005,11 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
|
|||
if (GL_CheckExtension("GL_ARB_seamless_cube_map"))
|
||||
qglEnable(0x884F); //TEXTURE_CUBE_MAP_SEAMLESS 0x884F
|
||||
|
||||
if (!gl_config.gles && gl_config.glversion >= 3.2)
|
||||
gl_config.geometryshaders = true;
|
||||
else
|
||||
gl_config.geometryshaders = false;
|
||||
|
||||
#ifdef GL_STATIC
|
||||
gl_config.ext_framebuffer_objects = true; //exists as core in gles2
|
||||
#else
|
||||
|
@ -1773,6 +1778,11 @@ static GLhandleARB GLSlang_CreateShader (const char *name, int ver, const char *
|
|||
strings++;
|
||||
}
|
||||
break;
|
||||
case GL_GEOMETRY_SHADER_ARB:
|
||||
prstrings[strings] = "#define GEOMETRY_SHADER\n";
|
||||
length[strings] = strlen(prstrings[strings]);
|
||||
strings++;
|
||||
break;
|
||||
case GL_TESS_CONTROL_SHADER_ARB:
|
||||
prstrings[strings] = "#define TESS_CONTROL_SHADER\n";
|
||||
length[strings] = strlen(prstrings[strings]);
|
||||
|
@ -1976,12 +1986,13 @@ static GLhandleARB GLSlang_FinishShader(GLhandleARB shader, const char *name, GL
|
|||
return shader;
|
||||
}
|
||||
|
||||
GLhandleARB GLSlang_CreateProgramObject (const char *name, GLhandleARB vert, GLhandleARB cont, GLhandleARB eval, GLhandleARB frag, qboolean silent)
|
||||
GLhandleARB GLSlang_CreateProgramObject (const char *name, GLhandleARB vert, GLhandleARB cont, GLhandleARB eval, GLhandleARB geom, GLhandleARB frag, qboolean silent)
|
||||
{
|
||||
GLhandleARB program;
|
||||
|
||||
program = qglCreateProgramObjectARB();
|
||||
if (vert) qglAttachObjectARB(program, vert);
|
||||
if (geom) qglAttachObjectARB(program, geom);
|
||||
if (cont) qglAttachObjectARB(program, cont);
|
||||
if (eval) qglAttachObjectARB(program, eval);
|
||||
if (frag) qglAttachObjectARB(program, frag);
|
||||
|
@ -2058,10 +2069,11 @@ qboolean GLSlang_ValidateProgram(union programhandle_u *h, const char *name, qbo
|
|||
return true;
|
||||
}
|
||||
|
||||
union programhandle_u GLSlang_CreateProgram(const char *name, int ver, const char **precompilerconstants, const char *vert, const char *cont, const char *eval, const char *frag, qboolean silent, vfsfile_t *blobfile)
|
||||
union programhandle_u GLSlang_CreateProgram(const char *name, int ver, const char **precompilerconstants, const char *vert, const char *cont, const char *eval, const char *geom, const char *frag, qboolean silent, vfsfile_t *blobfile)
|
||||
{
|
||||
union programhandle_u ret;
|
||||
GLhandleARB vs;
|
||||
GLhandleARB gs;
|
||||
GLhandleARB fs;
|
||||
GLhandleARB cs;
|
||||
GLhandleARB es;
|
||||
|
@ -2073,7 +2085,12 @@ union programhandle_u GLSlang_CreateProgram(const char *name, int ver, const cha
|
|||
return ret;
|
||||
if ((cont || eval) && !qglPatchParameteriARB)
|
||||
{
|
||||
Con_Printf("GLSlang_CreateProgram: %s requires tesselation support, but your gl drivers do not appear to support this\n", name);
|
||||
Con_Printf("GLSlang_CreateProgram: %s requires tesselation support, but your gl drivers do not appear to support this (gl4.0 feature)\n", name);
|
||||
return ret;
|
||||
}
|
||||
if (geom && !gl_config.geometryshaders)
|
||||
{
|
||||
Con_Printf("GLSlang_CreateProgram: %s requires geometry shader support, but your gl drivers do not appear to support this (gl3.2 feature)\n", name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -2081,11 +2098,13 @@ union programhandle_u GLSlang_CreateProgram(const char *name, int ver, const cha
|
|||
precompilerconstants = &nullconstants;
|
||||
|
||||
fs = GLSlang_CreateShader(name, ver, precompilerconstants, frag, GL_FRAGMENT_SHADER_ARB, silent);
|
||||
gs = GLSlang_CreateShader(name, ver, precompilerconstants, geom, GL_GEOMETRY_SHADER_ARB, silent);
|
||||
vs = GLSlang_CreateShader(name, ver, precompilerconstants, vert, GL_VERTEX_SHADER_ARB, silent);
|
||||
cs = GLSlang_CreateShader(name, ver, precompilerconstants, cont, GL_TESS_CONTROL_SHADER_ARB, silent);
|
||||
es = GLSlang_CreateShader(name, ver, precompilerconstants, eval, GL_TESS_EVALUATION_SHADER_ARB, silent);
|
||||
|
||||
fs = GLSlang_FinishShader(fs, name, GL_FRAGMENT_SHADER_ARB, silent);
|
||||
gs = GLSlang_FinishShader(gs, name, GL_GEOMETRY_SHADER_ARB, silent);
|
||||
vs = GLSlang_FinishShader(vs, name, GL_VERTEX_SHADER_ARB, silent);
|
||||
cs = GLSlang_FinishShader(cs, name, GL_TESS_CONTROL_SHADER_ARB, silent);
|
||||
es = GLSlang_FinishShader(es, name, GL_TESS_EVALUATION_SHADER_ARB, silent);
|
||||
|
@ -2093,9 +2112,10 @@ union programhandle_u GLSlang_CreateProgram(const char *name, int ver, const cha
|
|||
if (!vs || !fs)
|
||||
ret.glsl.handle = 0;
|
||||
else
|
||||
ret.glsl.handle = GLSlang_CreateProgramObject(name, vs, cs, es, fs, silent);
|
||||
ret.glsl.handle = GLSlang_CreateProgramObject(name, vs, cs, es, gs, fs, silent);
|
||||
//delete ignores 0s.
|
||||
if (vs) qglDeleteShaderObject_(vs);
|
||||
if (gs) qglDeleteShaderObject_(gs);
|
||||
if (fs) qglDeleteShaderObject_(fs);
|
||||
if (cs) qglDeleteShaderObject_(cs);
|
||||
if (es) qglDeleteShaderObject_(es);
|
||||
|
@ -2132,7 +2152,7 @@ qboolean GLSlang_ValidateProgramPermu(program_t *prog, const char *name, unsigne
|
|||
{
|
||||
return GLSlang_ValidateProgram(&prog->permu[permu].handle, name, noerrors, blobfile);
|
||||
}
|
||||
qboolean GLSlang_CreateProgramPermu(program_t *prog, const char *name, unsigned int permu, int ver, const char **precompilerconstants, const char *vert, const char *tcs, const char *tes, const char *frag, qboolean noerrors, vfsfile_t *blobfile)
|
||||
qboolean GLSlang_CreateProgramPermu(program_t *prog, const char *name, unsigned int permu, int ver, const char **precompilerconstants, const char *vert, const char *tcs, const char *tes, const char *geom, const char *frag, qboolean noerrors, vfsfile_t *blobfile)
|
||||
{
|
||||
#ifdef FTE_TARGET_WEB
|
||||
//emscripten's uniform code results in excessive stalls that hinder usability.
|
||||
|
@ -2150,7 +2170,7 @@ qboolean GLSlang_CreateProgramPermu(program_t *prog, const char *name, unsigned
|
|||
ver = 120;
|
||||
#endif
|
||||
}
|
||||
prog->permu[permu].handle = GLSlang_CreateProgram(name, ver, precompilerconstants, vert, tcs, tes, frag, noerrors, blobfile);
|
||||
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;
|
||||
return false;
|
||||
|
|
|
@ -235,6 +235,8 @@ typedef struct {
|
|||
|
||||
qboolean arb_texture_compression;
|
||||
|
||||
qboolean geometryshaders;
|
||||
|
||||
// qboolean arb_fragment_program;
|
||||
qboolean arb_shader_objects;
|
||||
qboolean arb_shadow;
|
||||
|
@ -1077,7 +1079,7 @@ extern void (APIENTRY *qglBindVertexArray)(GLuint vaoarray);
|
|||
|
||||
|
||||
//glslang helper api
|
||||
union programhandle_u GLSlang_CreateProgram(const char *name, int ver, const char **precompilerconstants, const char *vert, const char *cont, const char *eval, const char *frag, qboolean silent, vfsfile_t *blobfile);
|
||||
union programhandle_u GLSlang_CreateProgram(const char *name, int ver, const char **precompilerconstants, const char *vert, const char *cont, const char *eval, const char *geom, const char *frag, qboolean silent, vfsfile_t *blobfile);
|
||||
GLint GLSlang_GetUniformLocation (int prog, char *name);
|
||||
void GL_SelectProgram(int program);
|
||||
#define GLSlang_UseProgram(prog) GL_SelectProgram(prog)
|
||||
|
|
|
@ -586,6 +586,10 @@ typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei
|
|||
#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A
|
||||
#endif
|
||||
|
||||
#ifndef GL_GEOMETRY_SHADER_ARB
|
||||
#define GL_GEOMETRY_SHADER_ARB 0x8DD9
|
||||
#endif
|
||||
|
||||
#ifndef GL_PATCH_VERTICES_ARB //GL_ARB_tessellation_shader lacks _ARB postfix.
|
||||
#define GL_PATCHES_ARB 0xE
|
||||
#define GL_PATCH_VERTICES_ARB 0x8E72
|
||||
|
|
|
@ -443,6 +443,7 @@ union programhandle_u
|
|||
int topology; //D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST
|
||||
void *hull;
|
||||
void *domain;
|
||||
void *geom;
|
||||
void *layout;
|
||||
#endif
|
||||
} hlsl;
|
||||
|
@ -674,7 +675,7 @@ typedef struct
|
|||
|
||||
void (*pDeleteProg) (program_t *prog, unsigned int permu);
|
||||
qboolean (*pLoadBlob) (program_t *prog, const char *name, unsigned int permu, vfsfile_t *blobfile);
|
||||
qboolean (*pCreateProgram) (program_t *prog, const char *name, unsigned int permu, int ver, const char **precompilerconstants, const char *vert, const char *tcs, const char *tes, const char *frag, qboolean noerrors, vfsfile_t *blobfile);
|
||||
qboolean (*pCreateProgram) (program_t *prog, const char *name, unsigned int permu, int ver, const char **precompilerconstants, const char *vert, const char *tcs, const char *tes, const char *geom, const char *frag, qboolean noerrors, vfsfile_t *blobfile);
|
||||
qboolean (*pValidateProgram)(program_t *prog, const char *name, unsigned int permu, qboolean noerrors, vfsfile_t *blobfile);
|
||||
void (*pProgAutoFields) (program_t *prog, char **cvarnames, int *cvartypes);
|
||||
} sh_config_t;
|
||||
|
|
|
@ -103,6 +103,8 @@ struct dl_download
|
|||
unsigned int user_num;
|
||||
float user_float;
|
||||
void *user_ctx;
|
||||
int user_sequence;
|
||||
|
||||
qboolean isquery; //will not be displayed in the download/progress bar stuff.
|
||||
|
||||
#ifndef SERVERONLY
|
||||
|
|
|
@ -3375,7 +3375,7 @@ static void QCBUILTIN PF_checkclient (pubprogfuncs_t *prinst, struct globalvars_
|
|||
|
||||
//============================================================================
|
||||
|
||||
void PF_stuffcmd_Internal(int entnum, const char *str)
|
||||
void PF_stuffcmd_Internal(int entnum, const char *str, unsigned int flags)
|
||||
{
|
||||
client_t *cl;
|
||||
static qboolean expectingcolour;
|
||||
|
@ -3468,7 +3468,7 @@ stuffcmd (clientent, value)
|
|||
*/
|
||||
static void QCBUILTIN PF_stuffcmd (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
PF_stuffcmd_Internal(G_EDICTNUM(prinst, OFS_PARM0), PR_GetStringOfs(prinst, OFS_PARM1));
|
||||
PF_stuffcmd_Internal(G_EDICTNUM(prinst, OFS_PARM0), PR_GetStringOfs(prinst, OFS_PARM1), 0);
|
||||
}
|
||||
|
||||
//DP_QC_DROPCLIENT
|
||||
|
@ -3700,7 +3700,7 @@ void PR_CheckEmptyString (char *s)
|
|||
*/
|
||||
|
||||
//float(string effectname) particleeffectnum (EXT_CSQC)
|
||||
static void QCBUILTIN PF_sv_particleeffectnum(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
void QCBUILTIN PF_sv_particleeffectnum(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
const char *s = PR_GetStringOfs(prinst, OFS_PARM0);
|
||||
/*
|
||||
|
@ -3762,14 +3762,14 @@ static void QCBUILTIN PF_precache_file (pubprogfuncs_t *prinst, struct globalvar
|
|||
FS_FLocateFile(s, FSLFRT_IFFOUND, NULL);
|
||||
}
|
||||
|
||||
void PF_precache_sound_Internal (pubprogfuncs_t *prinst, const char *s)
|
||||
int PF_precache_sound_Internal (pubprogfuncs_t *prinst, const char *s)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (s[0] <= ' ')
|
||||
{
|
||||
PR_BIError (prinst, "PF_precache_sound: Bad string");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i=1 ; i<MAX_PRECACHE_SOUNDS ; i++)
|
||||
|
@ -3793,12 +3793,13 @@ void PF_precache_sound_Internal (pubprogfuncs_t *prinst, const char *s)
|
|||
MSG_WriteString(&sv.nqreliable_datagram, s);
|
||||
#endif
|
||||
}
|
||||
return;
|
||||
return i;
|
||||
}
|
||||
if (!strcmp(sv.strings.sound_precache[i], s))
|
||||
return;
|
||||
return i;
|
||||
}
|
||||
PR_BIError (prinst, "PF_precache_sound: overflow");
|
||||
return 0;
|
||||
}
|
||||
static void QCBUILTIN PF_precache_sound (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
|
@ -7724,7 +7725,7 @@ static void QCBUILTIN PF_CustomTEnt(pubprogfuncs_t *prinst, struct globalvars_s
|
|||
}
|
||||
|
||||
//void(float effectnum, entity ent, vector start, vector end) trailparticles (EXT_CSQC),
|
||||
static void QCBUILTIN PF_sv_trailparticles(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
void QCBUILTIN PF_sv_trailparticles(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
#ifdef PEXT_CSQC
|
||||
int efnum;
|
||||
|
@ -7768,7 +7769,7 @@ static void QCBUILTIN PF_sv_trailparticles(pubprogfuncs_t *prinst, struct global
|
|||
#endif
|
||||
}
|
||||
//void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
|
||||
static void QCBUILTIN PF_sv_pointparticles(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
void QCBUILTIN PF_sv_pointparticles(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
#ifdef PEXT_CSQC
|
||||
int efnum = G_FLOAT(OFS_PARM0);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -668,7 +668,7 @@ void SV_DropClient (client_t *drop)
|
|||
else if (ISQ3CLIENT(drop))
|
||||
{
|
||||
}
|
||||
if (drop->netchan.remote_address.type != NA_INVALID)
|
||||
if (drop->netchan.remote_address.type != NA_INVALID && drop->netchan.message.maxsize)
|
||||
{
|
||||
//send twice, to cover packetloss a little.
|
||||
Netchan_Transmit (&drop->netchan, termmsg.cursize, termmsg.data, 10000);
|
||||
|
@ -1958,7 +1958,7 @@ client_t *SV_AddSplit(client_t *controller, char *info, int id)
|
|||
|
||||
prev->controlled = cl;
|
||||
prev = cl;
|
||||
cl->controller = prev->controller?prev->controller:host_client;
|
||||
cl->controller = controller;
|
||||
cl->controlled = NULL;
|
||||
|
||||
Q_strncpyS (cl->userinfo, info, sizeof(cl->userinfo)-1);
|
||||
|
|
|
@ -4653,7 +4653,7 @@ void Cmd_Join_f (void)
|
|||
if (host_client->state != cs_spawned)
|
||||
return;
|
||||
|
||||
if (svs.gametype != GT_PROGS)
|
||||
if (svs.gametype != GT_PROGS && svs.gametype != GT_Q1QVM)
|
||||
{
|
||||
SV_TPrintToClient(host_client, PRINT_HIGH, "Sorry, not implemented in this gamecode type. Try moaning at the dev team\n");
|
||||
return;
|
||||
|
@ -4714,7 +4714,9 @@ void Cmd_Join_f (void)
|
|||
// call the prog function for removing a client
|
||||
// this will set the body to a dead frame, among other things
|
||||
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
|
||||
if (SpectatorDisconnect)
|
||||
if (svs.gametype == GT_Q1QVM)
|
||||
Q1QVM_DropClient(host_client);
|
||||
else if (SpectatorDisconnect)
|
||||
PR_ExecuteProgram (svprogfuncs, SpectatorDisconnect);
|
||||
sv.spawned_observer_slots--;
|
||||
|
||||
|
@ -4727,7 +4729,9 @@ void Cmd_Join_f (void)
|
|||
// FIXME, bump the client's userid?
|
||||
|
||||
// call the progs to get default spawn parms for the new client
|
||||
if (pr_global_ptrs->SetNewParms)
|
||||
if (svs.gametype == GT_Q1QVM)
|
||||
Q1QVM_SetNewParms();
|
||||
else if (pr_global_ptrs->SetNewParms)
|
||||
PR_ExecuteProgram (svprogfuncs, pr_global_struct->SetNewParms);
|
||||
for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
|
||||
{
|
||||
|
@ -4737,15 +4741,20 @@ void Cmd_Join_f (void)
|
|||
host_client->spawn_parms[i] = 0;
|
||||
}
|
||||
|
||||
// call the spawn function
|
||||
pr_global_struct->time = sv.world.physicstime;
|
||||
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
|
||||
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientConnect);
|
||||
if (svs.gametype == GT_Q1QVM)
|
||||
Q1QVM_ClientConnect(host_client);
|
||||
else
|
||||
{
|
||||
// call the spawn function
|
||||
pr_global_struct->time = sv.world.physicstime;
|
||||
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
|
||||
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientConnect);
|
||||
|
||||
// actually spawn the player
|
||||
pr_global_struct->time = sv.world.physicstime;
|
||||
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
|
||||
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PutClientInServer);
|
||||
// actually spawn the player
|
||||
pr_global_struct->time = sv.world.physicstime;
|
||||
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
|
||||
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PutClientInServer);
|
||||
}
|
||||
sv.spawned_client_slots++;
|
||||
|
||||
// send notification to all clients
|
||||
|
@ -4781,7 +4790,7 @@ void Cmd_Observe_f (void)
|
|||
if (host_client->state != cs_spawned)
|
||||
return;
|
||||
|
||||
if (svs.gametype != GT_PROGS)
|
||||
if (svs.gametype != GT_PROGS && svs.gametype != GT_Q1QVM)
|
||||
{
|
||||
SV_TPrintToClient(host_client, PRINT_HIGH, "Sorry, not implemented in this gamecode type. Try moaning at the dev team\n");
|
||||
return;
|
||||
|
@ -4835,8 +4844,13 @@ void Cmd_Observe_f (void)
|
|||
|
||||
// call the prog function for removing a client
|
||||
// this will set the body to a dead frame, among other things
|
||||
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
|
||||
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientDisconnect);
|
||||
if (svs.gametype == GT_Q1QVM)
|
||||
Q1QVM_DropClient(host_client);
|
||||
else
|
||||
{
|
||||
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
|
||||
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientDisconnect);
|
||||
}
|
||||
sv.spawned_client_slots--;
|
||||
|
||||
SV_SetUpClientEdict (host_client, host_client->edict);
|
||||
|
@ -4848,7 +4862,9 @@ void Cmd_Observe_f (void)
|
|||
// FIXME, bump the client's userid?
|
||||
|
||||
// call the progs to get default spawn parms for the new client
|
||||
if (pr_global_ptrs->SetNewParms)
|
||||
if (svs.gametype == GT_Q1QVM)
|
||||
Q1QVM_SetNewParms();
|
||||
else if (pr_global_ptrs->SetNewParms)
|
||||
PR_ExecuteProgram (svprogfuncs, pr_global_struct->SetNewParms);
|
||||
for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
|
||||
{
|
||||
|
@ -4861,17 +4877,22 @@ void Cmd_Observe_f (void)
|
|||
SV_SpawnSpectator ();
|
||||
|
||||
// call the spawn function
|
||||
if (SpectatorConnect)
|
||||
{
|
||||
pr_global_struct->time = sv.world.physicstime;
|
||||
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
|
||||
PR_ExecuteProgram (svprogfuncs, SpectatorConnect);
|
||||
}
|
||||
if (svs.gametype == GT_Q1QVM)
|
||||
Q1QVM_ClientConnect(host_client);
|
||||
else
|
||||
{
|
||||
sv_player->v->movetype = MOVETYPE_NOCLIP;
|
||||
sv_player->v->model = 0;
|
||||
sv_player->v->modelindex = 0;
|
||||
if (SpectatorConnect)
|
||||
{
|
||||
pr_global_struct->time = sv.world.physicstime;
|
||||
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
|
||||
PR_ExecuteProgram (svprogfuncs, SpectatorConnect);
|
||||
}
|
||||
else
|
||||
{
|
||||
sv_player->v->movetype = MOVETYPE_NOCLIP;
|
||||
sv_player->v->model = 0;
|
||||
sv_player->v->modelindex = 0;
|
||||
}
|
||||
}
|
||||
sv.spawned_observer_slots++;
|
||||
|
||||
|
|
|
@ -252,6 +252,42 @@ char *TP_ParseFunChars(char *str, qbool chat)
|
|||
*out++ = (dehex(str[2]) << 4) | dehex(str[3]);
|
||||
str+=4;
|
||||
}
|
||||
else if (str[0] == '$')
|
||||
{
|
||||
int c = 0;
|
||||
switch (str[1])
|
||||
{
|
||||
case '\\': c = 0x0D; break;
|
||||
case ':': c = 0x0A; break;
|
||||
case '[': c = 0x10; break;
|
||||
case ']': c = 0x11; break;
|
||||
case 'G': c = 0x86; break;
|
||||
case 'R': c = 0x87; break;
|
||||
case 'Y': c = 0x88; break;
|
||||
case 'B': c = 0x89; break;
|
||||
case '(': c = 0x80; break;
|
||||
case '=': c = 0x81; break;
|
||||
case ')': c = 0x82; break;
|
||||
case 'a': c = 0x83; break;
|
||||
case '<': c = 0x1d; break;
|
||||
case '-': c = 0x1e; break;
|
||||
case '>': c = 0x1f; break;
|
||||
case ',': c = 0x1c; break;
|
||||
case '.': c = 0x9c; break;
|
||||
case 'b': c = 0x8b; break;
|
||||
case 'c':
|
||||
case 'd': c = 0x8d; break;
|
||||
case '$': c = '$'; break;
|
||||
case '^': c = '^'; break;
|
||||
case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': c = str[1] -'0' + 0x12;break;
|
||||
}
|
||||
if (c)
|
||||
{
|
||||
*out++ = c;
|
||||
str++;
|
||||
}
|
||||
str++;
|
||||
}
|
||||
else if (*str)
|
||||
*out++ = *str++;
|
||||
else
|
||||
|
|
Loading…
Reference in a new issue