big commit. :(
fix crash from qwplayers with invalid modelindexes rework allow_skybox a little. now applies immediately. try to fix the appears-outside-of-map bug, again. dir *.wav now shows a little extra info on mouse-over. try loading music file extensions that we expect to be able to play via ffmpeg, not just the ones that are directly supported. rework the hidden fps_presets, show them with tab completion. fix a possible crash with r_temporalscenecache fix lightmap updates on submodels not happening properly with the scenecache. fix the serious memory leak with scenecache. add r_glsl_pbr cvar to force use of pbr pathways in our glsl. fix bug in alsa output not supporting float output properly. preliminary work to have the mixer use floating point mixing. disabled for now. try to update sys_register_file_associations on linux, still needs work though. try to work around nquake's config quirks, so config files don't get overwritten. repackage quake's conchars in order to add padding. this should avoid extra junk on the outside of glyphs. give fteqcc(commandline version) some extra package extration/creation support. our paks should be more end-user-friendly, and our spanned pk3s are awesome. write rune state to legacy saved games, so we don't ever have the missing-runes bug ever again... git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5780 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
0ceff5a31d
commit
4d25c073ec
60 changed files with 1733 additions and 839 deletions
|
@ -2018,11 +2018,11 @@ m-profile:
|
|||
_qcc-tmp: $(REQDIR)
|
||||
@$(MAKE) $(TYPE) EXE_NAME="$(EXE_NAME)$(EXEPOSTFIX)" PRECOMPHEADERS="" OUT_DIR="$(OUT_DIR)" WCFLAGS="$(CLIENT_ONLY_CFLAGS) $(WCFLAGS)" LDFLAGS="$(LDFLAGS) $(QCC_LDFLAGS)" OBJS="QCC_OBJS SOBJS"
|
||||
qcc-rel:
|
||||
@$(MAKE) _qcc-tmp TYPE=_out-rel REQDIR=reldir EXE_NAME="../fteqcc$(BITS)" OUT_DIR="$(RELEASE_DIR)/$(NCDIRPREFIX)$(QCC_DIR)" SOBJS="qcctui.o $(if $(findstring win,$(FTE_TARGET)),fteqcc.o)"
|
||||
@$(MAKE) _qcc-tmp TYPE=_out-rel REQDIR=reldir EXE_NAME="../fteqcc$(BITS)" OUT_DIR="$(RELEASE_DIR)/$(NCDIRPREFIX)$(QCC_DIR)" SOBJS="qcctui.o packager.o $(if $(findstring win,$(FTE_TARGET)),fteqcc.o)"
|
||||
qccgui-rel:
|
||||
@$(MAKE) _qcc-tmp TYPE=_out-rel REQDIR=reldir EXE_NAME="../fteqccgui$(BITS)" LTO= OUT_DIR="$(RELEASE_DIR)/$(NCDIRPREFIX)$(QCC_DIR)gui" SOBJS="qccgui.o qccguistuff.o packager.o decomp.o fteqcc.o" LDFLAGS="$(LDFLAGS) -lole32 -lcomdlg32 -lcomctl32 -lshlwapi -mwindows"
|
||||
qcc-dbg:
|
||||
@$(MAKE) _qcc-tmp TYPE=_out-dbg REQDIR=debugdir EXE_NAME="../fteqcc$(BITS)" OUT_DIR="$(DEBUG_DIR)/$(NCDIRPREFIX)$(QCC_DIR)" SOBJS="qcctui.o $(if $(findstring win,$(FTE_TARGET)),fteqcc.o)"
|
||||
@$(MAKE) _qcc-tmp TYPE=_out-dbg REQDIR=debugdir EXE_NAME="../fteqcc$(BITS)" OUT_DIR="$(DEBUG_DIR)/$(NCDIRPREFIX)$(QCC_DIR)" SOBJS="qcctui.o packager.o $(if $(findstring win,$(FTE_TARGET)),fteqcc.o)"
|
||||
qccgui-dbg:
|
||||
@$(MAKE) _qcc-tmp TYPE=_out-dbg REQDIR=debugdir EXE_NAME="../fteqccgui$(BITS)" LTO= OUT_DIR="$(DEBUG_DIR)/$(NCDIRPREFIX)$(QCC_DIR)gui" SOBJS="qccgui.o qccguistuff.o packager.o decomp.o fteqcc.o" LDFLAGS="$(LDFLAGS) -lole32 -lcomdlg32 -lcomctl32 -lshlwapi -mwindows"
|
||||
|
||||
|
|
|
@ -5199,7 +5199,7 @@ void CL_LinkPlayers (void)
|
|||
continue;
|
||||
#endif
|
||||
|
||||
if (info->spectator)
|
||||
if (info->spectator || state->modelindex >= countof(cl.model_precache))
|
||||
continue;
|
||||
|
||||
//the extra modelindex check is to stop lame mods from using vweps with rings
|
||||
|
|
|
@ -2280,7 +2280,8 @@ void CL_CheckServerInfo(void)
|
|||
qboolean spectating = true;
|
||||
int i;
|
||||
qboolean oldwatervis = cls.allow_watervis;
|
||||
|
||||
int oldskyboxes = cls.allow_unmaskedskyboxes;
|
||||
|
||||
//spectator 2 = spectator-with-scores, considered to be players. this means we don't want to allow spec cheats while they're inactive, because that would be weird.
|
||||
for (i = 0; i < cl.splitclients; i++)
|
||||
if (cl.playerview[i].spectator != 1)
|
||||
|
@ -2291,7 +2292,7 @@ void CL_CheckServerInfo(void)
|
|||
|
||||
cls.allow_cheats = false;
|
||||
cls.allow_semicheats=true;
|
||||
cls.allow_skyboxes=false;
|
||||
cls.allow_unmaskedskyboxes=false;
|
||||
cls.allow_fbskins = 1;
|
||||
// cls.allow_fbskins = 0;
|
||||
// cls.allow_overbrightlight;
|
||||
|
@ -2306,8 +2307,12 @@ void CL_CheckServerInfo(void)
|
|||
else
|
||||
cls.allow_watervis=false;
|
||||
|
||||
if (spectating || cls.demoplayback || atoi(InfoBuf_ValueForKey(&cl.serverinfo, "allow_skybox")) || atoi(InfoBuf_ValueForKey(&cl.serverinfo, "allow_skyboxes")))
|
||||
cls.allow_skyboxes=true; //mostly obsolete.
|
||||
s = InfoBuf_ValueForKey(&cl.serverinfo, "allow_skybox");
|
||||
if (!*s)
|
||||
s = InfoBuf_ValueForKey(&cl.serverinfo, "allow_skyboxes");
|
||||
if (!*s)
|
||||
cls.allow_unmaskedskyboxes = (cl.worldmodel && cl.worldmodel->fromgame != fg_quake);
|
||||
else cls.allow_unmaskedskyboxes = !!atoi(s);
|
||||
|
||||
s = InfoBuf_ValueForKey(&cl.serverinfo, "fbskins");
|
||||
if (*s)
|
||||
|
@ -2409,7 +2414,7 @@ void CL_CheckServerInfo(void)
|
|||
// if (allowed & 2)
|
||||
// cls.allow_rearview = true;
|
||||
if (allowed & 4)
|
||||
cls.allow_skyboxes = true;
|
||||
cls.allow_unmaskedskyboxes = true;
|
||||
// if (allowed & 8)
|
||||
// cls.allow_mirrors = true;
|
||||
//16
|
||||
|
@ -2480,7 +2485,7 @@ void CL_CheckServerInfo(void)
|
|||
|
||||
if (oldteamplay != cl.teamplay)
|
||||
Skin_FlushPlayers();
|
||||
if (oldwatervis != cls.allow_watervis)
|
||||
if (oldwatervis != cls.allow_watervis || oldskyboxes != cls.allow_unmaskedskyboxes)
|
||||
Shader_NeedReload(false);
|
||||
|
||||
CSQC_ServerInfoChanged();
|
||||
|
@ -5885,45 +5890,66 @@ qboolean Host_RunFile(const char *fname, int nlen, vfsfile_t *file)
|
|||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (nlen >= 5 && !strncmp(fname, "qw://", 5))
|
||||
{ //this is also implemented by ezquake, so be careful here...
|
||||
//"qw://[stream@]host[:port]/COMMAND" join, spectate, qtvplay
|
||||
char *t, *cmd;
|
||||
const char *url;
|
||||
char buffer[8192];
|
||||
t = Z_Malloc(nlen+1);
|
||||
memcpy(t, fname, nlen);
|
||||
t[nlen] = 0;
|
||||
url = t+5;
|
||||
{ //this is also implemented by ezquake, so be careful here...
|
||||
//"qw://[stream@]host[:port]/COMMAND" join, spectate, qtvplay
|
||||
char *t, *cmd;
|
||||
const char *url;
|
||||
char buffer[8192];
|
||||
t = Z_Malloc(nlen+1);
|
||||
memcpy(t, fname, nlen);
|
||||
t[nlen] = 0;
|
||||
url = t+5;
|
||||
|
||||
for (cmd = t+5; *cmd; cmd++)
|
||||
{
|
||||
if (*cmd == '/')
|
||||
for (cmd = t+5; *cmd; cmd++)
|
||||
{
|
||||
*cmd++ = 0;
|
||||
break;
|
||||
if (*cmd == '/')
|
||||
{
|
||||
*cmd++ = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//quote the url safely.
|
||||
url = COM_QuotedString(url, buffer, sizeof(buffer), false);
|
||||
|
||||
//now figure out what the command actually was
|
||||
if (!Q_strcasecmp(cmd, "join"))
|
||||
Cbuf_AddText(va("join %s\n", url), RESTRICT_LOCAL);
|
||||
else if (!Q_strcasecmp(cmd, "spectate") || !strcmp(cmd, "observe"))
|
||||
Cbuf_AddText(va("observe %s\n", url), RESTRICT_LOCAL);
|
||||
else if (!Q_strcasecmp(cmd, "qtvplay"))
|
||||
Cbuf_AddText(va("qtvplay %s\n", url), RESTRICT_LOCAL);
|
||||
else if (!*cmd || !Q_strcasecmp(cmd, "connect"))
|
||||
Cbuf_AddText(va("connect %s\n", url), RESTRICT_LOCAL);
|
||||
else
|
||||
Con_Printf("Unknown url command: %s\n", cmd);
|
||||
|
||||
if(file)
|
||||
VFS_CLOSE(file);
|
||||
Z_Free(t);
|
||||
return true;
|
||||
}
|
||||
|
||||
//quote the url safely.
|
||||
url = COM_QuotedString(url, buffer, sizeof(buffer), false);
|
||||
|
||||
//now figure out what the command actually was
|
||||
if (!Q_strcasecmp(cmd, "join"))
|
||||
Cbuf_AddText(va("join %s\n", url), RESTRICT_LOCAL);
|
||||
else if (!Q_strcasecmp(cmd, "spectate") || !strcmp(cmd, "observe"))
|
||||
Cbuf_AddText(va("observe %s\n", url), RESTRICT_LOCAL);
|
||||
else if (!Q_strcasecmp(cmd, "qtvplay"))
|
||||
Cbuf_AddText(va("qtvplay %s\n", url), RESTRICT_LOCAL);
|
||||
else if (!*cmd || !Q_strcasecmp(cmd, "connect"))
|
||||
Cbuf_AddText(va("connect %s\n", url), RESTRICT_LOCAL);
|
||||
else
|
||||
Con_Printf("Unknown url command: %s\n", cmd);
|
||||
|
||||
if(file)
|
||||
VFS_CLOSE(file);
|
||||
Z_Free(t);
|
||||
return true;
|
||||
{
|
||||
const char *netschemes[] = {"udp://", "udp4//", "udp6//", "ipx://", "tcp://", "tcp4//", "tcp6//", "spx://", "ws://", "wss://", "tls://", "dtls://", "ice://", "rtc://", "ices://", "rtcs://", "irc://", "udg://", "unix://"};
|
||||
int i;
|
||||
size_t slen;
|
||||
for (i = 0; i < countof(netschemes); i++)
|
||||
{
|
||||
slen = strlen(netschemes[i]);
|
||||
if (nlen >= slen && !strncmp(fname, netschemes[i], slen))
|
||||
{
|
||||
char quoted[8192];
|
||||
char *t = Z_Malloc(nlen+1);
|
||||
memcpy(t, fname, nlen);
|
||||
t[nlen] = 0;
|
||||
Cbuf_AddText(va("connect %s\n", COM_QuotedString(t, quoted, sizeof(quoted), false)), RESTRICT_LOCAL);
|
||||
Z_Free(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
f = Z_Malloc(sizeof(*f) + nlen);
|
||||
|
|
|
@ -891,6 +891,7 @@ void CL_PredictEntityMovement(entity_state_t *estate, float age)
|
|||
VectorClear(startstate.velocity);
|
||||
startstate.onground = false;
|
||||
startstate.jump_held = false;
|
||||
startstate.flags = 0;
|
||||
CL_EntStateToPlayerState(&startstate, estate);
|
||||
CL_EntStateToPlayerCommand(&cmd, estate, age);
|
||||
|
||||
|
@ -1174,6 +1175,8 @@ void CL_PredictMovePNum (int seat)
|
|||
{
|
||||
packet_entities_t *pe;
|
||||
pe = &cl.inframes[from.frame & UPDATE_MASK].packet_entities;
|
||||
if (!pe->num_entities && !from.frame)
|
||||
pe = &cl.inframes[to.frame & UPDATE_MASK].packet_entities;
|
||||
for (i = 0; i < pe->num_entities; i++)
|
||||
{
|
||||
if (pe->entities[i].number == trackent)
|
||||
|
|
|
@ -222,7 +222,7 @@ qboolean scr_drawloading;
|
|||
float scr_disabled_time;
|
||||
|
||||
cvar_t con_stayhidden = CVARFD("con_stayhidden", "1", CVAR_NOTFROMSERVER, "0: allow console to pounce on the user\n1: console stays hidden unless explicitly invoked\n2:toggleconsole command no longer works\n3: shift+escape key no longer works");
|
||||
cvar_t show_fps = CVARFD("show_fps", "0", CVAR_ARCHIVE, "Displays the current framerate on-screen.\n0: Off.\n1: framerate average over a second.\n2: Show a frametimes graph (with additional timing info).\n-1: Normalized graph that focuses on the variation ignoring base times.");
|
||||
cvar_t show_fps = CVARAFD("show_fps"/*qw*/, "0", "scr_showfps"/*qs*/, CVAR_ARCHIVE, "Displays the current framerate on-screen.\n0: Off.\n1: framerate average over a second.\n2: Show a frametimes graph (with additional timing info).\n-1: Normalized graph that focuses on the variation ignoring base times.");
|
||||
cvar_t show_fps_x = CVAR("show_fps_x", "-1");
|
||||
cvar_t show_fps_y = CVAR("show_fps_y", "-1");
|
||||
cvar_t show_clock = CVAR("cl_clock", "0");
|
||||
|
|
|
@ -527,8 +527,8 @@ typedef struct
|
|||
|
||||
float latency; // rolling average
|
||||
|
||||
char allow_unmaskedskyboxes; //skyboxes/domes do not need to be depth-masked when set. FIXME: we treat this as an optimisation hint, but some hl/q2/q3 maps require strict do-not-mask rules to look right.
|
||||
qboolean allow_anyparticles;
|
||||
qboolean allow_skyboxes; //skyboxes/domes do not need to be depth-masked when set. FIXME: we treat this as an optimisation hint, but some hl/q2/q3 maps require strict do-not-mask rules to look right.
|
||||
qboolean allow_watervis; //fixme: not checked any more
|
||||
float allow_fbskins; //fraction of allowance
|
||||
qboolean allow_cheats;
|
||||
|
|
|
@ -2770,6 +2770,8 @@ static void Con_DrawMouseOver(console_t *mouseconsole)
|
|||
char *tiptext = NULL;
|
||||
shader_t *shader = NULL;
|
||||
model_t *model = NULL;
|
||||
sfx_t *audio = NULL;
|
||||
|
||||
char *mouseover;
|
||||
if (!mouseconsole->mouseover || !mouseconsole->mouseover(mouseconsole, &tiptext, &shader))
|
||||
{
|
||||
|
@ -2856,17 +2858,25 @@ static void Con_DrawMouseOver(console_t *mouseconsole)
|
|||
if (model->loadstate != MLS_LOADED)
|
||||
model = NULL;
|
||||
}
|
||||
|
||||
key = Info_ValueForKey(info, "playaudio");
|
||||
if (*key)
|
||||
{
|
||||
audio = S_PrecacheSound(key);
|
||||
if (audio && audio->loadstate != SLS_LOADED)
|
||||
audio = NULL;
|
||||
}
|
||||
}
|
||||
tiptext = Info_ValueForKey(info, "tip");
|
||||
}
|
||||
Z_Free(mouseover);
|
||||
}
|
||||
}
|
||||
if ((tiptext && *tiptext) || shader || model)
|
||||
if ((tiptext && *tiptext) || shader || model || audio)
|
||||
{
|
||||
//FIXME: draw a proper background.
|
||||
//FIXME: support line breaks.
|
||||
conchar_t buffer[2048], *starts[64], *ends[countof(starts)];
|
||||
conchar_t buffer[2048], *starts[64], *ends[countof(starts)], *eot;
|
||||
int lines, i, px, py;
|
||||
float tw, th;
|
||||
float ih = 0, iw = 0;
|
||||
|
@ -2874,7 +2884,30 @@ static void Con_DrawMouseOver(console_t *mouseconsole)
|
|||
float y = mousecursor_y+8;
|
||||
|
||||
Font_BeginString(font_console, x, y, &px, &py);
|
||||
lines = Font_LineBreaks(buffer, COM_ParseFunString(CON_WHITEMASK, tiptext, buffer, sizeof(buffer), false), (256.0 * vid.pixelwidth) / vid.width, countof(starts), starts, ends);
|
||||
eot = COM_ParseFunString(CON_WHITEMASK, tiptext, buffer, sizeof(buffer), false);
|
||||
if (audio)
|
||||
{
|
||||
struct sfxcache_s cache;
|
||||
char name[MAX_OSPATH];
|
||||
float len;
|
||||
*name = 0;
|
||||
len = audio->decoder.querydata?audio->decoder.querydata(audio, &cache, name, sizeof(name)):-1;
|
||||
if (len >= 0)
|
||||
{
|
||||
eot = COM_ParseFunString(CON_WHITEMASK, va("\n\n%s\n%gkhz, %s, %ibit, %g seconds%s",
|
||||
name, cache.speed/1000.0, cache.numchannels==1?"mono":"stereo", QAF_BYTES(cache.format)*8, len, audio->loopstart>=0?" looped":""
|
||||
), eot, sizeof(buffer)-((char*)eot-(char*)buffer), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
cache = *(struct sfxcache_s *)audio->decoder.buf;
|
||||
len = (double)cache.length / cache.speed;
|
||||
eot = COM_ParseFunString(CON_WHITEMASK, va("\n\n\n%gkhz, %s, %ibit, %g seconds%s",
|
||||
cache.speed/1000.0, cache.numchannels==1?"mono":"stereo", QAF_BYTES(cache.format)*8, len, audio->loopstart>=0?" looped":""
|
||||
), eot, sizeof(buffer)-((char*)eot-(char*)buffer), false);
|
||||
}
|
||||
}
|
||||
lines = Font_LineBreaks(buffer, eot, (256.0 * vid.pixelwidth) / vid.width, countof(starts), starts, ends);
|
||||
th = (Font_CharHeight()*lines * vid.height) / vid.pixelheight;
|
||||
|
||||
if (model)
|
||||
|
|
|
@ -4812,7 +4812,7 @@ qboolean Image_WriteKTXFile(const char *filename, enum fs_relative fsroot, struc
|
|||
|
||||
Image_BlockSizeForEncoding(mips->encoding, &bb, &bw, &bh, &bd);
|
||||
|
||||
switch(mips->encoding)
|
||||
safeswitch(mips->encoding)
|
||||
{
|
||||
case PTI_ETC1_RGB8: header.glinternalformat = 0x8D64/*GL_ETC1_RGB8_OES*/; break;
|
||||
case PTI_ETC2_RGB8: header.glinternalformat = 0x9274/*GL_COMPRESSED_RGB8_ETC2*/; break;
|
||||
|
@ -4933,6 +4933,7 @@ qboolean Image_WriteKTXFile(const char *filename, enum fs_relative fsroot, struc
|
|||
case PTI_R16F: header.glinternalformat = 0x822D/*GL_R16F*/; header.glbaseinternalformat = 0x1903/*GL_RED*/; header.glformat = 0x1903/*GL_RED*/; header.gltype = 0x140B/*GL_HALF_FLOAT*/; header.gltypesize = 2; break;
|
||||
case PTI_R32F: header.glinternalformat = 0x822E/*GL_R32F*/; header.glbaseinternalformat = 0x1903/*GL_RED*/; header.glformat = 0x1903/*GL_RED*/; header.gltype = 0x1406/*GL_FLOAT*/; header.gltypesize = 4; break;
|
||||
case PTI_RGBA16F: header.glinternalformat = 0x881A/*GL_RGBA16F*/; header.glbaseinternalformat = 0x1908/*GL_RGBA*/; header.glformat = 0x1908/*GL_RGBA*/; header.gltype = 0x140B/*GL_HALF_FLOAT*/; header.gltypesize = 2; break;
|
||||
case PTI_RGB32F: header.glinternalformat = 0x8815/*GL_RGB32F*/; header.glbaseinternalformat = 0x1907/*GL_RGB*/; header.glformat = 0x1907/*GL_RGB*/; header.gltype = 0x1406/*GL_FLOAT*/; header.gltypesize = 4; break;
|
||||
case PTI_RGBA32F: header.glinternalformat = 0x8814/*GL_RGBA32F*/; header.glbaseinternalformat = 0x1908/*GL_RGBA*/; header.glformat = 0x1908/*GL_RGBA*/; header.gltype = 0x1406/*GL_FLOAT*/; header.gltypesize = 4; break;
|
||||
case PTI_A2BGR10: header.glinternalformat = 0x8059/*GL_RGB10_A2*/; header.glbaseinternalformat = 0x1908/*GL_RGBA*/; header.glformat = 0x1908/*GL_RGBA*/; header.gltype = 0x8368/*GL_UNSIGNED_INT_2_10_10_10_REV*/; header.gltypesize = 4; break;
|
||||
case PTI_E5BGR9: header.glinternalformat = 0x8C3D/*GL_RGB9_E5*/; header.glbaseinternalformat = 0x8C3D/*GL_RGB9_E5*/; header.glformat = 0x1907/*GL_RGB*/; header.gltype = 0x8C3E/*GL_UNSIGNED_INT_5_9_9_9_REV*/; header.gltypesize = 4; break;
|
||||
|
@ -4956,7 +4957,6 @@ qboolean Image_WriteKTXFile(const char *filename, enum fs_relative fsroot, struc
|
|||
case PTI_DEPTH32: header.glinternalformat = 0x81A7/*GL_DEPTH_COMPONENT32*/; header.glbaseinternalformat = 0x1902/*GL_DEPTH_COMPONENT*/; header.glformat = 0x1902/*GL_DEPTH_COMPONENT*/; header.gltype = 0x1406/*GL_FLOAT*/; header.gltypesize = 4; break;
|
||||
case PTI_DEPTH24_8: header.glinternalformat = 0x88F0/*GL_DEPTH24_STENCIL8*/; header.glbaseinternalformat = 0x84F9/*GL_DEPTH_STENCIL*/; header.glformat = 0x84F9/*GL_DEPTH_STENCIL*/; header.gltype = 0x84FA/*GL_UNSIGNED_INT_24_8*/; header.gltypesize = 4; break;
|
||||
|
||||
case PTI_RGB32F:
|
||||
#ifdef FTE_TARGET_WEB
|
||||
case PTI_WHOLEFILE:
|
||||
#endif
|
||||
|
@ -4964,8 +4964,8 @@ qboolean Image_WriteKTXFile(const char *filename, enum fs_relative fsroot, struc
|
|||
case PTI_MAX:
|
||||
return false;
|
||||
|
||||
// default:
|
||||
// return;
|
||||
safedefault:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strchr(filename, '*') || strchr(filename, ':'))
|
||||
|
@ -5142,6 +5142,7 @@ static struct pendingtextureinfo *Image_ReadKTXFile(unsigned int flags, const ch
|
|||
case 0x8040/*GL_LUMINANCE8*/: encoding = PTI_L8; break;
|
||||
case 0x8045/*GL_LUMINANCE8_ALPHA8*/: encoding = PTI_L8A8; break;
|
||||
case 0x881A/*GL_RGBA16F_ARB*/: encoding = PTI_RGBA16F; break;
|
||||
case 0x8815/*GL_RGB32F_ARB*/: encoding = PTI_RGB32F; break;
|
||||
case 0x8814/*GL_RGBA32F_ARB*/: encoding = PTI_RGBA32F; break;
|
||||
case 0x8059/*GL_RGB10_A2*/: encoding = PTI_A2BGR10; break;
|
||||
case 0x8229/*GL_R8*/: encoding = PTI_R8; break;
|
||||
|
@ -5200,6 +5201,10 @@ static struct pendingtextureinfo *Image_ReadKTXFile(unsigned int flags, const ch
|
|||
else if (header.glformat == 0x80E1/*GL_BGRA*/ && header.gltype == 0x8365/*GL_UNSIGNED_SHORT_4_4_4_4_REV*/)
|
||||
encoding = PTI_ARGB4444;
|
||||
break;
|
||||
|
||||
default:
|
||||
encoding = TF_INVALID;
|
||||
break;
|
||||
}
|
||||
if (encoding == TF_INVALID)
|
||||
{
|
||||
|
@ -6065,7 +6070,7 @@ qboolean Image_WriteDDSFile(const char *filename, enum fs_relative fsroot, struc
|
|||
#define DX9RGBA (0x40|0x1)
|
||||
#define DX9LUM 0x20000
|
||||
#define DX9LUMALPHA (0x20000|0x1)
|
||||
switch(mips->encoding)
|
||||
safeswitch(mips->encoding)
|
||||
{
|
||||
// case PTI_INVALID: h10.dxgiformat = 0x0/*DXGI_FORMAT_UNKNOWN*/; break;
|
||||
// case PTI_INVALID: h10.dxgiformat = 0x1/*DXGI_FORMAT_R32G32B32A32_TYPELESS*/; break;
|
||||
|
@ -6298,10 +6303,8 @@ qboolean Image_WriteDDSFile(const char *filename, enum fs_relative fsroot, struc
|
|||
case PTI_MAX:
|
||||
return false;
|
||||
|
||||
#ifndef _DEBUG
|
||||
// default: //don't enable in debug builds, so we get warnings for any cases being missed.
|
||||
// return false;
|
||||
#endif
|
||||
safedefault: //don't enable in debug builds, so we get warnings for any cases being missed.
|
||||
return false;
|
||||
}
|
||||
|
||||
//truncate the mip chain if they're dodgy sizes.
|
||||
|
|
|
@ -352,6 +352,20 @@ qboolean Media_CleanupTrackName(const char *track, int *out_track, char *result,
|
|||
".mp3",
|
||||
#endif
|
||||
".wav",
|
||||
#if defined(PLUGINS) //ffmpeg plugin? woo.
|
||||
#if !(defined(AVAIL_OGGOPUS) || defined(FTE_TARGET_WEB))
|
||||
".opus", //opus might be the future, but ogg is the present
|
||||
#endif
|
||||
#if !(defined(AVAIL_OGGVORBIS) || defined(FTE_TARGET_WEB))
|
||||
".ogg",
|
||||
#endif
|
||||
#if !(defined(AVAIL_MP3_ACM) || defined(FTE_TARGET_WEB))
|
||||
".mp3",
|
||||
#endif
|
||||
".flac", //supported by QS at least.
|
||||
//".s3m", //some variant of mod that noone cares about. listed because of qs.
|
||||
//".umx", //wtf? qs is weird.
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
unsigned int tracknum;
|
||||
|
|
|
@ -703,7 +703,7 @@ void M_Menu_Audio_f (void)
|
|||
MB_SLIDER("Volume", volume, 0, 1, 0.1, NULL),
|
||||
MB_COMBOCVAR("Speaker Setup", snd_speakers, speakeroptions, speakervalues, NULL),
|
||||
MB_COMBOCVAR("Frequency", snd_khz, soundqualityoptions, soundqualityvalues, NULL),
|
||||
MB_CHECKBOXCVAR("Low Quality (8-bit)", loadas8bit, 0),
|
||||
MB_CHECKBOXCVAR("Low Quality (8-bit)", snd_loadas8bit, 0),
|
||||
MB_CHECKBOXCVAR("Flip Speakers", snd_leftisright, 0),
|
||||
MB_SLIDER("Mixahead", _snd_mixahead, 0, 1, 0.05, NULL),
|
||||
MB_CHECKBOXCVAR("Disable All Sounds", nosound, 0),
|
||||
|
@ -795,7 +795,7 @@ void M_Menu_Particles_f (void)
|
|||
"highfps",
|
||||
"spikeset",
|
||||
"spikeset tsshaft",
|
||||
"spikeset high tsshaft",
|
||||
"high tsshaft",
|
||||
"minimal",
|
||||
NULL
|
||||
};
|
||||
|
@ -1052,6 +1052,116 @@ const char *presetexec[] =
|
|||
//end 'realtime'
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
const char *name;
|
||||
const char *desc;
|
||||
const char *settings;
|
||||
} builtinpresets[] =
|
||||
{
|
||||
{ "hdr",
|
||||
"Don't let colour depth stop you!",
|
||||
|
||||
"set vid_srgb 2\n"
|
||||
"set r_hdr_irisadaptation 1\n"
|
||||
},
|
||||
{ "shib",
|
||||
"Performance optimisations for large/detailed maps.",
|
||||
|
||||
"if r_dynamic >= 1\n"
|
||||
"{\n" //fake it anyway.
|
||||
"set r_shadow_realtime_dlight 1\n"
|
||||
"set r_shadow_realtime_dlight_shadows 0\n"
|
||||
"set r_dynamic 0\n"
|
||||
"}\n"
|
||||
"set r_temporalscenecache 1\n" //the main speedup.
|
||||
"set r_lightstylespeed 0\n" //FIXME: we shouldn't need this, but its too stuttery without.
|
||||
"set sv_autooffload 1\n" //Needs polish still.
|
||||
"set gl_pbolightmaps 1\n" //FIXME: this needs to be the default eventually.
|
||||
},
|
||||
{ "qw",
|
||||
"Enable QuakeWorld-isms, for better gameplay.",
|
||||
|
||||
"set sv_nqplayerphysics 0\n"
|
||||
"set sv_gameplayfix_multiplethinks 1\n"
|
||||
},
|
||||
{ "nq"
|
||||
"Disable QuakeWorld-isms, for nq mod compat.",
|
||||
|
||||
"set sv_nqplayerphysics 1\n"
|
||||
"set sv_gameplayfix_multiplethinks 0\n"
|
||||
},
|
||||
|
||||
{ "dp",
|
||||
"Reconfigures FTE to mimic DP for compat reasons.",
|
||||
|
||||
"if $server then echo Be sure to restart your server\n"
|
||||
|
||||
"fps_preset nq\n"
|
||||
//these are for smc+derived mods
|
||||
"sv_listen_dp 1\n" //awkward, but forces the server to load the effectinfo.txt in advance.
|
||||
"sv_bigcoords 1\n" //for viewmodel lep precision (would be better to use csqc)
|
||||
"r_particledesc \"effectinfo high\"\n" //blurgh.
|
||||
"dpcompat_noretouchground 1\n" //don't call touch functions on entities that already appear onground. this also changes the order that the onground flag is set relative to touch functions.
|
||||
"cl_nopred 1\n" //DP doesn't predict by default, and DP mods have a nasty habit of clearing .solid values during prethinks, which screws up prediction. so play safe.
|
||||
"r_dynamic 0\nr_shadow_realtime_dlight 1\n" //fte has separate cvars for everything. which kinda surprises people and makes stuff twice as bright as it should be.
|
||||
"r_coronas_intensity 0.25\n"
|
||||
"con_logcenterprint 0\n" //kinda annoying....
|
||||
"scr_fov_mode 4\n" //for fairer framerate comparisons
|
||||
|
||||
//general compat stuff
|
||||
"dpcompat_console 1\n" //
|
||||
"dpcompat_findradiusarealinks 1\n" //faster findradiuses (but that require things are setorigined properly)
|
||||
"dpcompat_makeshitup 2\n" //flatten shaders to a single pass, then add new specular etc passes.
|
||||
//"dpcompat_nopremulpics 1\n" //don't use premultiplied alpha (solving issues with compressed image formats)
|
||||
"dpcompat_psa_ungroup 1\n" //don't use framegroups with psk models at all.
|
||||
"dpcompat_set 1\n" //handle 3-arg sets differently
|
||||
"dpcompat_stats 1\n" //truncate float stats
|
||||
"dpcompat_strcat_limit 16383\n" //xonotic compat. maximum length of strcat strings.
|
||||
|
||||
// "sv_listen_dp 1\nsv_listen_nq 0\nsv_listen_qw 0\ncl_loopbackprotocol dpp7\ndpcompat_nopreparse 1\n"
|
||||
},
|
||||
|
||||
{ "tenebrae",
|
||||
"Reconfigures FTE to mimic Tenebrae for compat/style reasons.",
|
||||
//for the luls. combine with the tenebrae mod for maximum effect.
|
||||
"fps_preset nq\n"
|
||||
"set r_shadow_realtime_world 1\n"
|
||||
"set r_shadow_realtime_dlight 1\n"
|
||||
"set r_shadow_bumpscale_basetexture 4\n"
|
||||
"set r_shadow_shadowmapping 0\n"
|
||||
"set gl_specular 1\n"
|
||||
"set gl_specular_power 16\n"
|
||||
"set gl_specular_fallback 1\n"
|
||||
"set mod_litsprites_force 1\n"
|
||||
"set r_nolerp 1\n" //well, that matches tenebrae. for the luls, right?
|
||||
},
|
||||
|
||||
{ "timedemo",
|
||||
"Reconfigure some stuff to get through timedemos really fast. Some people might consider this cheating.",
|
||||
//some extra things to pwn timedemos.
|
||||
"fps_preset fast\n"
|
||||
"set r_renderscale 1\n"
|
||||
"set contrast 1\n"
|
||||
"set gamma 1\n"
|
||||
"set brightness 0\n"
|
||||
"set scr_autoid 0\n"
|
||||
"set scr_autoid_team 0\n"
|
||||
"set r_dynamic 0\n"
|
||||
"set sbar_teamstatus 2\n"
|
||||
"set gl_polyblend 0\n"
|
||||
#if 1
|
||||
//these are cheaty settings.
|
||||
"set gl_flashblend 0\n"
|
||||
"set cl_predict_players 0\n" //very cheaty. you won't realise its off, but noone would disable it for actual play.
|
||||
#else
|
||||
//to make things fair
|
||||
"set gl_flashblend 1\n"
|
||||
"set r_part_density 1\n"
|
||||
#endif
|
||||
},
|
||||
};
|
||||
|
||||
typedef struct fpsmenuinfo_s
|
||||
{
|
||||
menucombo_t *preset;
|
||||
|
@ -1159,125 +1269,6 @@ void FPS_Preset_f (void)
|
|||
}
|
||||
}
|
||||
|
||||
if (!stricmp("hdr", arg))
|
||||
{
|
||||
Cbuf_InsertText(
|
||||
"set vid_srgb 2\n"
|
||||
"set r_hdr_irisadaptation 1\n"
|
||||
, RESTRICT_LOCAL, false);
|
||||
return;
|
||||
}
|
||||
if (!stricmp("shib", arg))
|
||||
{
|
||||
Cbuf_InsertText(
|
||||
"if r_dynamic >= 1\n"
|
||||
"{\n" //fake it anyway.
|
||||
"set r_shadow_realtime_dlight 1\n"
|
||||
"set r_shadow_realtime_dlight_shadows 0\n"
|
||||
"set r_dynamic 0\n"
|
||||
"}\n"
|
||||
"set r_temporalscenecache 1\n" //the main speedup.
|
||||
"set r_lightstylespeed 0\n" //FIXME: we shouldn't need this, but its too stuttery without.
|
||||
"set sv_autooffload 1\n" //Needs polish still.
|
||||
"set gl_pbolightmaps 1\n" //FIXME: this needs to be the default eventually.
|
||||
, RESTRICT_LOCAL, false);
|
||||
return;
|
||||
}
|
||||
if (!stricmp("qw", arg))
|
||||
{ //enable qwisms
|
||||
Cbuf_InsertText(
|
||||
"set sv_nqplayerphysics 0\n"
|
||||
"set sv_gameplayfix_multiplethinks 1\n"
|
||||
, RESTRICT_LOCAL, false);
|
||||
return;
|
||||
}
|
||||
if (!stricmp("nq", arg))
|
||||
{ //disable qwisms, for better mod compat
|
||||
Cbuf_InsertText(
|
||||
"set sv_nqplayerphysics 1\n"
|
||||
"set sv_gameplayfix_multiplethinks 0\n"
|
||||
, RESTRICT_LOCAL, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!stricmp("dp", arg))
|
||||
{
|
||||
#ifdef HAVE_SERVER
|
||||
if (sv.state)
|
||||
Cbuf_InsertText("echo Be sure to restart your server\n", RESTRICT_LOCAL, false);
|
||||
#endif
|
||||
Cbuf_InsertText(
|
||||
"fps_preset nq\n"
|
||||
//these are for smc+derived mods
|
||||
"sv_listen_dp 1\n" //awkward, but forces the server to load the effectinfo.txt in advance.
|
||||
"sv_bigcoords 1\n" //for viewmodel lep precision (would be better to use csqc)
|
||||
"r_particledesc \"effectinfo high\"\n" //blurgh.
|
||||
"dpcompat_noretouchground 1\n" //don't call touch functions on entities that already appear onground. this also changes the order that the onground flag is set relative to touch functions.
|
||||
"cl_nopred 1\n" //DP doesn't predict by default, and DP mods have a nasty habit of clearing .solid values during prethinks, which screws up prediction. so play safe.
|
||||
"r_dynamic 0\nr_shadow_realtime_dlight 1\n" //fte has separate cvars for everything. which kinda surprises people and makes stuff twice as bright as it should be.
|
||||
"r_coronas_intensity 0.25\n"
|
||||
"con_logcenterprint 0\n" //kinda annoying....
|
||||
"scr_fov_mode 4\n" //for fairer framerate comparisons
|
||||
|
||||
//general compat stuff
|
||||
"dpcompat_console 1\n" //
|
||||
"dpcompat_findradiusarealinks 1\n" //faster findradiuses (but that require things are setorigined properly)
|
||||
"dpcompat_makeshitup 2\n" //flatten shaders to a single pass, then add new specular etc passes.
|
||||
//"dpcompat_nopremulpics 1\n" //don't use premultiplied alpha (solving issues with compressed image formats)
|
||||
"dpcompat_psa_ungroup 1\n" //don't use framegroups with psk models at all.
|
||||
"dpcompat_set 1\n" //handle 3-arg sets differently
|
||||
"dpcompat_stats 1\n" //truncate float stats
|
||||
"dpcompat_strcat_limit 16383\n" //xonotic compat. maximum length of strcat strings.
|
||||
|
||||
// "sv_listen_dp 1\nsv_listen_nq 0\nsv_listen_qw 0\ncl_loopbackprotocol dpp7\ndpcompat_nopreparse 1\n"
|
||||
, RESTRICT_LOCAL, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!stricmp("tenebrae", arg))
|
||||
{ //for the luls. combine with the tenebrae mod for maximum effect.
|
||||
Cbuf_InsertText(
|
||||
"fps_preset nq\n"
|
||||
"set r_shadow_realtime_world 1\n"
|
||||
"set r_shadow_realtime_dlight 1\n"
|
||||
"set r_shadow_bumpscale_basetexture 4\n"
|
||||
"set r_shadow_shadowmapping 0\n"
|
||||
"set gl_specular 1\n"
|
||||
"set gl_specular_power 16\n"
|
||||
"set gl_specular_fallback 1\n"
|
||||
"set mod_litsprites_force 1\n"
|
||||
"set r_nolerp 1\n" //well, that matches tenebrae. for the luls, right?
|
||||
, RESTRICT_LOCAL, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!stricmp("timedemo", arg))
|
||||
{
|
||||
//some extra things to pwn timedemos.
|
||||
Cbuf_InsertText(
|
||||
"fps_preset fast\n"
|
||||
"set r_renderscale 1\n"
|
||||
"set contrast 1\n"
|
||||
"set gamma 1\n"
|
||||
"set brightness 0\n"
|
||||
"set scr_autoid 0\n"
|
||||
"set scr_autoid_team 0\n"
|
||||
"set r_dynamic 0\n"
|
||||
"set sbar_teamstatus 2\n"
|
||||
"set gl_polyblend 0\n"
|
||||
#if 1
|
||||
//these are cheaty settings.
|
||||
"set gl_flashblend 0\n"
|
||||
"set cl_predict_players 0\n" //very cheaty. you won't realise its off, but noone would disable it for actual play.
|
||||
#else
|
||||
//to make things fair
|
||||
"set gl_flashblend 1\n"
|
||||
"set r_part_density 1\n"
|
||||
#endif
|
||||
, RESTRICT_LOCAL, false);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < PRESET_NUM; i++)
|
||||
{
|
||||
if (!stricmp(presetname[i], arg))
|
||||
|
@ -1287,10 +1278,53 @@ void FPS_Preset_f (void)
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < countof(builtinpresets); i++)
|
||||
{
|
||||
if (!stricmp(builtinpresets[i].name, arg))
|
||||
{
|
||||
if (doreload)
|
||||
Cbuf_InsertText("\nfs_restart\nvid_reload\n", RESTRICT_LOCAL, false);
|
||||
Cbuf_InsertText(builtinpresets[i].settings, RESTRICT_LOCAL, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Con_Printf("Preset %s not recognised\n", arg);
|
||||
Con_Printf("Valid presests:\n");
|
||||
for (i = 0; i < PRESET_NUM; i++)
|
||||
Con_Printf("%s\n", presetname[i]);
|
||||
for (i = 0; i < countof(builtinpresets); i++)
|
||||
Con_DPrintf("%s\n", builtinpresets[i].name);
|
||||
}
|
||||
|
||||
static int QDECL CompletePresetList (const char *name, qofs_t flags, time_t mtime, void *parm, searchpathfuncs_t *spath)
|
||||
{
|
||||
struct xcommandargcompletioncb_s *ctx = parm;
|
||||
if (!Q_strncasecmp(name, "configs/preset_", 15))
|
||||
{
|
||||
char preset[MAX_QPATH];
|
||||
COM_StripExtension(name+15, preset, sizeof(preset));
|
||||
ctx->cb(preset, NULL, NULL, ctx);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void FPS_Preset_c(int argn, const char *partial, struct xcommandargcompletioncb_s *ctx)
|
||||
{
|
||||
if (argn == 1)
|
||||
{
|
||||
int i;
|
||||
size_t partiallen = strlen(partial);
|
||||
|
||||
COM_EnumerateFiles(va("configs/preset_%s*.cfg", partial), CompletePresetList, ctx);
|
||||
|
||||
for (i = 0; i < PRESET_NUM; i++)
|
||||
if (!Q_strncasecmp(partial, presetname[i], partiallen))
|
||||
ctx->cb(presetname[i], NULL, NULL, ctx);
|
||||
|
||||
for (i = 0; i < countof(builtinpresets); i++)
|
||||
if (!Q_strncasecmp(partial, builtinpresets[i].name, partiallen))
|
||||
ctx->cb(builtinpresets[i].name, builtinpresets[i].desc, NULL, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
qboolean M_PresetApply (union menuoption_s *op, struct emenu_s *menu, int key)
|
||||
|
|
|
@ -1158,24 +1158,29 @@ void M_Menu_MediaFiles_f (void)
|
|||
// info->ext[info->numext] = ".m3u";
|
||||
// info->command[info->numext] = "mediaplaylist";
|
||||
// info->numext++;
|
||||
#if defined(AVAIL_MP3_ACM) || defined(FTE_TARGET_WEB)
|
||||
info->ext[info->numext] = ".mp3";
|
||||
info->command[info->numext] = "media_add";
|
||||
info->numext++;
|
||||
#endif
|
||||
info->ext[info->numext] = ".wav";
|
||||
info->command[info->numext] = "media_add";
|
||||
info->numext++;
|
||||
#if defined(AVAIL_OGGOPUS) || defined(FTE_TARGET_WEB)
|
||||
#if defined(AVAIL_OGGOPUS) || defined(FTE_TARGET_WEB) || defined(PLUGINS)
|
||||
info->ext[info->numext] = ".opus";
|
||||
info->command[info->numext] = "media_add";
|
||||
info->numext++;
|
||||
#endif
|
||||
#if defined(AVAIL_OGGVORBIS) || defined(FTE_TARGET_WEB)
|
||||
#if defined(AVAIL_OGGVORBIS) || defined(FTE_TARGET_WEB) || defined(PLUGINS)
|
||||
info->ext[info->numext] = ".ogg";
|
||||
info->command[info->numext] = "media_add";
|
||||
info->numext++;
|
||||
#endif
|
||||
#if defined(AVAIL_MP3_ACM) || defined(FTE_TARGET_WEB) || defined(PLUGINS)
|
||||
info->ext[info->numext] = ".mp3";
|
||||
info->command[info->numext] = "media_add";
|
||||
info->numext++;
|
||||
#endif
|
||||
#if defined(PLUGINS)
|
||||
info->ext[info->numext] = ".flac";
|
||||
info->command[info->numext] = "media_add";
|
||||
info->numext++;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MEDIA_DECODER
|
||||
|
|
|
@ -1430,6 +1430,7 @@ void M_Reinit(void)
|
|||
}
|
||||
|
||||
void FPS_Preset_f(void);
|
||||
void FPS_Preset_c(int argn, const char *partial, struct xcommandargcompletioncb_s *ctx);
|
||||
void M_MenuPop_f(void);
|
||||
|
||||
//menu.dat is loaded later... after the video and everything is up.
|
||||
|
@ -1438,7 +1439,7 @@ void M_Init (void)
|
|||
Cmd_AddCommand("menu_restart", M_Restart_f);
|
||||
Cmd_AddCommand("togglemenu", M_ToggleMenu_f);
|
||||
Cmd_AddCommand("closemenu", M_CloseMenu_f);
|
||||
Cmd_AddCommand("fps_preset", FPS_Preset_f);
|
||||
Cmd_AddCommandAD("fps_preset", FPS_Preset_f, FPS_Preset_c, "Apply a preset");
|
||||
Cmd_AddCommand("menupop", M_MenuPop_f);
|
||||
|
||||
//server browser is kinda complex, and has clipboard integration which we need to sandbox a little
|
||||
|
|
|
@ -232,9 +232,9 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#ifdef _WIN64
|
||||
#define PRIxSIZE "Ix"
|
||||
#define PRIuSIZE "Iu"
|
||||
#define PRIiSIZE "Ii"
|
||||
#define PRIxSIZE PRIx64
|
||||
#define PRIuSIZE PRIu64
|
||||
#define PRIiSIZE PRIi64
|
||||
#else
|
||||
//don't use I, for the sake of older libcs
|
||||
#define PRIxSIZE "x"
|
||||
|
|
|
@ -238,8 +238,17 @@ void R2D_Init(void)
|
|||
}
|
||||
|
||||
|
||||
glossval = min(gl_specular_fallback.value*255, 255);
|
||||
glossval *= 0x10101;
|
||||
if (strchr(gl_specular_fallback.string, ' '))
|
||||
{
|
||||
glossval = bound(0, (int)(gl_specular_fallback.vec4[0]*255), 255)<<0;
|
||||
glossval |= bound(0, (int)(gl_specular_fallback.vec4[1]*255), 255)<<8;
|
||||
glossval |= bound(0, (int)(gl_specular_fallback.vec4[2]*255), 255)<<16;
|
||||
}
|
||||
else
|
||||
{
|
||||
glossval = min(gl_specular_fallback.value*255, 255);
|
||||
glossval *= 0x10101;
|
||||
}
|
||||
glossval |= 0x01000000 * bound(0, (int)(gl_specular_fallbackexp.value*255), 255);
|
||||
glossval = LittleLong(glossval);
|
||||
normval = 0xffff8080;
|
||||
|
|
|
@ -29,6 +29,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#if (defined(GLQUAKE) || defined(VKQUAKE)) && defined(MULTITHREAD)
|
||||
#define THREADEDWORLD
|
||||
int webo_blocklightmapupdates; //0 no webo, &1=using threadedworld, &2=already uploaded. so update when !=3
|
||||
#endif
|
||||
#ifdef BEF_PUSHDEPTH
|
||||
qboolean r_pushdepth;
|
||||
|
@ -1776,7 +1777,7 @@ static void Surf_BuildLightMap_Worker (model_t *wmodel, msurface_t *surf, int sh
|
|||
}
|
||||
}
|
||||
}
|
||||
else switch(cl.worldmodel->lightmaps.fmt)
|
||||
else switch(wmodel->lightmaps.fmt)
|
||||
{
|
||||
case LM_E5BGR9:
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
|
@ -1876,7 +1877,7 @@ static void Surf_BuildLightMap_Worker (model_t *wmodel, msurface_t *surf, int sh
|
|||
// add all the lightmaps
|
||||
if (src)
|
||||
{
|
||||
switch(cl.worldmodel->lightmaps.fmt)
|
||||
switch(wmodel->lightmaps.fmt)
|
||||
{
|
||||
case LM_E5BGR9:
|
||||
for (maps = 0 ; maps < MAXCPULIGHTMAPS && surf->styles[maps] != INVALID_LIGHTSTYLE ; maps++)
|
||||
|
@ -2882,7 +2883,7 @@ void Surf_GenBrushBatches(batch_t **batches, entity_t *ent)
|
|||
|
||||
// calculate dynamic lighting for bmodel if it's not an
|
||||
// instanced model
|
||||
if (model->fromgame != fg_quake3 && model->fromgame != fg_doom3 && lightmap && !r_temporalscenecache.ival)
|
||||
if (model->fromgame != fg_quake3 && model->fromgame != fg_doom3 && lightmap && webo_blocklightmapupdates!=3)
|
||||
{
|
||||
int k;
|
||||
|
||||
|
@ -2981,12 +2982,12 @@ void Surf_GenBrushBatches(batch_t **batches, entity_t *ent)
|
|||
if (!b->shader)
|
||||
b->shader = R_TextureAnimation(ent->framestate.g[FS_REG].frame[0], b->texture)->shader;
|
||||
|
||||
if (bef & BEF_FORCEADDITIVE)
|
||||
if (bef & BEF_FORCEADDITIVE && b->shader->sort==SHADER_SORT_OPAQUE)
|
||||
{
|
||||
b->next = batches[SHADER_SORT_ADDITIVE];
|
||||
batches[SHADER_SORT_ADDITIVE] = b;
|
||||
}
|
||||
else if (bef & BEF_FORCETRANSPARENT)
|
||||
else if (bef & BEF_FORCETRANSPARENT && b->shader->sort==SHADER_SORT_OPAQUE)
|
||||
{
|
||||
b->next = batches[SHADER_SORT_BLEND];
|
||||
batches[SHADER_SORT_BLEND] = b;
|
||||
|
@ -3025,6 +3026,7 @@ struct webostate_s
|
|||
{
|
||||
size_t numidx;
|
||||
size_t maxidx;
|
||||
size_t firstidx; //offset into the final ebo
|
||||
index_t *idxbuffer;
|
||||
batch_t b;
|
||||
mesh_t m;
|
||||
|
@ -3035,12 +3037,15 @@ struct webostate_s
|
|||
static struct webostate_s *webostates;
|
||||
static struct webostate_s *webogenerating;
|
||||
static int webogeneratingstate; //1 if generating, 0 if not, for waiting for sync.
|
||||
int webo_blocklightmapupdates; //0 no webo, &1=using threadedworld, &2=already uploaded.
|
||||
static void R_DestroyWorldEBO(struct webostate_s *es)
|
||||
{
|
||||
int i;
|
||||
if (!es)
|
||||
return;
|
||||
|
||||
for (i = 0; i < es->numbatches; i++)
|
||||
BZ_Free(es->batches[i].idxbuffer);
|
||||
|
||||
#ifdef GLQUAKE
|
||||
if (qrenderer == QR_OPENGL)
|
||||
qglDeleteBuffersARB(1, &es->ebo.gl.vbo);
|
||||
|
@ -3077,14 +3082,16 @@ void R_GeneratedWorldEBO(void *ctx, void *data, size_t a_, size_t b_)
|
|||
GL_DeselectVAO();
|
||||
|
||||
webostate->ebo.gl.addr = NULL;
|
||||
qglGenBuffersARB(1, &webostate->ebo.gl.vbo);
|
||||
if (!webostate->ebo.gl.vbo)
|
||||
qglGenBuffersARB(1, &webostate->ebo.gl.vbo);
|
||||
GL_SelectEBO(webostate->ebo.gl.vbo);
|
||||
qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, idxcount*sizeof(index_t), NULL, GL_STATIC_DRAW_ARB);
|
||||
for (i = 0, idxcount = 0; i < webostate->numbatches; i++)
|
||||
{
|
||||
qglBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, idxcount*sizeof(index_t), webostate->batches[i].numidx*sizeof(index_t), webostate->batches[i].idxbuffer);
|
||||
BZ_Free(webostate->batches[i].idxbuffer);
|
||||
webostate->batches[i].idxbuffer = (index_t*)NULL + idxcount;
|
||||
// BZ_Free(webostate->batches[i].idxbuffer);
|
||||
// webostate->batches[i].idxbuffer = NULL;
|
||||
webostate->batches[i].firstidx = idxcount;
|
||||
idxcount += webostate->batches[i].numidx;
|
||||
}
|
||||
}
|
||||
|
@ -3094,12 +3101,16 @@ void R_GeneratedWorldEBO(void *ctx, void *data, size_t a_, size_t b_)
|
|||
{ //this malloc is stupid.
|
||||
//with vulkan we really should be doing this on the worker instead, at least the staging part.
|
||||
index_t *indexes = malloc(sizeof(*indexes) * idxcount);
|
||||
BE_VBO_Destroy(&webostate->ebo, webostate->ebomem);
|
||||
memset(&webostate->ebo, 0, sizeof(webostate->ebo));
|
||||
webostate->ebomem = NULL;
|
||||
webostate->ebo.vk.offs = 0;
|
||||
for (i = 0, idxcount = 0; i < webostate->numbatches; i++)
|
||||
{
|
||||
memcpy(indexes + idxcount, webostate->batches[i].idxbuffer, webostate->batches[i].numidx*sizeof(index_t));
|
||||
BZ_Free(webostate->batches[i].idxbuffer);
|
||||
webostate->batches[i].idxbuffer = (index_t*)NULL + idxcount;
|
||||
// BZ_Free(webostate->batches[i].idxbuffer);
|
||||
// webostate->batches[i].idxbuffer = NULL;
|
||||
webostate->batches[i].firstidx = idxcount;
|
||||
idxcount += webostate->batches[i].numidx;
|
||||
}
|
||||
if (idxcount)
|
||||
|
@ -3144,7 +3155,7 @@ void R_GeneratedWorldEBO(void *ctx, void *data, size_t a_, size_t b_)
|
|||
b->mesh = &webostate->batches[i].pm;
|
||||
b->meshes = 1;
|
||||
m->numindexes = webostate->batches[i].numidx;
|
||||
m->vbofirstelement = webostate->batches[i].idxbuffer - (index_t*)NULL;
|
||||
m->vbofirstelement = webostate->batches[i].firstidx;
|
||||
m->vbofirstvert = 0;
|
||||
m->indexes = NULL;
|
||||
b->vbo = &webostate->batches[i].vbo;
|
||||
|
@ -3277,13 +3288,25 @@ void R_GenWorldEBO(void *ctx, void *data, size_t a, size_t b)
|
|||
struct webostate_s *es = ctx;
|
||||
qbyte *pvs;
|
||||
|
||||
es->numbatches = es->wmodel->numbatches;
|
||||
|
||||
for (i = 0; i < es->numbatches; i++)
|
||||
if (!es->numbatches)
|
||||
{
|
||||
es->batches[i].numidx = 0;
|
||||
es->batches[i].maxidx = 0;
|
||||
es->batches[i].idxbuffer = NULL;
|
||||
es->numbatches = es->wmodel->numbatches;
|
||||
|
||||
for (i = 0; i < es->numbatches; i++)
|
||||
{
|
||||
es->batches[i].firstidx = 0;
|
||||
es->batches[i].numidx = 0;
|
||||
es->batches[i].maxidx = 0;
|
||||
es->batches[i].idxbuffer = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < es->numbatches; i++)
|
||||
{
|
||||
es->batches[i].firstidx = 0;
|
||||
es->batches[i].numidx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//maybe we should just use fatpvs instead, and wait for completion when outside?
|
||||
|
@ -3351,19 +3374,19 @@ void Surf_DrawWorld (void)
|
|||
#ifdef THREADEDWORLD
|
||||
if ((r_temporalscenecache.ival || currentmodel->numbatches) && !r_refdef.recurse && currentmodel->type == mod_brush)
|
||||
{
|
||||
struct webostate_s *webostate, *best = NULL, *kill;
|
||||
struct webostate_s *webostate, *best = NULL, *kill, **link;
|
||||
vec_t bestdist = FLT_MAX;
|
||||
for (webostate = webostates; webostate; webostate = webostate->next)
|
||||
{
|
||||
if (webostate->wmodel != currentmodel)
|
||||
continue;
|
||||
|
||||
kill = webostate->next;
|
||||
if (kill && kill->lastvalid < cls.framecount-5)
|
||||
{
|
||||
webostate->next = kill->next;
|
||||
R_DestroyWorldEBO(kill);
|
||||
}
|
||||
// kill = webostate->next;
|
||||
// if (kill && kill->lastvalid < cls.framecount-5)
|
||||
// {
|
||||
// webostate->next = kill->next;
|
||||
// R_DestroyWorldEBO(kill);
|
||||
// }
|
||||
|
||||
if (webostate->cluster[0] == r_viewcluster && webostate->cluster[1] == r_viewcluster2)
|
||||
{
|
||||
|
@ -3438,8 +3461,31 @@ void Surf_DrawWorld (void)
|
|||
}
|
||||
/*TODO submodels too*/
|
||||
}
|
||||
|
||||
webogeneratingstate = true;
|
||||
webogenerating = BZ_Malloc(sizeof(*webogenerating) + sizeof(webogenerating->batches[0]) * (currentmodel->numbatches-1) + currentmodel->pvsbytes);
|
||||
|
||||
webogenerating = NULL;
|
||||
if (webostate)
|
||||
webostate->lastvalid = cls.framecount;
|
||||
for (link = &webostates; (kill=*link); )
|
||||
{
|
||||
if (kill->lastvalid < cls.framecount-5 && kill->wmodel == currentmodel)
|
||||
{ //this one looks old... kill it.
|
||||
if (webogenerating)
|
||||
R_DestroyWorldEBO(webogenerating); //can't use more than one!
|
||||
webogenerating = kill;
|
||||
*link = kill->next;
|
||||
}
|
||||
else
|
||||
link = &(*link)->next;
|
||||
}
|
||||
if (!webogenerating)
|
||||
{
|
||||
webogenerating = BZ_Malloc(sizeof(*webogenerating) + sizeof(webogenerating->batches[0]) * (currentmodel->numbatches-1) + currentmodel->pvsbytes);
|
||||
memset(&webogenerating->ebo, 0, sizeof(webogenerating->ebo));
|
||||
webogenerating->ebomem = NULL;
|
||||
webogenerating->numbatches = 0;
|
||||
}
|
||||
webogenerating->wmodel = currentmodel;
|
||||
webogenerating->cluster[0] = r_viewcluster;
|
||||
webogenerating->cluster[1] = r_viewcluster2;
|
||||
|
@ -3912,7 +3958,7 @@ int Surf_NewLightmaps(int count, int width, int height, uploadfmt_t fmt, qboolea
|
|||
extern cvar_t gl_pbolightmaps;
|
||||
//we might as well use a pbo for our staging memory.
|
||||
if (qrenderer == QR_OPENGL && qglBufferStorage && qglMapBufferRange && gl_pbolightmaps.ival && Sys_IsMainThread())
|
||||
{ //glBufferStorage and GL_MAP_PERSISTENT_BIT generally means gl4.4+
|
||||
{ //glBufferStorage and GL_MAP_PERSISTENT_BIT generally means gl4.4+ (we need persistent for scenecache)
|
||||
//pbos are 2.1
|
||||
if (deluxe && ((i - numlightmaps)&1))
|
||||
{
|
||||
|
|
|
@ -173,7 +173,7 @@ cvar_t r_drawviewmodel = CVARF ("r_drawviewmodel", "1", CVAR_ARCHIVE);
|
|||
cvar_t r_drawviewmodelinvis = CVAR ("r_drawviewmodelinvis", "0");
|
||||
cvar_t r_dynamic = CVARFD ("r_dynamic", IFMINIMAL("0","1"),
|
||||
CVAR_ARCHIVE, "0: no standard dlights at all.\n1: coloured dlights will be used, they may show through walls. These are not realtime things.\n2: The dlights will be forced to monochrome (this does not affect coronas/flashblends/rtlights attached to the same light).");
|
||||
cvar_t r_temporalscenecache = CVARFD ("r_temporalscenecache", "0", CVAR_ARCHIVE, "Controls whether to generate+reuse a scene cache over multiple frames. This is generated on a separate thread to avoid any associated costs. This can significantly boost framerates on complex maps, but can also stress the gpu more (performance tradeoff that varies per map). An outdated cache may be used if the cache takes too long to build (eg: lightmap animations), which could cause the odd glitch when moving fast (but retain more consistent framerates - another tradeoff).\n0: Tranditional quake rendering.\n1: Generate+Use the scene cache.");
|
||||
cvar_t r_temporalscenecache = CVARFD ("r_temporalscenecache", "", CVAR_ARCHIVE, "Controls whether to generate+reuse a scene cache over multiple frames. This is generated on a separate thread to avoid any associated costs. This can significantly boost framerates on complex maps, but can also stress the gpu more (performance tradeoff that varies per map). An outdated cache may be used if the cache takes too long to build (eg: lightmap animations), which could cause the odd glitch when moving fast (but retain more consistent framerates - another tradeoff).\n0: Tranditional quake rendering.\n1: Generate+Use the scene cache.");
|
||||
cvar_t r_fastturb = CVARF ("r_fastturb", "0",
|
||||
CVAR_SHADERSYSTEM);
|
||||
cvar_t r_skycloudalpha = CVARFD ("r_skycloudalpha", "1", CVAR_RENDERERLATCH, "Controls how opaque the front layer of legacy scrolling skies should be.");
|
||||
|
@ -455,7 +455,7 @@ cvar_t gl_smoothcrosshair = CVAR ("gl_smoothcrosshair", "1");
|
|||
cvar_t gl_maxdist = CVARAD ("gl_maxdist", "0", "gl_farclip", "The distance of the far clip plane. If set to 0, some fancy maths will be used to place it at an infinite distance.");
|
||||
|
||||
#ifdef SPECULAR
|
||||
cvar_t gl_specular = CVARF ("gl_specular", "0.3", CVAR_ARCHIVE|CVAR_SHADERSYSTEM);
|
||||
cvar_t gl_specular = CVARFD ("gl_specular", "0.3", CVAR_ARCHIVE|CVAR_SHADERSYSTEM, "Multiplier for specular effects.");
|
||||
cvar_t gl_specular_power = CVARF ("gl_specular_power", "32", CVAR_ARCHIVE|CVAR_SHADERSYSTEM);
|
||||
cvar_t gl_specular_fallback = CVARF ("gl_specular_fallback", "0.05", CVAR_ARCHIVE|CVAR_RENDERERLATCH);
|
||||
cvar_t gl_specular_fallbackexp = CVARF ("gl_specular_fallbackexp", "1", CVAR_ARCHIVE|CVAR_RENDERERLATCH);
|
||||
|
@ -505,6 +505,7 @@ cvar_t r_shadow_bumpscale_bumpmap = CVARD ("r_shadow_bumpscale_bumpmap", "4",
|
|||
cvar_t r_shadow_heightscale_basetexture = CVARD ("r_shadow_heightscale_basetexture", "0", "scaler for generation of height maps from legacy paletted content.");
|
||||
cvar_t r_shadow_heightscale_bumpmap = CVARD ("r_shadow_heightscale_bumpmap", "1", "height scaler for 8bit _bump textures");
|
||||
|
||||
cvar_t r_glsl_pbr = CVARFD ("r_glsl_pbr", "0", CVAR_ARCHIVE|CVAR_SHADERSYSTEM, "Force PBR shading.");
|
||||
cvar_t r_glsl_offsetmapping = CVARFD ("r_glsl_offsetmapping", "0", CVAR_ARCHIVE|CVAR_SHADERSYSTEM, "Enables the use of paralax mapping, adding fake depth to textures.");
|
||||
cvar_t r_glsl_offsetmapping_scale = CVAR ("r_glsl_offsetmapping_scale", "0.04");
|
||||
cvar_t r_glsl_offsetmapping_reliefmapping = CVARFD("r_glsl_offsetmapping_reliefmapping", "0", CVAR_ARCHIVE|CVAR_SHADERSYSTEM, "Changes the paralax sampling mode to be a bit nicer, but noticably more expensive at high resolutions. r_glsl_offsetmapping must be set.");
|
||||
|
@ -904,6 +905,7 @@ void Renderer_Init(void)
|
|||
Cvar_Register (&r_coronas_fadedist, GRAPHICALNICETIES);
|
||||
Cvar_Register (&r_flashblend, GRAPHICALNICETIES);
|
||||
Cvar_Register (&r_flashblendscale, GRAPHICALNICETIES);
|
||||
Cvar_Register (&r_glsl_pbr, GRAPHICALNICETIES);
|
||||
Cvar_Register (&gl_specular, GRAPHICALNICETIES);
|
||||
Cvar_Register (&gl_specular_power, GRAPHICALNICETIES);
|
||||
Cvar_Register (&gl_specular_fallback, GRAPHICALNICETIES);
|
||||
|
|
|
@ -306,13 +306,20 @@ static qboolean QDECL ALSA_InitCard (soundcardinfo_t *sc, const char *pcmname)
|
|||
|
||||
#if 1
|
||||
if (!sc->sn.sampleformat)
|
||||
sc->sn.sampleformat = (sc->sn.samplebytes==1)?QSF_U8:QSF_S16;
|
||||
{
|
||||
if (sc->sn.samplebytes >= 4)
|
||||
sc->sn.sampleformat = QSF_F32;
|
||||
else if (sc->sn.samplebytes != 1)
|
||||
sc->sn.sampleformat = QSF_S16;
|
||||
else
|
||||
sc->sn.sampleformat = QSF_U8;
|
||||
}
|
||||
switch(sc->sn.sampleformat)
|
||||
{
|
||||
case QSF_U8: err = SND_PCM_FORMAT_U8; break;
|
||||
case QSF_S8: err = SND_PCM_FORMAT_S8; break;
|
||||
case QSF_S16: err = SND_PCM_FORMAT_S16; break;
|
||||
case QSF_F32: err = SND_PCM_FORMAT_FLOAT; break;
|
||||
case QSF_U8: err = SND_PCM_FORMAT_U8; sc->sn.samplebytes=1; break;
|
||||
case QSF_S8: err = SND_PCM_FORMAT_S8; sc->sn.samplebytes=1; break;
|
||||
case QSF_S16: err = SND_PCM_FORMAT_S16; sc->sn.samplebytes=2; break;
|
||||
case QSF_F32: err = SND_PCM_FORMAT_FLOAT; sc->sn.samplebytes=4; break;
|
||||
default:
|
||||
Con_Printf (CON_ERROR "ALSA: unsupported sample format %i\n", sc->sn.sampleformat);
|
||||
goto error;
|
||||
|
|
|
@ -89,7 +89,7 @@ cvar_t nosound = CVARFD( "nosound", "0", CVAR_ARCHIVE,
|
|||
"Disable all sound from the engine. Cannot be overriden by configs or anything if set via the -nosound commandline argument.");
|
||||
cvar_t snd_precache = CVARAF( "s_precache", "1",
|
||||
"precache", 0);
|
||||
cvar_t loadas8bit = CVARAFD( "s_loadas8bit", "0",
|
||||
cvar_t snd_loadas8bit = CVARAFD( "s_loadas8bit", "0",
|
||||
"loadas8bit", CVAR_ARCHIVE,
|
||||
"Downsample sounds on load as lower quality 8-bit sound, to save memory.");
|
||||
#ifdef FTE_TARGET_WEB
|
||||
|
@ -2315,7 +2315,7 @@ void S_Init (void)
|
|||
Cvar_Register(&mastervolume, "Sound controls");
|
||||
Cvar_Register(&volume, "Sound controls");
|
||||
Cvar_Register(&snd_precache, "Sound controls");
|
||||
Cvar_Register(&loadas8bit, "Sound controls");
|
||||
Cvar_Register(&snd_loadas8bit, "Sound controls");
|
||||
Cvar_Register(&snd_loadasstereo, "Sound controls");
|
||||
Cvar_Register(&bgmvolume, "Sound controls");
|
||||
Cvar_Register(&snd_nominaldistance, "Sound controls");
|
||||
|
@ -2857,8 +2857,9 @@ static void SND_Spatialize(soundcardinfo_t *sc, channel_t *ch)
|
|||
scale = 1;
|
||||
scale = (1.0 - dist) * scale;
|
||||
v = ch->master_vol * scale * volscale;
|
||||
v = bound(0, v, 255);
|
||||
for (i = 0; i < sc->sn.numchannels; i++)
|
||||
ch->vol[i] = bound(0, v, 255);
|
||||
ch->vol[i] = v;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2890,7 +2891,8 @@ static void SND_Spatialize(soundcardinfo_t *sc, channel_t *ch)
|
|||
scale = 1 + DotProduct(listener_vec, sc->speakerdir[i]);
|
||||
scale = (1.0 - dist) * scale * sc->dist[i];
|
||||
v = ch->master_vol * scale * volscale;
|
||||
ch->vol[i] = bound(0, v, 255);
|
||||
v = bound(0, v, 255);
|
||||
ch->vol[i] = v;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -569,9 +569,9 @@ static qboolean ResampleSfx (sfx_t *sfx, int inrate, int inchannels, qaudiofmt_t
|
|||
|
||||
scale = snd_speed / (double)inrate;
|
||||
outsamps = insamps * scale;
|
||||
if (loadas8bit.ival < 0)
|
||||
if (snd_loadas8bit.ival < 0)
|
||||
outformat = QAF_S16;
|
||||
else if (loadas8bit.ival)
|
||||
else if (snd_loadas8bit.ival)
|
||||
outformat = QAF_S8;
|
||||
else
|
||||
outformat = informat;
|
||||
|
@ -789,7 +789,7 @@ static qboolean QDECL S_LoadWavSound (sfx_t *s, qbyte *data, size_t datalen, int
|
|||
format = QAF_F32;
|
||||
}
|
||||
#else
|
||||
else if (info.format == 3 && info.bitwidth == 4) //signed floats
|
||||
else if (info.format == 3 && info.bitwidth == 32) //signed floats
|
||||
{
|
||||
short *out = (short *)(data + info.dataofs);
|
||||
float *in = (float *)(data + info.dataofs);
|
||||
|
|
|
@ -23,25 +23,42 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#ifdef HAVE_MIXER
|
||||
|
||||
|
||||
//#define MIXER_PAINT_F32
|
||||
#ifdef MIXER_PAINT_F32
|
||||
#define MIX_16_8(val) ((val)/(float)(1<<(15+8)))
|
||||
#define MIX_8_8(val) ((val)/(float)(1<<(7+8)))
|
||||
typedef struct {
|
||||
float s[MAXSOUNDCHANNELS];
|
||||
} portable_samplegroup_t;
|
||||
#else
|
||||
#define MIX_16_8(val) ((val)>>8) //value is a 16bit*8bit value (audio*vol) value. discard the lower 8 bits to treat the volume as a fraction
|
||||
#define MIX_8_8(val) (val) //value is a 8bit*8bit value (audio*vol) value. result is 16bit.
|
||||
|
||||
typedef struct {
|
||||
int s[MAXSOUNDCHANNELS]; //signed, 1=0x7fff ish. will be clamped to allow oversaturation
|
||||
} portable_samplegroup_t;
|
||||
#endif
|
||||
|
||||
#define PAINTBUFFER_SIZE 2048
|
||||
|
||||
portable_samplegroup_t paintbuffer[PAINTBUFFER_SIZE]; //FIXME: we really ought to be using SSE and floats or something.
|
||||
|
||||
int *snd_p, snd_vol;
|
||||
short *snd_out;
|
||||
static portable_samplegroup_t paintbuffer[PAINTBUFFER_SIZE]; //FIXME: we really ought to be using SSE and floats or something.
|
||||
|
||||
void S_TransferPaintBuffer(soundcardinfo_t *sc, int endtime)
|
||||
{
|
||||
unsigned int out_idx;
|
||||
unsigned int count;
|
||||
unsigned int outlimit;
|
||||
int *p;
|
||||
#ifdef MIXER_PAINT_F32
|
||||
float *p = (float *fte_restrict)paintbuffer;
|
||||
#else
|
||||
int *p = (int *fte_restrict) paintbuffer;
|
||||
#endif
|
||||
int val;
|
||||
// int snd_vol;
|
||||
short *pbuf;
|
||||
void *pbuf;
|
||||
int i, numc;
|
||||
|
||||
p = (int *) paintbuffer;
|
||||
count = (endtime - sc->paintedtime) * sc->sn.numchannels;
|
||||
outlimit = sc->sn.samples;
|
||||
out_idx = (sc->paintedtime * sc->sn.numchannels) % outlimit;
|
||||
|
@ -64,12 +81,21 @@ void S_TransferPaintBuffer(soundcardinfo_t *sc, int endtime)
|
|||
{
|
||||
for (i = 0; i < numc; i++)
|
||||
{
|
||||
val = *p++;// * snd_vol) >> 8;
|
||||
#ifdef MIXER_PAINT_F32
|
||||
val = (*p++ + 1)*128;
|
||||
if (val > 255)
|
||||
val = 255;
|
||||
else if (val < 0)
|
||||
val = 0;
|
||||
out[out_idx] = val;
|
||||
#else
|
||||
val = *p++;
|
||||
if (val > 0x7fff)
|
||||
val = 0x7fff;
|
||||
else if (val < (short)0x8000)
|
||||
val = (short)0x8000;
|
||||
out[out_idx] = (val>>8) + 128;
|
||||
#endif
|
||||
out_idx = (out_idx + 1) % outlimit;
|
||||
}
|
||||
p += MAXSOUNDCHANNELS - numc;
|
||||
|
@ -84,12 +110,21 @@ void S_TransferPaintBuffer(soundcardinfo_t *sc, int endtime)
|
|||
{
|
||||
for (i = 0; i < numc; i++)
|
||||
{
|
||||
val = *p++;// * snd_vol) >> 8;
|
||||
#ifdef MIXER_PAINT_F32
|
||||
val = *p++*128;
|
||||
if (val > 127)
|
||||
val = 127;
|
||||
else if (val < -128)
|
||||
val = -128;
|
||||
out[out_idx] = val;
|
||||
#else
|
||||
val = *p++;
|
||||
if (val > 0x7fff)
|
||||
val = 0x7fff;
|
||||
else if (val < (short)0x8000)
|
||||
val = (short)0x8000;
|
||||
out[out_idx] = (val>>8);
|
||||
#endif
|
||||
out_idx = (out_idx + 1) % outlimit;
|
||||
}
|
||||
p += MAXSOUNDCHANNELS - numc;
|
||||
|
@ -104,7 +139,11 @@ void S_TransferPaintBuffer(soundcardinfo_t *sc, int endtime)
|
|||
{
|
||||
for (i = 0; i < numc; i++)
|
||||
{
|
||||
val = *p++;// * snd_vol) >> 8;
|
||||
#ifdef MIXER_PAINT_F32
|
||||
val = *p++*0x7fff;
|
||||
#else
|
||||
val = *p++;
|
||||
#endif
|
||||
if (val > 0x7fff)
|
||||
val = 0x7fff;
|
||||
else if (val < (short)0x8000)
|
||||
|
@ -124,7 +163,11 @@ void S_TransferPaintBuffer(soundcardinfo_t *sc, int endtime)
|
|||
{
|
||||
for (i = 0; i < numc; i++)
|
||||
{
|
||||
#ifdef MIXER_PAINT_F32 //FIXME: replace with a memcpy.
|
||||
out[out_idx] = *p++;
|
||||
#else
|
||||
out[out_idx] = *p++ * (1.0 / 32768);
|
||||
#endif
|
||||
out_idx = (out_idx + 1) % outlimit;
|
||||
}
|
||||
p += MAXSOUNDCHANNELS - numc;
|
||||
|
@ -375,23 +418,23 @@ static void SND_PaintChannel8_O2I1 (channel_t *ch, sfxcache_t *sc, int starttime
|
|||
|
||||
if (rate != (1<<PITCHSHIFT))
|
||||
{
|
||||
sfx = (signed char *)sc->data;
|
||||
sfx = (signed char *fte_restrict)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[pos>>PITCHSHIFT];
|
||||
pos += rate;
|
||||
paintbuffer[starttime+i].s[0] += ch->vol[0] * data;
|
||||
paintbuffer[starttime+i].s[1] += ch->vol[1] * data;
|
||||
paintbuffer[starttime+i].s[0] += MIX_8_8(ch->vol[0] * data);
|
||||
paintbuffer[starttime+i].s[1] += MIX_8_8(ch->vol[1] * data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sfx = (signed char *)sc->data + (pos>>PITCHSHIFT);
|
||||
sfx = (signed char *fte_restrict)sc->data + (pos>>PITCHSHIFT);
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[i];
|
||||
paintbuffer[starttime+i].s[0] += ch->vol[0] * data;
|
||||
paintbuffer[starttime+i].s[1] += ch->vol[1] * data;
|
||||
paintbuffer[starttime+i].s[0] += MIX_8_8(ch->vol[0] * data);
|
||||
paintbuffer[starttime+i].s[1] += MIX_8_8(ch->vol[1] * data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -405,21 +448,21 @@ static void SND_PaintChannel8_O2I2 (channel_t *ch, sfxcache_t *sc, int starttime
|
|||
|
||||
if (rate != (1<<PITCHSHIFT))
|
||||
{
|
||||
sfx = (signed char *)sc->data;
|
||||
sfx = (signed char *fte_restrict)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
paintbuffer[starttime+i].s[0] += ch->vol[0] * sfx[(pos>>(PITCHSHIFT-1))&~1];
|
||||
paintbuffer[starttime+i].s[1] += ch->vol[1] * sfx[(pos>>(PITCHSHIFT-1))|1];
|
||||
paintbuffer[starttime+i].s[0] += MIX_8_8(ch->vol[0] * sfx[(pos>>(PITCHSHIFT-1))&~1]);
|
||||
paintbuffer[starttime+i].s[1] += MIX_8_8(ch->vol[1] * sfx[(pos>>(PITCHSHIFT-1))|1]);
|
||||
pos += rate;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sfx = (signed char *)sc->data + (pos>>PITCHSHIFT)*2;
|
||||
sfx = (signed char *fte_restrict)sc->data + (pos>>PITCHSHIFT)*2;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
paintbuffer[starttime+i].s[0] += ch->vol[0] * sfx[(i<<1)];
|
||||
paintbuffer[starttime+i].s[1] += ch->vol[1] * sfx[(i<<1)+1];
|
||||
paintbuffer[starttime+i].s[0] += MIX_8_8(ch->vol[0] * sfx[(i<<1)]);
|
||||
paintbuffer[starttime+i].s[1] += MIX_8_8(ch->vol[1] * sfx[(i<<1)+1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -433,26 +476,26 @@ static void SND_PaintChannel8_O4I1 (channel_t *ch, sfxcache_t *sc, int count, in
|
|||
if (rate != (1<<PITCHSHIFT))
|
||||
{
|
||||
signed char data;
|
||||
sfx = (signed char *)sc->data;
|
||||
sfx = (signed char *fte_restrict)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[pos>>PITCHSHIFT];
|
||||
pos += rate;
|
||||
paintbuffer[i].s[0] += ch->vol[0] * data;
|
||||
paintbuffer[i].s[1] += ch->vol[1] * data;
|
||||
paintbuffer[i].s[2] += ch->vol[2] * data;
|
||||
paintbuffer[i].s[3] += ch->vol[3] * data;
|
||||
paintbuffer[i].s[0] += MIX_8_8(ch->vol[0] * data);
|
||||
paintbuffer[i].s[1] += MIX_8_8(ch->vol[1] * data);
|
||||
paintbuffer[i].s[2] += MIX_8_8(ch->vol[2] * data);
|
||||
paintbuffer[i].s[3] += MIX_8_8(ch->vol[3] * data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sfx = (signed char *)sc->data + (pos>>PITCHSHIFT);
|
||||
sfx = (signed char *fte_restrict)sc->data + (pos>>PITCHSHIFT);
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
paintbuffer[i].s[0] += ch->vol[0] * sfx[i];
|
||||
paintbuffer[i].s[1] += ch->vol[1] * sfx[i];
|
||||
paintbuffer[i].s[2] += ch->vol[2] * sfx[i];
|
||||
paintbuffer[i].s[3] += ch->vol[3] * sfx[i];
|
||||
paintbuffer[i].s[0] += MIX_8_8(ch->vol[0] * sfx[i]);
|
||||
paintbuffer[i].s[1] += MIX_8_8(ch->vol[1] * sfx[i]);
|
||||
paintbuffer[i].s[2] += MIX_8_8(ch->vol[2] * sfx[i]);
|
||||
paintbuffer[i].s[3] += MIX_8_8(ch->vol[3] * sfx[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -466,30 +509,30 @@ static void SND_PaintChannel8_O6I1 (channel_t *ch, sfxcache_t *sc, int count, in
|
|||
if (rate != (1<<PITCHSHIFT))
|
||||
{
|
||||
signed char data;
|
||||
sfx = (signed char *)sc->data;
|
||||
sfx = (signed char *fte_restrict)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[pos>>PITCHSHIFT];
|
||||
pos += rate;
|
||||
paintbuffer[i].s[0] += ch->vol[0] * data;
|
||||
paintbuffer[i].s[1] += ch->vol[1] * data;
|
||||
paintbuffer[i].s[2] += ch->vol[2] * data;
|
||||
paintbuffer[i].s[3] += ch->vol[3] * data;
|
||||
paintbuffer[i].s[4] += ch->vol[4] * data;
|
||||
paintbuffer[i].s[5] += ch->vol[5] * data;
|
||||
paintbuffer[i].s[0] += MIX_8_8(ch->vol[0] * data);
|
||||
paintbuffer[i].s[1] += MIX_8_8(ch->vol[1] * data);
|
||||
paintbuffer[i].s[2] += MIX_8_8(ch->vol[2] * data);
|
||||
paintbuffer[i].s[3] += MIX_8_8(ch->vol[3] * data);
|
||||
paintbuffer[i].s[4] += MIX_8_8(ch->vol[4] * data);
|
||||
paintbuffer[i].s[5] += MIX_8_8(ch->vol[5] * data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sfx = (signed char *)sc->data + (pos>>PITCHSHIFT);
|
||||
sfx = (signed char *fte_restrict)sc->data + (pos>>PITCHSHIFT);
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
paintbuffer[i].s[0] += ch->vol[0] * sfx[i];
|
||||
paintbuffer[i].s[1] += ch->vol[1] * sfx[i];
|
||||
paintbuffer[i].s[2] += ch->vol[2] * sfx[i];
|
||||
paintbuffer[i].s[3] += ch->vol[3] * sfx[i];
|
||||
paintbuffer[i].s[4] += ch->vol[4] * sfx[i];
|
||||
paintbuffer[i].s[5] += ch->vol[5] * sfx[i];
|
||||
paintbuffer[i].s[0] += MIX_8_8(ch->vol[0] * sfx[i]);
|
||||
paintbuffer[i].s[1] += MIX_8_8(ch->vol[1] * sfx[i]);
|
||||
paintbuffer[i].s[2] += MIX_8_8(ch->vol[2] * sfx[i]);
|
||||
paintbuffer[i].s[3] += MIX_8_8(ch->vol[3] * sfx[i]);
|
||||
paintbuffer[i].s[4] += MIX_8_8(ch->vol[4] * sfx[i]);
|
||||
paintbuffer[i].s[5] += MIX_8_8(ch->vol[5] * sfx[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -503,34 +546,34 @@ static void SND_PaintChannel8_O8I1 (channel_t *ch, sfxcache_t *sc, int count, in
|
|||
if (rate != (1<<PITCHSHIFT))
|
||||
{
|
||||
signed char data;
|
||||
sfx = (signed char *)sc->data;
|
||||
sfx = (signed char *fte_restrict)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[pos>>PITCHSHIFT];
|
||||
pos += rate;
|
||||
paintbuffer[i].s[0] += ch->vol[0] * data;
|
||||
paintbuffer[i].s[1] += ch->vol[1] * data;
|
||||
paintbuffer[i].s[2] += ch->vol[2] * data;
|
||||
paintbuffer[i].s[3] += ch->vol[3] * data;
|
||||
paintbuffer[i].s[4] += ch->vol[4] * data;
|
||||
paintbuffer[i].s[5] += ch->vol[5] * data;
|
||||
paintbuffer[i].s[6] += ch->vol[6] * data;
|
||||
paintbuffer[i].s[7] += ch->vol[7] * data;
|
||||
paintbuffer[i].s[0] += MIX_8_8(ch->vol[0] * data);
|
||||
paintbuffer[i].s[1] += MIX_8_8(ch->vol[1] * data);
|
||||
paintbuffer[i].s[2] += MIX_8_8(ch->vol[2] * data);
|
||||
paintbuffer[i].s[3] += MIX_8_8(ch->vol[3] * data);
|
||||
paintbuffer[i].s[4] += MIX_8_8(ch->vol[4] * data);
|
||||
paintbuffer[i].s[5] += MIX_8_8(ch->vol[5] * data);
|
||||
paintbuffer[i].s[6] += MIX_8_8(ch->vol[6] * data);
|
||||
paintbuffer[i].s[7] += MIX_8_8(ch->vol[7] * data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sfx = (signed char *)sc->data + (pos>>PITCHSHIFT);
|
||||
sfx = (signed char *fte_restrict)sc->data + (pos>>PITCHSHIFT);
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
paintbuffer[i].s[0] += ch->vol[0] * sfx[i];
|
||||
paintbuffer[i].s[1] += ch->vol[1] * sfx[i];
|
||||
paintbuffer[i].s[2] += ch->vol[2] * sfx[i];
|
||||
paintbuffer[i].s[3] += ch->vol[3] * sfx[i];
|
||||
paintbuffer[i].s[4] += ch->vol[4] * sfx[i];
|
||||
paintbuffer[i].s[5] += ch->vol[5] * sfx[i];
|
||||
paintbuffer[i].s[6] += ch->vol[6] * sfx[i];
|
||||
paintbuffer[i].s[7] += ch->vol[7] * sfx[i];
|
||||
paintbuffer[i].s[0] += MIX_8_8(ch->vol[0] * sfx[i]);
|
||||
paintbuffer[i].s[1] += MIX_8_8(ch->vol[1] * sfx[i]);
|
||||
paintbuffer[i].s[2] += MIX_8_8(ch->vol[2] * sfx[i]);
|
||||
paintbuffer[i].s[3] += MIX_8_8(ch->vol[3] * sfx[i]);
|
||||
paintbuffer[i].s[4] += MIX_8_8(ch->vol[4] * sfx[i]);
|
||||
paintbuffer[i].s[5] += MIX_8_8(ch->vol[5] * sfx[i]);
|
||||
paintbuffer[i].s[6] += MIX_8_8(ch->vol[6] * sfx[i]);
|
||||
paintbuffer[i].s[7] += MIX_8_8(ch->vol[7] * sfx[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -539,7 +582,6 @@ static void SND_PaintChannel8_O8I1 (channel_t *ch, sfxcache_t *sc, int count, in
|
|||
static void SND_PaintChannel16_O2I1 (channel_t *ch, sfxcache_t *sc, int starttime, int count, int rate)
|
||||
{
|
||||
int data;
|
||||
int left, right;
|
||||
int leftvol, rightvol;
|
||||
signed short *sfx;
|
||||
int i;
|
||||
|
@ -551,26 +593,24 @@ static void SND_PaintChannel16_O2I1 (channel_t *ch, sfxcache_t *sc, int starttim
|
|||
if (rate != (1<<PITCHSHIFT))
|
||||
{
|
||||
signed int data;
|
||||
sfx = (signed short *)sc->data;
|
||||
sfx = (signed short *fte_restrict)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
int frac = pos&((1<<PITCHSHIFT)-1);
|
||||
data = sfx[pos>>PITCHSHIFT] * ((1<<PITCHSHIFT)-frac) + sfx[(pos>>PITCHSHIFT)+1] * frac;
|
||||
pos += rate;
|
||||
paintbuffer[starttime+i].s[0] += (leftvol * data)>>(PITCHSHIFT+8);
|
||||
paintbuffer[starttime+i].s[1] += (rightvol * data)>>(PITCHSHIFT+8);
|
||||
paintbuffer[starttime+i].s[0] += MIX_16_8((leftvol * data)>>PITCHSHIFT);
|
||||
paintbuffer[starttime+i].s[1] += MIX_16_8((rightvol * data)>>PITCHSHIFT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sfx = (signed short *)sc->data + (pos>>PITCHSHIFT);
|
||||
sfx = (signed short *fte_restrict)sc->data + (pos>>PITCHSHIFT);
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[i];
|
||||
left = (data * leftvol) >> 8;
|
||||
right = (data * rightvol) >> 8;
|
||||
paintbuffer[starttime+i].s[0] += left;
|
||||
paintbuffer[starttime+i].s[1] += right;
|
||||
paintbuffer[starttime+i].s[0] += MIX_16_8(data * leftvol);
|
||||
paintbuffer[starttime+i].s[1] += MIX_16_8(data * rightvol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -588,23 +628,23 @@ static void SND_PaintChannel16_O2I2 (channel_t *ch, sfxcache_t *sc, int starttim
|
|||
if (rate != (1<<PITCHSHIFT))
|
||||
{
|
||||
signed short l, r;
|
||||
sfx = (signed short *)sc->data;
|
||||
sfx = (signed short *fte_restrict)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
l = sfx[(pos>>(PITCHSHIFT-1))&~1];
|
||||
r = sfx[(pos>>(PITCHSHIFT-1))|1];
|
||||
pos += rate;
|
||||
paintbuffer[starttime+i].s[0] += (ch->vol[0] * l)>>8;
|
||||
paintbuffer[starttime+i].s[1] += (ch->vol[1] * r)>>8;
|
||||
paintbuffer[starttime+i].s[0] += MIX_16_8(ch->vol[0] * l);
|
||||
paintbuffer[starttime+i].s[1] += MIX_16_8(ch->vol[1] * r);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sfx = (signed short *)sc->data + (pos>>PITCHSHIFT)*2;
|
||||
sfx = (signed short *fte_restrict)sc->data + (pos>>PITCHSHIFT)*2;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
paintbuffer[starttime+i].s[0] += (*sfx++ * leftvol) >> 8;
|
||||
paintbuffer[starttime+i].s[1] += (*sfx++ * rightvol) >> 8;
|
||||
paintbuffer[starttime+i].s[0] += MIX_16_8(*sfx++ * leftvol);
|
||||
paintbuffer[starttime+i].s[1] += MIX_16_8(*sfx++ * rightvol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -624,26 +664,26 @@ static void SND_PaintChannel16_O4I1 (channel_t *ch, sfxcache_t *sc, int count, i
|
|||
if (rate != (1<<PITCHSHIFT))
|
||||
{
|
||||
signed short data;
|
||||
sfx = (signed short *)sc->data;
|
||||
sfx = (signed short *fte_restrict)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[pos>>PITCHSHIFT];
|
||||
pos += rate;
|
||||
paintbuffer[i].s[0] += (vol[0] * data)>>8;
|
||||
paintbuffer[i].s[1] += (vol[1] * data)>>8;
|
||||
paintbuffer[i].s[2] += (vol[2] * data)>>8;
|
||||
paintbuffer[i].s[3] += (vol[3] * data)>>8;
|
||||
paintbuffer[i].s[0] += MIX_16_8(vol[0] * data);
|
||||
paintbuffer[i].s[1] += MIX_16_8(vol[1] * data);
|
||||
paintbuffer[i].s[2] += MIX_16_8(vol[2] * data);
|
||||
paintbuffer[i].s[3] += MIX_16_8(vol[3] * data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sfx = (signed short *)sc->data + (pos>>PITCHSHIFT);
|
||||
sfx = (signed short *fte_restrict)sc->data + (pos>>PITCHSHIFT);
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
paintbuffer[i].s[0] += (sfx[i] * vol[0]) >> 8;
|
||||
paintbuffer[i].s[1] += (sfx[i] * vol[1]) >> 8;
|
||||
paintbuffer[i].s[2] += (sfx[i] * vol[2]) >> 8;
|
||||
paintbuffer[i].s[3] += (sfx[i] * vol[3]) >> 8;
|
||||
paintbuffer[i].s[0] += MIX_16_8(sfx[i] * vol[0]);
|
||||
paintbuffer[i].s[1] += MIX_16_8(sfx[i] * vol[1]);
|
||||
paintbuffer[i].s[2] += MIX_16_8(sfx[i] * vol[2]);
|
||||
paintbuffer[i].s[3] += MIX_16_8(sfx[i] * vol[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -665,30 +705,30 @@ static void SND_PaintChannel16_O6I1 (channel_t *ch, sfxcache_t *sc, int count, i
|
|||
if (rate != (1<<PITCHSHIFT))
|
||||
{
|
||||
signed short data;
|
||||
sfx = (signed short *)sc->data;
|
||||
sfx = (signed short *fte_restrict)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[pos>>PITCHSHIFT];
|
||||
pos += rate;
|
||||
paintbuffer[i].s[0] += (vol[0] * data)>>8;
|
||||
paintbuffer[i].s[1] += (vol[1] * data)>>8;
|
||||
paintbuffer[i].s[2] += (vol[2] * data)>>8;
|
||||
paintbuffer[i].s[3] += (vol[3] * data)>>8;
|
||||
paintbuffer[i].s[4] += (vol[4] * data)>>8;
|
||||
paintbuffer[i].s[5] += (vol[5] * data)>>8;
|
||||
paintbuffer[i].s[0] += MIX_16_8(vol[0] * data);
|
||||
paintbuffer[i].s[1] += MIX_16_8(vol[1] * data);
|
||||
paintbuffer[i].s[2] += MIX_16_8(vol[2] * data);
|
||||
paintbuffer[i].s[3] += MIX_16_8(vol[3] * data);
|
||||
paintbuffer[i].s[4] += MIX_16_8(vol[4] * data);
|
||||
paintbuffer[i].s[5] += MIX_16_8(vol[5] * data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sfx = (signed short *)sc->data + (pos>>PITCHSHIFT);
|
||||
sfx = (signed short *fte_restrict)sc->data + (pos>>PITCHSHIFT);
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
paintbuffer[i].s[0] += (sfx[i] * vol[0]) >> 8;
|
||||
paintbuffer[i].s[1] += (sfx[i] * vol[1]) >> 8;
|
||||
paintbuffer[i].s[2] += (sfx[i] * vol[2]) >> 8;
|
||||
paintbuffer[i].s[3] += (sfx[i] * vol[3]) >> 8;
|
||||
paintbuffer[i].s[4] += (sfx[i] * vol[4]) >> 8;
|
||||
paintbuffer[i].s[5] += (sfx[i] * vol[5]) >> 8;
|
||||
paintbuffer[i].s[0] += MIX_16_8(sfx[i] * vol[0]);
|
||||
paintbuffer[i].s[1] += MIX_16_8(sfx[i] * vol[1]);
|
||||
paintbuffer[i].s[2] += MIX_16_8(sfx[i] * vol[2]);
|
||||
paintbuffer[i].s[3] += MIX_16_8(sfx[i] * vol[3]);
|
||||
paintbuffer[i].s[4] += MIX_16_8(sfx[i] * vol[4]);
|
||||
paintbuffer[i].s[5] += MIX_16_8(sfx[i] * vol[5]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -712,34 +752,34 @@ static void SND_PaintChannel16_O8I1 (channel_t *ch, sfxcache_t *sc, int count, i
|
|||
if (rate != (1<<PITCHSHIFT))
|
||||
{
|
||||
signed short data;
|
||||
sfx = (signed short *)sc->data;
|
||||
sfx = (signed short *fte_restrict)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[pos>>PITCHSHIFT];
|
||||
pos += rate;
|
||||
paintbuffer[i].s[0] += (vol[0] * data)>>8;
|
||||
paintbuffer[i].s[1] += (vol[1] * data)>>8;
|
||||
paintbuffer[i].s[2] += (vol[2] * data)>>8;
|
||||
paintbuffer[i].s[3] += (vol[3] * data)>>8;
|
||||
paintbuffer[i].s[4] += (vol[4] * data)>>8;
|
||||
paintbuffer[i].s[5] += (vol[5] * data)>>8;
|
||||
paintbuffer[i].s[6] += (vol[6] * data)>>8;
|
||||
paintbuffer[i].s[7] += (vol[7] * data)>>8;
|
||||
paintbuffer[i].s[0] += MIX_16_8(vol[0] * data);
|
||||
paintbuffer[i].s[1] += MIX_16_8(vol[1] * data);
|
||||
paintbuffer[i].s[2] += MIX_16_8(vol[2] * data);
|
||||
paintbuffer[i].s[3] += MIX_16_8(vol[3] * data);
|
||||
paintbuffer[i].s[4] += MIX_16_8(vol[4] * data);
|
||||
paintbuffer[i].s[5] += MIX_16_8(vol[5] * data);
|
||||
paintbuffer[i].s[6] += MIX_16_8(vol[6] * data);
|
||||
paintbuffer[i].s[7] += MIX_16_8(vol[7] * data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sfx = (signed short *)sc->data + (pos>>PITCHSHIFT);
|
||||
sfx = (signed short *fte_restrict)sc->data + (pos>>PITCHSHIFT);
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
paintbuffer[i].s[0] += (sfx[i] * vol[0]) >> 8;
|
||||
paintbuffer[i].s[1] += (sfx[i] * vol[1]) >> 8;
|
||||
paintbuffer[i].s[2] += (sfx[i] * vol[2]) >> 8;
|
||||
paintbuffer[i].s[3] += (sfx[i] * vol[3]) >> 8;
|
||||
paintbuffer[i].s[4] += (sfx[i] * vol[4]) >> 8;
|
||||
paintbuffer[i].s[5] += (sfx[i] * vol[5]) >> 8;
|
||||
paintbuffer[i].s[6] += (sfx[i] * vol[6]) >> 8;
|
||||
paintbuffer[i].s[7] += (sfx[i] * vol[7]) >> 8;
|
||||
paintbuffer[i].s[0] += MIX_16_8(sfx[i] * vol[0]);
|
||||
paintbuffer[i].s[1] += MIX_16_8(sfx[i] * vol[1]);
|
||||
paintbuffer[i].s[2] += MIX_16_8(sfx[i] * vol[2]);
|
||||
paintbuffer[i].s[3] += MIX_16_8(sfx[i] * vol[3]);
|
||||
paintbuffer[i].s[4] += MIX_16_8(sfx[i] * vol[4]);
|
||||
paintbuffer[i].s[5] += MIX_16_8(sfx[i] * vol[5]);
|
||||
paintbuffer[i].s[6] += MIX_16_8(sfx[i] * vol[6]);
|
||||
paintbuffer[i].s[7] += MIX_16_8(sfx[i] * vol[7]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -759,7 +799,7 @@ static void SND_PaintChannel32F_O2I1 (channel_t *ch, sfxcache_t *sc, int startti
|
|||
|
||||
if (rate != (1<<PITCHSHIFT))
|
||||
{
|
||||
sfx = (float *)sc->data;
|
||||
sfx = (float *fte_restrict)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
float frac = pos&((1<<PITCHSHIFT)-1);
|
||||
|
@ -771,7 +811,7 @@ static void SND_PaintChannel32F_O2I1 (channel_t *ch, sfxcache_t *sc, int startti
|
|||
}
|
||||
else
|
||||
{
|
||||
sfx = (float *)sc->data + (pos>>PITCHSHIFT);
|
||||
sfx = (float *fte_restrict)sc->data + (pos>>PITCHSHIFT);
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[i];
|
||||
|
@ -796,7 +836,7 @@ static void SND_PaintChannel32F_O2I2 (channel_t *ch, sfxcache_t *sc, int startti
|
|||
if (rate != (1<<PITCHSHIFT))
|
||||
{
|
||||
float l, r;
|
||||
sfx = (float *)sc->data;
|
||||
sfx = (float *fte_restrict)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
l = sfx[(pos>>(PITCHSHIFT-1))&~1];
|
||||
|
@ -808,7 +848,7 @@ static void SND_PaintChannel32F_O2I2 (channel_t *ch, sfxcache_t *sc, int startti
|
|||
}
|
||||
else
|
||||
{
|
||||
sfx = (float *)sc->data + (pos>>PITCHSHIFT)*2;
|
||||
sfx = (float *fte_restrict)sc->data + (pos>>PITCHSHIFT)*2;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
paintbuffer[starttime+i].s[0] += (*sfx++ * leftvol);
|
||||
|
@ -832,7 +872,7 @@ static void SND_PaintChannel32F_O4I1 (channel_t *ch, sfxcache_t *sc, int count,
|
|||
if (rate != (1<<PITCHSHIFT))
|
||||
{
|
||||
float data;
|
||||
sfx = (float *)sc->data;
|
||||
sfx = (float *fte_restrict)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[pos>>PITCHSHIFT];
|
||||
|
@ -845,7 +885,7 @@ static void SND_PaintChannel32F_O4I1 (channel_t *ch, sfxcache_t *sc, int count,
|
|||
}
|
||||
else
|
||||
{
|
||||
sfx = (float *)sc->data + (pos>>PITCHSHIFT);
|
||||
sfx = (float *fte_restrict)sc->data + (pos>>PITCHSHIFT);
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
paintbuffer[i].s[0] += (sfx[i] * vol[0]);
|
||||
|
@ -873,7 +913,7 @@ static void SND_PaintChannel32F_O6I1 (channel_t *ch, sfxcache_t *sc, int count,
|
|||
if (rate != (1<<PITCHSHIFT))
|
||||
{
|
||||
float data;
|
||||
sfx = (float *)sc->data;
|
||||
sfx = (float *fte_restrict)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[pos>>PITCHSHIFT];
|
||||
|
@ -888,7 +928,7 @@ static void SND_PaintChannel32F_O6I1 (channel_t *ch, sfxcache_t *sc, int count,
|
|||
}
|
||||
else
|
||||
{
|
||||
sfx = (float *)sc->data + (pos>>PITCHSHIFT);
|
||||
sfx = (float *fte_restrict)sc->data + (pos>>PITCHSHIFT);
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
paintbuffer[i].s[0] += (sfx[i] * vol[0]);
|
||||
|
@ -921,7 +961,7 @@ static void SND_PaintChannel32F_O8I1 (channel_t *ch, sfxcache_t *sc, int count,
|
|||
if (rate != (1<<PITCHSHIFT))
|
||||
{
|
||||
float data;
|
||||
sfx = (float *)sc->data;
|
||||
sfx = (float *fte_restrict)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[pos>>PITCHSHIFT];
|
||||
|
@ -938,7 +978,7 @@ static void SND_PaintChannel32F_O8I1 (channel_t *ch, sfxcache_t *sc, int count,
|
|||
}
|
||||
else
|
||||
{
|
||||
sfx = (float *)sc->data + (pos>>PITCHSHIFT);
|
||||
sfx = (float *fte_restrict)sc->data + (pos>>PITCHSHIFT);
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
paintbuffer[i].s[0] += (sfx[i] * vol[0]);
|
||||
|
|
|
@ -32,10 +32,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define PITCHSHIFT 6 /*max audio file length = ((1<<32)>>PITCHSHIFT)/KHZ*/
|
||||
|
||||
struct sfx_s;
|
||||
typedef struct
|
||||
{
|
||||
int s[MAXSOUNDCHANNELS];
|
||||
} portable_samplegroup_t;
|
||||
|
||||
typedef struct {
|
||||
struct sfxcache_s *(QDECL *decodedata) (struct sfx_s *sfx, struct sfxcache_s *buf, ssamplepos_t start, int length); //return true when done.
|
||||
|
@ -135,7 +131,7 @@ typedef struct
|
|||
typedef struct
|
||||
{
|
||||
sfx_t *sfx; // sfx number
|
||||
int vol[MAXSOUNDCHANNELS]; // volume, .8 fixed point.
|
||||
int vol[MAXSOUNDCHANNELS]; // volume, 0.8 fixed point.
|
||||
ssamplepos_t pos; // sample position in sfx, <0 means delay sound start (shifted up by PITCHSHIFT)
|
||||
int rate; // fixed point rate scaling
|
||||
int flags; // cf_ flags
|
||||
|
@ -308,7 +304,7 @@ extern int snd_speed;
|
|||
|
||||
extern cvar_t snd_nominaldistance;
|
||||
|
||||
extern cvar_t loadas8bit;
|
||||
extern cvar_t snd_loadas8bit;
|
||||
extern cvar_t bgmvolume;
|
||||
extern cvar_t volume, mastervolume;
|
||||
extern cvar_t snd_capture;
|
||||
|
|
|
@ -292,17 +292,32 @@ void Sys_Quit (void)
|
|||
static void Sys_Register_File_Associations_f(void)
|
||||
{
|
||||
char xdgbase[MAX_OSPATH];
|
||||
char confbase[MAX_OSPATH];
|
||||
|
||||
if (1)
|
||||
{
|
||||
const char *e = getenv("XDG_DATA_HOME");
|
||||
if (e && *e)
|
||||
Q_strncpyz(xdgbase, e, sizeof(xdgbase));
|
||||
{ //user
|
||||
const char *data = getenv("XDG_DATA_HOME");
|
||||
const char *config = getenv("XDG_CONFIG_HOME");
|
||||
const char *home = getenv("HOME");
|
||||
if (data && *data)
|
||||
Q_strncpyz(xdgbase, data, sizeof(xdgbase));
|
||||
else
|
||||
{
|
||||
e = getenv("HOME");
|
||||
if (e && *e)
|
||||
Q_snprintfz(xdgbase, sizeof(xdgbase), "%s/.local/share", e);
|
||||
if (home && *home)
|
||||
Q_snprintfz(xdgbase, sizeof(xdgbase), "%s/.local/share", home);
|
||||
else
|
||||
{
|
||||
Con_Printf("homedir not known\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (config && *config)
|
||||
Q_strncpyz(confbase, config, sizeof(confbase));
|
||||
else
|
||||
{
|
||||
if (home && *home)
|
||||
Q_snprintfz(confbase, sizeof(confbase), "%s/.config", home);
|
||||
else
|
||||
{
|
||||
Con_Printf("homedir not known\n");
|
||||
|
@ -311,20 +326,33 @@ static void Sys_Register_File_Associations_f(void)
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *e = getenv("XDG_DATA_DIRS");
|
||||
while (e && *e == ':')
|
||||
e++;
|
||||
if (e && *e)
|
||||
{ //system... gotta be root...
|
||||
const char *data = getenv("XDG_DATA_DIRS");
|
||||
const char *config = getenv("XDG_CONFIG_DIRS");
|
||||
while (data && *data == ':')
|
||||
data++;
|
||||
if (data && *data)
|
||||
{
|
||||
char *c;
|
||||
Q_strncpyz(xdgbase, e, sizeof(xdgbase));
|
||||
Q_strncpyz(xdgbase, data, sizeof(xdgbase));
|
||||
c = strchr(xdgbase, ':');
|
||||
if (*c)
|
||||
*c = 0;
|
||||
}
|
||||
else
|
||||
Q_strncpyz(xdgbase, "/usr/local/share/", sizeof(xdgbase));
|
||||
while (config && *config == ':')
|
||||
config++;
|
||||
if (config && *config)
|
||||
{
|
||||
char *c;
|
||||
Q_strncpyz(confbase, config, sizeof(confbase));
|
||||
c = strchr(confbase, ':');
|
||||
if (*c)
|
||||
*c = 0;
|
||||
}
|
||||
else
|
||||
Q_strncpyz(confbase, "/etc/xdg/", sizeof(confbase));
|
||||
}
|
||||
|
||||
//we need to create some .desktop file first, so stuff knows how to start us up.
|
||||
|
@ -349,7 +377,7 @@ static void Sys_Register_File_Associations_f(void)
|
|||
if (!strcmp(iconname, "afterquake") || !strcmp(iconname, "nq")) //hacks so that we don't need to create icons.
|
||||
iconname = "quake";
|
||||
|
||||
if (FS_NativePath("icon.png", FS_GAME, iconsyspath, sizeof(iconsyspath)))
|
||||
if (FS_NativePath("icon.png", FS_PUBBASEGAMEONLY, iconsyspath, sizeof(iconsyspath)))
|
||||
iconname = iconsyspath;
|
||||
|
||||
desktopfile = va(desktopfile,
|
||||
|
@ -366,11 +394,11 @@ static void Sys_Register_File_Associations_f(void)
|
|||
//write out a new file and rename the new over the top of the old
|
||||
{
|
||||
char *foundassoc = NULL;
|
||||
vfsfile_t *out = FS_OpenVFS(va("%s/applications/.mimeapps.list.new", xdgbase), "wb", FS_SYSTEM);
|
||||
vfsfile_t *out = FS_OpenVFS(va("%s/.mimeapps.list.new", confbase), "wb", FS_SYSTEM);
|
||||
if (out)
|
||||
{
|
||||
qofs_t insize;
|
||||
char *in = FS_MallocFile(va("%s/applications/mimeapps.list", xdgbase), FS_SYSTEM, &insize);
|
||||
char *in = FS_MallocFile(va("%s/mimeapps.list", confbase), FS_SYSTEM, &insize);
|
||||
if (in)
|
||||
{
|
||||
qboolean inadded = false;
|
||||
|
@ -404,7 +432,7 @@ static void Sys_Register_File_Associations_f(void)
|
|||
if (foundassoc)
|
||||
{ //if we found it, or somewhere to insert it, then insert it.
|
||||
VFS_WRITE(out, in, foundassoc-in);
|
||||
VFS_PRINTF(out, "x-scheme-handler/qw=fte-%s.desktop\n", fs_manifest->installation);
|
||||
VFS_PRINTF(out, "x-scheme-handler/qw=fte-%s.desktop;\n", fs_manifest->installation);
|
||||
VFS_WRITE(out, foundassoc, insize - (foundassoc-in));
|
||||
}
|
||||
else
|
||||
|
@ -414,11 +442,11 @@ static void Sys_Register_File_Associations_f(void)
|
|||
if (!foundassoc)
|
||||
{ //if file not found, or no appropriate section, just concat it on the end.
|
||||
VFS_PRINTF(out, "[Added Associations]\n");
|
||||
VFS_PRINTF(out, "x-scheme-handler/qw=fte-%s.desktop\n", fs_manifest->installation);
|
||||
VFS_PRINTF(out, "x-scheme-handler/qw=fte-%s.desktop;\n", fs_manifest->installation);
|
||||
}
|
||||
VFS_FLUSH(out);
|
||||
VFS_CLOSE(out);
|
||||
FS_Rename2(va("%s/applications/.mimeapps.list.new", xdgbase), va("%s/applications/mimeapps.list", xdgbase), FS_SYSTEM, FS_SYSTEM);
|
||||
FS_Rename2(va("%s/.mimeapps.list.new", confbase), va("%s/mimeapps.list", confbase), FS_SYSTEM, FS_SYSTEM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -637,6 +637,8 @@ static rulesetrule_t rulesetrules_strict[] = {
|
|||
{"ruleset_allow_sensitive_texture_replacements", "0"},
|
||||
{"ruleset_allow_localvolume", "0"},
|
||||
{"ruleset_allow_fbmodels", "0"},
|
||||
{"r_particlesystem", "classic"}, /*block custom particles*/
|
||||
{"r_part_density", "1"}, /*don't let people thin them out*/
|
||||
{"scr_autoid_team", "0"}, /*sort of a wallhack*/
|
||||
{"tp_disputablemacros", "0"},
|
||||
{"cl_instantrotate", "0"},
|
||||
|
@ -645,6 +647,34 @@ static rulesetrule_t rulesetrules_strict[] = {
|
|||
{"ruleset_allow_in", "0"},
|
||||
{"r_projection", "0"},
|
||||
{"gl_shadeq1_name", "*"},
|
||||
{"cl_rollalpha", "20"},
|
||||
{"cl_iDrive", "0"},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
static rulesetrule_t rulesetrules_thunderdome[] = {
|
||||
{"ruleset_allow_shaders", "0"}, /*users can potentially create all sorts of wallhacks or spiked models with this*/
|
||||
{"ruleset_allow_watervis", "0"}, /*oh noes! users might be able to see underwater if they're already in said water. oh wait. what? why do we care, dude*/
|
||||
{"r_vertexlight", "0"},
|
||||
{"ruleset_allow_playercount", "0"},
|
||||
{"ruleset_allow_frj", "0"},
|
||||
{"ruleset_allow_packet", "0"},
|
||||
{"ruleset_allow_particle_lightning", "0"},
|
||||
{"ruleset_allow_overlong_sounds", "0"},
|
||||
{"ruleset_allow_larger_models", "0"},
|
||||
{"ruleset_allow_modified_eyes", "0"},
|
||||
{"ruleset_allow_sensitive_texture_replacements", "0"},
|
||||
{"ruleset_allow_localvolume", "0"},
|
||||
{"ruleset_allow_fbmodels", "0"},
|
||||
{"scr_autoid_team", "0"}, /*sort of a wallhack*/
|
||||
{"tp_disputablemacros", "0"},
|
||||
{"cl_instantrotate", "0"},
|
||||
{"v_projectionmode", "0"}, /*no extended fovs*/
|
||||
{"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", "*"},
|
||||
// {"cl_rollalpha", "20"},
|
||||
{"cl_iDrive", "0"},
|
||||
{NULL}
|
||||
};
|
||||
|
@ -673,9 +703,12 @@ static rulesetrule_t rulesetrules_nqr[] = {
|
|||
|
||||
static ruleset_t rulesets[] =
|
||||
{
|
||||
{"strict", rulesetrules_strict},
|
||||
{"nqr", rulesetrules_nqr},
|
||||
//{"eql", rulesetrules_nqr},
|
||||
{"strict", rulesetrules_strict},
|
||||
{"qcon", rulesetrules_strict}, //not authorised but oh well. imported configs tend to piss people off.
|
||||
{"smackdown", rulesetrules_strict}, //officially, smackdown cannot authorise this, thus we do not use that name. however, imported configs tend to piss people off.
|
||||
{"thunderdome", rulesetrules_thunderdome}, //more permissive (doesn't block particles.
|
||||
{"nqr", rulesetrules_nqr},
|
||||
//{"eql", rulesetrules_nqr},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
|
|
|
@ -2013,14 +2013,26 @@ void R_DrawNameTags(void)
|
|||
#if defined(CSQC_DAT) || !defined(CLIENTONLY)
|
||||
if (r_showshaders.ival && cl.worldmodel && cl.worldmodel->loadstate == MLS_LOADED)
|
||||
{
|
||||
#ifdef CSQC_DAT
|
||||
extern world_t csqc_world;
|
||||
#endif
|
||||
trace_t trace;
|
||||
char *str;
|
||||
vec3_t targ;
|
||||
vec2_t scale = {12,12};
|
||||
msurface_t *surf;
|
||||
VectorMA(r_refdef.vieworg, 8192, vpn, targ);
|
||||
//FIXME: should probably do a general trace, to hit (networked) submodels too
|
||||
cl.worldmodel->funcs.NativeTrace(cl.worldmodel, 0, PE_FRAMESTATE, NULL, r_refdef.vieworg, targ, vec3_origin, vec3_origin, false, ~0, &trace);
|
||||
#ifdef CSQC_DAT
|
||||
if (csqc_world.progs)
|
||||
{
|
||||
int oldhit = csqc_world.edicts->xv->hitcontentsmaski;
|
||||
csqc_world.edicts->xv->hitcontentsmaski = ~0;
|
||||
trace = World_Move(&csqc_world, r_refdef.vieworg, vec3_origin, vec3_origin, targ, MOVE_EVERYTHING, csqc_world.edicts);
|
||||
csqc_world.edicts->xv->hitcontentsmaski = oldhit;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
cl.worldmodel->funcs.NativeTrace(cl.worldmodel, 0, PE_FRAMESTATE, NULL, r_refdef.vieworg, targ, vec3_origin, vec3_origin, false, ~0, &trace);
|
||||
|
||||
surf = Mod_GetSurfaceNearPoint(cl.worldmodel, trace.endpos);
|
||||
if (surf)
|
||||
|
|
|
@ -707,8 +707,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#endif
|
||||
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
|
||||
#define FTE_DEPRECATED __attribute__((__deprecated__)) //no idea about the actual gcc version
|
||||
#ifdef _WIN32
|
||||
#define LIKEPRINTF(x) __attribute__((format(ms_printf,x,x+1)))
|
||||
#if defined(_WIN32)
|
||||
#include <stdio.h>
|
||||
#ifdef __MINGW_PRINTF_FORMAT
|
||||
#define LIKEPRINTF(x) __attribute__((format(__MINGW_PRINTF_FORMAT,x,x+1)))
|
||||
#else
|
||||
#define LIKEPRINTF(x) __attribute__((format(ms_printf,x,x+1)))
|
||||
#endif
|
||||
#else
|
||||
#define LIKEPRINTF(x) __attribute__((format(printf,x,x+1)))
|
||||
#endif
|
||||
|
|
|
@ -805,37 +805,56 @@ static void Cmd_Exec_f (void)
|
|||
#ifndef QUAKETC
|
||||
//hack to try to work around nquake's b0rkedness
|
||||
if (!strncmp(s, "// This is nQuake's Frogbot config", 33))
|
||||
s = "echo Refusing to exec nQuake's Frogbot config"; //otherwise many people with nquake installed will be fucked over whenever they try playing singleplayer
|
||||
else if (!strncmp(s, "// ", 3))
|
||||
{
|
||||
char *eol = strstr(s, "\n");
|
||||
if (eol)
|
||||
{
|
||||
*eol = 0;
|
||||
s = eol+1;
|
||||
if (strstr(f, "nQuake"))
|
||||
{ //this is evil, but if we're running quake then com_parseutf8 will be 0 and we can just convert to quake chars.
|
||||
char *in = s;
|
||||
char *out = s;
|
||||
int foundone = 0;
|
||||
while (*in)
|
||||
{
|
||||
if (*in == '^')
|
||||
{
|
||||
*out++ = 0x80|*++in;
|
||||
foundone++;
|
||||
}
|
||||
else
|
||||
*out++ = *in;
|
||||
in++;
|
||||
}
|
||||
if (foundone)
|
||||
Cbuf_InsertText(va("echo fixups for nquake config %s: %i replacements\n", buf, foundone), level, false);
|
||||
}
|
||||
}
|
||||
s = "echo Refusing to exec nQuake's Frogbot config"; //otherwise many people with nquake installed will be fucked over whenever they try playing singleplayer
|
||||
Cbuf_InsertText (s, level, true);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
int foundone = 0;
|
||||
while (!strncmp(s, "//", 2))
|
||||
{
|
||||
char *eol = strstr(s, "\n");
|
||||
if (eol)
|
||||
{
|
||||
*eol++ = 0;
|
||||
if (strstr(s, "nQuake") || strstr(s, "N Q U A K E"))
|
||||
{ //this is evil, but if we're running quake then com_parseutf8 will be 0 and we can just convert to quake chars (less text).
|
||||
char *out = s = eol;
|
||||
const char *in = s;
|
||||
while (*in)
|
||||
{
|
||||
if (*in == '\n' && !strncmp(in,"\nexec configs/config.cfg", 24))
|
||||
{ //ezquake writes its configs elsewhere, and nquake stomps on everything in its autoexec.cfg, so we need to try to work around its breakages
|
||||
memmove(out, in, 6);out+=6;in+=6;
|
||||
in += 8;
|
||||
foundone++;
|
||||
continue;
|
||||
}
|
||||
if (*in == '^')
|
||||
{
|
||||
*out++ = 0x80|*++in;
|
||||
foundone++;
|
||||
}
|
||||
else
|
||||
*out++ = *in;
|
||||
in++;
|
||||
}
|
||||
*out = 0;
|
||||
break;
|
||||
}
|
||||
s = eol;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
Cbuf_InsertText (s, level, true);
|
||||
if (foundone)
|
||||
Cbuf_InsertText(va("\necho \""CON_ERROR"fixups for nquake config %s: %i replacements\"\n", buf, foundone), level, false);
|
||||
}
|
||||
#else
|
||||
Cbuf_InsertText (s, level, true);
|
||||
#endif
|
||||
if (cvar_watched)
|
||||
Cbuf_InsertText (va("echo BEGIN %s", buf), level, true);
|
||||
BZ_Free(f);
|
||||
|
|
|
@ -23,6 +23,7 @@ cvar_t r_lerpmuzzlehack = CVARF ("r_lerpmuzzlehack", "1", CVAR_ARCHIVE);
|
|||
#ifdef MD1MODELS
|
||||
cvar_t mod_h2holey_bugged = CVARD ("mod_h2holey_bugged", "0", "Hexen2's holey-model flag uses index 0 as transparent (and additionally 255 in gl, due to a bug). GLQuake engines tend to have bugs that use ONLY index 255, resulting in a significant compatibility issue that can be resolved only with this shitty cvar hack.");
|
||||
cvar_t mod_halftexel = CVARD ("mod_halftexel", "1", "Offset texture coords by a half-texel, for compatibility with glquake and the majority of engine forks.");
|
||||
cvar_t mod_nomipmap = CVARD ("mod_nomipmap", "0", "Disables the use of mipmaps on quake1 mdls, consistent with its original software renderer.");
|
||||
#endif
|
||||
static void QDECL r_meshpitch_callback(cvar_t *var, char *oldvalue)
|
||||
{
|
||||
|
@ -3150,6 +3151,8 @@ void Mod_LoadAliasShaders(model_t *mod)
|
|||
if (!ruleset_allow_sensitive_texture_replacements.ival)
|
||||
imageflags |= IF_NOREPLACE;
|
||||
}
|
||||
if (mod->fromgame == fg_quake && mod_nomipmap.ival)
|
||||
imageflags |= IF_NOMIPMAP;
|
||||
|
||||
slash = COM_SkipPath(mod->name);
|
||||
if (slash != mod->name && slash-mod->name < sizeof(alttexpath))
|
||||
|
|
|
@ -24,8 +24,94 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
cvar_group_t *cvar_groups;
|
||||
|
||||
hashtable_t cvar_hash;
|
||||
bucket_t *cvar_buckets[1024];
|
||||
//static bucket_t *cvar_buckets[1024];
|
||||
//static hashtable_t cvar_hash;
|
||||
|
||||
typedef struct {
|
||||
size_t maxentries;
|
||||
size_t numentries;
|
||||
struct
|
||||
{
|
||||
const char *string;
|
||||
void *data;
|
||||
} entry[1];
|
||||
} abucket_t;
|
||||
typedef struct {
|
||||
abucket_t **bucket;
|
||||
unsigned int numbuckets;
|
||||
} ahashtable_t; //not thread-safe
|
||||
|
||||
static abucket_t *cvar_buckets[1024];
|
||||
static ahashtable_t cvar_hash = {cvar_buckets, countof(cvar_buckets)};
|
||||
|
||||
unsigned int Hash_KeyInsensitive(const char *name, unsigned int modulus);
|
||||
void *AHash_GetInsensitive(ahashtable_t *table, const char *name)
|
||||
{
|
||||
abucket_t *b = table->bucket[Hash_KeyInsensitive(name, table->numbuckets)];
|
||||
size_t i;
|
||||
if (b)
|
||||
for (i = 0; i < b->numentries; i++)
|
||||
{
|
||||
if (!strcasecmp(b->entry[i].string, name))
|
||||
return b->entry[i].data;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void AHash_RemoveDataInsensitive(ahashtable_t *table, const char *name, void *data)
|
||||
{
|
||||
abucket_t *b = table->bucket[Hash_KeyInsensitive(name, table->numbuckets)];
|
||||
size_t i;
|
||||
for (i = 0; i < b->numentries; i++)
|
||||
{
|
||||
if (b->entry[i].data == data && !strcasecmp(b->entry[i].string, name))
|
||||
{
|
||||
//strip it.
|
||||
b->numentries--;
|
||||
//shift everything down.
|
||||
if (b->numentries > i)
|
||||
memmove(&b->entry[i], &b->entry[i+1], b->numentries-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void AHash_AddInsensitive(ahashtable_t *table, const char *name, void *data)
|
||||
{
|
||||
unsigned int idx = Hash_KeyInsensitive(name, table->numbuckets);
|
||||
abucket_t *b = table->bucket[idx];
|
||||
if (!b)
|
||||
{ //nothing there!...
|
||||
b = table->bucket[idx] = BZ_Malloc(sizeof(*b));
|
||||
b->numentries = 0;
|
||||
b->maxentries = countof(b->entry);
|
||||
}
|
||||
else if (b->numentries == b->maxentries)
|
||||
{ //can't add anything new
|
||||
size_t n = b->maxentries*2;
|
||||
table->bucket[idx] = BZ_Malloc(sizeof(*b)-sizeof(b->entry) + sizeof(b->entry)*n);
|
||||
memcpy(table->bucket[idx]->entry, b->entry, sizeof(b->entry[0])*b->numentries);
|
||||
table->bucket[idx]->numentries = b->numentries;
|
||||
table->bucket[idx]->maxentries = n;
|
||||
BZ_Free(b);
|
||||
b = table->bucket[idx];
|
||||
}
|
||||
b->entry[b->numentries].data = data;
|
||||
b->entry[b->numentries].string = name;
|
||||
b->numentries++;
|
||||
}
|
||||
void AHash_Cleanup(ahashtable_t *table)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < table->numbuckets; i++)
|
||||
{
|
||||
if (table->bucket[i] && !table->bucket[i]->numentries)
|
||||
{
|
||||
BZ_Free(table->bucket[i]);
|
||||
table->bucket[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int cvar_watched;
|
||||
|
||||
//cvar_t *cvar_vars;
|
||||
|
@ -69,7 +155,7 @@ Cvar_FindVar
|
|||
*/
|
||||
cvar_t *Cvar_FindVar (const char *var_name)
|
||||
{
|
||||
return Hash_GetInsensitive(&cvar_hash, var_name);
|
||||
return AHash_GetInsensitive(&cvar_hash, var_name);
|
||||
/*
|
||||
cvar_group_t *grp;
|
||||
cvar_t *var;
|
||||
|
@ -1126,9 +1212,9 @@ unlinked:
|
|||
Cvar_DefaultFree(tbf->defaultstr);
|
||||
if (tbf->latched_string)
|
||||
Z_Free(tbf->latched_string);
|
||||
Hash_RemoveData(&cvar_hash, tbf->name, tbf);
|
||||
AHash_RemoveDataInsensitive(&cvar_hash, tbf->name, tbf);
|
||||
if (tbf->name2)
|
||||
Hash_RemoveData(&cvar_hash, tbf->name2, tbf);
|
||||
AHash_RemoveDataInsensitive(&cvar_hash, tbf->name2, tbf);
|
||||
Z_Free(tbf);
|
||||
}
|
||||
|
||||
|
@ -1190,9 +1276,9 @@ qboolean Cvar_Register (cvar_t *variable, const char *groupname)
|
|||
|
||||
Cvar_Free(old);
|
||||
|
||||
Hash_AddInsensitive(&cvar_hash, variable->name, variable, &variable->hbn1);
|
||||
AHash_AddInsensitive(&cvar_hash, variable->name, variable);
|
||||
if (variable->name2)
|
||||
Hash_AddInsensitive(&cvar_hash, variable->name2, variable, &variable->hbn2);
|
||||
AHash_AddInsensitive(&cvar_hash, variable->name2, variable);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1220,9 +1306,9 @@ qboolean Cvar_Register (cvar_t *variable, const char *groupname)
|
|||
variable->restriction = 0; //exe registered vars
|
||||
group->cvars = variable;
|
||||
|
||||
Hash_AddInsensitive(&cvar_hash, variable->name, variable, &variable->hbn1);
|
||||
AHash_AddInsensitive(&cvar_hash, variable->name, variable);
|
||||
if (variable->name2)
|
||||
Hash_AddInsensitive(&cvar_hash, variable->name2, variable, &variable->hbn2);
|
||||
AHash_AddInsensitive(&cvar_hash, variable->name2, variable);
|
||||
|
||||
variable->string = NULL;
|
||||
|
||||
|
@ -1588,7 +1674,7 @@ void QDECL Cvar_Limiter_ZeroToOne_Callback(struct cvar_s *var, char *oldvalue)
|
|||
void Cvar_Init(void)
|
||||
{
|
||||
memset(cvar_buckets, 0, sizeof(cvar_buckets));
|
||||
Hash_InitTable(&cvar_hash, sizeof(cvar_buckets)/Hash_BytesForBuckets(1), cvar_buckets);
|
||||
//Hash_InitTable(&cvar_hash, sizeof(cvar_buckets)/Hash_BytesForBuckets(1), cvar_buckets);
|
||||
}
|
||||
|
||||
void Cvar_Shutdown(void)
|
||||
|
@ -1622,4 +1708,5 @@ void Cvar_Shutdown(void)
|
|||
cvar_groups = grp->next;
|
||||
Z_Free(grp);
|
||||
}
|
||||
AHash_Cleanup(&cvar_hash);
|
||||
}
|
||||
|
|
|
@ -82,7 +82,6 @@ typedef struct cvar_s
|
|||
#ifdef HLSERVER
|
||||
struct hlcvar_s *hlcvar;
|
||||
#endif
|
||||
bucket_t hbn1, hbn2;
|
||||
} cvar_t;
|
||||
|
||||
#ifdef MINIMAL
|
||||
|
|
|
@ -1584,7 +1584,7 @@ static qboolean FSZIP_ReadCentralEntry(zipfile_t *zip, qbyte *data, struct zipce
|
|||
entry->gflags = LittleU2FromPtr(data+8);
|
||||
entry->cmethod = LittleU2FromPtr(data+10);
|
||||
entry->lastmodfiletime = LittleU2FromPtr(data+12);
|
||||
entry->lastmodfiledate = LittleU2FromPtr(data+12);
|
||||
entry->lastmodfiledate = LittleU2FromPtr(data+14);
|
||||
entry->crc32 = LittleU4FromPtr(data+16);
|
||||
entry->csize = LittleU4FromPtr(data+20);
|
||||
entry->usize = LittleU4FromPtr(data+24);
|
||||
|
|
|
@ -94,7 +94,7 @@ size_t Fragment_ClipPlaneToBrush(vecV_t *points, size_t maxpoints, void *planes,
|
|||
vec3_t right, forward;
|
||||
double t;
|
||||
float *plane;
|
||||
|
||||
|
||||
// if (face[2] != 1)
|
||||
// return 0;
|
||||
|
||||
|
@ -142,7 +142,7 @@ size_t Fragment_ClipPlaneToBrush(vecV_t *points, size_t maxpoints, void *planes,
|
|||
numverts = Fragment_ClipPolyToPlane((float*)verts, (float*)verts2, numverts, norm, -plane[3]);
|
||||
else
|
||||
numverts = Fragment_ClipPolyToPlane((float*)verts2, (float*)verts, numverts, norm, -plane[3]);
|
||||
|
||||
|
||||
if (numverts < 3) //totally clipped.
|
||||
return 0;
|
||||
}
|
||||
|
@ -621,7 +621,8 @@ void Mod_ClipDecal(struct model_s *mod, vec3_t center, vec3_t normal, vec3_t tan
|
|||
|
||||
if (!mod || mod->loadstate != MLS_LOADED)
|
||||
return;
|
||||
|
||||
else if (mod->type != mod_brush)
|
||||
;
|
||||
#ifdef Q1BSPS
|
||||
else if (mod->fromgame == fg_quake || mod->fromgame == fg_halflife)
|
||||
Q1BSP_ClipDecalToNodes(mod, &dec, mod->rootnode);
|
||||
|
@ -1498,7 +1499,7 @@ void Q1BSP_LoadBrushes(model_t *model, bspx_header_t *bspx, void *mod_base)
|
|||
brush->planes[brush->numplanes].dist = -perbrush->mins[pl];
|
||||
brush->numplanes++;
|
||||
}
|
||||
|
||||
|
||||
/*link it in to the bsp tree*/
|
||||
Q1BSP_InsertBrush(rootnode, brush, perbrush->mins, perbrush->maxs);
|
||||
|
||||
|
@ -1807,7 +1808,7 @@ static qbyte *Q1BSP_ClusterPVS (model_t *model, int cluster, pvsbuffer_t *buffer
|
|||
static void SV_Q1BSP_AddToFatPVS (model_t *mod, const vec3_t org, mnode_t *node, pvsbuffer_t *pvsbuffer)
|
||||
{
|
||||
mplane_t *plane;
|
||||
float d;
|
||||
float d;
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
@ -2760,7 +2761,7 @@ void Mod_FindCubemaps_f(void)
|
|||
size_t nenvmap = 0;
|
||||
unsigned int *envmapidx = NULL; //*numsurfaces
|
||||
size_t nenvmapidx = 0, i;
|
||||
|
||||
|
||||
//find targetnames, and store their origins so that we can deal with spotlights.
|
||||
for (lmp = entlump; ;)
|
||||
{
|
||||
|
@ -2808,7 +2809,7 @@ void Mod_FindCubemaps_f(void)
|
|||
else if (!strcmp("size", key))
|
||||
sscanf(value, "%f", &size);
|
||||
}
|
||||
|
||||
|
||||
if (isenvmap)
|
||||
{
|
||||
int e = nenvmap;
|
||||
|
|
|
@ -218,6 +218,16 @@ static const char *imgs[] =
|
|||
//they're provided as fallbacks.
|
||||
#define MAX_FACES 32
|
||||
|
||||
enum fontfmt_e
|
||||
{
|
||||
FMT_AUTO, //freetype, or quake
|
||||
FMT_QUAKE, //first is default
|
||||
FMT_ISO88591, //latin-1 (first 256 chars of unicode too, c1 glyphs are usually invisible)
|
||||
FMT_WINDOWS1252,//variation of latin-1 with extra glyphs
|
||||
FMT_KOI8U, //image is 16*16 koi8-u codepage.
|
||||
FMT_HORIZONTAL, //unicode, charcount=width/(height-2). single strip of chars, like halflife.
|
||||
};
|
||||
|
||||
typedef struct fontface_s
|
||||
{
|
||||
struct fontface_s *fnext;
|
||||
|
@ -228,8 +238,11 @@ typedef struct fontface_s
|
|||
struct
|
||||
{
|
||||
qbyte *data;
|
||||
size_t width;
|
||||
size_t height;
|
||||
size_t rows; //urgh.
|
||||
size_t stride;
|
||||
size_t charheight;
|
||||
enum fontfmt_e codepage;
|
||||
qboolean paletted;
|
||||
} horiz;
|
||||
|
||||
#ifdef HALFLIFEMODELS
|
||||
|
@ -997,6 +1010,164 @@ static struct charcache_s *Font_LoadPlaceholderGlyph(font_t *f, CHARIDXTYPE char
|
|||
return c;
|
||||
}
|
||||
|
||||
static struct charcache_s *Font_TryLoadGlyphRaster(font_t *f, fontface_t *qface, CHARIDXTYPE charidx)
|
||||
{
|
||||
size_t maxchar = 256;
|
||||
const unsigned short *c1tab;
|
||||
size_t c1tabsize;
|
||||
size_t glyph = charidx;
|
||||
|
||||
safeswitch(qface->horiz.codepage)
|
||||
{
|
||||
safedefault:
|
||||
case FMT_AUTO: //shouldn't happen.
|
||||
case FMT_ISO88591: //all identity.
|
||||
case FMT_HORIZONTAL: //erk...
|
||||
c1tab = NULL;
|
||||
c1tabsize = 0;
|
||||
break;
|
||||
case FMT_WINDOWS1252:
|
||||
{
|
||||
static const unsigned short win1252[] = {
|
||||
0x20ac, 0x81,0x201a,0x0192, 0x201e,0x2026,0x2020,0x2021, 0x02c6,0x2030,0x0160,0x2039, 0x0152, 0x8d,0x017d, 0x8f,
|
||||
0x90,0x2018,0x2019,0x101c, 0x201d,0x2022,0x2013,0x2014, 0x02dc,0x2122,0x0161,0x203a, 0x0153, 0x9d,0x017e,0x0178};
|
||||
c1tab = win1252;
|
||||
c1tabsize = sizeof(win1252);
|
||||
}
|
||||
break;
|
||||
case FMT_KOI8U:
|
||||
{
|
||||
static const unsigned short koi8u[] = {
|
||||
0x2500,0x2502,0x250C,0x2510, 0x2514,0x2518,0x251C,0x2524, 0x252C,0x2534,0x253C,0x2580, 0x2584,0x2588,0x258C,0x2590,
|
||||
0x2591,0x2592,0x2593,0x2320, 0x25A0,0x2219,0x221A,0x2248, 0x2264,0x2265,0x00A0,0x2321, 0x00B0,0x00B2,0x00B7,0x00F7,
|
||||
0x2550,0x2551,0x2552,0x0451, 0x0454,0x2554,0x0456,0x0457, 0x2557,0x2558,0x2559,0x255A, 0x255B,0x0491,0x255D,0x255E,
|
||||
0x255F,0x2560,0x2561,0x0401, 0x0404,0x2563,0x0406,0x0407, 0x2566,0x2567,0x2568,0x2569, 0x256A,0x0490,0x256C,0x00A9,
|
||||
0x044E,0x0430,0x0431,0x0446, 0x0434,0x0435,0x0444,0x0433, 0x0445,0x0438,0x0439,0x043A, 0x043B,0x043C,0x043D,0x043E,
|
||||
0x043F,0x044F,0x0440,0x0441, 0x0442,0x0443,0x0436,0x0432, 0x044C,0x044B,0x0437,0x0448, 0x044D,0x0449,0x0447,0x044A,
|
||||
0x042E,0x0410,0x0411,0x0426, 0x0414,0x0415,0x0424,0x0413, 0x0425,0x0418,0x0419,0x041A, 0x041B,0x041C,0x041D,0x041E,
|
||||
0x041F,0x042F,0x0420,0x0421, 0x0422,0x0423,0x0416,0x0412, 0x042C,0x042B,0x0417,0x0428, 0x042D,0x0429,0x0427,0x042A};
|
||||
c1tab = koi8u;
|
||||
c1tabsize = sizeof(koi8u);
|
||||
}
|
||||
break;
|
||||
case FMT_QUAKE:
|
||||
{
|
||||
c1tab = NULL;
|
||||
c1tabsize = 0;
|
||||
if (glyph >= 0xe000 && glyph < 0xe100)
|
||||
glyph -= 0xe000;
|
||||
else if (glyph < 32 || glyph >= 0x80)
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (glyph >= maxchar)
|
||||
return NULL;
|
||||
if (glyph >= 0x80 && glyph < 0x80+c1tabsize)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; ; i++)
|
||||
{
|
||||
if (i == c1tabsize)
|
||||
return NULL;
|
||||
if (glyph == c1tab[i])
|
||||
{
|
||||
glyph = 0x80+i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int gw = (qface->horiz.stride)/(maxchar/qface->horiz.rows);
|
||||
int gr = glyph / (maxchar/qface->horiz.rows);
|
||||
int gc = glyph - (gr*(maxchar/qface->horiz.rows));
|
||||
int gs = qface->horiz.stride;
|
||||
int gh = qface->horiz.charheight;
|
||||
struct charcache_s *c;
|
||||
if (qface->horiz.paletted)
|
||||
{
|
||||
qbyte *in = (qbyte*)qface->horiz.data + gc*gw + gr*gs*gh;
|
||||
/*while (gw >= 1)
|
||||
{
|
||||
int y;
|
||||
gw--; //see if we can strip this column
|
||||
for (y = 0; y < gh; y++)
|
||||
if (in[gw+y*gs])
|
||||
break;
|
||||
if (y < gh)
|
||||
{
|
||||
gw++;
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
{
|
||||
int ngw = (gw * f->charheight) / gh;
|
||||
int ngh = f->charheight;
|
||||
int x, y;
|
||||
unsigned int *out2 = alloca(ngw*ngh*4);
|
||||
if (ngw&&ngh)
|
||||
{
|
||||
unsigned int *out1 = alloca(gw*gh*4);
|
||||
for (y = 0; y < gh; y++)
|
||||
for (x = 0; x < gw; x++)
|
||||
out1[x+y*gw] = in[x+y*gs]?d_8to24rgbtable[in[x+y*gs]]:0;
|
||||
Image_ResampleTexture(PTI_RGBA8, out1, gw, gh, out2, ngw, ngh);
|
||||
}
|
||||
c = Font_LoadGlyphData(f, charidx, FT_PIXEL_MODE_RGBA, out2, ngw, ngh, ngw*4);
|
||||
gw = ngw;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int *in = (unsigned int*)qface->horiz.data + gc*gw + gr*gs*gh;
|
||||
while (gw >= 1)
|
||||
{
|
||||
int y;
|
||||
gw--; //see if we can strip this column
|
||||
for (y = 0; y < gh; y++)
|
||||
if (in[gw+y*gs] & 0x00ffffff)
|
||||
break;
|
||||
if (y < gh)
|
||||
{
|
||||
gw++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (f->charheight != gh)
|
||||
{
|
||||
int ngw = (gw * f->charheight) / gh;
|
||||
int ngh = f->charheight;
|
||||
int x, y;
|
||||
unsigned int *out2 = alloca(ngw*ngh*4);
|
||||
if (ngw&&ngh)
|
||||
{ //we need to repack the input, because Image_ResampleTexture can't handle strides
|
||||
unsigned int *out1 = alloca(gw*gh*4);
|
||||
for (y = 0; y < gh; y++)
|
||||
for (x = 0; x < gw; x++)
|
||||
out1[x+y*gw] = in[x+y*gs];
|
||||
Image_ResampleTexture(PTI_RGBA8, out1, gw, gh, out2, ngw, ngh);
|
||||
}
|
||||
c = Font_LoadGlyphData(f, charidx, FT_PIXEL_MODE_RGBA, out2, ngw, ngh, ngw*4);
|
||||
gw = ngw;
|
||||
}
|
||||
else
|
||||
c = Font_LoadGlyphData(f, charidx, FT_PIXEL_MODE_RGBA, in, gw, gh, gs*4);
|
||||
}
|
||||
if (!gw) //for invisble glyphs (eg: space), we attempt to ensure that there's some substance there. missing spaces is weird.
|
||||
gw = gh/3;
|
||||
if (c)
|
||||
{
|
||||
c->advance = gw;
|
||||
c->left = 0;
|
||||
c->top = 0;
|
||||
c->flags &= ~CHARF_FORCEWHITE;
|
||||
return c;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//loads the given charidx for the given font, importing from elsewhere if needed.
|
||||
static struct charcache_s *Font_TryLoadGlyph(font_t *f, CHARIDXTYPE charidx)
|
||||
{
|
||||
|
@ -1265,62 +1436,9 @@ static struct charcache_s *Font_TryLoadGlyph(font_t *f, CHARIDXTYPE charidx)
|
|||
#endif
|
||||
if (qface->horiz.data)
|
||||
{
|
||||
#if 1
|
||||
size_t maxchar = 256;
|
||||
int gw = qface->horiz.width/maxchar;
|
||||
#else
|
||||
int gw = qface->horiz.height-(qface->horiz.height/12);
|
||||
size_t maxchar = qface->horiz.width / gw;
|
||||
#endif
|
||||
size_t glyph = charidx /* - qface->horiz.firstcodepoint*/;
|
||||
if (glyph < maxchar)
|
||||
{
|
||||
unsigned int *glyphdata = (unsigned int*)qface->horiz.data + glyph*gw;
|
||||
int gh = qface->horiz.height;
|
||||
int gs = qface->horiz.width;
|
||||
unsigned int *out = glyphdata;
|
||||
while (gw >= 1)
|
||||
{
|
||||
int y;
|
||||
gw--; //see if we can strip this column
|
||||
for (y = 0; y < gh; y++)
|
||||
if (glyphdata[gw+y*gs] & 0x00ffffff)
|
||||
break;
|
||||
if (y < gh)
|
||||
{
|
||||
gw++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (f->charheight != gh)
|
||||
{
|
||||
int ngw = (gw * f->charheight) / gh;
|
||||
int ngh = f->charheight;
|
||||
int x, y;
|
||||
unsigned int *out2 = alloca(ngw*ngh*4);
|
||||
if (ngw&&ngh)
|
||||
{ //we need to repack the input, because Image_ResampleTexture can't handle strides
|
||||
unsigned int *out1 = alloca(gw*gh*4);
|
||||
for (y = 0; y < gh; y++)
|
||||
for (x = 0; x < gw; x++)
|
||||
out1[x+y*gw] = out[x+y*gs];
|
||||
Image_ResampleTexture(PTI_RGBA8, out1, gw, gh, out2, ngw, ngh);
|
||||
}
|
||||
c = Font_LoadGlyphData(f, charidx, FT_PIXEL_MODE_RGBA, out2, ngw, ngh, ngw*4);
|
||||
gw = ngw;
|
||||
}
|
||||
else
|
||||
c = Font_LoadGlyphData(f, charidx, FT_PIXEL_MODE_RGBA, out, gw, gh, gs*4);
|
||||
if (!gw) //for invisble glyphs (eg: space), we attempt to ensure that there's some substance there. missing spaces is weird.
|
||||
gw = gh/3;
|
||||
if (c)
|
||||
{
|
||||
c->advance = gw;
|
||||
c->left = 0;
|
||||
c->top = 0;
|
||||
return c;
|
||||
}
|
||||
}
|
||||
c = Font_TryLoadGlyphRaster(f, qface, charidx);
|
||||
if (c)
|
||||
return c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1447,8 +1565,11 @@ qboolean Font_LoadHorizontalFont(struct font_s *f, int fheight, const char *font
|
|||
if (qface->fnext)
|
||||
qface->fnext->flink = &qface->fnext;
|
||||
qface->horiz.data = rgbadata;
|
||||
qface->horiz.width = width;
|
||||
qface->horiz.height = height;
|
||||
qface->horiz.stride = width;
|
||||
qface->horiz.charheight = height;
|
||||
qface->horiz.rows = 1;
|
||||
qface->horiz.paletted = false;
|
||||
qface->horiz.codepage = FMT_ISO88591;
|
||||
qface->refs++;
|
||||
Q_strncpyz(qface->name, fontfilename, sizeof(qface->name));
|
||||
|
||||
|
@ -1707,28 +1828,6 @@ static texid_t Font_LoadReplacementConchars(void)
|
|||
return tex;
|
||||
return r_nulltex;
|
||||
}
|
||||
static texid_t Font_LoadQuakeConchars(void)
|
||||
{
|
||||
/*unsigned int i;
|
||||
qbyte *lump;
|
||||
lump = W_SafeGetLumpName ("conchars");
|
||||
if (lump)
|
||||
{
|
||||
// add ocrana leds
|
||||
if (con_ocranaleds.ival)
|
||||
{
|
||||
if (con_ocranaleds.ival != 2 || QCRC_Block(lump, 128*128) == 798)
|
||||
AddOcranaLEDsIndexed (lump, 128, 128);
|
||||
}
|
||||
|
||||
for (i=0 ; i<128*128 ; i++)
|
||||
if (lump[i] == 0)
|
||||
lump[i] = 255; // proper transparent color
|
||||
|
||||
return R_LoadTexture8("charset", 128, 128, (void*)lump, IF_LOADNOW|IF_UIPIC|IF_NOMIPMAP|IF_NOGAMMA, 1);
|
||||
}*/
|
||||
return r_nulltex;
|
||||
}
|
||||
|
||||
#ifdef HEXEN2
|
||||
static texid_t Font_LoadHexen2Conchars(qboolean iso88591)
|
||||
|
@ -1875,16 +1974,6 @@ static texid_t Font_LoadFallbackConchars(void)
|
|||
return tex;
|
||||
}
|
||||
|
||||
enum fontfmt_e
|
||||
{
|
||||
FMT_AUTO, //freetype, or quake
|
||||
FMT_QUAKE, //first is default
|
||||
FMT_ISO88591, //latin-1 (first 256 chars of unicode too, c1 glyphs are usually invisible)
|
||||
FMT_WINDOWS1252,//variation of latin-1 with extra glyphs
|
||||
FMT_KOI8U, //image is 16*16 koi8-u codepage.
|
||||
FMT_HORIZONTAL, //unicode, charcount=width/(height-2). single strip of chars, like halflife.
|
||||
};
|
||||
|
||||
/*loads a fallback image. not allowed to fail (use syserror if needed)*/
|
||||
static texid_t Font_LoadDefaultConchars(enum fontfmt_e *fmt)
|
||||
{
|
||||
|
@ -1892,11 +1981,6 @@ static texid_t Font_LoadDefaultConchars(enum fontfmt_e *fmt)
|
|||
tex = Font_LoadReplacementConchars();
|
||||
if (TEXLOADED(tex))
|
||||
return tex;
|
||||
tex = Font_LoadQuakeConchars();
|
||||
if (tex && tex->status == TEX_LOADING)
|
||||
COM_WorkerPartialSync(tex, &tex->status, TEX_LOADING);
|
||||
if (TEXLOADED(tex))
|
||||
return tex;
|
||||
#ifdef HEXEN2
|
||||
tex = Font_LoadHexen2Conchars(true);
|
||||
if (tex && tex->status == TEX_LOADING)
|
||||
|
@ -1959,6 +2043,54 @@ void Doom_ExpandPatch(doompatch_t *p, unsigned char *b, int stride)
|
|||
}
|
||||
}
|
||||
|
||||
static qboolean Font_LoadFontLump(font_t *f, const char *facename)
|
||||
{
|
||||
size_t lumpsize = 0;
|
||||
qbyte lumptype = 0;
|
||||
void *lumpdata;
|
||||
|
||||
if (f->faces == MAX_FACES)
|
||||
return false; //can't store it...
|
||||
lumpdata = W_GetLumpName(facename, &lumpsize, &lumptype);
|
||||
if (!lumpdata)
|
||||
return false;
|
||||
if ((lumptype == TYP_MIPTEX && lumpsize==(8*8)*(16*16)) || //proper format
|
||||
(lumptype == TYP_QPIC && lumpsize==(8*8)*(16*16)+8)) //fucked up buggy format used by some people
|
||||
{
|
||||
fontface_t *fa = Z_Malloc(sizeof(*fa));
|
||||
fa->horiz.data = lumpdata;
|
||||
fa->horiz.stride = 8*16;
|
||||
fa->horiz.charheight = 8;
|
||||
fa->horiz.codepage = FMT_QUAKE;
|
||||
fa->horiz.paletted = true;
|
||||
fa->horiz.rows = 16;
|
||||
|
||||
if (con_ocranaleds.ival)
|
||||
{
|
||||
if (con_ocranaleds.ival != 2 || QCRC_Block(lumpdata, 128*128) == 798)
|
||||
AddOcranaLEDsIndexed (lumpdata, 128, 128);
|
||||
}
|
||||
|
||||
fa->flink = &fa->fnext;
|
||||
fa->refs = 1;
|
||||
f->face[f->faces++] = fa;
|
||||
return true;
|
||||
}
|
||||
#ifdef HALFLIFEMODELS
|
||||
else if (lumptype == TYP_HLFONT)
|
||||
{
|
||||
fontface_t *fa = Z_Malloc(sizeof(*fa));
|
||||
fa->halflife = lumpdata;
|
||||
fa->flink = &fa->fnext;
|
||||
fa->refs = 1;
|
||||
f->face[f->faces++] = fa;
|
||||
// f->charheight = fa->halflife->fontheight1; //force the font to a specific size.
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false; //doesn't match a valid known format
|
||||
}
|
||||
|
||||
//creates a new font object from the given file, with each text row with the given height.
|
||||
//width is implicit and scales with height and choice of font.
|
||||
struct font_s *Font_LoadFont(const char *fontfilename, float vheight, float scale, int outline)
|
||||
|
@ -2226,9 +2358,18 @@ struct font_s *Font_LoadFont(const char *fontfilename, float vheight, float scal
|
|||
if (fmt == FMT_HORIZONTAL)
|
||||
Font_LoadHorizontalFont(f, height, start);
|
||||
#ifdef AVAIL_FREETYPE
|
||||
else if (fmt == FMT_AUTO)
|
||||
Font_LoadFreeTypeFont(f, height, start);
|
||||
else if (fmt == FMT_AUTO && Font_LoadFreeTypeFont(f, height, start))
|
||||
;
|
||||
#endif
|
||||
else if (!TEXLOADED(f->singletexture) && *start)
|
||||
{
|
||||
f->singletexture = R_LoadHiResTexture(start, "fonts:charsets", IF_PREMULTIPLYALPHA|(r_font_linear.ival?IF_LINEAR:IF_NEAREST)|IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP|IF_NOPURGE|IF_LOADNOW);
|
||||
if (f->singletexture->status == TEX_LOADING)
|
||||
COM_WorkerPartialSync(f->singletexture, &f->singletexture->status, TEX_LOADING);
|
||||
|
||||
if (!TEXLOADED(f->singletexture) && f->faces < MAX_FACES)
|
||||
Font_LoadFontLump(f, start);
|
||||
}
|
||||
|
||||
if (end)
|
||||
{
|
||||
|
@ -2240,42 +2381,8 @@ struct font_s *Font_LoadFont(const char *fontfilename, float vheight, float scal
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef HALFLIFEMODELS
|
||||
if (!f->faces)
|
||||
{
|
||||
if (f->faces < MAX_FACES)
|
||||
{
|
||||
size_t lumpsize;
|
||||
qbyte lumptype = 0;
|
||||
void *lumpdata = NULL;
|
||||
if ((!lumpdata || lumptype != TYP_HLFONT) && *fontfilename)
|
||||
lumpdata = W_GetLumpName(fontfilename, &lumpsize, &lumptype);
|
||||
if (!lumpdata || lumptype != TYP_HLFONT)
|
||||
lumpdata = W_GetLumpName("conchars", &lumpsize, &lumptype);
|
||||
if (lumpdata && lumptype == TYP_HLFONT)
|
||||
{
|
||||
fontface_t *fa = Z_Malloc(sizeof(*fa));
|
||||
fa->halflife = lumpdata;
|
||||
fa->flink = &fa->fnext;
|
||||
fa->refs = 1;
|
||||
f->face[f->faces++] = fa;
|
||||
// f->charheight = fa->halflife->fontheight1; //force the font to a specific size.
|
||||
return f;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!f->faces)
|
||||
{
|
||||
//default to only map the ascii-compatible chars from the quake font.
|
||||
if (*fontfilename)
|
||||
{
|
||||
f->singletexture = R_LoadHiResTexture(fontfilename, "fonts:charsets", IF_PREMULTIPLYALPHA|(r_font_linear.ival?IF_LINEAR:IF_NEAREST)|IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP|IF_NOPURGE);
|
||||
if (f->singletexture->status == TEX_LOADING)
|
||||
COM_WorkerPartialSync(f->singletexture, &f->singletexture->status, TEX_LOADING);
|
||||
}
|
||||
}
|
||||
if (!f->faces && !TEXLOADED(f->singletexture) && r_font_linear.ival)
|
||||
Font_LoadFontLump(f, "conchars");
|
||||
|
||||
defaultplane = INVALIDPLANE;/*assume the bitmap plane - don't use the fallback as people don't think to use com_parseutf8*/
|
||||
if (TEXLOADED(f->singletexture))
|
||||
|
|
|
@ -327,6 +327,8 @@ static qboolean Shader_EvaluateCondition(shader_t *shader, const char **ptr)
|
|||
lhs = r_deluxemapping;
|
||||
else if (!Q_stricmp(token, "softwarebanding"))
|
||||
lhs = r_softwarebanding;
|
||||
else if (!Q_stricmp(token, "unmaskedsky"))
|
||||
lhs = cls.allow_unmaskedskyboxes; //can/should skip writing depth values for sky surfaces.
|
||||
|
||||
//normalmaps are generated if they're not already known.
|
||||
else if (!Q_stricmp(token, "normalmap"))
|
||||
|
@ -1372,7 +1374,7 @@ struct programpermu_s *Shader_LoadPermutation(program_t *prog, unsigned int p)
|
|||
size_t offset;
|
||||
qboolean fail = false;
|
||||
|
||||
extern cvar_t gl_specular, gl_specular_power;
|
||||
extern cvar_t r_glsl_pbr, gl_specular, gl_specular_power;
|
||||
|
||||
if (~prog->supportedpermutations & p)
|
||||
return NULL; //o.O
|
||||
|
@ -1384,6 +1386,8 @@ struct programpermu_s *Shader_LoadPermutation(program_t *prog, unsigned int p)
|
|||
Q_strlcatfz(defines, &offset, sizeof(defines), "#define MAX_GPU_BONES %i\n", sh_config.max_gpu_bones);
|
||||
if (gl_specular.value)
|
||||
Q_strlcatfz(defines, &offset, sizeof(defines), "#define SPECULAR\n#define SPECULAR_BASE_MUL %f\n#define SPECULAR_BASE_POW %f\n", 1.0*gl_specular.value, max(1,gl_specular_power.value));
|
||||
if (r_glsl_pbr.ival)
|
||||
Q_strlcatfz(defines, &offset, sizeof(defines), "#define PBR\n");
|
||||
#ifdef RTLIGHTS
|
||||
if (r_fakeshadows)
|
||||
Q_strlcatfz(defines, &offset, sizeof(defines), "#define FAKESHADOWS\n%s",
|
||||
|
@ -1932,7 +1936,7 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
|
|||
break;
|
||||
while (*script && *script != '\n')
|
||||
script++;
|
||||
};
|
||||
}
|
||||
prog->shadertext = Z_StrDup(script);
|
||||
|
||||
if (qrenderer == qrtype && ver < 150)
|
||||
|
@ -6584,6 +6588,9 @@ char *Shader_DefaultBSPWater(parsestate_t *ps, const char *shortname, char *buff
|
|||
"{\n"
|
||||
"surfaceparm nodlight\n"
|
||||
"surfaceparm nomarks\n"
|
||||
"if %g < 1\n"
|
||||
"sort underwater\n"
|
||||
"endif\n"
|
||||
"{\n"
|
||||
"program defaultwarp%s\n"
|
||||
"map $diffuse\n"
|
||||
|
@ -6595,7 +6602,7 @@ char *Shader_DefaultBSPWater(parsestate_t *ps, const char *shortname, char *buff
|
|||
"}\n"
|
||||
"surfaceparm hasdiffuse\n"
|
||||
"}\n"
|
||||
, (explicitalpha||alpha==1)?"":va("#ALPHA=%g",alpha), alpha, alpha);
|
||||
, alpha, (explicitalpha||alpha==1)?"":va("#ALPHA=%g",alpha), alpha, alpha);
|
||||
return buffer;
|
||||
case 2: //refraction of the underwater surface, with a fresnel
|
||||
return (
|
||||
|
|
|
@ -94,12 +94,20 @@ void R_SetSky(const char *sky)
|
|||
COM_WorkerPartialSync(tex.reflectcube, &tex.reflectcube->status, TEX_LOADING);
|
||||
if (tex.reflectcube->width && TEXLOADED(tex.reflectcube))
|
||||
{
|
||||
/* FIXME: Q2/HL require the skybox to not draw over geometry, shouldn't we force it? --eukara */
|
||||
if (cls.allow_skyboxes) {
|
||||
forcedsky = R_RegisterShader(va("skybox_%s", sky), 0, "{\nsort sky\nprogram defaultskybox\n{\nmap \"$cube:$reflectcube\"\ntcgen skybox\n}\nsurfaceparm nodlight\nsurfaceparm sky\n}");
|
||||
} else {
|
||||
forcedsky = R_RegisterShader(va("skybox_%s", sky), 0, "{\nsort sky\nprogram defaultskybox\n{\ndepthwrite\nmap \"$cube:$reflectcube\"\ntcgen skybox\n}\nsurfaceparm nodlight\nsurfaceparm sky\n}");
|
||||
}
|
||||
forcedsky = R_RegisterShader(va("skybox_%s", sky), 0,
|
||||
"{\n"
|
||||
"sort sky\n"
|
||||
"program defaultskybox\n"
|
||||
"{\n"
|
||||
"if !$unmaskedsky\n" /* Q2/HL require the skybox to not draw over geometry, shouldn't we force it? --eukara */
|
||||
"depthwrite\n"
|
||||
"endif\n"
|
||||
"map \"$cube:$reflectcube\"\n"
|
||||
"tcgen skybox\n"
|
||||
"}\n"
|
||||
"surfaceparm nodlight\n"
|
||||
"surfaceparm sky\n"
|
||||
"}");
|
||||
R_BuildDefaultTexnums(&tex, forcedsky, IF_WORLDTEX);
|
||||
return;
|
||||
}
|
||||
|
@ -222,7 +230,7 @@ qboolean R_DrawSkyroom(shader_t *skyshader)
|
|||
|
||||
//q3 mustn't mask sky (breaks q3map2's invisible skyportals), whereas q1 must (or its a cheat). halflife doesn't normally expect masking.
|
||||
//we also MUST mask any sky inside skyrooms, or you'll see all the entities outside of the skyroom through the room's own sky (q3map2 skyportals are hopefully irrelevant in this case).
|
||||
#define SKYMUSTBEMASKED (r_worldentity.model->fromgame != fg_quake3 || ((r_refdef.flags & RDF_DISABLEPARTICLES) && r_ignoreentpvs.ival))
|
||||
#define SKYMUSTBEMASKED (r_worldentity.model->fromgame != fg_quake3 || ((r_refdef.flags & RDF_DISABLEPARTICLES) && r_ignoreentpvs.ival) || !cls.allow_unmaskedskyboxes)
|
||||
|
||||
/*
|
||||
=================
|
||||
|
@ -691,7 +699,7 @@ static void gl_skyspherecalc(int skytype)
|
|||
|
||||
static void GL_SkyForceDepth(batch_t *batch)
|
||||
{
|
||||
if (!cls.allow_skyboxes && batch->texture) //allow a little extra fps.
|
||||
if (!cls.allow_unmaskedskyboxes && batch->texture) //allow a little extra fps.
|
||||
{
|
||||
BE_SelectMode(BEM_DEPTHONLY);
|
||||
BE_DrawMesh_List(batch->shader, batch->meshes-batch->firstmesh, batch->mesh+batch->firstmesh, batch->vbo, NULL, batch->flags);
|
||||
|
|
|
@ -3004,7 +3004,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
|
||||
"affine varying vec2 tc;\n"
|
||||
"varying vec4 light;\n"
|
||||
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)\n"
|
||||
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)\n"
|
||||
"varying vec3 eyevector;\n"
|
||||
"#endif\n"
|
||||
"#if defined(PBR)||defined(REFLECTCUBEMASK)\n"
|
||||
|
@ -3039,9 +3039,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"#endif\n"
|
||||
"#endif\n"
|
||||
|
||||
"#if defined(PBR)\n"
|
||||
"eyevector = e_eyepos - w.xyz;\n"
|
||||
"#elif defined(SPECULAR)||defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)\n"
|
||||
"#if defined(SPECULAR)||defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)\n"
|
||||
"vec3 eyeminusvertex = e_eyepos - w.xyz;\n"
|
||||
"eyevector.x = dot(eyeminusvertex, s.xyz);\n"
|
||||
"eyevector.y = dot(eyeminusvertex, t.xyz);\n"
|
||||
|
@ -3086,7 +3084,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"affine out vec2 t_tc[];\n"
|
||||
"in vec4 light[];\n"
|
||||
"out vec4 t_light[];\n"
|
||||
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)\n"
|
||||
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)\n"
|
||||
"in vec3 eyevector[];\n"
|
||||
"out vec3 t_eyevector[];\n"
|
||||
"#endif\n"
|
||||
|
@ -3102,7 +3100,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"t_normal[id] = normal[id];\n"
|
||||
"t_tc[id] = tc[id];\n"
|
||||
"t_light[id] = light[id];\n"
|
||||
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)\n"
|
||||
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)\n"
|
||||
"t_eyevector[id] = eyevector[id];\n"
|
||||
"#endif\n"
|
||||
"#ifdef REFLECTCUBEMASK\n"
|
||||
|
@ -3135,7 +3133,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"affine out vec2 tc;\n"
|
||||
"in vec4 t_light[];\n"
|
||||
"out vec4 light;\n"
|
||||
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)\n"
|
||||
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)\n"
|
||||
"in vec3 t_eyevector[];\n"
|
||||
"out vec3 eyevector;\n"
|
||||
"#endif\n"
|
||||
|
@ -3158,7 +3156,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
|
||||
//FIXME: we should be recalcing these here, instead of just lerping them
|
||||
"light = LERP(t_light);\n"
|
||||
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)\n"
|
||||
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)\n"
|
||||
"eyevector = LERP(t_eyevector);\n"
|
||||
"#endif\n"
|
||||
"#ifdef REFLECTCUBEMASK\n"
|
||||
|
@ -3198,7 +3196,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
|
||||
"affine varying vec2 tc;\n"
|
||||
"varying vec4 light;\n"
|
||||
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)\n"
|
||||
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)\n"
|
||||
"varying vec3 eyevector;\n"
|
||||
"#endif\n"
|
||||
"#if defined(PBR) || defined(REFLECTCUBEMASK)\n"
|
||||
|
@ -3292,7 +3290,8 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"#endif\n"
|
||||
"#else\n"
|
||||
"#define roughness 0.3\n"
|
||||
"#define specrgb 1.0 //vec3(dielectricSpecular)\n"
|
||||
"#define specrgb vec3(1.0) //vec3(dielectricSpecular)\n"
|
||||
"#define ambientrgb col.rgb\n"
|
||||
"#endif\n"
|
||||
|
||||
"#ifdef BUMP\n"
|
||||
|
@ -5668,7 +5667,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"#include \"sys/fog.h\"\n"
|
||||
|
||||
"#if !defined(TESS_CONTROL_SHADER)\n"
|
||||
"#if defined(OFFSETMAPPING) || defined(SPECULAR) || defined(REFLECTCUBEMASK)\n"
|
||||
"#if defined(OFFSETMAPPING) || defined(SPECULAR) || defined(REFLECTCUBEMASK) || defined(PBR)\n"
|
||||
"varying vec3 eyevector;\n"
|
||||
"#endif\n"
|
||||
|
||||
|
@ -5700,7 +5699,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"#endif\n"
|
||||
"void main ()\n"
|
||||
"{\n"
|
||||
"#if defined(OFFSETMAPPING) || defined(SPECULAR) || defined(REFLECTCUBEMASK)\n"
|
||||
"#if defined(OFFSETMAPPING) || defined(SPECULAR) || defined(REFLECTCUBEMASK) || defined(PBR)\n"
|
||||
"vec3 eyeminusvertex = e_eyepos - v_position.xyz;\n"
|
||||
"eyevector.x = dot(eyeminusvertex, v_svector.xyz);\n"
|
||||
"eyevector.y = dot(eyeminusvertex, v_tvector.xyz);\n"
|
||||
|
@ -5751,7 +5750,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"out vec3 t_vertex[];\n"
|
||||
"in vec3 normal[];\n"
|
||||
"out vec3 t_normal[];\n"
|
||||
"#if defined(OFFSETMAPPING) || defined(SPECULAR) || defined(REFLECTCUBEMASK)\n"
|
||||
"#if defined(OFFSETMAPPING) || defined(SPECULAR) || defined(REFLECTCUBEMASK) || defined(PBR)\n"
|
||||
"in vec3 eyevector[];\n"
|
||||
"out vec3 t_eyevector[];\n"
|
||||
"#endif\n"
|
||||
|
@ -5793,7 +5792,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"#endif\n"
|
||||
"#endif\n"
|
||||
|
||||
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)\n"
|
||||
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)\n"
|
||||
"t_eyevector[id] = eyevector[id];\n"
|
||||
"#endif\n"
|
||||
|
||||
|
@ -5817,7 +5816,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
|
||||
"in vec3 t_vertex[];\n"
|
||||
"in vec3 t_normal[];\n"
|
||||
"#if defined(OFFSETMAPPING) || defined(SPECULAR) || defined(REFLECTCUBEMASK)\n"
|
||||
"#if defined(OFFSETMAPPING) || defined(SPECULAR) || defined(REFLECTCUBEMASK) || defined(PBR)\n"
|
||||
"in vec3 t_eyevector[];\n"
|
||||
"#endif\n"
|
||||
"#ifdef REFLECTCUBEMASK\n"
|
||||
|
@ -5867,7 +5866,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"#ifdef REFLECTCUBEMASK\n"
|
||||
"invsurface = LERP(t_invsurface);\n"
|
||||
"#endif\n"
|
||||
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)\n"
|
||||
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)\n"
|
||||
"eyevector = LERP(t_eyevector);\n"
|
||||
"#endif\n"
|
||||
|
||||
|
@ -5973,27 +5972,47 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"#define gloss (1.0-roughness)\n"
|
||||
"#define ambientrgb (specrgb+col.rgb)\n"
|
||||
"vec3 specrgb = mix(vec3(dielectricSpecular), col.rgb, metalness);\n"
|
||||
"col.rgb = col.rgb * (1.0 - dielectricSpecular) * (1.0-metalness);\n"
|
||||
"vec3 albedorgb = col.rgb * (1.0 - dielectricSpecular) * (1.0-metalness);\n"
|
||||
"#elif defined(SG) //pbr-style specular+glossiness\n"
|
||||
//occlusion needs to be baked in. :(
|
||||
"#define roughness (1.0-specs.a)\n"
|
||||
"#define gloss specs.a\n"
|
||||
"#define specrgb specs.rgb\n"
|
||||
"#define ambientrgb (specs.rgb+col.rgb)\n"
|
||||
"#else //blinn-phong\n"
|
||||
"#define roughness (1.0-specs.a)\n"
|
||||
"#define albedorgb col.rgb\n"
|
||||
"#elif defined(PBR) //PBR using legacy texturemaps\n"
|
||||
"#define gloss specs.a\n"
|
||||
"#define specrgb specs.rgb\n"
|
||||
"#define roughness (1.0-gloss)\n"
|
||||
//metalness not relevant
|
||||
|
||||
//our pbr stuff doesn't much like our inputs.
|
||||
"vec3 specrgb, albedorgb;\n"
|
||||
//if (1==0)
|
||||
//{ //metal
|
||||
// specrgb = col.rgb;//+specs.rgb;
|
||||
// albedorgb = vec3(0.0);
|
||||
//}
|
||||
//else
|
||||
//{ //non-metal
|
||||
"specrgb = vec3(dielectricSpecular);\n"
|
||||
"albedorgb = col.rgb;//+specs.rgb;\n"
|
||||
//}
|
||||
"#define ambientrgb col.rgb\n"
|
||||
"#else //blinn-phong\n"
|
||||
"#define gloss specs.a\n"
|
||||
//occlusion not defined
|
||||
"#define specrgb specs.rgb\n"
|
||||
"#endif\n"
|
||||
"#else\n"
|
||||
//no specular map specified. doesn't mean we shouldn't have any though, at least with pbr enabled.
|
||||
"#define roughness 0.3\n"
|
||||
"#define specrgb 1.0 //vec3(dielectricSpecular)\n"
|
||||
"#define albedorgb col.rgb\n"
|
||||
"#endif\n"
|
||||
|
||||
//add in specular, if applicable.
|
||||
"#ifdef PBR\n"
|
||||
"col.rgb = DoPBR(norm, normalize(eyevector), deluxe, roughness, col.rgb, specrgb, vec3(0.0,1.0,1.0));//*e_light_mul + e_light_ambient*.25*ambientrgb;\n"
|
||||
"col.rgb = DoPBR(norm, normalize(eyevector), deluxe, roughness, albedorgb, specrgb, vec3(0.0,1.0,1.0));//*e_light_mul + e_light_ambient*.25*ambientrgb;\n"
|
||||
"#elif defined(gloss)\n"
|
||||
"vec3 halfdir = normalize(normalize(eyevector) + deluxe); //this norm should be the deluxemap info instead\n"
|
||||
"float spec = pow(max(dot(halfdir, norm), 0.0), FTE_SPECULAR_EXPONENT * gloss);\n"
|
||||
|
@ -11124,7 +11143,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"#if defined(VERTEXCOLOURS)\n"
|
||||
"varying vec4 vc;\n"
|
||||
"#endif\n"
|
||||
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)\n"
|
||||
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)\n"
|
||||
"varying vec3 eyevector;\n"
|
||||
"#endif\n"
|
||||
"#ifdef REFLECTCUBEMASK\n"
|
||||
|
@ -11169,7 +11188,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"#if defined(VERTEXCOLOURS)\n"
|
||||
"vc = v_colour;\n"
|
||||
"#endif\n"
|
||||
"#if defined(SPECULAR)||defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)\n"
|
||||
"#if defined(SPECULAR)||defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)\n"
|
||||
"vec3 eyeminusvertex = e_eyepos - w.xyz;\n"
|
||||
"eyevector.x = dot(eyeminusvertex, s.xyz);\n"
|
||||
"eyevector.y = dot(eyeminusvertex, t.xyz);\n"
|
||||
|
@ -11210,7 +11229,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"in vec4 vc[];\n"
|
||||
"out vec4 t_vc[];\n"
|
||||
"#endif\n"
|
||||
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)\n"
|
||||
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)\n"
|
||||
"in vec3 eyevector[];\n"
|
||||
"out vec3 t_eyevector[];\n"
|
||||
"#endif\n"
|
||||
|
@ -11225,7 +11244,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"#if defined(VERTEXCOLOURS)\n"
|
||||
"t_vc[id] = vc[id];\n"
|
||||
"#endif\n"
|
||||
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)\n"
|
||||
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)\n"
|
||||
"t_eyevector[id] = eyevector[id];\n"
|
||||
"#endif\n"
|
||||
|
||||
|
@ -11254,7 +11273,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"#if defined(VERTEXCOLOURS)\n"
|
||||
"in vec4 t_vc[];\n"
|
||||
"#endif\n"
|
||||
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)\n"
|
||||
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)\n"
|
||||
"in vec3 t_eyevector[];\n"
|
||||
"#endif\n"
|
||||
|
||||
|
@ -11280,7 +11299,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"#if defined(VERTEXCOLOURS)\n"
|
||||
"vc = LERP(t_vc);\n"
|
||||
"#endif\n"
|
||||
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)\n"
|
||||
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)\n"
|
||||
"eyevector = LERP(t_eyevector);\n"
|
||||
"#endif\n"
|
||||
|
||||
|
@ -11347,7 +11366,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"vec4 lc = texture2D(s_lower, tcbase);\n"
|
||||
"bases.rgb += lc.rgb*e_lowercolour*lc.a;\n"
|
||||
"#endif\n"
|
||||
"#if defined(BUMP) || defined(SPECULAR) || defined(REFLECTCUBEMASK)\n"
|
||||
"#if defined(BUMP) || defined(SPECULAR) || defined(REFLECTCUBEMASK) || defined(PBR)\n"
|
||||
"vec3 bumps = normalize(vec3(texture2D(s_normalmap, tcbase)) - 0.5);\n"
|
||||
"#elif defined(REFLECTCUBEMASK)\n"
|
||||
"vec3 bumps = vec3(0.0,0.0,1.0);\n"
|
||||
|
@ -11380,7 +11399,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"#endif\n"
|
||||
"#else\n"
|
||||
"#define roughness 0.3\n"
|
||||
"#define specrgb 1.0 //vec3(dielectricSpecular)\n"
|
||||
"#define specrgb bases.rgb //vec3(dielectricSpecular)\n"
|
||||
"#endif\n"
|
||||
|
||||
"#ifdef PBR\n"
|
||||
|
|
|
@ -49,37 +49,15 @@ pbool QC_strlcpy(char *dest, const char *src, size_t destsize) WARN_UNUSED_RESUL
|
|||
pbool QC_strnlcpy(char *dest, const char *src, size_t srclen, size_t destsize) WARN_UNUSED_RESULT;
|
||||
char *QC_strcasestr(const char *haystack, const char *needle);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define QC_vsnprintf _vsnprintf
|
||||
static void VARGS QC_snprintfz (char *dest, size_t size, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start (args, fmt);
|
||||
_vsnprintf (dest, size-1, fmt, args);
|
||||
va_end (args);
|
||||
//make sure its terminated.
|
||||
dest[size-1] = 0;
|
||||
}
|
||||
#else
|
||||
#define QC_vsnprintf vsnprintf
|
||||
#define QC_snprintfz snprintf
|
||||
#endif
|
||||
|
||||
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
|
||||
#ifndef LIKEPRINTF
|
||||
#define LIKEPRINTF(x) __attribute__((format(printf,x,x+1)))
|
||||
#endif
|
||||
#endif
|
||||
#ifndef LIKEPRINTF
|
||||
#define LIKEPRINTF(x)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
|
||||
#define FTE_DEPRECATED __attribute__((__deprecated__)) //no idea about the actual gcc version
|
||||
#ifdef _WIN32
|
||||
#define LIKEPRINTF(x) __attribute__((format(ms_printf,x,x+1)))
|
||||
#if defined(_WIN32)
|
||||
#include <stdio.h>
|
||||
#ifdef __MINGW_PRINTF_FORMAT
|
||||
#define LIKEPRINTF(x) __attribute__((format(__MINGW_PRINTF_FORMAT,x,x+1)))
|
||||
#else
|
||||
#define LIKEPRINTF(x) __attribute__((format(ms_printf,x,x+1)))
|
||||
#endif
|
||||
#else
|
||||
#define LIKEPRINTF(x) __attribute__((format(printf,x,x+1)))
|
||||
#endif
|
||||
|
@ -90,6 +68,25 @@ static void VARGS QC_snprintfz (char *dest, size_t size, const char *fmt, ...)
|
|||
#ifndef NORETURN
|
||||
#define NORETURN
|
||||
#endif
|
||||
#ifndef LIKEPRINTF
|
||||
#define LIKEPRINTF(x)
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define QC_vsnprintf _vsnprintf
|
||||
static void VARGS QC_snprintfz (char *dest, size_t size, const char *fmt, ...) LIKEPRINTF(3)
|
||||
{
|
||||
va_list args;
|
||||
va_start (args, fmt);
|
||||
_vsnprintf (dest, size-1, fmt, args);
|
||||
va_end (args);
|
||||
//make sure its terminated.
|
||||
dest[size-1] = 0;
|
||||
}
|
||||
#else
|
||||
#define QC_vsnprintf vsnprintf
|
||||
#define QC_snprintfz snprintf
|
||||
#endif
|
||||
|
||||
double I_FloatTime (void);
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ unsigned int Hash_Key(const char *name, unsigned int modulus)
|
|||
|
||||
return (key%modulus);
|
||||
}
|
||||
static unsigned int Hash_KeyInsensitive(const char *name, unsigned int modulus)
|
||||
unsigned int Hash_KeyInsensitive(const char *name, unsigned int modulus)
|
||||
{ //fixme: optimize.
|
||||
unsigned int key;
|
||||
for (key=0;*name; name++)
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
#include "qcc.h"
|
||||
#if !defined(MINIMAL) && !defined(OMIT_QCC)
|
||||
#include <time.h>
|
||||
#ifndef _WIN32
|
||||
#ifdef _WIN32
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
void QCC_Canonicalize(char *fullname, size_t fullnamesize, const char *newfile, const char *base);
|
||||
|
||||
|
@ -79,6 +84,7 @@ struct pkgctx_s
|
|||
struct oldpack_s *next;
|
||||
char filename[128];
|
||||
size_t numfiles;
|
||||
unsigned int part;
|
||||
struct
|
||||
{
|
||||
char name[128];
|
||||
|
@ -194,7 +200,7 @@ static struct class_s *PKG_FindClass(struct pkgctx_s *ctx, char *code)
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
static struct dataset_s *PKG_FindDataset(struct pkgctx_s *ctx, char *code)
|
||||
static struct dataset_s *PKG_FindDataset(struct pkgctx_s *ctx, const char *code)
|
||||
{
|
||||
struct dataset_s *o;
|
||||
for (o = ctx->datasets; o; o = o->next)
|
||||
|
@ -204,7 +210,7 @@ static struct dataset_s *PKG_FindDataset(struct pkgctx_s *ctx, char *code)
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
static struct dataset_s *PKG_GetDataset(struct pkgctx_s *ctx, char *code)
|
||||
static struct dataset_s *PKG_GetDataset(struct pkgctx_s *ctx, const char *code)
|
||||
{
|
||||
struct dataset_s *s = PKG_FindDataset(ctx, code);
|
||||
if (!s)
|
||||
|
@ -373,6 +379,37 @@ static void PKG_CreateOutput(struct pkgctx_s *ctx, struct dataset_s *s, const ch
|
|||
QCC_Canonicalize(o->filename, sizeof(o->filename), path, ctx->gamepath);
|
||||
o->next = s->outputs;
|
||||
s->outputs = o;
|
||||
|
||||
|
||||
if (diff)
|
||||
{
|
||||
char *end = path + strlen(path)-2;
|
||||
unsigned int i;
|
||||
for (i = 0; i <= 99; i++)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
struct _stat statbuf;
|
||||
#else
|
||||
struct stat statbuf;
|
||||
#endif
|
||||
sprintf(end, "%02u", i+1);
|
||||
#ifdef _WIN32
|
||||
//FIXME: use the utf16 version because microsoft suck and don't allow utf-8
|
||||
if (_stat(path, &statbuf) == 0)
|
||||
#else
|
||||
if (stat(path, &statbuf) == 0)
|
||||
#endif
|
||||
{
|
||||
struct oldpack_s *span = malloc(sizeof(*span));
|
||||
strcpy(span->filename, path);
|
||||
span->numfiles = 0;
|
||||
span->file = NULL;
|
||||
span->next = o->oldparts;
|
||||
span->part = i;
|
||||
o->oldparts = span;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void PKG_ParseOutput(struct pkgctx_s *ctx, pbool diff)
|
||||
|
@ -440,6 +477,7 @@ static void PKG_AddOldPack(struct pkgctx_s *ctx, const char *fname)
|
|||
ctx->oldpacks = pack;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void PKG_ParseOldPack(struct pkgctx_s *ctx)
|
||||
{
|
||||
char token[MAX_OSPATH];
|
||||
|
@ -596,7 +634,6 @@ static void PKG_ParseRule(struct pkgctx_s *ctx)
|
|||
r->next = ctx->rules;
|
||||
ctx->rules = r;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
static void PKG_AddClassFile(struct pkgctx_s *ctx, struct class_s *c, const char *fname, time_t mtime)
|
||||
{
|
||||
struct file_s *f;
|
||||
|
@ -618,7 +655,6 @@ static void PKG_AddClassFile(struct pkgctx_s *ctx, struct class_s *c, const char
|
|||
f->next = c->files;
|
||||
c->files = f;
|
||||
}
|
||||
#endif
|
||||
static void PKG_AddClassFiles(struct pkgctx_s *ctx, struct class_s *c, const char *fname)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
@ -638,7 +674,45 @@ static void PKG_AddClassFiles(struct pkgctx_s *ctx, struct class_s *c, const cha
|
|||
} while(FindNextFile(h, &fd));
|
||||
}
|
||||
#else
|
||||
ctx->messagecallback(ctx->userctx, "no wildcard support, sorry\n");
|
||||
DIR *dir;
|
||||
struct dirent *ent;
|
||||
char basepath[MAX_OSPATH], tmppath[MAX_OSPATH];
|
||||
struct stat statbuf;
|
||||
|
||||
QCC_Canonicalize(basepath, sizeof(basepath), fname, ctx->sourcepath);
|
||||
QC_strlcat(basepath, "/", sizeof(basepath));
|
||||
dir = opendir(basepath);
|
||||
if (!dir)
|
||||
{
|
||||
ctx->messagecallback(ctx->userctx, "unable to open dir %s\n", basepath);
|
||||
return;
|
||||
}
|
||||
while ((ent = readdir(dir)))
|
||||
{
|
||||
if (*ent->d_name == '.')
|
||||
continue;
|
||||
QCC_Canonicalize(basepath, sizeof(basepath), ent->d_name, fname);
|
||||
QCC_Canonicalize(tmppath, sizeof(tmppath), basepath, ctx->sourcepath);
|
||||
if (stat(tmppath, &statbuf)!=0)
|
||||
continue;
|
||||
|
||||
switch (statbuf.st_mode & S_IFMT)
|
||||
{
|
||||
default: //some weird file type. shouldn't be a symlink sadly.
|
||||
// ctx->messagecallback(ctx->userctx, "found weird %s\n", basepath);
|
||||
break;
|
||||
case S_IFDIR:
|
||||
QC_strlcat(basepath, "/", sizeof(basepath));
|
||||
// ctx->messagecallback(ctx->userctx, "found dir %s\n", basepath);
|
||||
PKG_AddClassFiles(ctx, c, basepath);
|
||||
break;
|
||||
case S_IFREG:
|
||||
// ctx->messagecallback(ctx->userctx, "found file %s\n", basepath);
|
||||
PKG_AddClassFile(ctx, c, basepath, statbuf.st_mtime);
|
||||
break;
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
#endif
|
||||
}
|
||||
static void PKG_ParseClass(struct pkgctx_s *ctx, char *output)
|
||||
|
@ -887,6 +961,7 @@ static void *PKG_OpenSourceFile(struct pkgctx_s *ctx, struct file_s *file, size_
|
|||
QCC_Canonicalize(fullname, sizeof(fullname), file->name, ctx->sourcepath);
|
||||
strcpy(file->write.name, file->name);
|
||||
|
||||
//WIN32 FIXME: use the utf16 version because microsoft suck and don't allow utf-8
|
||||
f = fopen(fullname, "rb");
|
||||
if (!f)
|
||||
return NULL;
|
||||
|
@ -1010,7 +1085,7 @@ static void *PKG_OpenSourceFile(struct pkgctx_s *ctx, struct file_s *file, size_
|
|||
return data;
|
||||
}
|
||||
|
||||
static void PKG_WritePackageData(struct pkgctx_s *ctx, struct output_s *out, unsigned int index, pbool directoryonly)
|
||||
static pbool PKG_WritePackageData(struct pkgctx_s *ctx, struct output_s *out, unsigned int index, pbool directoryonly)
|
||||
{
|
||||
//helpers to deal with misaligned data. writes little-endian.
|
||||
#define misbyte(ptr,ofs,data) ((unsigned char*)(ptr))[ofs] = (data)&0xff
|
||||
|
@ -1044,12 +1119,27 @@ static void PKG_WritePackageData(struct pkgctx_s *ctx, struct output_s *out, uns
|
|||
#else
|
||||
#define compmethod 0/*Z_RAW*/
|
||||
#endif
|
||||
if (!compmethod && !directoryonly)
|
||||
if (!compmethod && !directoryonly && !index)
|
||||
pak = true; //might as well boost compat...
|
||||
ext = strrchr(out->filename, '.');
|
||||
if (ext && !QC_strcasecmp(ext, ".pak") && !index)
|
||||
pak = true;
|
||||
|
||||
if (!directoryonly)
|
||||
{
|
||||
for (f = out->files; f ; f=f->write.nextwrite)
|
||||
{
|
||||
if (index != f->write.zdisk)
|
||||
continue; //not in this disk...
|
||||
break;
|
||||
}
|
||||
if (!f)
|
||||
{
|
||||
ctx->messagecallback(ctx->userctx, "\t\tNo files to write to %s\n", out->filename);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (out->usediffs && !directoryonly)
|
||||
{
|
||||
char newname[MAX_OSPATH];
|
||||
|
@ -1068,8 +1158,8 @@ static void PKG_WritePackageData(struct pkgctx_s *ctx, struct output_s *out, uns
|
|||
outf = fopen(out->filename, "wb");
|
||||
if (!outf)
|
||||
{
|
||||
ctx->messagecallback(ctx->userctx, "Unable to open %s\n", out->filename);
|
||||
return;
|
||||
ctx->messagecallback(ctx->userctx, "\t\tUnable to open %s\n", out->filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pak) //reserve space for the pak header
|
||||
|
@ -1080,7 +1170,7 @@ static void PKG_WritePackageData(struct pkgctx_s *ctx, struct output_s *out, uns
|
|||
for (f = out->files; f ; f=f->write.nextwrite)
|
||||
{
|
||||
char header[32+sizeof(f->write.name)];
|
||||
size_t fnamelen = strlen(f->write.name);
|
||||
size_t fnamelen;
|
||||
size_t hofs;
|
||||
unsigned short gpflags = GPF_UTF8;
|
||||
|
||||
|
@ -1090,8 +1180,9 @@ static void PKG_WritePackageData(struct pkgctx_s *ctx, struct output_s *out, uns
|
|||
filedata = PKG_OpenSourceFile(ctx, f, &f->write.rawsize);
|
||||
if (!filedata)
|
||||
{
|
||||
ctx->messagecallback(ctx->userctx, "Unable to open %s\n", f->name);
|
||||
ctx->messagecallback(ctx->userctx, "\t\tUnable to open %s\n", f->name);
|
||||
}
|
||||
fnamelen = strlen(f->write.name);
|
||||
|
||||
f->write.zcrc = QC_encodecrc(f->write.rawsize, filedata);
|
||||
misint (header, 0, 0x04034b50);
|
||||
|
@ -1104,10 +1195,10 @@ static void PKG_WritePackageData(struct pkgctx_s *ctx, struct output_s *out, uns
|
|||
misint (header, 18, f->write.rawsize);//compressed size
|
||||
misint (header, 22, f->write.rawsize);//uncompressed size
|
||||
misshort(header, 26, fnamelen);//filename length
|
||||
misshort(header, 28, 0);//extradata length
|
||||
strcpy(header+30, f->write.name);
|
||||
misshort(header, 28, 0);//extradata length (filled in later)
|
||||
memcpy(header+30, f->write.name, fnamelen);
|
||||
hofs = 30+fnamelen;
|
||||
|
||||
//Write extra data here...
|
||||
misshort(header, 28, hofs-(30+fnamelen));//extradata length
|
||||
f->write.zhdrofs = ftell(outf);
|
||||
fwrite(header, 1, hofs, outf);
|
||||
|
@ -1170,8 +1261,8 @@ static void PKG_WritePackageData(struct pkgctx_s *ctx, struct output_s *out, uns
|
|||
struct
|
||||
{
|
||||
char name[56];
|
||||
unsigned int size;
|
||||
unsigned int offset;
|
||||
unsigned int size;
|
||||
} pakentry;
|
||||
pakheader.tabofs = ftell(outf);
|
||||
|
||||
|
@ -1216,7 +1307,7 @@ static void PKG_WritePackageData(struct pkgctx_s *ctx, struct output_s *out, uns
|
|||
misint (centralheader, 20, f->write.zipsize);//compressed size
|
||||
misint (centralheader, 24, f->write.rawsize);//uncompressed size
|
||||
misshort(centralheader, 28, fnamelen);//filename length
|
||||
misshort(centralheader, 30, 0);//extradata length
|
||||
misshort(centralheader, 30, 0);//extradata length (filled in later)
|
||||
misshort(centralheader, 32, 0);//comment length
|
||||
misshort(centralheader, 34, f->write.zdisk);//first disk number
|
||||
misshort(centralheader, 36, 0);//internal file attribs
|
||||
|
@ -1292,6 +1383,8 @@ static void PKG_WritePackageData(struct pkgctx_s *ctx, struct output_s *out, uns
|
|||
fwrite(centralheader, 1, 22, outf);
|
||||
|
||||
fclose(outf);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1337,7 +1430,7 @@ static void PKG_ReadPackContents(struct pkgctx_s *ctx, struct oldpack_s *old)
|
|||
|
||||
if (header[0] == 'P' && header[1] == 'K' && header[2] == 5 && header[3] == 6)
|
||||
{
|
||||
//thisdisk = shortfromptr(header+4);
|
||||
old->part = shortfromptr(header+4);
|
||||
//centraldirstart = shortfromptr(header+6);
|
||||
old->numfiles = shortfromptr(header+8);
|
||||
//numfiles_all = shortfromptr(header+10);
|
||||
|
@ -1360,7 +1453,7 @@ static void PKG_ReadPackContents(struct pkgctx_s *ctx, struct oldpack_s *old)
|
|||
//gflags = shortfromptr(header+8);
|
||||
old->file[u].zmethod = shortfromptr(header+10);
|
||||
old->file[u].dostime = shortfromptr(header+12);
|
||||
old->file[u].dosdate = shortfromptr(header+12);
|
||||
old->file[u].dosdate = shortfromptr(header+14);
|
||||
old->file[u].zcrc = longfromptr(header+16);
|
||||
old->file[u].zipsize = longfromptr(header+20);
|
||||
old->file[u].rawsize = longfromptr(header+24);
|
||||
|
@ -1462,8 +1555,13 @@ static void PKG_WriteDataset(struct pkgctx_s *ctx, struct dataset_s *set)
|
|||
for (out = set->outputs; out; out = out->next)
|
||||
{
|
||||
if(out->usediffs)
|
||||
{ //FIXME: look for old parts
|
||||
|
||||
{
|
||||
for (old = out->oldparts; old; old = old->next)
|
||||
{
|
||||
PKG_ReadPackContents(ctx, old);
|
||||
if (out->numparts <= old->part)
|
||||
out->numparts = old->part + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1514,7 +1612,10 @@ static void PKG_WriteDataset(struct pkgctx_s *ctx, struct dataset_s *set)
|
|||
for (old = out->oldparts; old; old = old->next)
|
||||
{
|
||||
if (!PKG_FileIsModified(ctx, old, file))
|
||||
{
|
||||
file->write.zdisk = old->part;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
file->write.nextwrite = out->files;
|
||||
|
@ -1545,11 +1646,12 @@ static void PKG_WriteDataset(struct pkgctx_s *ctx, struct dataset_s *set)
|
|||
else
|
||||
{
|
||||
ctx->messagecallback(ctx->userctx, "\tGenerating %s[%s] \"%s\"\n", out->code, set->name, out->filename);
|
||||
PKG_WritePackageData(ctx, out, out->numparts, false);
|
||||
if (PKG_WritePackageData(ctx, out, out->numparts, false))
|
||||
{
|
||||
if(out->usediffs)
|
||||
PKG_WritePackageData(ctx, out, out->numparts+1, true);
|
||||
}
|
||||
}
|
||||
|
||||
if(out->usediffs)
|
||||
PKG_WritePackageData(ctx, out, out->numparts+1, true);
|
||||
}
|
||||
}
|
||||
void Packager_WriteDataset(struct pkgctx_s *ctx, char *setname)
|
||||
|
@ -1647,5 +1749,46 @@ void Packager_ParseFile(struct pkgctx_s *ctx, char *scriptname)
|
|||
|
||||
void Packager_Destroy(struct pkgctx_s *ctx)
|
||||
{
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
pbool Packager_CompressDir(const char *dirname, enum pkgtype_e type, void (*messagecallback)(void *userctx, const char *message, ...), void *userctx)
|
||||
{
|
||||
char *ext;
|
||||
char filename[MAX_QPATH];
|
||||
struct pkgctx_s *ctx = Packager_Create(messagecallback, userctx);
|
||||
struct dataset_s *s;
|
||||
struct class_s *c;
|
||||
QC_strlcpy(ctx->sourcepath, dirname, sizeof(ctx->sourcepath));
|
||||
ext = strrchr(ctx->sourcepath, '/');
|
||||
if (*ctx->sourcepath && (!ext || ext[1]))
|
||||
QC_strlcat(ctx->sourcepath, "/", sizeof(ctx->sourcepath));
|
||||
|
||||
QC_strlcpy(filename, dirname, sizeof(filename));
|
||||
for (;(ext = strrchr(filename, '/')) && !ext[1]; *ext = 0)
|
||||
;
|
||||
ext = strrchr(filename, '.');
|
||||
if (ext)
|
||||
*ext = 0;
|
||||
if (type == PACKAGER_PAK)
|
||||
QC_strlcat(filename, ".pak", sizeof(filename));
|
||||
else
|
||||
QC_strlcat(filename, ".pk3", sizeof(filename));
|
||||
|
||||
s = PKG_GetDataset(ctx, "default");
|
||||
PKG_CreateOutput(ctx, s, "default", filename, type == PACKAGER_PK3_SPANNED);
|
||||
|
||||
c = malloc(sizeof(*c));
|
||||
memset(c, 0, sizeof(*c));
|
||||
strcpy(c->name, "file");
|
||||
strcpy(c->outname, "default");
|
||||
c->next = ctx->classes;
|
||||
ctx->classes = c;
|
||||
PKG_AddClassFiles(ctx, c, "");
|
||||
|
||||
Packager_WriteDataset(ctx, NULL);
|
||||
Packager_Destroy(ctx);
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -498,7 +498,7 @@ PR_EnterFunction
|
|||
Returns the new program statement counter
|
||||
====================
|
||||
*/
|
||||
int ASMCALL PR_EnterFunction (progfuncs_t *progfuncs, mfunction_t *f, int progsnum)
|
||||
static int ASMCALL PR_EnterFunction (progfuncs_t *progfuncs, mfunction_t *f, int progsnum)
|
||||
{
|
||||
int i, j, c, o;
|
||||
prstack_t *st;
|
||||
|
@ -562,7 +562,7 @@ int ASMCALL PR_EnterFunction (progfuncs_t *progfuncs, mfunction_t *f, int progsn
|
|||
PR_LeaveFunction
|
||||
====================
|
||||
*/
|
||||
int ASMCALL PR_LeaveFunction (progfuncs_t *progfuncs)
|
||||
static int ASMCALL PR_LeaveFunction (progfuncs_t *progfuncs)
|
||||
{
|
||||
int i, c;
|
||||
prstack_t *st;
|
||||
|
|
|
@ -8,8 +8,13 @@
|
|||
#define VARGS __cdecl
|
||||
#endif
|
||||
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
|
||||
#ifdef _WIN32
|
||||
#define LIKEPRINTF(x) __attribute__((format(ms_printf,x,x+1)))
|
||||
#if defined(_WIN32)
|
||||
#include <stdio.h>
|
||||
#ifdef __MINGW_PRINTF_FORMAT
|
||||
#define LIKEPRINTF(x) __attribute__((format(__MINGW_PRINTF_FORMAT,x,x+1)))
|
||||
#else
|
||||
#define LIKEPRINTF(x) __attribute__((format(ms_printf,x,x+1)))
|
||||
#endif
|
||||
#else
|
||||
#define LIKEPRINTF(x) __attribute__((format(printf,x,x+1)))
|
||||
#endif
|
||||
|
|
|
@ -1189,10 +1189,16 @@ int WriteSourceFiles(qcc_cachedsourcefile_t *filelist, int h, pbool sourceaswell
|
|||
|
||||
|
||||
struct pkgctx_s;
|
||||
enum pkgtype_e
|
||||
{
|
||||
PACKAGER_PAK,
|
||||
PACKAGER_PK3,
|
||||
PACKAGER_PK3_SPANNED,
|
||||
};
|
||||
pbool Packager_CompressDir(const char *dirname, enum pkgtype_e type, void (*messagecallback)(void *userctx, const char *message, ...), void *userctx);
|
||||
struct pkgctx_s *Packager_Create(void (*messagecallback)(void *userctx, const char *message, ...), void *userctx);
|
||||
void Packager_ParseFile(struct pkgctx_s *ctx, char *scriptfilename);
|
||||
void Packager_ParseText(struct pkgctx_s *ctx, char *scripttext);
|
||||
void Packager_WriteDataset(struct pkgctx_s *ctx, char *setname);
|
||||
void Packager_Destroy(struct pkgctx_s *ctx);
|
||||
|
||||
|
||||
|
|
|
@ -6914,7 +6914,7 @@ QCC_sref_t QCC_PR_GenerateFunctionCallRef (QCC_sref_t newself, QCC_sref_t func,
|
|||
if (QCC_OPCodeValid(&pr_opcodes[OP_LOADA_V]))
|
||||
{
|
||||
copyop[2] = OP_LOADA_V;
|
||||
// copyop[1] = OP_LOADA_L;
|
||||
// copyop[1] = OP_LOADA_I64;
|
||||
copyop[0] = OP_LOADA_F;
|
||||
copyop_idx = -1;
|
||||
copyop_index = arglist[i]->index;
|
||||
|
@ -8551,6 +8551,7 @@ void QCC_PR_EmitClassFromFunction(QCC_def_t *scope, QCC_type_t *basetype)
|
|||
|
||||
static QCC_sref_t QCC_PR_ExpandField(QCC_sref_t ent, QCC_sref_t field, QCC_type_t *fieldtype, unsigned int preserveflags)
|
||||
{
|
||||
QCC_type_t *basicfieldtype;
|
||||
QCC_sref_t r;
|
||||
if (!fieldtype)
|
||||
{
|
||||
|
@ -8563,20 +8564,26 @@ static QCC_sref_t QCC_PR_ExpandField(QCC_sref_t ent, QCC_sref_t field, QCC_type_
|
|||
fieldtype = type_variant;
|
||||
}
|
||||
}
|
||||
basicfieldtype = fieldtype;
|
||||
while(basicfieldtype->type == ev_accessor || basicfieldtype->type == ev_boolean || basicfieldtype->type == ev_enum)
|
||||
basicfieldtype = (basicfieldtype->type == ev_enum)?basicfieldtype->aux_type:basicfieldtype->parentclass;
|
||||
|
||||
//FIXME: class.staticmember should directly read staticmember instead of trying to dereference
|
||||
switch(fieldtype->type)
|
||||
switch(basicfieldtype->type)
|
||||
{
|
||||
case ev_struct:
|
||||
case ev_union:
|
||||
case ev_enum:
|
||||
{
|
||||
int i;
|
||||
int i = 0;
|
||||
QCC_type_t *type = fieldtype;
|
||||
QCC_sref_t dest = QCC_GetTemp(type);
|
||||
QCC_sref_t source = field;
|
||||
//don't bother trying to optimise any temps here, its not likely to happen anyway.
|
||||
for (i = 0; i+2 < type->size; i+=3, dest.ofs += 3, source.ofs += 3)
|
||||
for (; i+2 < type->size; i+=3, dest.ofs += 3, source.ofs += 3)
|
||||
QCC_PR_SimpleStatement(&pr_opcodes[OP_LOAD_V], ent, source, dest, false);
|
||||
if (QCC_OPCodeValid(&pr_opcodes[OP_LOAD_I64]))
|
||||
for (; i+1 < type->size; i+=2, dest.ofs += 2, source.ofs += 2)
|
||||
QCC_PR_SimpleStatement(&pr_opcodes[OP_LOAD_I64], ent, source, dest, false);
|
||||
for (; i < type->size; i++, dest.ofs++, source.ofs++)
|
||||
QCC_PR_SimpleStatement(&pr_opcodes[OP_LOAD_F], ent, source, dest, false);
|
||||
source.ofs -= type->size;
|
||||
|
@ -8586,15 +8593,20 @@ static QCC_sref_t QCC_PR_ExpandField(QCC_sref_t ent, QCC_sref_t field, QCC_type_
|
|||
if (!(preserveflags & STFL_PRESERVEB))
|
||||
QCC_FreeTemp(field);
|
||||
|
||||
QCC_PR_ParseWarning(WARN_UNDESIRABLECONVENTION, "QCC_PR_ExpandField: inefficient");
|
||||
if (type->size > 3)
|
||||
QCC_PR_ParseWarning(WARN_UNDESIRABLECONVENTION, "inefficient - copying %u words to a temp", type->size);
|
||||
return dest;
|
||||
}
|
||||
break;
|
||||
case ev_void:
|
||||
case ev_accessor:
|
||||
case ev_boolean:
|
||||
case ev_enum:
|
||||
default:
|
||||
QCC_PR_ParseErrorPrintSRef(ERR_INTERNAL, field, "QCC_PR_ExpandField: invalid field type");
|
||||
{
|
||||
char temp[256];
|
||||
QCC_PR_ParseErrorPrintSRef(ERR_INTERNAL, field, "QCC_PR_ExpandField: invalid field type %s%s%s", col_type,TypeName(fieldtype, temp, sizeof(temp)),col_none);
|
||||
}
|
||||
r = field;
|
||||
break;
|
||||
case ev_integer:
|
||||
|
|
|
@ -4926,6 +4926,7 @@ QCC_type_t *QCC_PR_ParseFunctionType (int newtype, QCC_type_t *returntype)
|
|||
t = QCC_PR_FieldType(t);
|
||||
t = QCC_PR_FieldType(t);
|
||||
paramlist[numparms].type = t;
|
||||
foundinout = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -51,6 +51,9 @@ extern int sourcefilesnumdefs;
|
|||
};
|
||||
static char *cmdlineargs;
|
||||
|
||||
static progfuncs_t guiprogfuncs;
|
||||
static progexterns_t guiprogexterns;
|
||||
|
||||
#undef NULL
|
||||
#define NULL nullptr
|
||||
|
||||
|
@ -541,6 +544,7 @@ private:
|
|||
time_t filemodifiedtime;
|
||||
bool modified;
|
||||
int cursorline;
|
||||
int cursorindex;
|
||||
enum endings_e endings; //line endings for this file.
|
||||
int savefmt; //encoding to save as
|
||||
QsciDocument doc;
|
||||
|
@ -564,6 +568,10 @@ private:
|
|||
return;
|
||||
dl.curdoc = oldval;
|
||||
dl.s->setDocument(dl.curdoc->doc);
|
||||
|
||||
//annoying, but it completely loses your position otherwise.
|
||||
dl.s->setCursorPosition(dl.curdoc->cursorline-1, dl.curdoc->cursorindex);
|
||||
dl.s->ensureCursorVisible();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -615,6 +623,7 @@ public:
|
|||
if (curdoc)
|
||||
{
|
||||
curdoc->cursorline = line+1;
|
||||
curdoc->cursorindex = index;
|
||||
UpdateTitle();
|
||||
}
|
||||
});
|
||||
|
@ -1381,6 +1390,7 @@ public:
|
|||
//UpdateEditorTitle(d);
|
||||
}
|
||||
|
||||
UpdateTitle();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2079,27 +2089,25 @@ void RunCompiler(const char *args, pbool quick)
|
|||
static FILE *logfile;
|
||||
const char *argv[128];
|
||||
int argc;
|
||||
progexterns_t ext;
|
||||
progfuncs_t funcs;
|
||||
|
||||
mainwnd->docs.saveAll();
|
||||
|
||||
memset(&funcs, 0, sizeof(funcs));
|
||||
funcs.funcs.parms = &ext;
|
||||
memset(&ext, 0, sizeof(ext));
|
||||
ext.ReadFile = GUIReadFile;
|
||||
ext.FileSize = GUIFileSize;
|
||||
ext.WriteFile = QCC_WriteFile;
|
||||
ext.Sys_Error = Sys_Error;
|
||||
memset(&guiprogfuncs, 0, sizeof(guiprogfuncs));
|
||||
guiprogfuncs.funcs.parms = &guiprogexterns;
|
||||
memset(&guiprogexterns, 0, sizeof(guiprogexterns));
|
||||
guiprogexterns.ReadFile = GUIReadFile;
|
||||
guiprogexterns.FileSize = GUIFileSize;
|
||||
guiprogexterns.WriteFile = QCC_WriteFile;
|
||||
guiprogexterns.Sys_Error = Sys_Error;
|
||||
|
||||
if (quick)
|
||||
ext.Printf = Dummyprintf;
|
||||
guiprogexterns.Printf = Dummyprintf;
|
||||
else
|
||||
{
|
||||
ext.Printf = GUIprintf;
|
||||
guiprogexterns.Printf = GUIprintf;
|
||||
GUIprintf("");
|
||||
}
|
||||
ext.DPrintf = ext.Printf;
|
||||
guiprogexterns.DPrintf = guiprogexterns.Printf;
|
||||
|
||||
if (logfile)
|
||||
fclose(logfile);
|
||||
|
@ -2110,7 +2118,7 @@ void RunCompiler(const char *args, pbool quick)
|
|||
|
||||
argc = GUI_BuildParms(args, argv, quick);
|
||||
|
||||
if (CompileParams(&funcs, NULL, argc, argv))
|
||||
if (CompileParams(&guiprogfuncs, NULL, argc, argv))
|
||||
{
|
||||
if (!quick)
|
||||
{
|
||||
|
@ -2151,18 +2159,16 @@ void GUI_DoDecompile(void *buf, size_t size)
|
|||
{
|
||||
int h = SafeOpenWrite(fname.toUtf8().data(), -1);
|
||||
|
||||
progfuncs_t funcs;
|
||||
progexterns_t ext;
|
||||
memset(&funcs, 0, sizeof(funcs));
|
||||
funcs.funcs.parms = &ext;
|
||||
memset(&ext, 0, sizeof(ext));
|
||||
ext.ReadFile = GUIReadFile;
|
||||
ext.FileSize = GUIFileSize;
|
||||
ext.WriteFile = QCC_WriteFile;
|
||||
ext.Sys_Error = Sys_Error;
|
||||
ext.Printf = GUIprintf;
|
||||
memset(&guiprogfuncs, 0, sizeof(guiprogfuncs));
|
||||
guiprogfuncs.funcs.parms = &guiprogexterns;
|
||||
memset(&guiprogexterns, 0, sizeof(guiprogexterns));
|
||||
guiprogexterns.ReadFile = GUIReadFile;
|
||||
guiprogexterns.FileSize = GUIFileSize;
|
||||
guiprogexterns.WriteFile = QCC_WriteFile;
|
||||
guiprogexterns.Sys_Error = Sys_Error;
|
||||
guiprogexterns.Printf = GUIprintf;
|
||||
|
||||
qccprogfuncs = &funcs;
|
||||
qccprogfuncs = &guiprogfuncs;
|
||||
WriteSourceFiles(qcc_vfiles, h, true, false);
|
||||
qccprogfuncs = NULL;
|
||||
|
||||
|
|
|
@ -380,7 +380,7 @@ static char *GUI_ParseInPlace(char **state)
|
|||
{
|
||||
if (*end == '\"')
|
||||
{
|
||||
end++;
|
||||
*end++ = 0;
|
||||
break;
|
||||
}
|
||||
else if (*end == '\'' && end[1] == '\\')
|
||||
|
|
|
@ -406,7 +406,7 @@ compiler_flag_t compiler_flag[] = {
|
|||
{&pr_subscopedlocals, FLAG_MIDCOMPILE,"subscope", "Subscoped Locals", "Restrict the scope of locals to the block they are actually defined within, as in C."},
|
||||
{&verbose, FLAG_MIDCOMPILE,"verbose", "Verbose", "Lots of extra compiler messages."},
|
||||
{&flag_typeexplicit, FLAG_MIDCOMPILE,"typeexplicit", "Explicit types", "All type conversions must be explicit or directly supported by instruction set."},
|
||||
{&flag_boundchecks, defaultflag, "boundchecks", "Disable Bound Checks", "Disable array index checks, speeding up array access but can result in your code misbehaving."},
|
||||
{&flag_boundchecks, defaultflag, "boundchecks", "Enforce Bound Checks", "Enforce array index checks to avoid accessing arrays out of bounds. This can be disabled for a speedup (the qcvm will still verify that the access is within the qcvm's memory, but it can't verify that its within the intended array)."},
|
||||
{&flag_attributes, hideflag, "attributes", "[[attributes]]", "WARNING: This syntax conflicts with vector constructors."},
|
||||
{&flag_assumevar, hideflag, "assumevar", "explicit consts", "Initialised globals will be considered non-const by default."},
|
||||
{&flag_dblstarexp, hideflag, "ssp", "** exponent", "Treat ** as an operator for exponents, instead of multiplying by a dereferenced pointer."},
|
||||
|
@ -4114,7 +4114,7 @@ static void QCC_CopyFiles (void)
|
|||
return;
|
||||
}
|
||||
|
||||
for ( p = 0; p < 5; p++)
|
||||
for ( p = 0; p < countof(QCC_Packname); p++)
|
||||
{
|
||||
s = QCC_Packname[p];
|
||||
if (!*s)
|
||||
|
|
|
@ -115,6 +115,89 @@ static int logprintf(const char *format, ...)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static size_t totalsize, filecount;
|
||||
static void QCC_FileList(const char *name, const void *compdata, size_t compsize, int method, size_t plainsize)
|
||||
{
|
||||
totalsize += plainsize;
|
||||
filecount += 1;
|
||||
if (!method && compsize==plainsize)
|
||||
externs->Printf("%8u %s\n", (unsigned)plainsize, name);
|
||||
else
|
||||
externs->Printf("%8u %3u%% %s\n", (unsigned)plainsize, plainsize?(unsigned)((100*compsize)/plainsize):100u, name);
|
||||
}
|
||||
#include <limits.h>
|
||||
#ifdef __unix__
|
||||
#include <sys/stat.h>
|
||||
void QCC_Mkdir(const char *path)
|
||||
{
|
||||
char buf[MAX_OSPATH], *sl;
|
||||
if (!strchr(path, '/'))
|
||||
return; //no need to create anything
|
||||
memcpy(buf, path, MAX_OSPATH);
|
||||
while((sl=strrchr(buf, '/')))
|
||||
{
|
||||
*sl = 0;
|
||||
mkdir(buf, 0777);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void QCC_Mkdir(const char *path)
|
||||
{
|
||||
//unsupported.
|
||||
}
|
||||
#endif
|
||||
static const char *extractonly;
|
||||
static pbool extractonlyfound;
|
||||
static void QCC_FileExtract(const char *name, const void *compdata, size_t compsize, int method, size_t plainsize)
|
||||
{
|
||||
if (extractonly)
|
||||
{
|
||||
const char *sl = strrchr(extractonly, '/');
|
||||
if (sl && !sl[1])
|
||||
{ //trailing / - extract the entire dir.
|
||||
if (!strcmp(name, extractonly))
|
||||
return; //ignore the dir itself...
|
||||
if (strncmp(name, extractonly, strlen(extractonly)))
|
||||
return;
|
||||
}
|
||||
else
|
||||
if (strcmp(name, extractonly))
|
||||
return; //ignore it if its not the one we're going for.
|
||||
}
|
||||
extractonlyfound = true;
|
||||
externs->Printf("Extracting %s...", name);
|
||||
if (plainsize <= INT_MAX)
|
||||
{
|
||||
void *buffer = malloc(plainsize);
|
||||
if (buffer && QC_decode(progfuncs, compsize, plainsize, method, compdata, buffer))
|
||||
{
|
||||
QCC_Mkdir(name);
|
||||
if (!QCC_WriteFile(name, buffer, plainsize))
|
||||
externs->Printf(" write failure\n");
|
||||
else
|
||||
externs->Printf(" done\n");
|
||||
}
|
||||
else
|
||||
externs->Printf(" read failure\n");
|
||||
|
||||
free(buffer);
|
||||
}
|
||||
else
|
||||
externs->Printf(" too large\n");
|
||||
}
|
||||
|
||||
static void QCC_PR_PackagerMessage(void *userctx, const char *message, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char string[1024];
|
||||
|
||||
va_start (argptr,message);
|
||||
QC_vsnprintf (string,sizeof(string)-1,message,argptr);
|
||||
va_end (argptr);
|
||||
|
||||
externs->Printf ("%s", string);
|
||||
}
|
||||
|
||||
int main (int argc, const char **argv)
|
||||
{
|
||||
unsigned int i;
|
||||
|
@ -137,6 +220,52 @@ int main (int argc, const char **argv)
|
|||
funcs.funcs.parms->Printf = logprintf;
|
||||
funcs.funcs.parms->Sys_Error = Sys_Error;
|
||||
|
||||
if ((argc == 3 && !strcmp(argv[1], "-l")) || (argc >= 3 && !strcmp(argv[1], "-x")))
|
||||
{
|
||||
size_t blobsize;
|
||||
void *blob = QCC_ReadFile(argv[2], NULL, NULL, &blobsize, false);
|
||||
if (!blob)
|
||||
{
|
||||
logprintf("Unable to read %s\n", argv[2]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (argc > 3)
|
||||
{
|
||||
for (i = 3; i < argc; i++)
|
||||
{
|
||||
extractonly = argv[i];
|
||||
extractonlyfound = false;
|
||||
QC_EnumerateFilesFromBlob(blob, blobsize, QCC_FileExtract);
|
||||
if (!extractonlyfound)
|
||||
externs->Printf("Unable to find file %s\n", extractonly);
|
||||
}
|
||||
extractonly = NULL;
|
||||
}
|
||||
else if (argv[1][1] == 'x')
|
||||
QC_EnumerateFilesFromBlob(blob, blobsize, QCC_FileExtract);
|
||||
else
|
||||
{
|
||||
QC_EnumerateFilesFromBlob(blob, blobsize, QCC_FileList);
|
||||
externs->Printf("Total size %u bytes, %u files\n", (unsigned)totalsize, (unsigned)filecount);
|
||||
}
|
||||
free(blob);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
if (argc == 3 && (!strncmp(argv[1], "-z", 2) || !strcmp(argv[1], "-0") || !strcmp(argv[1], "-9")))
|
||||
{ //exe -0 foo.pk3dir
|
||||
enum pkgtype_e t;
|
||||
if (argv[1][1] == '9')
|
||||
t = PACKAGER_PK3;
|
||||
else if (argv[1][1] == '0')
|
||||
t = PACKAGER_PAK; //not really any difference but oh well
|
||||
else
|
||||
t = PACKAGER_PK3_SPANNED;
|
||||
|
||||
if (Packager_CompressDir(argv[2], t, QCC_PR_PackagerMessage, NULL))
|
||||
return EXIT_SUCCESS;
|
||||
else
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
if (!argv[i])
|
||||
|
|
|
@ -257,13 +257,14 @@ int QC_EnumerateFilesFromBlob(const void *blob, size_t blobsize, void (*cb)(cons
|
|||
continue;
|
||||
if (nl != QC_ReadRawShort(le+26))
|
||||
continue; //name is weird...
|
||||
if (el != QC_ReadRawShort(le+28))
|
||||
continue; //name is weird...
|
||||
// if (el != QC_ReadRawShort(le+28))
|
||||
// continue; //extradata is weird...
|
||||
|
||||
csize = QC_ReadRawInt(le+18);
|
||||
usize = QC_ReadRawInt(le+22);
|
||||
if (!QC_strlcpy(name, cd+46, (nl+1<sizeof(name))?nl+1:sizeof(name)))
|
||||
continue; //name was too long.
|
||||
if (nl >= sizeof(name))
|
||||
continue; //name is too long
|
||||
QC_strlcpy(name, cd+46, (nl+1<sizeof(name))?nl+1:sizeof(name));
|
||||
|
||||
cb(name, le+30+QC_ReadRawShort(le+26)+QC_ReadRawShort(le+28), csize, method, usize);
|
||||
ret++;
|
||||
|
|
|
@ -11409,7 +11409,7 @@ static BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"bufstr_add", PF_Fixme, 0, 0, 0, 448, "float(strbuf bufhandle, string str, float ordered)"},//DP_QC_STRINGBUFFERS
|
||||
{"bufstr_free", PF_Fixme, 0, 0, 0, 449, "void(strbuf bufhandle, float string_index)"},//DP_QC_STRINGBUFFERS
|
||||
{"iscachedpic", PF_Fixme, 0, 0, 0, 451, "float(string name)"},// (EXT_CSQC)
|
||||
{"precache_pic", PF_Fixme, 0, 0, 0, 452, "string(string name, optional float trywad)"},// (EXT_CSQC)
|
||||
{"precache_pic", PF_Fixme, 0, 0, 0, 452, "string(string name, optional float flags)"},// (EXT_CSQC)
|
||||
{"freepic", PF_Fixme, 0, 0, 0, 453, "void(string name)"},// (EXT_CSQC)
|
||||
{"drawcharacter", PF_Fixme, 0, 0, 0, 454, "float(vector position, float character, vector scale, vector rgb, float alpha, optional float flag)"},// (EXT_CSQC, [EXT_CSQC_???])
|
||||
{"drawrawstring", PF_Fixme, 0, 0, 0, 455, "float(vector position, string text, vector scale, vector rgb, float alpha, optional float flag)"},// (EXT_CSQC, [EXT_CSQC_???])
|
||||
|
@ -13144,6 +13144,8 @@ void PR_DumpPlatform_f(void)
|
|||
#endif
|
||||
|
||||
{"PRECACHE_PIC_FROMWAD","const float", CS|MENU, D("Attempt to load it from the legacy gfx.wad file (usually its better to just use a gfx/ prefix instead)."), 1},
|
||||
{"PRECACHE_PIC_NOCLAMP","const float", CS|MENU, D("Texture coords for the pic will not be clamped nor padded nor atlased."), 4},
|
||||
// {"PRECACHE_PIC_MIPMAP", "const float", CS|MENU, D("Force the image to be mipmapped. This might result in it being blurry, but will not be noisy."), 8},
|
||||
{"PRECACHE_PIC_DOWNLOAD","const float", CS|MENU, D("If no image could be loaded then attempt to download one from the server. This flag can cause the function to block until completion. (Slow!)"), 256},
|
||||
{"PRECACHE_PIC_TEST", "const float", CS|MENU, D("The precache will block until the image is fully loaded, returning a null string on failure. (Slow!)"), 512},
|
||||
|
||||
|
|
|
@ -16,6 +16,26 @@ extern cvar_t pr_ssqc_memsize;
|
|||
|
||||
void SV_Savegame_f (void);
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char name[32];
|
||||
union
|
||||
{
|
||||
int i;
|
||||
float f;
|
||||
} parm[NUM_SPAWN_PARMS];
|
||||
char *parmstr;
|
||||
|
||||
client_t *source;
|
||||
} loadplayer_t;
|
||||
|
||||
struct loadinfo_s
|
||||
{
|
||||
size_t numplayers;
|
||||
loadplayer_t *players;
|
||||
};
|
||||
|
||||
//Writes a SAVEGAME_COMMENT_LENGTH character comment describing the current
|
||||
void SV_SavegameComment (char *text, size_t textsize)
|
||||
{
|
||||
|
@ -80,7 +100,8 @@ void SV_SavegameComment (char *text, size_t textsize)
|
|||
|
||||
pbool PDECL SV_ExtendedSaveData(pubprogfuncs_t *progfuncs, void *loadctx, const char **ptr)
|
||||
{
|
||||
char token[8192];
|
||||
struct loadinfo_s *loadinfo = loadctx;
|
||||
char token[65536];
|
||||
com_tokentype_t tt;
|
||||
const char *l = *ptr;
|
||||
size_t idx;
|
||||
|
@ -155,28 +176,35 @@ pbool PDECL SV_ExtendedSaveData(pubprogfuncs_t *progfuncs, void *loadctx, const
|
|||
l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt);if (tt != TTP_STRING)return false;
|
||||
sv.strings.particle_precache[idx] = PR_AddString(svprogfuncs, token, 0, false);
|
||||
}
|
||||
else if (!strcmp(token, "serverflags"))
|
||||
{ //serverflags N (for map_restart to work properly)
|
||||
l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt);if (tt != TTP_RAWTOKEN)return false;
|
||||
idx = atoi(token);
|
||||
svs.serverflags = idx;
|
||||
}
|
||||
else if (!strcmp(token, "startspot"))
|
||||
{ //startspot "foo" (for map_restart to work properly)
|
||||
l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt);if (tt != TTP_RAWTOKEN)return false;
|
||||
InfoBuf_SetStarKey(&svs.info, "*startspot", token);
|
||||
}
|
||||
else if (loadinfo && !strcmp(token, "spawnparm"))
|
||||
{ //spawnparm idx val (for map_restart to work properly)
|
||||
l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt);if (tt != TTP_RAWTOKEN)return false;
|
||||
idx = atoi(token);
|
||||
if (idx == 0)
|
||||
{ //the parmstr...
|
||||
l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt);if (tt != TTP_STRING)return false;
|
||||
loadinfo->players[0].parmstr = Z_StrDup(token);
|
||||
}
|
||||
else if (idx >= 1 && idx <= countof(loadinfo->players->parm))
|
||||
{ //regular parm
|
||||
l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt);if (tt != TTP_RAWTOKEN)return false;
|
||||
loadinfo->players[0].parm[idx-1].f = atof(token);
|
||||
}
|
||||
}
|
||||
//strbuffer+hashtable+etc junk
|
||||
else if (PR_Common_LoadGame(svprogfuncs, token, &l))
|
||||
;
|
||||
/*
|
||||
else if (!strcmp(token, "buffer"))
|
||||
{
|
||||
l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt);if (tt != TTP_RAWTOKEN)return false;
|
||||
//buffer = atoi(token);
|
||||
l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt);if (tt != TTP_RAWTOKEN)return false;
|
||||
//flags = atoi(token);
|
||||
l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt);if (tt != TTP_STRING)return false;
|
||||
//"string" == token
|
||||
return false;
|
||||
}
|
||||
else if (!strcmp(token, "bufstr"))
|
||||
{
|
||||
l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt);if (tt != TTP_RAWTOKEN)return false;
|
||||
//buffer = atoi(token);
|
||||
l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt);if (tt != TTP_RAWTOKEN)return false;
|
||||
//idx = atoi(token);
|
||||
l = COM_ParseTokenOut(l, NULL, token, sizeof(token), &tt);if (tt != TTP_STRING)return false;
|
||||
return false;
|
||||
}*/
|
||||
else
|
||||
return false;
|
||||
*ptr = l;
|
||||
|
@ -312,8 +340,25 @@ static qboolean SV_LegacySavegame (const char *savename, qboolean verbose)
|
|||
for (i=1 ; i < countof(sv.strings.sound_precache); i++)
|
||||
{
|
||||
if (sv.strings.sound_precache[i])
|
||||
VFS_PRINTF(f, "sv.lightstyles %i %s\n", i, sv.strings.sound_precache[i]);
|
||||
VFS_PRINTF(f, "sv.sound_precache %i %s\n", i, sv.strings.sound_precache[i]);
|
||||
}
|
||||
for (i=1 ; i < countof(sv.strings.particle_precache); i++)
|
||||
{
|
||||
if (sv.strings.particle_precache[i])
|
||||
VFS_PRINTF(f, "sv.particle_precache %i %s\n", i, sv.strings.particle_precache[i]);
|
||||
}
|
||||
VFS_PRINTF(f, "sv.serverflags %i\n", svs.serverflags); //zomg! a fix for losing runes on load;restart!
|
||||
// VFS_PRINTF(f, "sv.startspot %s\n", InfoBuf_ValueForKey(&svs.info, "*startspot")); //startspot, for restarts.
|
||||
if (svs.clients->spawn_parmstring)
|
||||
{
|
||||
size_t maxlen = strlen(svs.clients->spawn_parmstring)*2+4 + 1;
|
||||
char *buffer = BZ_Malloc(maxlen);
|
||||
VFS_PRINTF(f, "spawnparm 0 %s\n", COM_QuotedString(svs.clients->spawn_parmstring, buffer, sizeof(maxlen), false));
|
||||
BZ_Free(buffer);
|
||||
}
|
||||
if (version == SAVEGAME_VERSION_NQ || version == SAVEGAME_VERSION_QW)
|
||||
for (i=16 ; i < countof(svs.clients->spawn_parms); i++)
|
||||
VFS_PRINTF(f, "spawnparm %i %g\n", i+1, svs.clients->spawn_parms[i]);
|
||||
// sv.buffer %i %i "string"
|
||||
// sv.bufstr %i %i "%s"
|
||||
VFS_PUTS(f, "*/\n");
|
||||
|
@ -1396,18 +1441,6 @@ void SV_AutoSave(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char name[32];
|
||||
union
|
||||
{
|
||||
int i;
|
||||
float f;
|
||||
} parm[NUM_SPAWN_PARMS];
|
||||
char *parmstr;
|
||||
|
||||
client_t *source;
|
||||
} loadplayer_t;
|
||||
static void SV_SwapPlayers(client_t *a, client_t *b)
|
||||
{
|
||||
size_t i;
|
||||
|
@ -1671,6 +1704,10 @@ static qboolean SV_Loadgame_Legacy(const char *savename, const char *filename, v
|
|||
char *modelnames[MAX_PRECACHE_MODELS];
|
||||
char *soundnames[MAX_PRECACHE_SOUNDS];
|
||||
loadplayer_t lp[255];
|
||||
struct loadinfo_s loadinfo;
|
||||
|
||||
loadinfo.numplayers = countof(lp);
|
||||
loadinfo.players = lp;
|
||||
|
||||
if (version != SAVEGAME_VERSION_FTE_LEG && version != SAVEGAME_VERSION_NQ && version != SAVEGAME_VERSION_QW)
|
||||
{
|
||||
|
@ -1867,7 +1904,7 @@ static qboolean SV_Loadgame_Legacy(const char *savename, const char *filename, v
|
|||
strcpy(file, "loadgame");
|
||||
clnum=VFS_READ(f, file+8, filelen);
|
||||
file[filelen+8]='\0';
|
||||
sv.world.edict_size=svprogfuncs->load_ents(svprogfuncs, file, NULL, NULL, SV_ExtendedSaveData);
|
||||
sv.world.edict_size=svprogfuncs->load_ents(svprogfuncs, file, &loadinfo, NULL, SV_ExtendedSaveData);
|
||||
BZ_Free(file);
|
||||
|
||||
PR_LoadGlabalStruct(false);
|
||||
|
|
|
@ -505,7 +505,7 @@ typedef struct client_s
|
|||
usercmd_t lastcmd; // for filling in big drops and partial predictions
|
||||
double localtime; // of last message
|
||||
qboolean jump_held;
|
||||
qboolean lockangles; //mod is spamming angle changes, don't do relative changes
|
||||
unsigned int lockanglesseq; //mod is spamming angle changes, don't do relative changes. outgoing sequence. v_angles isn't really known until netchan.incoming_acknowledged>=lockangles
|
||||
|
||||
float maxspeed; // localized maxspeed
|
||||
float entgravity; // localized ent gravity
|
||||
|
|
|
@ -87,6 +87,12 @@ client_t *SV_GetClientForString(const char *name, int *id)
|
|||
int first=0;
|
||||
if (id && *id != -1)
|
||||
first = *id;
|
||||
if (first < 0)
|
||||
{
|
||||
if (id)
|
||||
*id=sv.allocated_client_slots;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!strcmp(name, "*")) //match with all
|
||||
{
|
||||
|
@ -95,10 +101,12 @@ client_t *SV_GetClientForString(const char *name, int *id)
|
|||
if (cl->state<=cs_loadzombie)
|
||||
continue;
|
||||
|
||||
*id=i+1;
|
||||
if (id)
|
||||
*id=i+1;
|
||||
return cl;
|
||||
}
|
||||
*id=sv.allocated_client_slots;
|
||||
if (id)
|
||||
*id=sv.allocated_client_slots;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -114,7 +122,7 @@ client_t *SV_GetClientForString(const char *name, int *id)
|
|||
if (!*s)
|
||||
{
|
||||
int uid = Q_atoi(name);
|
||||
for (i = first, cl = svs.clients; i < sv.allocated_client_slots; i++, cl++)
|
||||
for (i = first, cl = svs.clients+first; i < sv.allocated_client_slots; i++, cl++)
|
||||
{
|
||||
if (cl->state<=cs_loadzombie)
|
||||
continue;
|
||||
|
@ -585,7 +593,7 @@ void SV_Map_f (void)
|
|||
Con_DPrintf ("map_restart delay not implemented yet\n");
|
||||
}
|
||||
Q_strncpyz (level, ".", sizeof(level));
|
||||
startspot = NULL;
|
||||
startspot = NULL; //FIXME: startspot forgotten on restart
|
||||
|
||||
//FIXME: if precaches+statics don't change, don't do the whole networking thing.
|
||||
}
|
||||
|
|
|
@ -3827,9 +3827,10 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, pvscamera_t
|
|||
|
||||
if (cameras && tracecullent && !((unsigned int)ent->v->effects & (EF_DIMLIGHT|EF_BLUE|EF_RED|EF_BRIGHTLIGHT|EF_BRIGHTFIELD|EF_NODEPTHTEST)))
|
||||
{ //more expensive culling
|
||||
if ((e <= sv.allocated_client_slots && sv_cullplayers_trace.value) || sv_cullentities_trace.value)
|
||||
if (Cull_Traceline(e < client->lastseen_count?&client->lastseen_time[e]:NULL, cameras, tracecullent))
|
||||
continue;
|
||||
if (!(pvsflags & PVSF_MODE_MASK))
|
||||
if ((e <= sv.allocated_client_slots && sv_cullplayers_trace.value) || sv_cullentities_trace.value)
|
||||
if (Cull_Traceline(e < client->lastseen_count?&client->lastseen_time[e]:NULL, cameras, tracecullent))
|
||||
continue;
|
||||
}
|
||||
|
||||
//EXT_CSQC
|
||||
|
|
|
@ -187,7 +187,7 @@ cvar_t skill = CVARF("skill", "" , CVAR_SERVERINFO); // 0, 1, 2 or 3
|
|||
cvar_t spawn = CVARF("spawn", "" , CVAR_SERVERINFO);
|
||||
cvar_t watervis = CVARF("watervis", "" , CVAR_SERVERINFO);
|
||||
#pragma warningmsg("Remove this some time")
|
||||
cvar_t allow_skybox = CVARF("allow_skybox", "", CVAR_SERVERINFO);
|
||||
cvar_t allow_skybox = CVARFD("allow_skybox", "", CVAR_SERVERINFO, "This setting says whether clients should skip writing skybox depth when rendering skyboxes/skydomes. Skipping depth writes is required for halflife, quake2, and quake3 compat, but q1 content generally requires depth masking. Empty uses format-specific defaults.");
|
||||
cvar_t sv_allow_splitscreen = CVARFD("allow_splitscreen","",CVAR_SERVERINFO, "Specifies whether clients can use splitscreen extensions to dynamically add additional clients. This only affects remote clients and not the built-in client.\nClients may need to reconnect in order to add seats when this is changed.");
|
||||
cvar_t fbskins = CVARF("fbskins", "", CVAR_SERVERINFO); //to get rid of lame fuhquake fbskins
|
||||
|
||||
|
|
|
@ -349,32 +349,10 @@ static void WPhys_PortalTransform(world_t *w, wedict_t *ent, wedict_t *portal, v
|
|||
if (ent->entnum > 0 && ent->entnum <= svs.allocated_client_slots)
|
||||
{
|
||||
client_t *cl = &svs.clients[ent->entnum-1];
|
||||
int i;
|
||||
vec3_t delta;
|
||||
ent->v->angles[0] *= r_meshpitch.value;
|
||||
if (!cl->lockangles && (cl->fteprotocolextensions2 & PEXT2_SETANGLEDELTA))
|
||||
{
|
||||
cl = ClientReliableWrite_BeginSplit(cl, svcfte_setangledelta, 7);
|
||||
|
||||
VectorSubtract(ent->v->angles, ent->v->v_angle, delta);
|
||||
delta[2] = anglemod(delta[2]);
|
||||
if (delta[2] > 90 && delta[2] < 270)
|
||||
{
|
||||
delta[2] -= 180;
|
||||
delta[1] -= 180;
|
||||
delta[0] -= -180;
|
||||
}
|
||||
for (i=0 ; i < 3 ; i++)
|
||||
ClientReliableWrite_Angle16 (cl, delta[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
cl = ClientReliableWrite_BeginSplit (cl, svc_setangle, 7);
|
||||
for (i=0 ; i < 3 ; i++)
|
||||
ClientReliableWrite_Angle (cl, ent->v->angles[i]);
|
||||
}
|
||||
VectorCopy(ent->v->angles, ent->v->v_angle);
|
||||
ent->v->angles[0] *= r_meshpitch.value;
|
||||
SV_SendFixAngle(cl, NULL, FIXANGLE_AUTO, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1637,7 +1637,7 @@ void SV_SendFixAngle(client_t *client, sizebuf_t *msg, int fixtype, qboolean rol
|
|||
|
||||
if (fixtype == FIXANGLE_AUTO)
|
||||
{
|
||||
if (!client->lockangles && controller->delta_sequence != -1 && !client->viewent)
|
||||
if (client->lockanglesseq<controller->netchan.incoming_acknowledged && controller->delta_sequence != -1 && !client->viewent)
|
||||
fixtype = FIXANGLE_DELTA;
|
||||
else
|
||||
fixtype = FIXANGLE_FIXED;
|
||||
|
@ -1645,7 +1645,7 @@ void SV_SendFixAngle(client_t *client, sizebuf_t *msg, int fixtype, qboolean rol
|
|||
if (fixtype == FIXANGLE_DELTA && !(controller->fteprotocolextensions2 & PEXT2_SETANGLEDELTA))
|
||||
fixtype = FIXANGLE_FIXED; //sorry, can't do it.
|
||||
|
||||
if (!client->lockangles && controller->netchan.message.cursize < controller->netchan.message.maxsize/2)
|
||||
if (client->lockanglesseq>=controller->netchan.incoming_acknowledged && controller->netchan.message.cursize < controller->netchan.message.maxsize/2)
|
||||
msg = NULL; //try to keep them vaugely reliable, where feasable.
|
||||
if (!msg)
|
||||
msg = ClientReliable_StartWrite(client, 10);
|
||||
|
@ -1673,7 +1673,7 @@ void SV_SendFixAngle(client_t *client, sizebuf_t *msg, int fixtype, qboolean rol
|
|||
for (i=0 ; i < 3 ; i++)
|
||||
MSG_WriteAngle (msg, (i==2&&!roll)?0:ang[i]);
|
||||
}
|
||||
client->lockangles = true; //so that spammed fixangles use absolute values, locking the camera in place.
|
||||
client->lockanglesseq = controller->netchan.outgoing_sequence+1; //so that spammed fixangles use absolute values, locking the camera in place.
|
||||
}
|
||||
|
||||
void SV_WriteEntityDataToMessage (client_t *client, sizebuf_t *msg, int pnum)
|
||||
|
@ -1723,8 +1723,6 @@ void SV_WriteEntityDataToMessage (client_t *client, sizebuf_t *msg, int pnum)
|
|||
SV_SendFixAngle(client, msg, ent->v->fixangle, true);
|
||||
ent->v->fixangle = FIXANGLE_NO;
|
||||
}
|
||||
else
|
||||
client->lockangles = false;
|
||||
}
|
||||
|
||||
/*sends the a centerprint string directly to the client*/
|
||||
|
|
|
@ -2432,6 +2432,8 @@ static void World_ClipToNetwork (world_t *w, moveclip_t *clip)
|
|||
if (touch->modelindex <= 0 || touch->modelindex >= MAX_PRECACHE_MODELS)
|
||||
continue; //erk
|
||||
model = cl.model_precache[touch->modelindex];
|
||||
if (!model)
|
||||
continue;
|
||||
VectorCopy(model->mins, bmins);
|
||||
VectorCopy(model->maxs, bmaxs);
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
|
||||
affine varying vec2 tc;
|
||||
varying vec4 light;
|
||||
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)
|
||||
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)
|
||||
varying vec3 eyevector;
|
||||
#endif
|
||||
#if defined(PBR)||defined(REFLECTCUBEMASK)
|
||||
|
@ -92,9 +92,7 @@ void main ()
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(PBR)
|
||||
eyevector = e_eyepos - w.xyz;
|
||||
#elif defined(SPECULAR)||defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)
|
||||
#if defined(SPECULAR)||defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)
|
||||
vec3 eyeminusvertex = e_eyepos - w.xyz;
|
||||
eyevector.x = dot(eyeminusvertex, s.xyz);
|
||||
eyevector.y = dot(eyeminusvertex, t.xyz);
|
||||
|
@ -139,7 +137,7 @@ affine in vec2 tc[];
|
|||
affine out vec2 t_tc[];
|
||||
in vec4 light[];
|
||||
out vec4 t_light[];
|
||||
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)
|
||||
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)
|
||||
in vec3 eyevector[];
|
||||
out vec3 t_eyevector[];
|
||||
#endif
|
||||
|
@ -155,7 +153,7 @@ void main()
|
|||
t_normal[id] = normal[id];
|
||||
t_tc[id] = tc[id];
|
||||
t_light[id] = light[id];
|
||||
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)
|
||||
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)
|
||||
t_eyevector[id] = eyevector[id];
|
||||
#endif
|
||||
#ifdef REFLECTCUBEMASK
|
||||
|
@ -188,7 +186,7 @@ affine in vec2 t_tc[];
|
|||
affine out vec2 tc;
|
||||
in vec4 t_light[];
|
||||
out vec4 light;
|
||||
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)
|
||||
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)
|
||||
in vec3 t_eyevector[];
|
||||
out vec3 eyevector;
|
||||
#endif
|
||||
|
@ -211,7 +209,7 @@ void main()
|
|||
|
||||
//FIXME: we should be recalcing these here, instead of just lerping them
|
||||
light = LERP(t_light);
|
||||
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)
|
||||
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)
|
||||
eyevector = LERP(t_eyevector);
|
||||
#endif
|
||||
#ifdef REFLECTCUBEMASK
|
||||
|
@ -251,7 +249,7 @@ uniform float cvar_gl_specular;
|
|||
|
||||
affine varying vec2 tc;
|
||||
varying vec4 light;
|
||||
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)
|
||||
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)
|
||||
varying vec3 eyevector;
|
||||
#endif
|
||||
#if defined(PBR) || defined(REFLECTCUBEMASK)
|
||||
|
@ -345,7 +343,8 @@ void main ()
|
|||
#endif
|
||||
#else
|
||||
#define roughness 0.3
|
||||
#define specrgb 1.0 //vec3(dielectricSpecular)
|
||||
#define specrgb vec3(1.0) //vec3(dielectricSpecular)
|
||||
#define ambientrgb col.rgb
|
||||
#endif
|
||||
|
||||
#ifdef BUMP
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include "sys/fog.h"
|
||||
|
||||
#if !defined(TESS_CONTROL_SHADER)
|
||||
#if defined(OFFSETMAPPING) || defined(SPECULAR) || defined(REFLECTCUBEMASK)
|
||||
#if defined(OFFSETMAPPING) || defined(SPECULAR) || defined(REFLECTCUBEMASK) || defined(PBR)
|
||||
varying vec3 eyevector;
|
||||
#endif
|
||||
|
||||
|
@ -68,7 +68,7 @@ varying vec3 vertex, normal;
|
|||
#endif
|
||||
void main ()
|
||||
{
|
||||
#if defined(OFFSETMAPPING) || defined(SPECULAR) || defined(REFLECTCUBEMASK)
|
||||
#if defined(OFFSETMAPPING) || defined(SPECULAR) || defined(REFLECTCUBEMASK) || defined(PBR)
|
||||
vec3 eyeminusvertex = e_eyepos - v_position.xyz;
|
||||
eyevector.x = dot(eyeminusvertex, v_svector.xyz);
|
||||
eyevector.y = dot(eyeminusvertex, v_tvector.xyz);
|
||||
|
@ -119,7 +119,7 @@ in vec3 vertex[];
|
|||
out vec3 t_vertex[];
|
||||
in vec3 normal[];
|
||||
out vec3 t_normal[];
|
||||
#if defined(OFFSETMAPPING) || defined(SPECULAR) || defined(REFLECTCUBEMASK)
|
||||
#if defined(OFFSETMAPPING) || defined(SPECULAR) || defined(REFLECTCUBEMASK) || defined(PBR)
|
||||
in vec3 eyevector[];
|
||||
out vec3 t_eyevector[];
|
||||
#endif
|
||||
|
@ -161,7 +161,7 @@ void main()
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)
|
||||
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)
|
||||
t_eyevector[id] = eyevector[id];
|
||||
#endif
|
||||
|
||||
|
@ -185,7 +185,7 @@ layout(triangles) in;
|
|||
|
||||
in vec3 t_vertex[];
|
||||
in vec3 t_normal[];
|
||||
#if defined(OFFSETMAPPING) || defined(SPECULAR) || defined(REFLECTCUBEMASK)
|
||||
#if defined(OFFSETMAPPING) || defined(SPECULAR) || defined(REFLECTCUBEMASK) || defined(PBR)
|
||||
in vec3 t_eyevector[];
|
||||
#endif
|
||||
#ifdef REFLECTCUBEMASK
|
||||
|
@ -235,7 +235,7 @@ void main()
|
|||
#ifdef REFLECTCUBEMASK
|
||||
invsurface = LERP(t_invsurface);
|
||||
#endif
|
||||
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)
|
||||
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)
|
||||
eyevector = LERP(t_eyevector);
|
||||
#endif
|
||||
|
||||
|
@ -331,37 +331,57 @@ void main ()
|
|||
#endif
|
||||
|
||||
// col *= factor_base;
|
||||
#define dielectricSpecular 0.04
|
||||
#ifdef SPECULAR
|
||||
vec4 specs = texture2D(s_specular, tc);//*factor_spec;
|
||||
#ifdef ORM
|
||||
#define occlusion specs.r
|
||||
#define roughness specs.g
|
||||
#define metalness specs.b
|
||||
#define gloss (1.0-roughness)
|
||||
#define ambientrgb (specrgb+col.rgb)
|
||||
vec3 specrgb = mix(vec3(dielectricSpecular), col.rgb, metalness);
|
||||
col.rgb = col.rgb * (1.0 - dielectricSpecular) * (1.0-metalness);
|
||||
#elif defined(SG) //pbr-style specular+glossiness
|
||||
//occlusion needs to be baked in. :(
|
||||
#define roughness (1.0-specs.a)
|
||||
#define gloss specs.a
|
||||
#define specrgb specs.rgb
|
||||
#define ambientrgb (specs.rgb+col.rgb)
|
||||
#else //blinn-phong
|
||||
#define roughness (1.0-specs.a)
|
||||
#define gloss specs.a
|
||||
#define specrgb specs.rgb
|
||||
#define ambientrgb col.rgb
|
||||
#endif
|
||||
#else
|
||||
#define roughness 0.3
|
||||
#define specrgb 1.0 //vec3(dielectricSpecular)
|
||||
#endif
|
||||
#define dielectricSpecular 0.04
|
||||
#ifdef SPECULAR
|
||||
vec4 specs = texture2D(s_specular, tc);//*factor_spec;
|
||||
#ifdef ORM
|
||||
#define occlusion specs.r
|
||||
#define roughness specs.g
|
||||
#define metalness specs.b
|
||||
#define gloss (1.0-roughness)
|
||||
#define ambientrgb (specrgb+col.rgb)
|
||||
vec3 specrgb = mix(vec3(dielectricSpecular), col.rgb, metalness);
|
||||
vec3 albedorgb = col.rgb * (1.0 - dielectricSpecular) * (1.0-metalness);
|
||||
#elif defined(SG) //pbr-style specular+glossiness
|
||||
//occlusion needs to be baked in. :(
|
||||
#define roughness (1.0-specs.a)
|
||||
#define gloss specs.a
|
||||
#define specrgb specs.rgb
|
||||
#define ambientrgb (specs.rgb+col.rgb)
|
||||
#define albedorgb col.rgb
|
||||
#elif defined(PBR) //PBR using legacy texturemaps
|
||||
#define gloss specs.a
|
||||
#define roughness (1.0-gloss)
|
||||
//metalness not relevant
|
||||
|
||||
//our pbr stuff doesn't much like our inputs.
|
||||
vec3 specrgb, albedorgb;
|
||||
//if (1==0)
|
||||
//{ //metal
|
||||
// specrgb = col.rgb;//+specs.rgb;
|
||||
// albedorgb = vec3(0.0);
|
||||
//}
|
||||
//else
|
||||
//{ //non-metal
|
||||
specrgb = vec3(dielectricSpecular);
|
||||
albedorgb = col.rgb;//+specs.rgb;
|
||||
//}
|
||||
#define ambientrgb col.rgb
|
||||
#else //blinn-phong
|
||||
#define gloss specs.a
|
||||
//occlusion not defined
|
||||
#define specrgb specs.rgb
|
||||
#endif
|
||||
#else
|
||||
//no specular map specified. doesn't mean we shouldn't have any though, at least with pbr enabled.
|
||||
#define roughness 0.3
|
||||
#define specrgb 1.0 //vec3(dielectricSpecular)
|
||||
#define albedorgb col.rgb
|
||||
#endif
|
||||
|
||||
//add in specular, if applicable.
|
||||
#ifdef PBR
|
||||
col.rgb = DoPBR(norm, normalize(eyevector), deluxe, roughness, col.rgb, specrgb, vec3(0.0,1.0,1.0));//*e_light_mul + e_light_ambient*.25*ambientrgb;
|
||||
col.rgb = DoPBR(norm, normalize(eyevector), deluxe, roughness, albedorgb, specrgb, vec3(0.0,1.0,1.0));//*e_light_mul + e_light_ambient*.25*ambientrgb;
|
||||
#elif defined(gloss)
|
||||
vec3 halfdir = normalize(normalize(eyevector) + deluxe); //this norm should be the deluxemap info instead
|
||||
float spec = pow(max(dot(halfdir, norm), 0.0), FTE_SPECULAR_EXPONENT * gloss);
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
#if defined(VERTEXCOLOURS)
|
||||
varying vec4 vc;
|
||||
#endif
|
||||
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)
|
||||
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)
|
||||
varying vec3 eyevector;
|
||||
#endif
|
||||
#ifdef REFLECTCUBEMASK
|
||||
|
@ -97,7 +97,7 @@ t = normalize(t);
|
|||
#if defined(VERTEXCOLOURS)
|
||||
vc = v_colour;
|
||||
#endif
|
||||
#if defined(SPECULAR)||defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)
|
||||
#if defined(SPECULAR)||defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)
|
||||
vec3 eyeminusvertex = e_eyepos - w.xyz;
|
||||
eyevector.x = dot(eyeminusvertex, s.xyz);
|
||||
eyevector.y = dot(eyeminusvertex, t.xyz);
|
||||
|
@ -138,7 +138,7 @@ out vec3 t_lightvector[];
|
|||
in vec4 vc[];
|
||||
out vec4 t_vc[];
|
||||
#endif
|
||||
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)
|
||||
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)
|
||||
in vec3 eyevector[];
|
||||
out vec3 t_eyevector[];
|
||||
#endif
|
||||
|
@ -153,7 +153,7 @@ void main()
|
|||
#if defined(VERTEXCOLOURS)
|
||||
t_vc[id] = vc[id];
|
||||
#endif
|
||||
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)
|
||||
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)
|
||||
t_eyevector[id] = eyevector[id];
|
||||
#endif
|
||||
|
||||
|
@ -182,7 +182,7 @@ in vec3 t_lightvector[];
|
|||
#if defined(VERTEXCOLOURS)
|
||||
in vec4 t_vc[];
|
||||
#endif
|
||||
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)
|
||||
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)
|
||||
in vec3 t_eyevector[];
|
||||
#endif
|
||||
|
||||
|
@ -208,7 +208,7 @@ void main()
|
|||
#if defined(VERTEXCOLOURS)
|
||||
vc = LERP(t_vc);
|
||||
#endif
|
||||
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)
|
||||
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) || defined(PBR)
|
||||
eyevector = LERP(t_eyevector);
|
||||
#endif
|
||||
|
||||
|
@ -275,7 +275,7 @@ void main ()
|
|||
vec4 lc = texture2D(s_lower, tcbase);
|
||||
bases.rgb += lc.rgb*e_lowercolour*lc.a;
|
||||
#endif
|
||||
#if defined(BUMP) || defined(SPECULAR) || defined(REFLECTCUBEMASK)
|
||||
#if defined(BUMP) || defined(SPECULAR) || defined(REFLECTCUBEMASK) || defined(PBR)
|
||||
vec3 bumps = normalize(vec3(texture2D(s_normalmap, tcbase)) - 0.5);
|
||||
#elif defined(REFLECTCUBEMASK)
|
||||
vec3 bumps = vec3(0.0,0.0,1.0);
|
||||
|
@ -308,7 +308,7 @@ void main ()
|
|||
#endif
|
||||
#else
|
||||
#define roughness 0.3
|
||||
#define specrgb 1.0 //vec3(dielectricSpecular)
|
||||
#define specrgb bases.rgb //vec3(dielectricSpecular)
|
||||
#endif
|
||||
|
||||
#ifdef PBR
|
||||
|
|
Loading…
Reference in a new issue