Added .dz playback support.

demo menu now properly lists the contents of archives.
demos played from subdirs/archives can now chain properly.
autodetect nehahra's demos. Add -nehahra argument to register/override cvar defaults (and set the right gamedir+startmap).
fix some q2 download bugs.
lame attempt at proper sRGB support (gl+vk+d3d9+d3d11 renderers).
fix q3bsp wrong-lightmaps bug.
match DP's viewzoom behaviour by not applying it when VF_[A]FOV was explicitly used.
fix d3d9 issue with missing textures screwing up blend modes.
vk: use a staging buffer instead of a staging textures per mip.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5128 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2017-07-12 08:15:27 +00:00
parent 2c17bcc3d5
commit 776b8f6565
61 changed files with 2930 additions and 684 deletions

View File

@ -781,6 +781,7 @@ COMMON_OBJS = \
fs_stdio.o \
fs_pak.o \
fs_zip.o \
fs_dzip.o \
fs_xz.o \
m_download.o \
mathlib.o \

View File

@ -31,8 +31,6 @@ int cls_lasttype;
void CL_PlayDemo(char *demoname, qboolean usesystempath);
void CL_PlayDemoFile(vfsfile_t *f, char *demoname, qboolean issyspath);
char lastdemoname[256];
static qboolean lastdemowassystempath;
extern cvar_t qtvcl_forceversion1;
extern cvar_t qtvcl_eztvextensions;
@ -439,10 +437,10 @@ void CL_DemoJump_f(void)
{
VFS_SEEK(df, 0);
cls.demoinfile = NULL;
CL_PlayDemoFile(df, lastdemoname, lastdemowassystempath);
CL_PlayDemoFile(df, cls.lastdemoname, cls.lastdemowassystempath);
}
else
CL_PlayDemo(lastdemoname, lastdemowassystempath);
CL_PlayDemo(cls.lastdemoname, cls.lastdemowassystempath);
//now fastparse it.
cls.demoseektime = newtime;
@ -1247,6 +1245,7 @@ void CLNQ_WriteServerData(sizebuf_t *buf)
{
default:
case CPNQ_ID: protmain = PROTOCOL_VERSION_NQ; break;
case CPNQ_NEHAHRA: protmain = PROTOCOL_VERSION_NEHD; break;
case CPNQ_BJP1: protmain = PROTOCOL_VERSION_BJP1; break;
case CPNQ_BJP2: protmain = PROTOCOL_VERSION_BJP2; break;
case CPNQ_BJP3: protmain = PROTOCOL_VERSION_BJP3; break;
@ -1274,14 +1273,14 @@ void CLNQ_WriteServerData(sizebuf_t *buf)
}
#endif
void CL_Record_Baseline(sizebuf_t *buf, entity_state_t *state, unsigned int bits)
void CL_Record_Baseline(sizebuf_t *buf, entity_state_t *state, unsigned int fitzbits)
{
unsigned int j;
if (bits & FITZ_B_LARGEMODEL)
if (fitzbits & FITZ_B_LARGEMODEL)
MSG_WriteShort (buf, state->modelindex);
else
MSG_WriteByte (buf, state->modelindex);
if (bits & FITZ_B_LARGEFRAME)
if (fitzbits & FITZ_B_LARGEFRAME)
MSG_WriteShort (buf, state->frame);
else
MSG_WriteByte (buf, state->frame);
@ -1293,9 +1292,9 @@ void CL_Record_Baseline(sizebuf_t *buf, entity_state_t *state, unsigned int bits
MSG_WriteAngle (buf, state->angles[j]);
}
if (bits & FITZ_B_ALPHA)
if (fitzbits & FITZ_B_ALPHA)
MSG_WriteByte(buf, state->trans);
if (bits & RMQFITZ_B_SCALE)
if (fitzbits & RMQFITZ_B_SCALE)
MSG_WriteByte(buf, state->scale);
}
@ -1404,40 +1403,40 @@ static int CL_Record_ParticlesStaticsBaselines(sizebuf_t *buf, int seq)
else
#endif
{
unsigned int bits = 0;
unsigned int fitzbits = 0; //must take some consistent form for this to work
#ifdef NQPROT
if (es->modelindex > 255)
bits |= FITZ_B_LARGEMODEL;
fitzbits |= FITZ_B_LARGEMODEL;
if (es->frame > 255)
bits |= FITZ_B_LARGEFRAME;
fitzbits |= FITZ_B_LARGEFRAME;
if (es->trans != 255)
bits |= FITZ_B_ALPHA;
fitzbits |= FITZ_B_ALPHA;
if (es->scale != 16)
bits |= RMQFITZ_B_SCALE;
fitzbits |= RMQFITZ_B_SCALE;
if (cls.protocol == CP_NETQUAKE && CPNQ_IS_BJP)
{
MSG_WriteByte (buf, svc_spawnbaseline);
bits = FITZ_B_LARGEMODEL; //bjp always uses shorts for models.
fitzbits = FITZ_B_LARGEMODEL; //bjp always uses shorts for models.
}
else if (cls.protocol == CP_NETQUAKE && cls.protocol_nq == CPNQ_FITZ666 && bits)
else if (cls.protocol == CP_NETQUAKE && cls.protocol_nq == CPNQ_FITZ666 && fitzbits)
{
MSG_WriteByte (buf, svcfitz_spawnbaseline2);
MSG_WriteByte (buf, bits);
MSG_WriteByte (buf, fitzbits);
}
else if (cls.protocol == CP_NETQUAKE && CPNQ_IS_DP && (bits & (FITZ_B_LARGEMODEL|FITZ_B_LARGEFRAME)))
else if (cls.protocol == CP_NETQUAKE && CPNQ_IS_DP && (fitzbits & (FITZ_B_LARGEMODEL|FITZ_B_LARGEFRAME)))
{
MSG_WriteByte (buf, svcdp_spawnbaseline2);
bits = FITZ_B_LARGEMODEL|FITZ_B_LARGEFRAME; //dp's baseline2 always has these (regular baseline is unmodified)
fitzbits = FITZ_B_LARGEMODEL|FITZ_B_LARGEFRAME; //dp's baseline2 always has these (regular baseline is unmodified)
}
else
#endif
{
MSG_WriteByte (buf,svc_spawnbaseline);
bits = 0;
fitzbits = 0;
}
MSG_WriteEntity (buf, i);
CL_Record_Baseline(buf, es, bits);
CL_Record_Baseline(buf, es, fitzbits);
}
if (buf->cursize > buf->maxsize/2)
CL_WriteRecordDemoMessage (buf, seq++);
@ -1989,6 +1988,9 @@ void CL_DemoList_c(int argn, char *partial, struct xcommandargcompletioncb_s *ct
COM_EnumerateFiles(va("%s*.dem", partial), CompleteDemoList, ctx);
COM_EnumerateFiles(va("%s*.mvd", partial), CompleteDemoList, ctx);
COM_EnumerateFiles(va("%s*.mvd.gz", partial), CompleteDemoList, ctx);
//fixme: show files in both .zip and .dz
// COM_EnumerateFiles(va("%s*.dz", partial), CompleteDemoList, ctx);
}
}
/*
@ -2172,8 +2174,8 @@ void CL_PlayDemoStream(vfsfile_t *file, char *filename, qboolean issyspath, int
}
if (filename)
{
Q_strncpyz (lastdemoname, filename, sizeof(lastdemoname));
lastdemowassystempath = issyspath;
Q_strncpyz (cls.lastdemoname, filename, sizeof(cls.lastdemoname));
cls.lastdemowassystempath = issyspath;
Con_Printf ("Playing demo from %s.\n", filename);
}
@ -2375,7 +2377,7 @@ void CL_PlayDemo(char *demoname, qboolean usesystempath)
TP_ExecTrigger ("f_demoend", true);
return;
}
Q_strncpyz (lastdemoname, demoname, sizeof(lastdemoname));
Q_strncpyz (cls.lastdemoname, demoname, sizeof(cls.lastdemoname));
#ifdef AVAIL_GZDEC
if (strlen(name) >= 3 && !Q_strcasecmp(name + strlen(name) - 3, ".gz"))

View File

@ -1700,7 +1700,7 @@ void CLNQ_ParseEntity(unsigned int bits)
entity_state_t *base;
packet_entities_t *pack;
qboolean isnehahra = CPNQ_IS_BJP;//||(cls.protocol_nq == CPNQ_ID && cls.demoplayback);
qboolean isnehahra = CPNQ_IS_BJP||(cls.protocol_nq == CPNQ_NEHAHRA);
if (cls.signon == 4 - 1)
{ // first update is the final signon stage
@ -1716,17 +1716,18 @@ void CLNQ_ParseEntity(unsigned int bits)
bits |= (i<<8);
}
if (!isnehahra)
if (bits & DPU_EXTEND1)
{
if (bits & DPU_EXTEND1)
if (!isnehahra)
{
i = MSG_ReadByte ();
bits |= (i<<16);
}
if (bits & DPU_EXTEND2)
{
i = MSG_ReadByte ();
bits |= (i<<24);
if (bits & DPU_EXTEND2)
{
i = MSG_ReadByte ();
bits |= (i<<24);
}
}
}
@ -1812,6 +1813,8 @@ void CLNQ_ParseEntity(unsigned int bits)
if (MSG_ReadFloat() > 0.5)
state->effects |= EF_FULLBRIGHT;
}
if (!alpha)
alpha = 1;
state->trans = bound(0, 255 * alpha, 255);
}
}
@ -1833,7 +1836,11 @@ void CLNQ_ParseEntity(unsigned int bits)
MSG_ReadByte();
}
else
{
{ //dp tends to leak stuff, so parse as quakedp if the normal protocol doesn't define it as something better.
// if (bits & DPU_DELTA) //should delta from the previous frame. DP doesn't generate this any more, so whatever.
// Host_EndGame("CLNQ_ParseEntity: DPU_DELTA not supported");
if (bits & DPU_ALPHA)
state->trans = MSG_ReadByte();

View File

@ -330,10 +330,7 @@ void CL_UpdateWindowTitle(void)
else
#endif
if (cls.demoplayback)
{
extern char lastdemoname[];
Q_snprintfz(title, sizeof(title), "%s: %s", fs_gamename.string, lastdemoname);
}
Q_snprintfz(title, sizeof(title), "%s: %s", fs_gamename.string, cls.lastdemoname);
else
Q_snprintfz(title, sizeof(title), "%s: %s", fs_gamename.string, cls.servername);
break;
@ -2564,7 +2561,7 @@ void CL_Startdemos_f (void)
for (i=1 ; i<c+1 ; i++)
Q_strncpyz (cls.demos[i-1], Cmd_Argv(i), sizeof(cls.demos[0]));
cls.demonum = 0;
cls.demonum = -1;
//don't start it here - we might have been given a +connect or whatever argument.
}
@ -3963,6 +3960,9 @@ void CL_Status_f(void)
if (cls.proquake_angles_hack)
Con_Printf("With ProQuake's extended angles\n");
break;
case CPNQ_NEHAHRA:
Con_Printf("Nehahra protocol\n");
break;
case CPNQ_BJP1:
Con_Printf("BJP1 protocol\n");
break;
@ -5766,7 +5766,10 @@ void CL_StartCinematicOrMenu(void)
M_Menu_Mods_f();
#endif
if (!cls.state && !Key_Dest_Has(kdm_emenu) && cl_demoreel.ival)
{
cls.demonum = 0;
CL_NextDemo();
}
if (!cls.state && !Key_Dest_Has(kdm_emenu))
//if we're (now) meant to be using csqc for menus, make sure that its running.
if (!CSQC_UnconnectedInit())

View File

@ -1129,7 +1129,10 @@ static void Model_CheckDownloads (void)
if (!cl.image_name[i] || !*cl.image_name[i])
continue;
Q_snprintfz(picname, sizeof(picname), "pics/%s.pcx", cl.image_name[i]);
CL_CheckOrEnqueDownloadFile(picname, picname, 0);
if (!strncmp(cl.image_name[i], "../", 3)) //some servers are just awkward.
CL_CheckOrEnqueDownloadFile(picname, picname+8, 0);
else
CL_CheckOrEnqueDownloadFile(picname, picname, 0);
}
if (!CLQ2_RegisterTEntModels())
return;
@ -2429,8 +2432,9 @@ void DL_Abort(qdownload_t *dl, enum qdlabort aborttype)
CLQ3_SendClientCommand("stopdl");
break;
#endif
case DL_DARKPLACES:
case DL_QW:
break;
case DL_DARKPLACES:
case DL_QWCHUNKS:
{
char *serverversion = Info_ValueForKey(cl.serverinfo, "*version");
@ -3438,8 +3442,19 @@ static void CLNQ_ParseProtoVersion(void)
cls.protocol_nq = CPNQ_ID;
cls.z_ext = 0;
#ifndef NOLEGACY
if (protover == PROTOCOL_VERSION_NQ && cls.demoplayback)
{
if (!Q_strcasecmp(FS_GetGamedir(true), "nehahra"))
protover = PROTOCOL_VERSION_NEHD; //if we're using the nehahra gamedir, pretend that it was the nehahra protocol version. clients should otherwise be using a different protocol.
}
#endif
if (protover == PROTOCOL_VERSION_NEHD)
Host_EndGame ("Nehahra demo net protocol is not supported\n");
{
cls.protocol_nq = CPNQ_NEHAHRA;
Con_DPrintf("Nehahra demo net protocol\n");
}
else if (protover == PROTOCOL_VERSION_FITZ)
{
//fitzquake 0.85
@ -3890,10 +3905,10 @@ static void CLNQ_ParseClientdata (void)
i = MSG_ReadByte();
if (i < 2)
i = 2;
CL_SetStatInt(0, STAT_VIEWZOOM, i);
CL_SetStatFloat(0, STAT_VIEWZOOM, i*(STAT_VIEWZOOM_SCALE/255.0));
}
else
CL_SetStatInt(0, STAT_VIEWZOOM, 255);
CL_SetStatFloat(0, STAT_VIEWZOOM, STAT_VIEWZOOM_SCALE);
}
}
#endif
@ -4115,6 +4130,8 @@ static void CLQ2_ParseConfigString (void)
if (i >= 0x8000 && i < 0x8000+MAX_PRECACHE_MODELS)
{
if (*s == '/')
s++; //*sigh*
Q_strncpyz(cl.model_name[i-0x8000], s, MAX_QPATH);
if (cl.model_name[i-0x8000][0] == '#')
{
@ -4125,14 +4142,17 @@ static void CLQ2_ParseConfigString (void)
}
cl.model_precache[i-0x8000] = NULL;
}
else
else if (cl.contentstage)
cl.model_precache[i-0x8000] = Mod_ForName (cl.model_name[i-0x8000], MLV_WARN);
return;
}
else if (i >= 0xc000 && i < 0xc000+MAX_PRECACHE_SOUNDS)
{
if (*s == '/')
s++; //*sigh*
Q_strncpyz(cl.sound_name[i-0xc000], s, MAX_QPATH);
cl.sound_precache[i-0xc000] = S_PrecacheSound (s);
if (cl.contentstage)
cl.sound_precache[i-0xc000] = S_PrecacheSound (s);
return;
}
@ -4186,6 +4206,8 @@ static void CLQ2_ParseConfigString (void)
}
else if (i >= Q2CS_MODELS && i < Q2CS_MODELS+Q2MAX_MODELS)
{
if (*s == '/')
s++; //*sigh*
Q_strncpyz(cl.model_name[i-Q2CS_MODELS], s, MAX_QPATH);
if (cl.model_name[i-Q2CS_MODELS][0] == '#')
{
@ -4196,13 +4218,16 @@ static void CLQ2_ParseConfigString (void)
}
cl.model_precache[i-Q2CS_MODELS] = NULL;
}
else
else if (cl.contentstage)
cl.model_precache[i-Q2CS_MODELS] = Mod_ForName (cl.model_name[i-Q2CS_MODELS], MLV_WARN);
}
else if (i >= Q2CS_SOUNDS && i < Q2CS_SOUNDS+Q2MAX_SOUNDS)
{
if (*s == '/')
s++; //*sigh*
Q_strncpyz(cl.sound_name[i-Q2CS_SOUNDS], s, MAX_QPATH);
cl.sound_precache[i-Q2CS_SOUNDS] = S_PrecacheSound (s);
if (cl.contentstage)
cl.sound_precache[i-Q2CS_SOUNDS] = S_PrecacheSound (s);
}
else if (i >= Q2CS_IMAGES && i < Q2CS_IMAGES+Q2MAX_IMAGES)
{
@ -6273,7 +6298,7 @@ static void CL_ParseStuffCmd(char *msg, int destsplit) //this protects stuffcmds
cl_dp_csqc_progscrc = atoi(stufftext+13);
//NQ servers/mods like spamming this. Its annoying, but we might as well use it if we can, while also muting it.
else if (!strncmp(stufftext, "cl_fullpitch ", 13) || !strncmp(stufftext, "pq_fullpitch ", 13))
else if (!strncmp(stufftext, "cl_fullpitch ", 13) || !strncmp(stufftext, "pq_fullpitch ", 13))
{
if (!cl.haveserverinfo)
{
@ -6284,16 +6309,6 @@ static void CL_ParseStuffCmd(char *msg, int destsplit) //this protects stuffcmds
}
#endif
else if (!strncmp(stufftext, "//querycmd ", 11)) //for servers to check if a command exists or not.
{
COM_Parse(stufftext + 11);
if (Cmd_Exists(com_token))
{
Cbuf_AddText ("cmd cmdsupported ", RESTRICT_SERVER+destsplit);
Cbuf_AddText (com_token, RESTRICT_SERVER+destsplit);
Cbuf_AddText ("\n", RESTRICT_SERVER+destsplit);
}
}
else if (!strncmp(stufftext, "//paknames ", 11)) //so that the client knows what to download...
{ //there's a couple of prefixes involved etc
Q_strncatz(cl.serverpaknames, stufftext+11, sizeof(cl.serverpaknames));
@ -6325,6 +6340,43 @@ static void CL_ParseStuffCmd(char *msg, int destsplit) //this protects stuffcmds
}
}
}
else if (cls.demoplayback && !strncmp(stufftext, "playdemo ", 9))
{ //some demos (like speed-demos-archive's marathon runs) chain multiple demos with playdemo commands
//these should still chain properly even when the demo is in some archive(like .dz) or subdir
char newdemo[MAX_OSPATH], temp[MAX_OSPATH], *s;
Cmd_TokenizeString(stufftext, false, false);
s = Cmd_Argv(1);
if (strchr(s, ':') || strchr(s, '/') || strchr(s, '\\'))
Q_strncpyz(newdemo, s, sizeof(newdemo));
else
{
newdemo[0] = 0;
if (cls.lastdemowassystempath)
Q_strncatz(newdemo, "#", sizeof(newdemo));
Q_strncatz(newdemo, cls.lastdemoname, sizeof(newdemo));
*COM_SkipPath(newdemo) = 0;
Q_strncatz(newdemo, Cmd_Argv(1), sizeof(newdemo));
}
Cbuf_AddText ("playdemo ", RESTRICT_SERVER+destsplit);
Cbuf_AddText (COM_QuotedString(newdemo, temp, sizeof(temp), false), RESTRICT_SERVER+destsplit);
Cbuf_AddText ("\n", RESTRICT_SERVER+destsplit);
}
#ifdef CSQC_DAT
else if (CSQC_StuffCmd(destsplit, stufftext, msg))
{
}
#endif
else if (!strncmp(stufftext, "//querycmd ", 11)) //for servers to check if a command exists or not.
{
COM_Parse(stufftext + 11);
if (Cmd_Exists(com_token))
{
Cbuf_AddText ("cmd cmdsupported ", RESTRICT_SERVER+destsplit);
Cbuf_AddText (com_token, RESTRICT_SERVER+destsplit);
Cbuf_AddText ("\n", RESTRICT_SERVER+destsplit);
}
}
else if (!strncmp(stufftext, "//exectrigger ", 14)) //so that mods can add whatever 'alias grabbedarmour' or whatever triggers that users might want to script responses for, without errors about unknown commands
{
COM_Parse(stufftext + 14);
@ -6405,11 +6457,6 @@ static void CL_ParseStuffCmd(char *msg, int destsplit) //this protects stuffcmds
Cmd_TokenizeString(stufftext+2, false, false);
Plug_Command_f();
}
#endif
#ifdef CSQC_DAT
else if (CSQC_StuffCmd(destsplit, stufftext, msg))
{
}
#endif
else
{

View File

@ -448,9 +448,10 @@ typedef struct
enum
{
CPNQ_ID,
CPNQ_BJP1, //16bit models, strict 8bit sounds
CPNQ_NEHAHRA,
CPNQ_BJP1, //16bit models, strict 8bit sounds (otherwise based on nehahra)
CPNQ_BJP2, //16bit models, strict 16bit sounds
CPNQ_BJP3, //16bit models, flagged 16bit sounds
CPNQ_BJP3, //16bit models, flagged 16bit sounds, 8bit static sounds.
CPNQ_FITZ666, /*and rmqe999 protocol*/
CPNQ_DP5,
CPNQ_DP6,
@ -504,6 +505,8 @@ typedef struct
qboolean demoseeking;
float demoseektime;
qboolean timedemo;
char lastdemoname[MAX_OSPATH];
qboolean lastdemowassystempath;
vfsfile_t *demoinfile;
float td_lastframe; // to meter out one message a frame
int td_startframe; // host_framecount at start

View File

@ -3062,6 +3062,10 @@ static void Image_GenerateMips(struct pendingtextureinfo *mips, unsigned int fla
mips->mipcount = mip+1;
}
return;
case PTI_RGBA8_SRGB:
case PTI_RGBX8_SRGB:
case PTI_BGRA8_SRGB:
case PTI_BGRX8_SRGB:
case PTI_RGBA8:
case PTI_RGBX8:
case PTI_BGRA8:
@ -4161,6 +4165,37 @@ static qboolean Image_GenMip0(struct pendingtextureinfo *mips, unsigned int flag
//FIXME: fill alpha channel with 255?
}
if (vid.srgb /*&& (flags & IF_SRGB)*/ && !(flags & IF_NOSRGB))
{ //most modern editors write srgb images.
//however, that might not be supported.
int nf = PTI_MAX;
switch(mips->encoding)
{
case PTI_RGBA8: nf = PTI_RGBA8_SRGB; break;
case PTI_RGBX8: nf = PTI_RGBX8_SRGB; break;
case PTI_BGRA8: nf = PTI_BGRA8_SRGB; break;
case PTI_BGRX8: nf = PTI_BGRX8_SRGB; break;
default:
if (freedata)
BZ_Free(rgbadata);
return false;
}
if (sh_config.texfmt[nf])
mips->encoding = nf;
else
{ //srgb->linear
int m = mips->mip[0].width*mips->mip[0].height*4;
if (mips->type == PTI_3D)
m *= mips->mip[0].height;
for (i = 0; i < m; i+=4)
{
((qbyte*)rgbadata)[i+0] = 255*Image_LinearFloatFromsRGBFloat(((qbyte*)rgbadata)[i+0] * (1.0/255));
((qbyte*)rgbadata)[i+1] = 255*Image_LinearFloatFromsRGBFloat(((qbyte*)rgbadata)[i+1] * (1.0/255));
((qbyte*)rgbadata)[i+2] = 255*Image_LinearFloatFromsRGBFloat(((qbyte*)rgbadata)[i+2] * (1.0/255));
}
}
}
Image_RoundDimensions(&mips->mip[0].width, &mips->mip[0].height, flags);
if (rgbadata)
@ -4170,7 +4205,7 @@ static qboolean Image_GenMip0(struct pendingtextureinfo *mips, unsigned int flag
else
{
mips->mip[0].data = BZ_Malloc(((mips->mip[0].width+3)&~3)*mips->mip[0].height*4);
// memset(mips->mip[0].data, 0, mips->mip[0].width*mips->mip[0].height*4);
//FIXME: should be sRGB-aware, but probably not a common path on hardware that can actually do srgb.
Image_ResampleTexture(rgbadata, imgwidth, imgheight, mips->mip[0].data, mips->mip[0].width, mips->mip[0].height);
if (freedata)
BZ_Free(rgbadata);
@ -4241,6 +4276,17 @@ static qboolean Image_LoadRawTexture(texid_t tex, unsigned int flags, void *rawd
tex->width = imgwidth;
tex->height = imgheight;
tex->flags &= ~IF_SRGB;
switch(mips->encoding)
{
case PTI_RGBA8_SRGB:
case PTI_RGBX8_SRGB:
case PTI_BGRA8_SRGB:
case PTI_BGRX8_SRGB:
tex->flags |= IF_SRGB;
break;
}
if (flags & IF_NOWORKER)
Image_LoadTextureMips(tex, mips, 0, 0);
else
@ -4786,7 +4832,7 @@ image_t *Image_FindTexture(const char *identifier, const char *subdir, unsigned
tex = Hash_Get(&imagetable, identifier);
while(tex)
{
if (!((tex->flags ^ flags) & (IF_CLAMP|IF_PALETTIZE)))
if (!((tex->flags ^ flags) & (IF_CLAMP|IF_PALETTIZE|IF_PREMULTIPLYALPHA)))
{
#ifdef PURGEIMAGES
if (!strcmp(subdir, tex->subpath?tex->subpath:""))

View File

@ -761,8 +761,8 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum, float frame
#ifdef QUAKESTATS
if (cl.playerview[pnum].statsf[STAT_VIEWZOOM])
{
mouse_x *= cl.playerview[pnum].statsf[STAT_VIEWZOOM]/255.0f;
mouse_y *= cl.playerview[pnum].statsf[STAT_VIEWZOOM]/255.0f;
mouse_x *= cl.playerview[pnum].statsf[STAT_VIEWZOOM]/STAT_VIEWZOOM_SCALE;
mouse_y *= cl.playerview[pnum].statsf[STAT_VIEWZOOM]/STAT_VIEWZOOM_SCALE;
}
#endif

View File

@ -703,15 +703,19 @@ static qboolean M_DemoKey(menucustom_t *control, menu_t *menu, int key, unsigned
{
extern int shift_down;
int extnum;
const char *ext = COM_GetFileExtension(info->selected->name, NULL);
for (extnum = 0; extnum < info->numext; extnum++)
if (!stricmp(info->selected->name + strlen(info->selected->name)-4, info->ext[extnum]))
if (!stricmp(ext, info->ext[extnum]))
break;
if (extnum == info->numext) //wasn't on our list of extensions.
extnum = 0;
if (!info->command[extnum])
return true; //FIXME: archives
{ //acceptable archive formats
ShowDemoMenu(menu, va("%s/", info->selected->name));
return true;
}
Cbuf_AddText(va("%s \"%s%s\"\n", info->command[extnum], (info->fs->fsroot==FS_SYSTEM)?"#":"", info->selected->name), RESTRICT_LOCAL);
if (!shift_down)
@ -745,7 +749,7 @@ static int QDECL DemoAddItem(const char *filename, qofs_t size, time_t modified,
if (i == NULL)
{
for (extnum = 0; extnum < menu->numext; extnum++)
if (!stricmp(filename + strlen(filename)-4, menu->ext[extnum]))
if (!stricmp(COM_GetFileExtension(filename, NULL), menu->ext[extnum]))
break;
if (extnum == menu->numext) //wasn't on our list of extensions.
@ -950,7 +954,8 @@ static void ShowDemoMenu (menu_t *menu, const char *path)
else
{
Q_snprintfz(match, sizeof(match), "%s*", info->fs->path);
COM_EnumerateFiles(match, DemoAddItem, info);
CL_ListFilesInPackage(NULL, match, DemoAddItem, info, NULL);
// COM_EnumerateFiles(match, DemoAddItem, info);
}
M_Demo_Flatten(info);
}
@ -1012,14 +1017,22 @@ void M_Menu_Demos_f (void)
//we don't support them, but if we were to ask quizmo to decode them for us, we could do.
//and some archive formats... for the luls
#ifdef PACKAGE_PK3
info->command[info->numext] = NULL;
info->ext[info->numext++] = ".zip";
info->command[info->numext] = NULL;
info->ext[info->numext++] = ".pk3";
info->command[info->numext] = NULL;
info->ext[info->numext++] = ".pk4";
#endif
#ifdef PACKAGE_Q1PAK
info->command[info->numext] = NULL;
info->ext[info->numext++] = ".pak";
#endif
#ifdef PACKAGE_DZIP
info->command[info->numext] = NULL;
info->ext[info->numext++] = ".dz";
#endif
MC_AddWhiteText(menu, 24, 170, 8, "Choose a Demo", false);
MC_AddWhiteText(menu, 16, 170, 24, "^Ue01d^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01f", false);

View File

@ -272,6 +272,9 @@ typedef struct texid_s texid_tf;
#define TEXVALID(t) 1
#endif
#define Image_LinearFloatFromsRGBFloat(c) (((c) <= 0.04045f) ? (c) * (1.0f / 12.92f) : (float)pow(((c) + 0.055f)*(1.0f/1.055f), 2.4f))
#define Image_sRGBFloatFromLinearFloat(c) (((c) < 0.0031308f) ? (c) * 12.92f : 1.055f * (float)pow((c), 1.0f/2.4f) - 0.055f)
struct pendingtextureinfo
{
enum
@ -280,6 +283,7 @@ struct pendingtextureinfo
PTI_3D,
PTI_CUBEMAP //mips are packed (to make d3d11 happy)
} type;
enum
{
//these formats are specified as direct byte access
@ -287,6 +291,10 @@ struct pendingtextureinfo
PTI_RGBX8, //rgb pad byte ordering
PTI_BGRA8, //alpha channel
PTI_BGRX8, //no alpha channel
PTI_RGBA8_SRGB, //rgba byte ordering
PTI_RGBX8_SRGB, //rgb pad byte ordering
PTI_BGRA8_SRGB, //alpha channel
PTI_BGRX8_SRGB, //no alpha channel
//these formats are specified in native endian order
PTI_RGB565, //16bit alphaless format.
PTI_RGBA4444, //16bit format (gl)
@ -311,7 +319,7 @@ struct pendingtextureinfo
PTI_DEPTH24,
PTI_DEPTH32,
PTI_DEPTH24_8,
PTI_MAX
PTI_MAX,
} encoding; //0
int mipcount;
struct

View File

@ -3327,10 +3327,7 @@ static const char *PF_cs_serverkey_internal(const char *keyname)
if (!strcmp(keyname, "ip"))
{
if (cls.demoplayback)
{
extern char lastdemoname[];
ret = lastdemoname;
}
ret = cls.lastdemoname;
else
ret = NET_AdrToString(adr, sizeof(adr), &cls.netchan.remote_address);
}

View File

@ -89,9 +89,9 @@ static void R_BuildDefaultTexnums_Doom3(shader_t *shader)
if ((shader->flags & SHADER_HASNORMALMAP) && r_loadbumpmapping)
{
if (!TEXVALID(tex->bump) && *mapname && (shader->flags & SHADER_HASNORMALMAP))
tex->bump = R_LoadHiResTexture(va("%s_local", mapname), NULL, imageflags|IF_TRYBUMP);
tex->bump = R_LoadHiResTexture(va("%s_local", mapname), NULL, imageflags|IF_TRYBUMP|IF_NOSRGB);
if (!TEXVALID(tex->bump))
tex->bump = R_LoadHiResTexture(va("%s_local", imagename), subpath, imageflags|IF_TRYBUMP);
tex->bump = R_LoadHiResTexture(va("%s_local", imagename), subpath, imageflags|IF_TRYBUMP|IF_NOSRGB);
}
}

View File

@ -3483,6 +3483,28 @@ void Surf_BuildModelLightmaps (model_t *m)
int j;
unsigned char *src;
unsigned char *dst;
//fixup surface lightmaps, and paint
for (i=0; i<m->nummodelsurfaces; i++)
{
surf = m->surfaces + i + m->firstmodelsurface;
for (j = 0; j < MAXRLIGHTMAPS; j++)
{
if (surf->lightmaptexturenums[j] < m->lightmaps.first)
{
surf->lightmaptexturenums[j] = -1;
continue;
}
if (surf->lightmaptexturenums[j] >= m->lightmaps.first+m->lightmaps.count)
{
surf->lightmaptexturenums[j] = -1;
continue;
}
surf->lightmaptexturenums[j] = surf->lightmaptexturenums[0] - m->lightmaps.first + newfirst;
}
}
if (!m->submodelof)
for (i = 0; i < m->lightmaps.count; i++)
{

View File

@ -399,17 +399,21 @@ enum imageflags
IF_NEAREST = 1<<2, //force nearest
IF_LINEAR = 1<<3, //force linear
IF_UIPIC = 1<<4, //subject to texturemode2d
//IF_DEPTHCMD=1<<5, //Reserved for d3d11
IF_SRGB = 1<<6, //texture data is srgb
/*WARNING: If the above are changed, be sure to change shader pass flags*/
IF_NOPICMIP = 1<<5,
IF_NOALPHA = 1<<6, /*hint rather than requirement*/
IF_NOGAMMA = 1<<7,
IF_3DMAP = 1<<8, /*waning - don't test directly*/
IF_CUBEMAP = 1<<9, /*waning - don't test directly*/
IF_TEXTYPE = (1<<8) | (1<<9), /*0=2d, 1=3d, 2=cubeface, 3=?*/
IF_TEXTYPESHIFT = 8, /*0=2d, 1=3d, 2-7=cubeface*/
IF_MIPCAP = 1<<10,
IF_PREMULTIPLYALPHA = 1<<12, //rgb *= alpha
IF_NOPICMIP = 1<<7,
IF_NOALPHA = 1<<8, /*hint rather than requirement*/
IF_NOGAMMA = 1<<9,
IF_3DMAP = 1<<10, /*waning - don't test directly*/
IF_CUBEMAP = 1<<11, /*waning - don't test directly*/
IF_TEXTYPE = (1<<10) | (1<<11), /*0=2d, 1=3d, 2=cubeface, 3=?*/
IF_TEXTYPESHIFT = 10, /*0=2d, 1=3d, 2-7=cubeface*/
IF_MIPCAP = 1<<12,
IF_PREMULTIPLYALPHA = 1<<13, //rgb *= alpha
IF_NOSRGB = 1<<20, //ignore srgb when loading. this is guarenteed to be linear, for normalmaps etc.
IF_PALETTIZE = 1<<21,
IF_NOPURGE = 1<<22,

View File

@ -255,7 +255,7 @@ cvar_t vid_multisample = CVARFD ("vid_multisample", "0",
cvar_t vid_refreshrate = CVARF ("vid_displayfrequency", "0",
CVAR_ARCHIVE | CVAR_RENDERERLATCH);
cvar_t vid_srgb = CVARFD ("vid_srgb", "0",
CVAR_ARCHIVE, "The framebuffer should use sRGB colourspace. This has the effect of brightening the screen");
CVAR_ARCHIVE, "0: Off. Colour blending will be wrong.\n1: Only the framebuffer should use sRGB colourspace, textures and colours will be assumed to be linear. This has the effect of brightening the screen.\n2: Use sRGB extensions/support to ensure that the sh");
cvar_t vid_wndalpha = CVARD ("vid_wndalpha", "1", "When running windowed, specifies the window's transparency level.");
//more readable defaults to match conwidth/conheight.
cvar_t vid_width = CVARFD ("vid_width", "0",

View File

@ -88,6 +88,7 @@ typedef struct
unsigned height; /*virtual 2d screen height*/
int numpages;
qboolean srgb; /*we're forcing linear fragment shaders, both inputs and outputs (and not using srgb as a gamma hack)*/
unsigned rotpixelwidth; /*width after rotation in pixels*/
unsigned rotpixelheight; /*pixel after rotation in pixels*/

View File

@ -1170,11 +1170,13 @@ void V_ApplyAFov(playerview_t *pv)
float afov = r_refdef.afov;
if (!afov) //make sure its sensible.
{
afov = scr_fov.value;
#ifdef QUAKESTATS
if (pv && pv->statsf[STAT_VIEWZOOM])
afov *= pv->statsf[STAT_VIEWZOOM]/255.0f;
if (pv && pv->statsf[STAT_VIEWZOOM]) //match dp - viewzoom only happens when defaulted.
afov *= pv->statsf[STAT_VIEWZOOM]/STAT_VIEWZOOM_SCALE;
#endif
}
afov = bound(0.001, afov, 170);
ws = 1;

View File

@ -281,6 +281,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// #define HLCLIENT 7 //we can run HL gamecode (not protocol compatible, set to 6 or 7)
// #define HLSERVER 140 //we can run HL gamecode (not protocol compatible, set to 138 or 140)
#define NQPROT //server and client are capable of using quake1/netquake protocols. (qw is still prefered. uses the command 'nqconnect')
#define PACKAGE_DZIP //support for the dzip format, common with the speed-demos-archive site
// #define WEBSERVER //http server
#define FTPSERVER //ftp server
#define WEBCLIENT //http clients.
@ -587,6 +588,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#undef QWOVERQ3
#endif
#if !defined(NQPROT) || defined(SERVERONLY) || !defined(AVAIL_ZLIB) || defined(DYNAMIC_ZLIB)
#undef PACKAGE_DZIP
#endif
//fix things a little...
#ifdef NPQTV
#define NPFTE
@ -981,6 +986,7 @@ STAT_MATCHSTARTTIME = 18,
STAT_VIEW2 = 20,
#endif
STAT_VIEWZOOM = 21, // DP
#define STAT_VIEWZOOM_SCALE 255
//STAT_UNUSED = 22,
//STAT_UNUSED = 23,
//STAT_UNUSED = 24,

View File

@ -3364,7 +3364,7 @@ static void *Q1MDL_LoadSkins_GL (galiasinfo_t *galias, dmdl_t *pq1inmodel, model
if (r_loadbumpmapping)
{
Q_snprintfz(skinname, sizeof(skinname), "%s_%i_norm.lmp", slash, i);
frames[0].texnums.bump = R_LoadReplacementTexture(skinname, alttexpath, texflags|IF_TRYBUMP, frames[0].texels, outskin->skinwidth, outskin->skinheight, TF_HEIGHT8PAL);
frames[0].texnums.bump = R_LoadReplacementTexture(skinname, alttexpath, texflags|IF_TRYBUMP|IF_NOSRGB, frames[0].texels, outskin->skinwidth, outskin->skinheight, TF_HEIGHT8PAL);
}
Q_snprintfz(skinname, sizeof(skinname), "%s_%i_shirt.lmp", slash, i);
frames[0].texnums.upperoverlay = R_LoadReplacementTexture(skinname, alttexpath, texflags, NULL, outskin->skinwidth, outskin->skinheight, TF_INVALID);

View File

@ -2104,7 +2104,7 @@ void COM_CleanUpPath(char *str)
while ((dots = strstr(str, "..")))
{
criticize = 0;
for (slash = dots-2; slash >= str; slash--)
for (slash = dots-1; slash >= str; slash--)
{
if (*slash == '/')
{

View File

@ -599,6 +599,7 @@ void FS_PureMode(int mode, char *purenamelist, char *purecrclist, char *refnamel
//recursively tries to open files until it can get a zip.
vfsfile_t *CL_OpenFileInPackage(searchpathfuncs_t *search, char *name);
qboolean CL_ListFilesInPackage(searchpathfuncs_t *search, char *name, int (QDECL *func)(const char *fname, qofs_t fsize, time_t mtime, void *parm, searchpathfuncs_t *spath), void *parm, void *recursioninfo);
qbyte *QDECL COM_LoadStackFile (const char *path, void *buffer, int bufsize, size_t *fsize);
qbyte *COM_LoadTempFile (const char *path, size_t *fsize);

View File

@ -1717,6 +1717,7 @@ qboolean FS_NativePath(const char *fname, enum fs_relative relativeto, char *out
last = fs_manifest->gamepath[i].path;
if (*last == '*')
last++;
break;
}
}
if (!last)
@ -1735,6 +1736,7 @@ qboolean FS_NativePath(const char *fname, enum fs_relative relativeto, char *out
if (*fs_manifest->gamepath[i].path == '*')
continue;
last = fs_manifest->gamepath[i].path;
break;
}
}
if (!last)
@ -1753,6 +1755,7 @@ qboolean FS_NativePath(const char *fname, enum fs_relative relativeto, char *out
if (*fs_manifest->gamepath[i].path == '*')
continue;
last = fs_manifest->gamepath[i].path;
break;
}
}
if (!last)
@ -2435,11 +2438,11 @@ void FS_AddHashedPackage(searchpath_t **oldpaths, const char *parentpath, const
{
if (search->handle->FindFile(search->handle, &loc, pakpath+ptlen+1, NULL))
{
vfs = search->handle->OpenVFS(search->handle, &loc, "r");
vfs = search->handle->OpenVFS(search->handle, &loc, "rb");
snprintf (lname, sizeof(lname), "%s", lname2);
}
else if (search->handle->FindFile(search->handle, &loc, pname+ptlen+1, NULL))
vfs = search->handle->OpenVFS(search->handle, &loc, "r");
vfs = search->handle->OpenVFS(search->handle, &loc, "rb");
}
else
{
@ -2594,7 +2597,7 @@ static void FS_AddDataFiles(searchpath_t **oldpaths, const char *purepath, const
handle = FS_GetOldPath(oldpaths, pakfile, &keptflags);
if (!handle)
{
vfs = search->handle->OpenVFS(search->handle, &loc, "r");
vfs = search->handle->OpenVFS(search->handle, &loc, "rb");
if (!vfs)
break;
handle = searchpathformats[j].OpenNew (vfs, pakfile, "");
@ -3018,6 +3021,8 @@ void COM_Gamedir (const char *dir, const struct gamepacks *packagespaths)
/*quake requires a few settings for compatibility*/
#define EZQUAKECOMPETITIVE "set ruleset_allow_fbmodels 1\n"
#define QCFG "set com_parseutf8 0\nset allow_download_refpackages 0\nset sv_bigcoords \"\"\nmap_autoopenportals 1\n" "sv_port "STRINGIFY(PORT_QWSERVER)" "STRINGIFY(PORT_NQSERVER)"\n" ZFIXHACK EZQUAKECOMPETITIVE
//nehahra has to be weird with extra cvars, and buggy fullbrights.
#define NEHCFG QCFG "set nospr32 0\nset cutscene 1\nalias startmap_sp \"map nehstart\"\nr_fb_bmodels 0\nr_fb_models 0\n"
/*stuff that makes dp-only mods work a bit better*/
#define DPCOMPAT QCFG "set _cl_playermodel \"\"\n set dpcompat_set 1\nset dpcompat_corruptglobals 1\nset vid_pixelheight 1\n"
/*nexuiz/xonotic has a few quirks/annoyances...*/
@ -3084,6 +3089,10 @@ const gamemode_info_t gamemode_info[] = {
{"-hipnotic", "hipnotic", "FTE-Hipnotic",{"id1/pak0.pak","id1/quake.rc"},QCFG, {"id1", "qw", "hipnotic", "*fte"}, "Quake: Scourge of Armagon"},
{"-rogue", "rogue", "FTE-Rogue", {"id1/pak0.pak","id1/quake.rc"},QCFG, {"id1", "qw", "rogue", "*fte"}, "Quake: Dissolution of Eternity"},
//various quake-dependant non-standalone mods that require hacks
//quoth needed an extra arg just to enable hipnotic hud drawing, it doesn't actually do anything weird, but most engines have a -quoth arg, so lets have one too.
{"-quoth", "quoth", "FTE-Quake", {"id1/pak0.pak","id1/quake.rc"},QCFG, {"id1", "qw", "quoth", "*fte"}, "Quake: Quoth"},
{"-nehahra", "nehahra", "FTE-Quake", {"id1/pak0.pak","id1/quake.rc"},NEHCFG, {"id1", "qw", "nehahra", "*fte"}, "Quake: Seal Of Nehahra"},
//various quake-based standalone mods.
{"-nexuiz", "nexuiz", "Nexuiz", {"nexuiz.exe"}, NEXCFG, {"data", "*ftedata"}, "Nexuiz"},
{"-xonotic", "xonotic", "Xonotic", {"xonotic.exe"}, NEXCFG, {"data", "*ftedata"}, "Xonotic"},
@ -3327,6 +3336,113 @@ vfsfile_t *CL_OpenFileInPackage(searchpathfuncs_t *search, char *name)
return NULL;
}
//some annoying struct+func to prefix the enumerated file name properly.
struct CL_ListFilesInPackageCB_s
{
char *nameprefix;
size_t nameprefixlen;
int (QDECL *func)(const char *fname, qofs_t fsize, time_t mtime, void *parm, searchpathfuncs_t *spath);
void *parm;
searchpathfuncs_t *spath;
};
static int QDECL CL_ListFilesInPackageCB(const char *fname, qofs_t fsize, time_t mtime, void *parm, searchpathfuncs_t *spath)
{
struct CL_ListFilesInPackageCB_s *cb = parm;
char name[MAX_OSPATH];
if (cb->nameprefixlen)
{
memcpy(name, cb->nameprefix, cb->nameprefixlen-1);
name[cb->nameprefixlen-1] = '/';
Q_strncpyz(name+cb->nameprefixlen, fname, sizeof(name)-(cb->nameprefixlen));
return cb->func(name, fsize, mtime, cb->parm, cb->spath);
}
else
return cb->func(fname, fsize, mtime, cb->parm, cb->spath);
}
//'small' wrapper to list foo.zip/* to list files within zips that are not part of the gamedir.
//same rules as CL_OpenFileInPackage, except that wildcards should only be in the final part
qboolean CL_ListFilesInPackage(searchpathfuncs_t *search, char *name, int (QDECL *func)(const char *fname, qofs_t fsize, time_t mtime, void *parm, searchpathfuncs_t *spath), void *parm, void *recursioninfo)
{
int found;
vfsfile_t *f;
flocation_t loc;
char e, *n;
char ext[8];
char *end;
int i;
qboolean ret = false;
struct CL_ListFilesInPackageCB_s cb;
cb.nameprefix = recursioninfo?recursioninfo:name;
cb.nameprefixlen = name-cb.nameprefix;
cb.func = func;
cb.parm = parm;
//keep chopping off the last part of the filename until we get an actual package
//once we do, recurse into that package
end = name + strlen(name);
while (end > name)
{
e = *end;
*end = 0;
COM_FileExtension(name, ext, sizeof(ext));
for (i = 0; i < countof(searchpathformats); i++)
{
if (!searchpathformats[i].extension || !searchpathformats[i].OpenNew)
continue;
if (!strcmp(ext, searchpathformats[i].extension))
{
loc.search = NULL;
if (search)
found = search->FindFile(search, &loc, name, NULL);
else
found = FS_FLocateFile(name, FSLF_IFFOUND, &loc);
if (found)
{
f = (search?search:loc.search->handle)->OpenVFS(search?search:loc.search->handle, &loc, "rb");
if (f)
{
searchpathfuncs_t *newsearch = searchpathformats[i].OpenNew(f, name, "");
if (newsearch)
{
ret = CL_ListFilesInPackage(newsearch, end+1, func, parm, cb.nameprefix);
newsearch->ClosePath(newsearch);
if (ret)
{
*end = e;
return ret;
}
}
else
VFS_CLOSE(f);
}
}
break;
}
}
n = COM_SkipPath(name);
*end = e;
end = n-1;
}
//always open the last file properly.
loc.search = NULL;
if (search)
ret = search->EnumerateFiles(search, name, CL_ListFilesInPackageCB, &cb);
else
{
ret = true;
if (ret)
COM_EnumerateFiles(name, CL_ListFilesInPackageCB, &cb);
}
return ret;
}
void FS_PureMode(int puremode, char *purenamelist, char *purecrclist, char *refnamelist, char *refcrclist, int pureseed)
{
qboolean pureflush;
@ -5930,6 +6046,9 @@ extern searchpathfuncs_t *(QDECL FSDWD_LoadArchive) (vfsfile_t *packhandle, cons
#endif
void FS_RegisterDefaultFileSystems(void)
{
#ifdef PACKAGE_DZIP
FS_RegisterFileSystemType(NULL, "dz", FSDZ_LoadArchive, false);
#endif
#ifdef PACKAGE_Q1PAK
FS_RegisterFileSystemType(NULL, "pak", FSPAK_LoadArchive, true);
#if !defined(_WIN32) && !defined(ANDROID)

View File

@ -60,6 +60,7 @@ extern searchpathfuncs_t *(QDECL VFSOS_OpenPath) (vfsfile_t *file, const char *d
extern searchpathfuncs_t *(QDECL FSZIP_LoadArchive) (vfsfile_t *packhandle, const char *desc, const char *prefix);
extern searchpathfuncs_t *(QDECL FSPAK_LoadArchive) (vfsfile_t *packhandle, const char *desc, const char *prefix);
extern searchpathfuncs_t *(QDECL FSDWD_LoadArchive) (vfsfile_t *packhandle, const char *desc, const char *prefix);
extern searchpathfuncs_t *(QDECL FSDZ_LoadArchive) (vfsfile_t *file, const char *desc, const char *prefix);
vfsfile_t *QDECL VFSOS_Open(const char *osname, const char *mode);
vfsfile_t *FS_DecompressGZip(vfsfile_t *infile, vfsfile_t *outfile);

1484
engine/common/fs_dzip.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -2882,6 +2882,7 @@ static qboolean CModQ3_LoadRFaces (model_t *mod, qbyte *mod_base, lump_t *l)
mod->surfaces = out;
mod->numsurfaces = count;
mod->lightmaps.first = 0;
for (surfnum = 0; surfnum < count; surfnum++, out++, in++, pl++)
{

View File

@ -242,7 +242,7 @@ typedef struct
unsigned int texflags[MAX_TMUS];
unsigned int tmuflags[MAX_TMUS];
ID3D11SamplerState *cursamplerstate[MAX_TMUS];
ID3D11SamplerState *sampstate[(SHADER_PASS_IMAGE_FLAGS|SHADER_PASS_DEPTHCMP)+1];
ID3D11SamplerState *sampstate[SHADER_PASS_IMAGE_FLAGS_D3D11+1];
ID3D11DepthStencilState *depthstates[1u<<4]; //index, its fairly short.
blendstates_t *blendstates; //list. this could get big.
@ -305,7 +305,7 @@ void D3D11_UpdateFiltering(image_t *imagelist, int filtermip[3], int filterpic[3
{
D3D11_SAMPLER_DESC sampdesc;
int flags;
for (flags = 0; flags <= (SHADER_PASS_IMAGE_FLAGS|SHADER_PASS_DEPTHCMP); flags++)
for (flags = 0; flags <= (SHADER_PASS_IMAGE_FLAGS_D3D11); flags++)
{
int *filter;
sampdesc.Filter = 0;
@ -386,7 +386,7 @@ static void BE_DestroyVariousStates(void)
if (d3ddevctx && i)
ID3D11DeviceContext_PSSetSamplers(d3ddevctx, 0, i, shaderstate.cursamplerstate);
for (flags = 0; flags <= (SHADER_PASS_IMAGE_FLAGS|SHADER_PASS_DEPTHCMP); flags++)
for (flags = 0; flags <= SHADER_PASS_IMAGE_FLAGS_D3D11; flags++)
{
if (shaderstate.sampstate[flags])
ID3D11SamplerState_Release(shaderstate.sampstate[flags]);
@ -459,7 +459,7 @@ static void BE_ApplyTMUState(unsigned int tu, unsigned int flags)
{
ID3D11SamplerState *nstate;
flags = (flags & (SHADER_PASS_IMAGE_FLAGS|SHADER_PASS_DEPTHCMP));
flags = (flags & SHADER_PASS_IMAGE_FLAGS_D3D11);
flags |= shaderstate.texflags[tu];
nstate = shaderstate.sampstate[flags];
if (nstate != shaderstate.cursamplerstate[tu])
@ -958,7 +958,7 @@ static void BindTexture(unsigned int tu, const texid_t id)
shaderstate.textureschanged = true;
shaderstate.pendingtextures[tu] = view;
if (id)
shaderstate.texflags[tu] = id->flags&SHADER_PASS_IMAGE_FLAGS;
shaderstate.texflags[tu] = id->flags&SHADER_PASS_IMAGE_FLAGS_D3D11;
}
}

View File

@ -213,6 +213,23 @@ qboolean D3D11_LoadTextureMips(image_t *tex, struct pendingtextureinfo *mips)
bytesperpixel = 4;
break;
case PTI_RGBA8_SRGB:
tdesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
bytesperpixel = 4;
break;
case PTI_RGBX8_SRGB: //d3d11 has no alphaless format. be sure to proprly disable alpha in the shader.
tdesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
bytesperpixel = 4;
break;
case PTI_BGRA8_SRGB:
tdesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
bytesperpixel = 4;
break;
case PTI_BGRX8_SRGB:
tdesc.Format = DXGI_FORMAT_B8G8R8X8_UNORM_SRGB;
bytesperpixel = 4;
break;
case PTI_S3RGB1: //d3d11 provides no way to disable alpha with dxt1. be sure to proprly disable alpha in the shader.
case PTI_S3RGBA1:
tdesc.Format = DXGI_FORMAT_BC1_UNORM;

View File

@ -535,7 +535,7 @@ static void BindTexture(unsigned int tu, texid_t tex)
if (tex)
{
dt = tex->ptr;
shaderstate.curtexflags[tu] = tex->flags & SHADER_PASS_IMAGE_FLAGS;
shaderstate.curtexflags[tu] = tex->flags & SHADER_PASS_IMAGE_FLAGS_D3D8;
}
else
dt = NULL;

View File

@ -53,6 +53,7 @@ extern LPDIRECT3DDEVICE9 pD3DDev9;
#define MAX_TC_TMUS 4
extern texid_t r_whiteimage;
extern float d3d_trueprojection[16];
static void BE_RotateForEntity (const entity_t *e, const model_t *mod);
@ -265,6 +266,8 @@ static void BE_ApplyTMUState(unsigned int tu, unsigned int flags)
unsigned int delta = shaderstate.tmuflags[tu] ^ flags;
if (!delta)
return;
if (delta & SHADER_PASS_SRGB)
IDirect3DDevice9_SetSamplerState(pD3DDev9, tu, D3DSAMP_SRGBTEXTURE, (flags & SHADER_PASS_SRGB)?TRUE:FALSE);
if (delta & SHADER_PASS_CLAMP)
{
if (flags & SHADER_PASS_CLAMP)
@ -715,11 +718,14 @@ static unsigned int allocindexbuffer(void **dest, unsigned int entries)
static void BindTexture(unsigned int tu, texid_t tex)
{
extern texid_t r_whiteimage;
IDirect3DTexture9 *dt;
if (tex)
{
dt = tex->ptr;
shaderstate.curtexflags[tu] = tex->flags & SHADER_PASS_IMAGE_FLAGS;
if (!dt)
dt = r_whiteimage->ptr;
shaderstate.curtexflags[tu] = tex->flags & SHADER_PASS_IMAGE_FLAGS_D3D9;
}
else
dt = NULL;

View File

@ -48,19 +48,23 @@ qboolean D3D9_LoadTextureMips(image_t *tex, struct pendingtextureinfo *mips)
pixelsize = 2;
fmt = D3DFMT_A1R5G5B5;
break;
case PTI_RGBA8_SRGB:
case PTI_RGBA8:
// fmt = D3DFMT_A8B8G8R8; /*how do we check
fmt = D3DFMT_A8R8G8B8;
swap = true;
break;
case PTI_RGBX8_SRGB:
case PTI_RGBX8:
// fmt = D3DFMT_X8B8G8R8;
fmt = D3DFMT_X8R8G8B8;
swap = true;
break;
case PTI_BGRA8_SRGB:
case PTI_BGRA8:
fmt = D3DFMT_A8R8G8B8;
break;
case PTI_BGRX8_SRGB:
case PTI_BGRX8:
fmt = D3DFMT_X8R8G8B8;
break;

View File

@ -473,15 +473,6 @@ void D3D9Shader_Init(void)
sh_config.nv_tex_env_combine4 = 1;
sh_config.env_add = 1;
//FIXME: check caps
sh_config.texfmt[PTI_RGBX8] = true; //fixme: shouldn't support
sh_config.texfmt[PTI_RGBA8] = true; //fixme: shouldn't support
sh_config.texfmt[PTI_BGRX8] = true;
sh_config.texfmt[PTI_BGRA8] = true;
sh_config.texfmt[PTI_RGB565] = true;
sh_config.texfmt[PTI_ARGB1555] = true;
sh_config.texfmt[PTI_ARGB4444] = true;
sh_config.can_mipcap = true; //at creation time, I think.
IDirect3DDevice9_GetDeviceCaps(pD3DDev9, &caps);

View File

@ -14,6 +14,9 @@
#endif
#include <d3d9.h>
#ifndef D3DPRESENT_LINEAR_CONTENT
#define D3DPRESENT_LINEAR_CONTENT 2
#endif
//#pragma comment(lib, "../libs/dxsdk9/lib/d3d9.lib")
@ -65,6 +68,7 @@ extern qboolean scr_con_forcedraw;
static qboolean d3d_resized;
extern cvar_t vid_hardwaregamma;
extern cvar_t vid_srgb;
//sound/error code needs this
@ -434,7 +438,15 @@ static LRESULT WINAPI D3D9_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
static void D3D9_VID_SwapBuffers(void)
{
IDirect3DDevice9_Present(pD3DDev9, NULL, NULL, NULL, NULL);
if (d3dpp.Windowed && (vid_srgb.ival==1 || vid.srgb))
{
IDirect3DSwapChain9 *swapchain;
IDirect3DDevice9_GetSwapChain(pD3DDev9, 0, &swapchain);
IDirect3DSwapChain9_Present(swapchain, NULL, NULL, NULL, NULL, D3DPRESENT_LINEAR_CONTENT);
IDirect3DSwapChain9_Release(swapchain);
}
else
IDirect3DDevice9_Present(pD3DDev9, NULL, NULL, NULL, NULL);
}
static void resetD3D9(void)
@ -452,7 +464,7 @@ static void resetD3D9(void)
IDirect3DDevice9_BeginScene(pD3DDev9);
IDirect3DDevice9_Clear(pD3DDev9, 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
IDirect3DDevice9_EndScene(pD3DDev9);
IDirect3DDevice9_Present(pD3DDev9, NULL, NULL, NULL, NULL);
D3D9_VID_SwapBuffers();
@ -587,6 +599,36 @@ static qboolean initD3D9Device(HWND hWnd, rendererstate_t *info, unsigned int de
MoveWindow(d3dpp.hDeviceWindow, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, false);
}
D3D9Shader_Init();
{
int i;
struct {
unsigned int pti;
unsigned int d3d9;
unsigned int usage;
} fmts[] =
{
{PTI_BGRX8, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_FILTER},
{PTI_BGRA8, D3DFMT_A8R8G8B8, D3DUSAGE_QUERY_FILTER},
{PTI_RGB565, D3DFMT_R5G6B5, D3DUSAGE_QUERY_FILTER},
{PTI_ARGB1555, D3DFMT_A1R5G5B5, D3DUSAGE_QUERY_FILTER},
{PTI_ARGB4444, D3DFMT_A4R4G4B4, D3DUSAGE_QUERY_FILTER},
{PTI_BGRX8_SRGB, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_SRGBREAD},
{PTI_BGRA8_SRGB, D3DFMT_A8R8G8B8, D3DUSAGE_QUERY_SRGBREAD},
};
for (i = 0; i < countof(fmts); i++)
if (SUCCEEDED(IDirect3D9_CheckDeviceFormat(pD3D, devno, devtype, d3dpp.BackBufferFormat, fmts[i].usage, D3DRTYPE_TEXTURE, fmts[i].d3d9)))
sh_config.texfmt[fmts[i].pti] = true;
}
//fixme: the engine kinda insists on rgba textures, which d3d9 does NOT support.
//we currently have some swapping, so these load, just slowly.
sh_config.texfmt[PTI_RGBX8] = sh_config.texfmt[PTI_BGRX8];
sh_config.texfmt[PTI_RGBA8] = sh_config.texfmt[PTI_BGRA8];
sh_config.texfmt[PTI_RGBX8_SRGB] = sh_config.texfmt[PTI_BGRX8_SRGB];
sh_config.texfmt[PTI_RGBA8_SRGB] = sh_config.texfmt[PTI_BGRA8_SRGB];
return true; //successful
}
else
@ -726,7 +768,7 @@ static qboolean D3D9_VID_Init(rendererstate_t *info, unsigned char *palette)
IDirect3DDevice9_Clear(pD3DDev9, 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
IDirect3DDevice9_BeginScene(pD3DDev9);
IDirect3DDevice9_EndScene(pD3DDev9);
IDirect3DDevice9_Present(pD3DDev9, NULL, NULL, NULL, NULL);
D3D9_VID_SwapBuffers();
D3D9_Set2D();
@ -947,6 +989,12 @@ static qboolean (D3D9_SCR_UpdateScreen) (void)
Cvar_ForceCallback(&vid_conwidth);
}
if (vid_srgb.modified)
{
vid_srgb.modified = false;
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_SRGBWRITEENABLE, (vid_srgb.ival==1 || vid.srgb) && !d3dpp.Windowed);
}
switch (IDirect3DDevice9_TestCooperativeLevel(pD3DDev9))
{
case D3DERR_DEVICELOST:
@ -992,7 +1040,7 @@ static qboolean (D3D9_SCR_UpdateScreen) (void)
if (R2D_Flush)
R2D_Flush();
IDirect3DDevice9_EndScene(pD3DDev9);
IDirect3DDevice9_Present(pD3DDev9, NULL, NULL, NULL, NULL);
D3D9_VID_SwapBuffers();
return true;
}
}
@ -1031,7 +1079,7 @@ static qboolean (D3D9_SCR_UpdateScreen) (void)
Media_RecordFrame();
// R2D_BrightenScreen();
IDirect3DDevice9_EndScene(pD3DDev9);
IDirect3DDevice9_Present(pD3DDev9, NULL, NULL, NULL, NULL);
D3D9_VID_SwapBuffers();
return true;
}
@ -1091,7 +1139,7 @@ static qboolean (D3D9_SCR_UpdateScreen) (void)
d3d9error(IDirect3DDevice9_EndScene(pD3DDev9));
{
RSpeedMark();
d3d9error(IDirect3DDevice9_Present(pD3DDev9, NULL, NULL, NULL, NULL));
D3D9_VID_SwapBuffers();
RSpeedEnd(RSPEED_PRESENT);
}
@ -1111,6 +1159,9 @@ static qboolean (D3D9_SCR_UpdateScreen) (void)
static void (D3D9_Draw_Init) (void)
{
vid.srgb = vid_srgb.ival>1;
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_SRGBWRITEENABLE, (vid_srgb.ival==1 || vid.srgb) && !d3dpp.Windowed);
R2D_Init();
}
static void (D3D9_Draw_Shutdown) (void)
@ -1245,7 +1296,6 @@ static void (D3D9_R_RenderView) (void)
D3D9_Set2D ();
}
void (D3D9_R_NewMap) (void);
void (D3D9_R_PreNewMap) (void);
void (D3D9_R_PushDlights) (void);

View File

@ -845,12 +845,16 @@ static qboolean initD3D11Device(HWND hWnd, rendererstate_t *info, PFN_D3D11_CREA
//11.1 formats
#define DXGI_FORMAT_B4G4R4A4_UNORM 115
//why does d3d11 have no rgbx format? anyone else think that weird?
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_B5G6R5_UNORM, &support); sh_config.texfmt[PTI_RGB565] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_B5G5R5A1_UNORM, &support); sh_config.texfmt[PTI_ARGB1555] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_B4G4R4A4_UNORM, &support); sh_config.texfmt[PTI_ARGB4444] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_R8G8B8A8_UNORM, &support); sh_config.texfmt[PTI_RGBA8] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_B8G8R8A8_UNORM, &support); sh_config.texfmt[PTI_BGRA8] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_B8G8R8X8_UNORM, &support); sh_config.texfmt[PTI_BGRX8] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, &support); sh_config.texfmt[PTI_RGBA8_SRGB] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, &support); sh_config.texfmt[PTI_BGRA8_SRGB] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, &support); sh_config.texfmt[PTI_BGRX8_SRGB] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC1_UNORM, &support); sh_config.texfmt[PTI_S3RGBA1] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC2_UNORM, &support); sh_config.texfmt[PTI_S3RGBA3] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC3_UNORM, &support); sh_config.texfmt[PTI_S3RGBA5] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
@ -859,6 +863,8 @@ static qboolean initD3D11Device(HWND hWnd, rendererstate_t *info, PFN_D3D11_CREA
sh_config.texfmt[PTI_RGBX8] = sh_config.texfmt[PTI_RGBA8];
sh_config.texfmt[PTI_S3RGB1] = sh_config.texfmt[PTI_S3RGBA1];
vid.srgb = info->srgb>1;
vid.numpages = scd.BufferCount;
if (!D3D11Shader_Init(flevel))
{

View File

@ -734,6 +734,7 @@ static qboolean D3D8_VID_Init(rendererstate_t *info, unsigned char *palette)
vid.pixelheight = 480;
vid.width = 640;
vid.height = 480;
vid.srgb = false;
vid_initializing = false;
@ -820,6 +821,8 @@ static qboolean D3D8_VID_Init(rendererstate_t *info, unsigned char *palette)
vid.width = width;
vid.height = height;
vid.srgb = false;
vid_initializing = false;
IDirect3DDevice8_SetRenderState(pD3DDev8, D3DRS_LIGHTING, FALSE);
@ -1341,7 +1344,6 @@ static void (D3D8_R_RenderView) (void)
D3D8_Set2D ();
}
void (D3D8_R_NewMap) (void);
void (D3D8_R_PreNewMap) (void);
void (D3D8_R_PushDlights) (void);

View File

@ -27505,7 +27505,6 @@
</FileConfiguration>
<FileConfiguration
Name="MDebug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
@ -31532,6 +31531,10 @@
/>
</FileConfiguration>
</File>
<File
RelativePath="..\common\fs_dzip.c"
>
</File>
<File
RelativePath="..\common\fs_pak.c"
>

View File

@ -4984,7 +4984,7 @@ static void BE_UpdateLightmaps(void)
lightmapinfo_t *lm;
int lmidx;
int glformat, gltype;
int internalformat = GL_RGBA;
int internalformat = /*vid.srgb?GL_SRGB8_ALPHA8_EXT:*/GL_RGBA;
switch (lightmap_fmt)
{
case TF_INVALID: return;

View File

@ -66,6 +66,18 @@ void GLDraw_Init (void)
if (gl_config.gles && gl_config.glversion < 3.0)
r_softwarebanding = false;
if (!gl_config.gles)
{
extern cvar_t vid_srgb;
GLint srgb;
qglGetIntegerv(GL_FRAMEBUFFER_SRGB_CAPABLE, &srgb);
vid.srgb = vid_srgb.ival>1 && srgb;
if (vid.srgb)
qglEnable(GL_FRAMEBUFFER_SRGB);
}
else
vid.srgb = false;
R2D_Init();
qglDisable(GL_SCISSOR_TEST);
@ -381,8 +393,8 @@ qboolean GL_LoadTextureMips(texid_t tex, struct pendingtextureinfo *mips)
case PTI_BGRX8:
qglTexImage3D(targface, i, GL_RGB, size, size, size, 0, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, mips->mip[i].data);
break;
case PTI_BGRA8:
default:
case PTI_BGRA8:
qglTexImage3D(targface, i, GL_RGBA, size, size, size, 0, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, mips->mip[i].data);
break;
case PTI_RGBA4444:
@ -442,10 +454,23 @@ qboolean GL_LoadTextureMips(texid_t tex, struct pendingtextureinfo *mips)
case PTI_BGRX8:
qglTexImage2D(targface, j, GL_RGB, mips->mip[i].width, mips->mip[i].height, 0, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, mips->mip[i].data);
break;
case PTI_BGRA8:
default:
case PTI_BGRA8:
qglTexImage2D(targface, j, GL_RGBA, mips->mip[i].width, mips->mip[i].height, 0, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, mips->mip[i].data);
break;
case PTI_RGBX8_SRGB:
qglTexImage2D(targface, j, GL_SRGB_EXT, mips->mip[i].width, mips->mip[i].height, 0, GL_RGBA, GL_UNSIGNED_BYTE, mips->mip[i].data);
break;
case PTI_RGBA8_SRGB:
qglTexImage2D(targface, j, GL_SRGB_ALPHA_EXT, mips->mip[i].width, mips->mip[i].height, 0, gl_config.gles?GL_SRGB_ALPHA_EXT:GL_RGBA, GL_UNSIGNED_BYTE, mips->mip[i].data);
break;
case PTI_BGRX8_SRGB:
qglTexImage2D(targface, j, GL_SRGB_EXT, mips->mip[i].width, mips->mip[i].height, 0, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, mips->mip[i].data);
break;
case PTI_BGRA8_SRGB:
qglTexImage2D(targface, j, GL_SRGB_ALPHA_EXT, mips->mip[i].width, mips->mip[i].height, 0, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, mips->mip[i].data);
break;
case PTI_RGBA16F:
qglTexImage2D(targface, j, GL_RGBA16F_ARB, mips->mip[i].width, mips->mip[i].height, 0, GL_RGBA, GL_UNSIGNED_BYTE, mips->mip[i].data);
break;

View File

@ -1548,7 +1548,7 @@ int R_LightPoint (vec3_t p)
if (r_refdef.flags & 1)
return 255;
if (!cl.worldmodel || !cl.worldmodel->lightdata)
if (!cl.worldmodel || cl.worldmodel->loadstate != MLS_LOADED || !cl.worldmodel->lightdata)
return 255;
if (cl.worldmodel->fromgame == fg_quake3)

View File

@ -626,8 +626,8 @@ void R_SetupGL (float stereooffset, int i)
if (vid_srgb.modified && !gl_config_gles)
{
vid_srgb.modified = false;
if (vid_srgb.ival)
qglEnable(GL_FRAMEBUFFER_SRGB);
if (vid_srgb.ival == 1 || vid.srgb)
qglEnable(GL_FRAMEBUFFER_SRGB); //specifies that the glsl is writing colours in the linear colour space, even if the framebuffer is not sRGB.
else
qglDisable(GL_FRAMEBUFFER_SRGB);
}

View File

@ -549,10 +549,10 @@ void GLBE_UploadAllLightmaps(void)
switch(lightmap_fmt) //bgra32, rgba32, rgb24, lum8
{
default: Sys_Error("Bad lightmap_fmt\n"); break;
case TF_BGRA32: qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, lm->width, lm->height, 0, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV,lightmap[i]->lightmaps); break;
case TF_BGRA32: qglTexImage2D(GL_TEXTURE_2D, 0, /*vid.srgb?GL_SRGB8_ALPHA8_EXT:*/GL_RGBA, lm->width, lm->height, 0, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV,lightmap[i]->lightmaps); break;
// case TF_RGBA32: qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, lm->width, lm->height, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV,lightmap[i]->lightmaps); break;
// case TF_BGR24: qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, lm->width, lm->height, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, lightmap[i]->lightmaps); break;
case TF_RGB24: qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, lm->width, lm->height, 0, GL_RGB, GL_UNSIGNED_BYTE, lightmap[i]->lightmaps); break;
case TF_RGB24: qglTexImage2D(GL_TEXTURE_2D, 0, /*vid.srgb?GL_SRGB8_EXT:*/GL_RGB, lm->width, lm->height, 0, GL_RGB, GL_UNSIGNED_BYTE, lightmap[i]->lightmaps); break;
case TF_LUM8: qglTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, lm->width, lm->height, 0, GL_LUMINANCE,GL_UNSIGNED_BYTE, lightmap[i]->lightmaps); break;
}
//for completeness.

View File

@ -1766,7 +1766,7 @@ static void Shader_LoadGeneric(sgeneric_t *g, int qrtype)
if (file)
{
Con_DPrintf("Loaded %s from disk\n", va(sh_config.progpath, basicname));
Con_DPrintf("Loaded %s from disk\n", sh_config.progpath?va(sh_config.progpath, basicname):basicname);
g->failed = !Shader_LoadPermutations(g->name, &g->prog, file, qrtype, 0, blobname);
FS_FreeFile(file);
return;
@ -2280,7 +2280,7 @@ static void Shader_NormalMap(shader_t *shader, shaderpass_t *pass, char **ptr)
{
char *token = Shader_ParseString(ptr);
unsigned int flags = Shader_SetImageFlags (shader, NULL, &token);
shader->defaulttextures->bump = Shader_FindImage(token, flags|IF_TRYBUMP);
shader->defaulttextures->bump = Shader_FindImage(token, flags|IF_TRYBUMP|IF_NOSRGB);
}
static void Shader_FullbrightMap(shader_t *shader, shaderpass_t *pass, char **ptr)
{
@ -5084,9 +5084,9 @@ void QDECL R_BuildDefaultTexnums(texnums_t *src, shader_t *shader)
if (r_loadbumpmapping || (shader->flags & SHADER_HASNORMALMAP))
{
if (!TEXVALID(tex->bump) && *mapname && (shader->flags & SHADER_HASNORMALMAP))
tex->bump = R_LoadHiResTexture(va("%s_norm", mapname), NULL, imageflags|IF_TRYBUMP);
tex->bump = R_LoadHiResTexture(va("%s_norm", mapname), NULL, imageflags|IF_TRYBUMP|IF_NOSRGB);
if (!TEXVALID(tex->bump))
tex->bump = R_LoadHiResTexture(va("%s_norm", imagename), subpath, imageflags|IF_TRYBUMP);
tex->bump = R_LoadHiResTexture(va("%s_norm", imagename), subpath, imageflags|IF_TRYBUMP|IF_NOSRGB);
}
}
@ -5277,9 +5277,9 @@ void QDECL R_BuildLegacyTexnums(shader_t *shader, const char *fallbackname, cons
{
extern cvar_t r_shadow_bumpscale_basetexture;
if (!TEXVALID(tex->bump) && *mapname)
tex->bump = R_LoadHiResTexture(va("%s_norm", mapname), NULL, imageflags|IF_TRYBUMP);
tex->bump = R_LoadHiResTexture(va("%s_norm", mapname), NULL, imageflags|IF_TRYBUMP|IF_NOSRGB);
if (!TEXVALID(tex->bump) && (r_shadow_bumpscale_basetexture.ival||*imagename=='#'||gl_load24bit.ival))
tex->bump = Image_GetTexture(va("%s_norm", imagename), subpath, imageflags|IF_TRYBUMP|(*imagename=='#'?IF_LINEAR:0), (r_shadow_bumpscale_basetexture.ival||*imagename=='#')?mipdata[0]:NULL, palette, width, height, TF_HEIGHT8PAL);
tex->bump = Image_GetTexture(va("%s_norm", imagename), subpath, imageflags|IF_TRYBUMP|IF_NOSRGB|(*imagename=='#'?IF_LINEAR:0), (r_shadow_bumpscale_basetexture.ival||*imagename=='#')?mipdata[0]:NULL, palette, width, height, TF_HEIGHT8PAL);
}
if (loadflags & SHADER_HASTOPBOTTOM)

View File

@ -2610,7 +2610,7 @@ static void GLSlang_ProgAutoFields(program_t *prog, const char *progname, cvar_t
}
//the vid routines have initialised a window, and now they are giving us a reference to some of of GetProcAddress to get pointers to the funcs.
void GL_Init(void *(*getglfunction) (char *name))
void GL_Init(rendererstate_t *info, void *(*getglfunction) (char *name))
{
#ifndef GL_STATIC
qglBindTexture = (void *)getglcore("glBindTexture"); //for compleateness. core in 1.1. needed by fte.
@ -2830,13 +2830,20 @@ void GL_Init(void *(*getglfunction) (char *name))
if (gl_config.gles)
{
qboolean srgb = false;//TEST ME GL_CheckExtension("GL_EXT_sRGB");
sh_config.texfmt[PTI_RGBX8] = sh_config.texfmt[PTI_RGBA8]; //FIXME: this is faked with PTI_RGBA8
sh_config.texfmt[PTI_RGB565] = !gl_config.webgl_ie; //ie sucks and doesn't support things that webgl requires it to support.
sh_config.texfmt[PTI_RGBA4444] = !gl_config.webgl_ie;
sh_config.texfmt[PTI_RGBA5551] = !gl_config.webgl_ie;
sh_config.texfmt[PTI_BGRA8] = false;
sh_config.texfmt[PTI_BGRX8] = sh_config.texfmt[PTI_BGRA8];
sh_config.texfmt[PTI_BGRX8] = sh_config.texfmt[PTI_BGRA8] = false;
// sh_config.texfmt[PTI_RGBX8_SRGB] = sh_config.texfmt[PTI_RGBX8] && srgb;
sh_config.texfmt[PTI_RGBA8_SRGB] = sh_config.texfmt[PTI_RGBA8] && srgb;
// sh_config.texfmt[PTI_BGRX8_SRGB] = sh_config.texfmt[PTI_BGRX8] && srgb;
sh_config.texfmt[PTI_BGRA8_SRGB] = sh_config.texfmt[PTI_BGRA8] && srgb;
vid.srgb = info->srgb && srgb;
sh_config.minver = 100;
sh_config.maxver = 100;
@ -2848,6 +2855,7 @@ void GL_Init(void *(*getglfunction) (char *name))
}
else
{
GLint srgb = gl_config.glversion >= 2.1 || GL_CheckExtension("GL_EXT_texture_sRGB"); //became core in gl 2.1
sh_config.can_mipcap = gl_config.glversion >= 1.2;
sh_config.texfmt[PTI_RGBX8] = true; //proper support
@ -2889,6 +2897,11 @@ void GL_Init(void *(*getglfunction) (char *name))
sh_config.blobpath = "glsl/%s.blob";
sh_config.progpath = "glsl/%s.glsl";
sh_config.shadernamefmt = "%s_glsl";
sh_config.texfmt[PTI_RGBX8_SRGB] = sh_config.texfmt[PTI_RGBX8] && srgb;
sh_config.texfmt[PTI_RGBA8_SRGB] = sh_config.texfmt[PTI_RGBA8] && srgb;
sh_config.texfmt[PTI_BGRX8_SRGB] = sh_config.texfmt[PTI_BGRX8] && srgb;
sh_config.texfmt[PTI_BGRA8_SRGB] = sh_config.texfmt[PTI_BGRA8] && srgb;
}
sh_config.progs_supported = gl_config.arb_shader_objects;

View File

@ -84,7 +84,7 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
vid.activeapp = true;
GL_Init(GLES_GetSymbol);
GL_Init(info, GLES_GetSymbol);
return true;
}
#else
@ -174,7 +174,7 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
vid.pixelwidth = w;
vid.pixelheight = h;
GL_Init(GLES_GetSymbol);
GL_Init(info, GLES_GetSymbol);
return true;
}

View File

@ -1951,7 +1951,7 @@ qboolean X11VID_Init (rendererstate_t *info, unsigned char *palette, int psl)
return false;
}
GL_Init(&GLX_GetSymbol);
GL_Init(info, &GLX_GetSymbol);
break;
#ifdef USE_EGL
case PSL_EGL:
@ -1961,7 +1961,7 @@ qboolean X11VID_Init (rendererstate_t *info, unsigned char *palette, int psl)
GLVID_Shutdown();
return false;
}
GL_Init(&EGL_Proc);
GL_Init(info, &EGL_Proc);
break;
#endif
#endif

View File

@ -101,7 +101,7 @@ qboolean GLVID_Init(rendererstate_t *info, unsigned char *palette)
if (vid.height < 200)
vid.height = 200;
GL_Init(AGL_GetProcAddress);
GL_Init(info, AGL_GetProcAddress);
GLVID_SetPalette(palette);

View File

@ -119,8 +119,6 @@ extern cvar_t vid_width;
extern cvar_t vid_height;
extern cvar_t vid_wndalpha;
typedef enum {MS_WINDOWED, MS_FULLDIB, MS_FULLWINDOW, MS_UNINIT} modestate_t;
static qboolean VID_SetWindowedMode (rendererstate_t *info); //-1 on bpp or hz for default.
static qboolean VID_SetFullDIBMode (rendererstate_t *info); //-1 on bpp or hz for default.
@ -162,7 +160,7 @@ viddef_t vid; // global video state
//unsigned short d_8to16bgrtable[256];
//unsigned d_8to24bgrtable[256];
static modestate_t modestate = MS_UNINIT;
static enum {MS_WINDOWED, MS_FULLDIB, MS_FULLWINDOW, MS_UNINIT} modestate = MS_UNINIT;
extern float gammapending;
@ -232,6 +230,7 @@ static int (WINAPI *qDescribePixelFormat)(HDC, int, UINT, LPPIXELFORMATDESCRIP
static BOOL (WINAPI *qwglSwapIntervalEXT) (int);
static BOOL (APIENTRY *qwglChoosePixelFormatARB)(HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int* piFormats, UINT* nNumFormats);
static BOOL (APIENTRY *qwglGetPixelFormatAttribfvARB)(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues);
static HGLRC (APIENTRY *qwglCreateContextAttribsARB)(HDC hDC, HGLRC hShareContext, const int *attribList);
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
@ -1441,6 +1440,7 @@ static int GLVID_SetMode (rendererstate_t *info, unsigned char *palette)
#endif
// Set either the fullscreen or windowed mode
qwglChoosePixelFormatARB = NULL;
qwglGetPixelFormatAttribfvARB = NULL;
qwglCreateContextAttribsARB = NULL;
stat = CreateMainWindow(info, true);
@ -1454,7 +1454,7 @@ static int GLVID_SetMode (rendererstate_t *info, unsigned char *palette)
{
HMODULE oldgl = hInstGL;
hInstGL = NULL; //don't close the gl library, just in case
VID_UnSetMode();
VID_UnSetMode(); //SetPixelFormat may only be used once per window. which means we *MUST* destroy the window if we're using a different pixelformat.
hInstGL = oldgl;
if (CreateMainWindow(info, true) && VID_AttachGL(info))
@ -1480,6 +1480,9 @@ static int GLVID_SetMode (rendererstate_t *info, unsigned char *palette)
}
}
GL_Init(info, getglfunc);
qSwapBuffers(maindc);
#ifdef VKQUAKE
if (platform_rendermode == MODE_NVVULKAN && stat)
{
@ -1497,7 +1500,7 @@ static int GLVID_SetMode (rendererstate_t *info, unsigned char *palette)
stat = EGL_Init (info, palette, mainwindow, maindc);
if (stat)
GL_Init(&EGL_Proc);
GL_Init(info, &EGL_Proc);
}
break;
#endif
@ -1950,8 +1953,8 @@ qboolean VID_AttachGL (rendererstate_t *info)
}
#endif
TRACE(("dbg: VID_AttachGL: GL_Init\n"));
GL_Init(getglfunc);
qwglChoosePixelFormatARB = getglfunc("wglChoosePixelFormatARB");
qwglGetPixelFormatAttribfvARB = getglfunc("wglGetPixelFormatAttribfvARB");
if (info->stereo)
{
@ -1961,19 +1964,12 @@ qboolean VID_AttachGL (rendererstate_t *info)
Con_Printf("Unable to create stereoscopic/quad-buffered OpenGL context. Please use a different stereoscopic method.\n");
}
qwglChoosePixelFormatARB = getglfunc("wglChoosePixelFormatARB");
qwglSwapIntervalEXT = getglfunc("wglSwapIntervalEXT");
if (qwglSwapIntervalEXT && *vid_vsync.string)
{
TRACE(("dbg: VID_AttachGL: qwglSwapIntervalEXT\n"));
qwglSwapIntervalEXT(vid_vsync.value);
}
TRACE(("dbg: VID_AttachGL: qSwapBuffers\n"));
qglClearColor(0, 0, 0, 1);
qglClear(GL_COLOR_BUFFER_BIT);
qSwapBuffers(maindc);
return true;
}
#endif
@ -2234,14 +2230,15 @@ static BOOL CheckForcePixelFormat(rendererstate_t *info)
int valid;
float fAttribute[] = {0,0};
UINT numFormats;
int pixelformat;
int pixelformats[1];
int iAttributes = 0;
int iAttribute[16*2];
iAttribute[iAttributes++] = WGL_DRAW_TO_WINDOW_ARB; iAttribute[iAttributes++] = GL_TRUE;
iAttribute[iAttributes++] = WGL_SUPPORT_OPENGL_ARB; iAttribute[iAttributes++] = GL_TRUE;
iAttribute[iAttributes++] = WGL_ACCELERATION_ARB; iAttribute[iAttributes++] = WGL_FULL_ACCELERATION_ARB;
iAttribute[iAttributes++] = WGL_COLOR_BITS_ARB; iAttribute[iAttributes++] = info->bpp;
iAttribute[iAttributes++] = WGL_ALPHA_BITS_ARB; iAttribute[iAttributes++] = 4;
iAttribute[iAttributes++] = WGL_COLOR_BITS_ARB; iAttribute[iAttributes++] = (info->bpp>24)?24:info->bpp;
// iAttribute[iAttributes++] = WGL_ALPHA_BITS_ARB; iAttribute[iAttributes++] = 4;
iAttribute[iAttributes++] = WGL_DEPTH_BITS_ARB; iAttribute[iAttributes++] = 16;
iAttribute[iAttributes++] = WGL_STENCIL_BITS_ARB; iAttribute[iAttributes++] = 8;
iAttribute[iAttributes++] = WGL_DOUBLE_BUFFER_ARB; iAttribute[iAttributes++] = GL_TRUE;
@ -2261,7 +2258,7 @@ static BOOL CheckForcePixelFormat(rendererstate_t *info)
TRACE(("dbg: bSetupPixelFormat: attempting wglChoosePixelFormatARB (multisample 4)\n"));
hDC = GetDC(mainwindow);
valid = qwglChoosePixelFormatARB(hDC,iAttribute,fAttribute,1,&pixelformat,&numFormats);
valid = qwglChoosePixelFormatARB(hDC,iAttribute,fAttribute,countof(pixelformats),pixelformats,&numFormats);
/* while ((!valid || numFormats < 1) && iAttribute[19] > 1)
{ //failed, switch wgl_samples to 2
iAttribute[19] /= 2;
@ -2269,11 +2266,115 @@ static BOOL CheckForcePixelFormat(rendererstate_t *info)
valid = qwglChoosePixelFormatARB(hDC,iAttribute,fAttribute,1,&pixelformat,&numFormats);
}
*/
#if 0
for (iAttributes = -1; iAttributes < (int)numFormats; iAttributes++)
{
int j;
struct
{
char *name;
int id;
} iAttributeTable[] = {
{"WGL_DRAW_TO_WINDOW", WGL_DRAW_TO_WINDOW_ARB},
{"WGL_DRAW_TO_BITMAP", 0x2002},
{"WGL_ACCELERATION", WGL_ACCELERATION_ARB},
{"WGL_NEED_PALETTE", 0x2004},
{"WGL_NEED_SYSTEM_PALETTE", 0x2005},
{"WGL_SWAP_LAYER_BUFFERS", WGL_SWAP_LAYER_BUFFERS_ARB},
{"WGL_SWAP_METHOD", 0x2007},
{"WGL_NUMBER_OVERLAYS", 0x2008},
{"WGL_NUMBER_UNDERLAYS", 0x2009},
{"WGL_TRANSPARENT", 0x200A},
{"WGL_TRANSPARENT_RED_VALUE", 0x2037},
{"WGL_TRANSPARENT_GREEN_VALUE", 0x2038},
{"WGL_TRANSPARENT_BLUE_VALUE", 0x2039},
{"WGL_TRANSPARENT_ALPHA_VALUE", 0x203a},
{"WGL_TRANSPARENT_INDEX_VALUE", 0x203B},
{"WGL_SHARE_DEPTH", 0x200C},
{"WGL_SHARE_STENCIL", 0x200D},
{"WGL_SHARE_ACCUM", 0x200E},
{"WGL_SUPPORT_GDI", 0x200F},
{"WGL_SUPPORT_OPENGL", WGL_SUPPORT_OPENGL_ARB},
{"WGL_DOUBLE_BUFFER", WGL_DOUBLE_BUFFER_ARB},
{"WGL_STEREO", WGL_STEREO_ARB},
{"WGL_PIXEL_TYPE", 0x2013},
{"WGL_COLOR_BITS", WGL_COLOR_BITS_ARB},
{"WGL_RED_BITS", 0x2015},
{"WGL_RED_SHIFT", 0x2016},
{"WGL_GREEN_BITS", 0x2017},
{"WGL_GREEN_SHIFT", 0x2018},
{"WGL_BLUE_BITS", 0x2019},
{"WGL_BLUE_SHIFT", 0x201A},
{"WGL_ALPHA_BITS", WGL_ALPHA_BITS_ARB},
{"WGL_ALPHA_SHIFT", 0x201C},
{"WGL_ACCUM_BITS", 0x201D},
{"WGL_ACCUM_RED_BITS", 0x201E},
{"WGL_ACCUM_GREEN_BITS", 0x201F},
{"WGL_ACCUM_BLUE_BITS", 0x2020},
{"WGL_ACCUM_ALPHA_BITS", 0x2021},
{"WGL_DEPTH_BITS", WGL_DEPTH_BITS_ARB},
{"WGL_STENCIL_BITS", WGL_STENCIL_BITS_ARB},
{"WGL_AUX_BUFFERS", 0x2024},
//extra extensions
{"WGL_SAMPLE_BUFFERS_ARB", WGL_SAMPLE_BUFFERS_ARB}, //multisample
{"WGL_SAMPLES_ARB", WGL_SAMPLES_ARB}, //multisample
{"WGL_DRAW_TO_PBUFFER_ARB", 0x202D}, //pbuffers
{"WGL_MAX_PBUFFER_PIXELS_ARB", 0x202E}, //pbuffers
{"WGL_MAX_PBUFFER_WIDTH_ARB", 0x202F}, //pbuffers
{"WGL_MAX_PBUFFER_HEIGHT_ARB", 0x2030}, //pbuffers
{"WGL_BIND_TO_TEXTURE_RGB_ARB", 0x2070},
{"WGL_BIND_TO_TEXTURE_RGBA_ARB", 0x2071},
{"WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB",WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB},
{"WGL_COLORSPACE_EXT", 0x309D}, //WGL_EXT_colorspace
//stuff my drivers don't support
// {"WGL_TYPE_RGBA_FLOAT_ARB", 0x21A0},
// {"WGL_DEPTH_FLOAT_EXT", 0x2040},
// {"WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT",0x20A8}, //EXT_packed_float
};
int iAttributeNames[countof(iAttributeTable)];
float fAttributeValues[countof(iAttributeTable)];
float basevalues[countof(iAttributeTable)];
for (j = 0; j < countof(iAttributeTable); j++)
iAttributeNames[j] = iAttributeTable[j].id;
Sys_Printf("Pixel Format %i --------------------------\n", iAttributes<0?currentpixelformat:pixelformats[iAttributes]);
if (qwglGetPixelFormatAttribfvARB(hDC, iAttributes<0?currentpixelformat:pixelformats[iAttributes], 0, countof(iAttributeTable), iAttributeNames, fAttributeValues))
{
if (iAttributes==-1)
memcpy(basevalues, fAttributeValues, sizeof(basevalues));
for (j = 0; j < countof(iAttributeTable); j++)
{
if (iAttributes==-1 || fAttributeValues[j] != basevalues[j])
{
if (iAttributeTable[j].id == 0x2007 && fAttributeValues[j] == 0x2028)
Sys_Printf("%s: exchange\n", iAttributeTable[j].name);
else if (iAttributeTable[j].id == 0x2007 && fAttributeValues[j] == 0x2029)
Sys_Printf("%s: copy\n", iAttributeTable[j].name);
else if (iAttributeTable[j].id == 0x309D && fAttributeValues[j] == 0x3089)
Sys_Printf("%s: WGL_COLORSPACE_SRGB\n", iAttributeTable[j].name);
else if (iAttributeTable[j].id == 0x309D && fAttributeValues[j] == 0x308A)
Sys_Printf("%s: WGL_COLORSPACE_LINEAR\n", iAttributeTable[j].name);
else if (iAttributeTable[j].id == 0x202E)
Sys_Printf("%s: %#x\n", iAttributeTable[j].name, (int)fAttributeValues[j]);
else
Sys_Printf("%s: %g\n", iAttributeTable[j].name, fAttributeValues[j]);
}
}
}
}
#endif
ReleaseDC(mainwindow, hDC);
if (valid && numFormats > 0)
if (valid && numFormats > 0 && pixelformats[0] != currentpixelformat)
{
shouldforcepixelformat = true;
forcepixelformat = pixelformat;
forcepixelformat = pixelformats[0];
return true;
}
}

View File

@ -230,7 +230,7 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
#endif
vid.activeapp = true;
GL_Init(GLVID_getsdlglfunction);
GL_Init(info, GLVID_getsdlglfunction);
qglViewport (0, 0, vid.pixelwidth, vid.pixelheight);

File diff suppressed because it is too large Load Diff

View File

@ -1079,7 +1079,7 @@ void GL_SelectProgram(int program);
void GL_Init(void *(*getglfunction) (char *name));
void GL_Init(rendererstate_t *info, void *(*getglfunction) (char *name));
#endif

View File

@ -610,8 +610,29 @@ typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei
#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2
#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9
#define GL_FRAMEBUFFER_SRGB 0x8DB9
#define GL_FRAMEBUFFER_SRGB_CAPABLE 0x8DBA
#endif
#ifndef GL_EXT_texture_sRGB
#define GL_EXT_texture_sRGB 1
#define GL_SRGB_EXT 0x8C40
#define GL_SRGB8_EXT 0x8C41
#define GL_SRGB_ALPHA_EXT 0x8C42
#define GL_SRGB8_ALPHA8_EXT 0x8C43
#define GL_SLUMINANCE_ALPHA_EXT 0x8C44
#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45
#define GL_SLUMINANCE_EXT 0x8C46
#define GL_SLUMINANCE8_EXT 0x8C47
#define GL_COMPRESSED_SRGB_EXT 0x8C48
#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49
#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A
#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B
#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
#endif /* GL_EXT_texture_sRGB */
#ifndef GL_ARB_pixel_buffer_object
#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB
#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC

View File

@ -294,17 +294,20 @@ typedef struct shaderpass_s {
SHADER_PASS_NEAREST = 1<<2, //needed for d3d's sampler states, MUST MATCH IMAGE FLAGS
SHADER_PASS_LINEAR = 1<<3, //needed for d3d's sampler states, MUST MATCH IMAGE FLAGS
SHADER_PASS_UIPIC = 1<<4, // MUST MATCH IMAGE FLAGS
#define SHADER_PASS_IMAGE_FLAGS (SHADER_PASS_CLAMP|SHADER_PASS_NOMIPMAP|SHADER_PASS_NEAREST|SHADER_PASS_LINEAR|SHADER_PASS_UIPIC)
SHADER_PASS_DEPTHCMP = 1<<5, //needed for d3d11's sampler states
SHADER_PASS_SRGB = 1<<6, //d3d9 does srgb via samplers. everyone else does it via texture formats
#define SHADER_PASS_IMAGE_FLAGS_D3D8 (SHADER_PASS_CLAMP|SHADER_PASS_NOMIPMAP|SHADER_PASS_NEAREST|SHADER_PASS_LINEAR|SHADER_PASS_UIPIC)
#define SHADER_PASS_IMAGE_FLAGS_D3D9 (SHADER_PASS_CLAMP|SHADER_PASS_NOMIPMAP|SHADER_PASS_NEAREST|SHADER_PASS_LINEAR|SHADER_PASS_UIPIC|SHADER_PASS_SRGB)
#define SHADER_PASS_IMAGE_FLAGS_D3D11 (SHADER_PASS_CLAMP|SHADER_PASS_NOMIPMAP|SHADER_PASS_NEAREST|SHADER_PASS_LINEAR|SHADER_PASS_UIPIC|SHADER_PASS_DEPTHCMP) //NEEDS to be tightly-packed. indexing will bug out otherwise.
SHADER_PASS_DEPTHCMP = 1<<5, //needed for d3d's sampler states
SHADER_PASS_NOCOLORARRAY = 1<<6,
SHADER_PASS_NOCOLORARRAY = 1<<7,
//FIXME: remove these
SHADER_PASS_VIDEOMAP = 1 << 7,
SHADER_PASS_DETAIL = 1 << 8,
SHADER_PASS_LIGHTMAP = 1 << 9,
SHADER_PASS_DELUXMAP = 1 << 10,
SHADER_PASS_ANIMMAP = 1 << 11
SHADER_PASS_VIDEOMAP = 1 << 8,
SHADER_PASS_DETAIL = 1 << 9,
SHADER_PASS_LIGHTMAP = 1 << 10,
SHADER_PASS_DELUXMAP = 1 << 11,
SHADER_PASS_ANIMMAP = 1 << 12
} flags;
#if defined(D3D11QUAKE) || defined(VKQUAKE)

View File

@ -2,8 +2,10 @@
#include "qcc.h"
//#include "decomp.h"
//This file is derived from frikdec, but has some extra tweaks to make it more friendly with fte's compiler/opcodes (its not perfect though)
//FIXME: there's still a load of mallocs, so we don't allow this more than once per process.
//convert vector terms into floats when its revealed that they're using vector ops and not floats
//FIXME: fteqcc converts do {} while(1); into a goto -1; which is a really weeeird construct.
#if defined(_WIN32) || defined(__DJGPP__)
#include <malloc.h>
@ -14,9 +16,8 @@
#undef printf
#define printf GUIprintf
#define OPF_FORSTART OP_NUMOPS
#define OP_MARK_END_DO 40000
#define OP_MARK_END_ELSE 1000
#define OP_MARK_END_DO 0x00010000 //do{
#define OP_MARK_END_ELSE 0x00000400 //}
#define MAX_REGS 65536
#define dstatement_t QCC_dstatement32_t
@ -571,7 +572,9 @@ int DecompileReadData(char *srcfilename, char *buf, size_t bufsize)
else
statements[i].a = (unsigned short)statements6[i].a;
if (statements[i].op == OP_IF_I || statements[i].op == OP_IFNOT_I || statements[i].op == OP_IF_F || statements[i].op == OP_IFNOT_F || statements[i].op == OP_IF_S || statements[i].op == OP_IFNOT_S)
if (statements[i].op == OP_IF_I || statements[i].op == OP_IFNOT_I ||
statements[i].op == OP_IF_F || statements[i].op == OP_IFNOT_F ||
statements[i].op == OP_IF_S || statements[i].op == OP_IFNOT_S)
statements[i].b = (signed short)statements6[i].b;
else
statements[i].b = (unsigned short)statements6[i].b;
@ -801,7 +804,8 @@ DecompileAlreadySeen(char *fname, vfile_t **rfile)
ret = 0;
if (rfile)
{
*rfile = QCC_AddVFile(fname, NULL, 0);
char *header = "//Decompiled code. Please respect the original copyright.\n";
*rfile = QCC_AddVFile(fname, header, strlen(header));
AddSourceFile("progs.src", fname);
}
}
@ -1239,6 +1243,7 @@ gofs_t DecompileScaleIndex(dfunction_t *df, gofs_t ofs)
if ((nofs < 0) || (nofs > MAX_REGS - 1))
{
printf("Fatal Error - Index (%i) out of bounds.\n", nofs);
return 0;
exit(1);
}
@ -1538,7 +1543,7 @@ void DecompileDecompileStatement(dfunction_t * df, dstatement_t * s, int *indent
char *arg1, *arg2, *arg3;
int nargs, i, j;
dstatement_t *t;
unsigned short dom, doc, ifc, tom;
unsigned int dom, doc, ifc, tom;
QCC_type_t *typ1, *typ2, *typ3;
QCC_ddef_t *par;
dstatement_t *k;
@ -1879,13 +1884,15 @@ void DecompileDecompileStatement(dfunction_t * df, dstatement_t * s, int *indent
QCC_CatVFile(Decompileofile, "%s;\n", line);
}
}
else if (s->op == OP_IF_I || s->op == OP_IFNOT_I || s->op == OP_IF_F || s->op == OP_IFNOT_F/* || s->op == OPQF_IFA || s->op == OPQF_IFB || s->op == OPQF_IFAE || s->op == OPQF_IFBE*/)
else if (s->op == OP_IF_I || s->op == OP_IFNOT_I ||
s->op == OP_IF_F || s->op == OP_IFNOT_F ||
s->op == OP_IF_S || s->op == OP_IFNOT_S/* || s->op == OPQF_IFA || s->op == OPQF_IFB || s->op == OPQF_IFAE || s->op == OPQF_IFBE*/)
{
arg1 = DecompileGet(df, s->a, type_float); //FIXME: this isn't quite accurate...
arg2 = DecompileGlobal(df, s->a, NULL);
if (s->op == OP_IFNOT_I || s->op == OP_IFNOT_F)
if (s->op == OP_IFNOT_I || s->op == OP_IFNOT_F || s->op == OP_IFNOT_S)
{
lameifnot:
if ((signed int)s->b < 1)
@ -1964,7 +1971,10 @@ void DecompileDecompileStatement(dfunction_t * df, dstatement_t * s, int *indent
for (k = t + (signed int)(t->a); k < s; k++)
{
tom = k->op % OP_MARK_END_ELSE;
if (tom == OP_GOTO || tom == OP_IF_I || tom == OP_IFNOT_I || tom == OP_IF_F || tom == OP_IFNOT_F)
if (tom == OP_GOTO ||
tom == OP_IF_I || tom == OP_IFNOT_I ||
tom == OP_IF_F || tom == OP_IFNOT_F ||
tom == OP_IF_S || tom == OP_IFNOT_S)
dum = 0;
}
if (dum)
@ -2050,7 +2060,7 @@ void DecompileDecompileStatement(dfunction_t * df, dstatement_t * s, int *indent
}
}
else if (s->op == OPF_FORSTART)
else if (s->op == OPD_GOTO_FORSTART)
{
DecompileIndent(*indent);
QCC_CatVFile(Decompileofile, "do_tail\n", (s-statements) + (signed int)s->a);
@ -2058,6 +2068,12 @@ void DecompileDecompileStatement(dfunction_t * df, dstatement_t * s, int *indent
QCC_CatVFile(Decompileofile, "{\n");
(*indent)++;
}
else if (s->op == OPD_GOTO_WHILE1)
{
(*indent)--;
DecompileIndent(*indent);
QCC_CatVFile(Decompileofile, "} while(1);\n");
}
else if (s->op == OP_GOTO)
{
@ -2592,6 +2608,27 @@ void DecompileFunction(const char *name, int *lastglobal)
ts = ds + (signed int)ds->a;
ts->op += OP_MARK_END_ELSE; // mark the end of a if/ite construct
}
else
{
ts = ds + (signed int)ds->a;
//if its a negative goto then it should normally be the end of a while{} loop. if we can't find the while statement itself, then its an infinite loop
for (k = (ts); k < ds; k++)
{
tom = k->op % OP_MARK_END_ELSE;
if (tom == OP_IF_I || tom == OP_IFNOT_I ||
tom == OP_IF_F || tom == OP_IFNOT_F ||
tom == OP_IF_S || tom == OP_IFNOT_S)
{
if (k + (signed int)k->b == ds+1)
break;
}
}
if (k == ds)
{
ds->op += OPD_GOTO_WHILE1-OP_GOTO;
ts->op += OP_MARK_END_DO;
}
}
}
else if (dom == OP_IFNOT_I || dom == OP_IFNOT_F || dom == OP_IFNOT_S)
{
@ -2616,7 +2653,10 @@ void DecompileFunction(const char *name, int *lastglobal)
for (k = (ts - 1) + (signed int)((ts - 1)->a); k < ds; k++)
{
tom = k->op % OP_MARK_END_ELSE;
if (tom == OP_GOTO || tom == OP_IF_I || tom == OP_IFNOT_I || tom == OP_IF_F || tom == OP_IFNOT_F)
if (tom == OP_GOTO ||
tom == OP_IF_I || tom == OP_IFNOT_I ||
tom == OP_IF_F || tom == OP_IFNOT_F ||
tom == OP_IF_S || tom == OP_IFNOT_S)
dum = 0;
}
if (!dum)
@ -2637,7 +2677,7 @@ void DecompileFunction(const char *name, int *lastglobal)
//if the statement before the 'do' is a forwards goto, and it jumps to within the loop (instead of after), then we have to assume that it is a for loop and not a loop inside an else block.
if ((ts-1)->op%OP_MARK_END_ELSE == OP_GOTO && (signed int)(ts-1)->a > 0 && (ts-1)+(signed int)(ts-1)->a <= ds)
{
(--ts)->op += OPF_FORSTART - OP_GOTO;
(--ts)->op += OPD_GOTO_FORSTART - OP_GOTO;
//because it was earlier, we need to unmark that goto's target as an end_else
ts = ts + (signed int)ts->a;
ts->op -= OP_MARK_END_ELSE;
@ -2664,7 +2704,10 @@ void DecompileFunction(const char *name, int *lastglobal)
for (k = (ts - 1) + (signed int)((ts - 1)->a); k < ds; k++)
{
tom = k->op % OP_MARK_END_ELSE;
if (tom == OP_GOTO || tom == OP_IF_I || tom == OP_IFNOT_I || tom == OP_IF_F || tom == OP_IFNOT_F)
if (tom == OP_GOTO ||
tom == OP_IF_I || tom == OP_IFNOT_I ||
tom == OP_IF_F || tom == OP_IFNOT_F ||
tom == OP_IF_S || tom == OP_IFNOT_S)
dum = 0;
}
if (!dum)
@ -3031,7 +3074,9 @@ void DecompilePrintStatement(dstatement_t * s)
for (; i < 10; i++)
printf(" ");
if (s->op == OP_IF_I || s->op == OP_IFNOT_I || s->op == OP_IF_F || s->op == OP_IFNOT_F)
if (s->op == OP_IF_I || s->op == OP_IFNOT_I ||
s->op == OP_IF_F || s->op == OP_IFNOT_F ||
s->op == OP_IF_S || s->op == OP_IFNOT_S)
printf("%sbranch %i", DecompileGlobalString(s->a), s->b);
else if (s->op == OP_GOTO)
{

View File

@ -422,6 +422,10 @@ enum qcop_e {
OP_BITNOT_V,
OP_BITXOR_V,
//special/fake opcodes used by the decompiler.
OPD_GOTO_FORSTART,
OPD_GOTO_WHILE1,
OP_NUMOPS
};

View File

@ -22,6 +22,7 @@
void OptionsDialog(void);
static void GUI_CreateInstaller_Windows(void);
static void GUI_CreateInstaller_Android(void);
static void SetProgsSrcFileAndPath(char *filename);
void AddSourceFile(const char *parentsrc, const char *filename);
#ifndef TVM_SETBKCOLOR
@ -345,6 +346,18 @@ static pbool QCC_RegSetValue(HKEY base, char *keyname, char *valuename, int type
*/
static vfile_t *qcc_vfiles;
void QCC_CloseAllVFiles(void)
{
vfile_t *f;
while(qcc_vfiles)
{
f = qcc_vfiles;
qcc_vfiles = f->next;
free(f->fdata);
free(f);
}
}
vfile_t *QCC_FindVFile(const char *name)
{
vfile_t *f;
@ -1553,6 +1566,7 @@ HWND CreateAnEditControl(HWND parent, pbool *scintillaokay)
enum {
IDM_OPENDOCU=32,
IDM_OPENNEW,
IDM_OPENPROJECT,
IDM_GREP,
IDM_GOTODEF,
IDM_RETURNDEF,
@ -1595,7 +1609,7 @@ enum {
IDI_O_LEVEL3,
IDI_O_DEFAULT,
IDI_O_DEBUG,
IDI_O_CHANGE_PROGS_SRC,
// IDI_O_CHANGE_PROGS_SRC,
IDI_O_ADDITIONALPARAMETERS,
IDI_O_OPTIMISATION,
IDI_O_COMPILER_FLAG,
@ -1637,6 +1651,29 @@ void GenericMenu(WPARAM wParam)
{
switch(LOWORD(wParam))
{
case IDM_OPENPROJECT:
{
char filename[MAX_PATH];
char oldpath[MAX_PATH+10];
OPENFILENAME ofn;
memset(&ofn, 0, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hInstance = ghInstance;
ofn.lpstrFile = filename;
ofn.lpstrTitle = "Please find progs.src or progs.dat";
ofn.nMaxFile = sizeof(filename)-1;
ofn.lpstrFilter = "QuakeC Projects\0*.src;*.dat\0All files\0*.*\0";
memset(filename, 0, sizeof(filename));
GetCurrentDirectory(sizeof(oldpath)-1, oldpath);
ofn.lpstrInitialDir = oldpath;
if (GetOpenFileName(&ofn))
{
SetProgsSrcFileAndPath(filename);
}
resetprogssrc = true;
}
break;
case IDM_OPENNEW:
QueryOpenFile();
break;
@ -5222,7 +5259,7 @@ static LRESULT CALLBACK OptionsWndProc(HWND hWnd,UINT message,
GUI_SaveConfig();
DestroyWindow(hWnd);
break;
case IDI_O_CHANGE_PROGS_SRC:
/* case IDI_O_CHANGE_PROGS_SRC:
{
char filename[MAX_PATH];
char oldpath[MAX_PATH+10];
@ -5240,10 +5277,10 @@ static LRESULT CALLBACK OptionsWndProc(HWND hWnd,UINT message,
if (GetOpenFileName(&ofn))
{
SetProgsSrcFileAndPath(filename);
resetprogssrc = true;
}
resetprogssrc = true;
}
break;
break;*/
case IDI_O_LEVEL0:
case IDI_O_LEVEL1:
case IDI_O_LEVEL2:
@ -5328,9 +5365,9 @@ static LRESULT CALLBACK OptionsWndProc(HWND hWnd,UINT message,
case IDI_O_LEVEL3:
MessageBox(hWnd, "Sets a specific optimisation level", "Help", MB_OK|MB_ICONINFORMATION);
break;
case IDI_O_CHANGE_PROGS_SRC:
MessageBox(hWnd, "Use this button to change your root source file.\nNote that fteqcc compiles sourcefiles from editors first, rather than saving. This means that changes are saved ONLY when you save them, but means that switching project mid-compile can result in problems.", "Help", MB_OK|MB_ICONINFORMATION);
break;
// case IDI_O_CHANGE_PROGS_SRC:
// MessageBox(hWnd, "Use this button to change your root source file.\nNote that fteqcc compiles sourcefiles from editors first, rather than saving. This means that changes are saved ONLY when you save them, but means that switching project mid-compile can result in problems.", "Help", MB_OK|MB_ICONINFORMATION);
// break;
case IDI_O_ADDITIONALPARAMETERS:
MessageBox(hWnd, "Type in additional commandline parameters here. Use -Dname to define a named precompiler constant before compiling.", "Help", MB_OK|MB_ICONINFORMATION);
break;
@ -5609,14 +5646,14 @@ void OptionsDialog(void)
ghInstance,
NULL);
AddTip(tipwnd, wnd, "Use selected settings and save them to disk so that they're also used the next time you start fteqccgui.");
wnd = CreateWindow("BUTTON","progs.src",
/*wnd = CreateWindow("BUTTON","progs.src",
WS_CHILD | WS_VISIBLE,
8+64*2,height-40,64,32,
optionsmenu,
(HMENU)IDI_O_CHANGE_PROGS_SRC,
ghInstance,
NULL);
AddTip(tipwnd, wnd, "Change the initial src file.");
AddTip(tipwnd, wnd, "Change the initial src file.");*/
@ -5766,8 +5803,9 @@ static LRESULT CALLBACK MainWndProc(HWND hWnd,UINT message,
rootmenu = CreateMenu();
AppendMenu(rootmenu, MF_POPUP, (UINT_PTR)(m = CreateMenu()), "&File");
AppendMenu(m, 0, IDM_OPENNEW, "Open new file ");
AppendMenu(m, 0, IDM_SAVE, "&Save\tCtrl+S ");
AppendMenu(m, 0, IDM_OPENPROJECT, "Open Project / Decompile");
AppendMenu(m, 0, IDM_OPENNEW, "Open File");
AppendMenu(m, 0, IDM_SAVE, "&Save\tCtrl+S");
// AppendMenu(m, 0, IDM_FIND, "&Find");
AppendMenu(m, 0, IDM_UNDO, "Undo\tCtrl+Z");
AppendMenu(m, 0, IDM_REDO, "Redo\tCtrl+Y");
@ -5777,10 +5815,10 @@ static LRESULT CALLBACK MainWndProc(HWND hWnd,UINT message,
AppendMenu(m, MF_SEPARATOR, 0, NULL);
AppendMenu(m, 0, IDM_QUIT, "Exit");
AppendMenu(rootmenu, MF_POPUP, (UINT_PTR)(m = CreateMenu()), "&Navigation");
AppendMenu(m, 0, IDM_GOTODEF, "Go to definition\tF12");
AppendMenu(m, 0, IDM_RETURNDEF, "Return from definition\tShift+F12");
AppendMenu(m, 0, IDM_GREP, "Grep for selection\tCtrl+G");
AppendMenu(m, 0, IDM_OPENDOCU, "Open selected file");
AppendMenu(m, 0, IDM_GOTODEF, "Go To Definition\tF12");
AppendMenu(m, 0, IDM_RETURNDEF, "Return From Definition\tShift+F12");
AppendMenu(m, 0, IDM_GREP, "Grep For Selection\tCtrl+G");
AppendMenu(m, 0, IDM_OPENDOCU, "Open Selected File");
AppendMenu(m, 0, IDM_OUTPUT_WINDOW, "Show Output Window\tF6");
AppendMenu(m, (fl_extramargins?MF_CHECKED:MF_UNCHECKED), IDM_UI_SHOWLINENUMBERS, "Show Line Numbers");
AppendMenu(m, ((fl_tabsize>4)?MF_CHECKED:MF_UNCHECKED), IDM_UI_TABSIZE, "Large Tabs");
@ -6897,12 +6935,9 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
GUI_SetDefaultOpts();
// if (!QCC_RegGetStringValue(HKEY_CURRENT_USER, "Software\\FTE QuakeWorld\\fteqccgui", "enginebinary", enginebinary, sizeof(enginebinary)))
strcpy(enginebinary, "");
// if (!QCC_RegGetStringValue(HKEY_CURRENT_USER, "Software\\FTE QuakeWorld\\fteqccgui", "enginebasedir", enginebasedir, sizeof(enginebasedir)))
strcpy(enginebasedir, "");
// if (!QCC_RegGetStringValue(HKEY_CURRENT_USER, "Software\\FTE QuakeWorld\\fteqccgui", "enginecommandline", enginecommandline, sizeof(enginecommandline)))
strcpy(enginecommandline, "");
strcpy(enginebinary, "");
strcpy(enginebasedir, "");
strcpy(enginecommandline, "");
if(strstr(lpCmdLine, "-stdout"))
{
@ -6911,34 +6946,6 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
return 0;
}
if (!*lpCmdLine)
{
int len;
FILE *f;
char *s;
f = fopen("fteqcc.arg", "rb");
if (f)
{
fseek(f, 0, SEEK_END);
len = ftell(f);
fseek(f, 0, SEEK_SET);
lpCmdLine = malloc(len+1);
fread(lpCmdLine, 1, len, f);
lpCmdLine[len] = '\0';
fclose(f);
while((s = strchr(lpCmdLine, '\r')))
*s = ' ';
while((s = strchr(lpCmdLine, '\n')))
*s = ' ';
}
}
GUI_ParseCommandLine(lpCmdLine);
GUI_RevealOptions();
for (i = 0, fl_acc = false; compiler_flag[i].enabled; i++)
{
if (!strcmp("acc", compiler_flag[i].abbrev))
@ -6957,7 +6964,6 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
strcpy(progssrcname, "progs.src");
if (QCC_RawFileSize(progssrcname)==-1)
{
char *s, *s2;
char filename[MAX_PATH];
char oldpath[MAX_PATH+10];
OPENFILENAME ofn;
@ -6972,30 +6978,12 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
GetCurrentDirectory(sizeof(oldpath)-1, oldpath);
ofn.lpstrInitialDir = oldpath;
if (GetOpenFileName(&ofn))
{
strcpy(progssrcdir, filename);
for(s = progssrcdir; s; s = s2)
{
s2 = strchr(s+1, '\\');
if (!s2)
break;
s = s2;
}
if (s)
{
*s = '\0';
strcpy(progssrcname, s+1);
}
else
strcpy(progssrcname, filename);
}
strcpy(progssrcname, filename);
else
{
MessageBox(NULL, "You didn't select a file", "Error", 0);
return 0;
}
SetCurrentDirectory(progssrcdir);
*progssrcdir = '\0';
}
}
@ -7064,71 +7052,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
ShowWindow(mainwindow, SW_SHOWDEFAULT);
{
char *ext = strrchr(progssrcname, '.');
if (ext && !QC_strcasecmp(ext, ".dat"))
{
FILE *f = fopen(progssrcname, "rb");
if (f)
{
char *buf;
size_t size;
fseek(f, 0, SEEK_END);
size = ftell(f);
fseek(f, 0, SEEK_SET);
buf = malloc(size);
fread(buf, 1, size, f);
fclose(f);
if (!QC_EnumerateFilesFromBlob(buf, size, QCC_EnumerateFilesResult))
{
char *c = ReadProgsCopyright(buf, size);
if (!c || !*c)
c = "COPYRIGHT OWNER NOT KNOWN"; //all work is AUTOMATICALLY copyrighted under the terms of the Berne Convention. It _IS_ copyrighted, even if there's no license etc included. Good luck guessing what rights you have.
if (MessageBox(mainwindow, qcva("The copyright message from this progs is\n%s\n\nPlease respect the wishes and legal rights of the person who created this.", c), "Copyright", MB_OKCANCEL|MB_DEFBUTTON2|MB_ICONSTOP) == IDOK)
{
CreateOutputWindow(true);
compilecb();
DecompileProgsDat(progssrcname, buf, size);
if (SplitterGet(outputbox))
{
SendMessage(outputbox, WM_SETREDRAW, TRUE, 0);
RedrawWindow(outputbox, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
}
}
}
free(buf);
}
strcpy(progssrcname, "progs.src");
for (i = 0; ; i++)
{
if (!strcmp("embedsrc", compiler_flag[i].abbrev))
{
compiler_flag[i].flags |= FLAG_SETINGUI;
break;
}
}
}
}
if (fl_compileonstart)
{
CreateOutputWindow(false);
RunCompiler(lpCmdLine, false);
}
else
{
if (!mdibox)
{
GUIprintf("Welcome to FTE QCC\n");
GUIprintf("Source file: ");
GUIprintf(progssrcname);
GUIprintf("\n");
RunCompiler("-?", false);
}
}
resetprogssrc = true;
while(mainwindow || editors)
{
@ -7136,6 +7060,110 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
if (resetprogssrc)
{ //this here, with the compiler below, means that we don't run recursivly.
if (projecttree)
TreeView_DeleteAllItems(projecttree);
//if progssrcname is a path, then change working directory now.
//this shouldn't affect that much, but should ensure well-defined behaviour.
{
char *s, *s2;
strcpy(progssrcdir, progssrcname);
for(s = NULL, s2 = progssrcdir; s2;)
{
char *bs = strchr(s2, '\\');
char *sl = strchr(s2, '/');
if (bs)
s2 = bs;
else if (sl)
s2 = sl;
else
break;
s = s2++;
}
if (s)
{
*s = '\0';
strcpy(progssrcname, s+1);
}
SetCurrentDirectory(progssrcdir);
*progssrcdir = '\0';
}
//reset project/directory options
GUI_SetDefaultOpts();
GUI_ParseCommandLine(lpCmdLine);
GUI_RevealOptions();
//if the project is a .dat or .zip then decompile it now (so we can access the 'source')
{
char *ext = strrchr(progssrcname, '.');
if (ext && (!QC_strcasecmp(ext, ".dat") || !QC_strcasecmp(ext, ".zip") || !QC_strcasecmp(ext, ".pk3")))
{
FILE *f = fopen(progssrcname, "rb");
if (f)
{
char *buf;
size_t size;
fseek(f, 0, SEEK_END);
size = ftell(f);
fseek(f, 0, SEEK_SET);
buf = malloc(size);
fread(buf, 1, size, f);
fclose(f);
QCC_CloseAllVFiles();
strcpy(progssrcname, "progs.src");
if (!QC_EnumerateFilesFromBlob(buf, size, QCC_EnumerateFilesResult) && !QC_strcasecmp(ext, ".dat"))
{
char *c = ReadProgsCopyright(buf, size);
if (!c || !*c)
c = "COPYRIGHT OWNER NOT KNOWN"; //all work is AUTOMATICALLY copyrighted under the terms of the Berne Convention in all major nations. It _IS_ copyrighted, even if there's no license etc included. Good luck guessing what rights you have.
if (MessageBox(mainwindow, qcva("The copyright message from this progs is\n%s\n\nPlease respect the wishes and legal rights of the person who created this.", c), "Copyright", MB_OKCANCEL|MB_DEFBUTTON2|MB_ICONSTOP) == IDOK)
{
CreateOutputWindow(true);
compilecb();
DecompileProgsDat(progssrcname, buf, size);
if (SplitterGet(outputbox))
{
SendMessage(outputbox, WM_SETREDRAW, TRUE, 0);
RedrawWindow(outputbox, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
}
}
}
free(buf);
}
else
strcpy(progssrcname, "progs.src");
for (i = 0; ; i++)
{
if (!strcmp("embedsrc", compiler_flag[i].abbrev))
{
compiler_flag[i].flags |= FLAG_SETINGUI;
break;
}
}
}
}
if (fl_compileonstart)
{
CreateOutputWindow(false);
RunCompiler(lpCmdLine, false);
}
else
{
if (!mdibox)
{
GUIprintf("Welcome to FTE QCC\n");
GUIprintf("Source file: ");
GUIprintf(progssrcname);
GUIprintf("\n");
RunCompiler("-?", false);
}
}
resetprogssrc = false;
UpdateFileList();
}
@ -7150,7 +7178,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
DoTranslateMessage(&msg);
}
if (mainwindow)
if (mainwindow)
{
if (buttons[ID_COMPILE].washit)
{

View File

@ -452,12 +452,37 @@ void GUI_ParseCommandLine(char *args)
int l, p;
char *next;
if (!*args)
{
int len;
FILE *f;
char *s;
f = fopen("fteqcc.arg", "rb");
if (f)
{
fseek(f, 0, SEEK_END);
len = ftell(f);
fseek(f, 0, SEEK_SET);
args = _alloca(len+1);
fread(args, 1, len, f);
args[len] = '\0';
fclose(f);
while((s = strchr(args, '\r')))
*s = ' ';
while((s = strchr(args, '\n')))
*s = ' ';
}
}
//find the first argument
while (*args == ' ' || *args == '\t')
args++;
for (next = args; *next&&*next!=' '&&*next !='\t'; next++)
;
if (*args != '-')
{
pbool qt = *args == '\"';

View File

@ -639,8 +639,10 @@ typedef struct client_s
SCP_QUAKE3,
//all the below are considered netquake clients.
SCP_NETQUAKE,
//bjp1, bjp2
SCP_BJP3, //16bit angles,model+sound indexes. nothing else (assume raised ent limits too).
SCP_FITZ666,
//dp5
SCP_DARKPLACES6,
SCP_DARKPLACES7 //extra prediction stuff
//note, nq is nq+

View File

@ -2201,9 +2201,9 @@ void SV_CalcClientStats(client_t *client, int statsi[MAX_CL_STATS], float statsf
#endif
if (!ent->xv->viewzoom)
statsi[STAT_VIEWZOOM] = 255;
statsf[STAT_VIEWZOOM] = STAT_VIEWZOOM_SCALE;
else
statsi[STAT_VIEWZOOM] = max(1,ent->xv->viewzoom*255);
statsf[STAT_VIEWZOOM] = max(1,ent->xv->viewzoom*STAT_VIEWZOOM_SCALE);
#endif
#ifdef NQPROT

View File

@ -532,7 +532,7 @@ void SVNQ_New_f (void)
{SCP_DARKPLACES6, true},
{SCP_FITZ666, true}, //actually 999... shh...
{SCP_FITZ666, false},
{SCP_BJP3, false}
{SCP_BJP3, false} //should we only use this when we have >255 models/sounds?
};
for (i = 0; i < countof(preferedprot); i++)
{

View File

@ -251,7 +251,7 @@ static qboolean VK_CreateSwapChain(void)
uint32_t i, curpri;
VkSwapchainKHR newvkswapchain;
VkImage *images;
VkDeviceMemory *memories;
VkDeviceMemory *memories;
VkImageView attachments[2];
VkFramebufferCreateInfo fb_info = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO};
@ -262,7 +262,7 @@ static qboolean VK_CreateSwapChain(void)
if (vk.swapchain || vk.backbuf_count)
VK_DestroySwapChain();
vk.backbufformat = vid_srgb.ival?VK_FORMAT_B8G8R8A8_SRGB:VK_FORMAT_B8G8R8A8_UNORM;
vk.backbufformat = (vid.srgb||vid_srgb.ival)?VK_FORMAT_B8G8R8A8_SRGB:VK_FORMAT_B8G8R8A8_UNORM;
vk.backbuf_count = 4;
swapinfo.imageExtent.width = vid.pixelwidth;
@ -388,8 +388,9 @@ static qboolean VK_CreateSwapChain(void)
}
}
vk.srgbcapable = false;
swapinfo.imageColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
swapinfo.imageFormat = vid_srgb.ival?VK_FORMAT_B8G8R8A8_SRGB:VK_FORMAT_B8G8R8A8_UNORM;
swapinfo.imageFormat = (vid.srgb||vid_srgb.ival)?VK_FORMAT_B8G8R8A8_SRGB:VK_FORMAT_B8G8R8A8_UNORM;
for (i = 0, curpri = 0; i < fmtcount; i++)
{
uint32_t priority = 0;
@ -397,11 +398,12 @@ static qboolean VK_CreateSwapChain(void)
{
case VK_FORMAT_B8G8R8A8_UNORM:
case VK_FORMAT_R8G8B8A8_UNORM:
priority = 4+!vid_srgb.ival;
priority = 4+!(vid.srgb||vid_srgb.ival);
break;
case VK_FORMAT_B8G8R8A8_SRGB:
case VK_FORMAT_R8G8B8A8_SRGB:
priority = 4+!!vid_srgb.ival;
priority = 4+!!(vid.srgb||vid_srgb.ival);
vk.srgbcapable = true;
break;
case VK_FORMAT_R16G16B16A16_SFLOAT: //16bit per-channel formats
case VK_FORMAT_R16G16B16A16_SNORM:
@ -521,7 +523,7 @@ static qboolean VK_CreateSwapChain(void)
depthinfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
depthinfo.queueFamilyIndexCount = 0;
depthinfo.pQueueFamilyIndices = NULL;
depthinfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
depthinfo.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
VkAssert(vkCreateImage(vk.device, &depthinfo, vkallocationcb, &vk.backbufs[i].depth.image));
}
@ -575,6 +577,11 @@ static qboolean VK_CreateSwapChain(void)
void VK_Draw_Init(void)
{
qboolean srgb = vid_srgb.ival > 1 && vk.srgbcapable;
if (vid.srgb != srgb)
vid_srgb.modified = true;
vid.srgb = srgb;
R2D_Init();
}
void VK_Draw_Shutdown(void)
@ -710,6 +717,11 @@ vk_image_t VK_CreateTexture2DArray(uint32_t width, uint32_t height, uint32_t lay
format = VK_FORMAT_D32_SFLOAT;
else if (encoding == PTI_DEPTH24_8)
format = VK_FORMAT_D24_UNORM_S8_UINT;
//srgb formats
else if (encoding == PTI_BGRA8_SRGB || encoding == PTI_BGRX8_SRGB)
format = VK_FORMAT_B8G8R8A8_SRGB;
else if (encoding == PTI_RGBA8_SRGB || encoding == PTI_RGBX8_SRGB)
format = VK_FORMAT_R8G8B8A8_SRGB;
//standard formats
else if (encoding == PTI_BGRA8 || encoding == PTI_BGRX8)
format = VK_FORMAT_B8G8R8A8_UNORM;
@ -902,16 +914,26 @@ void *VK_AtFrameEnd(void (*passed)(void *work), size_t worksize)
return w;
}
#define USE_STAGING_BUFFERS
struct texturefence
{
struct vk_fencework w;
int mips;
#ifdef USE_STAGING_BUFFERS
VkBuffer stagingbuffer;
VkDeviceMemory stagingmemory;
#else
vk_image_t staging[32];
#endif
};
static void VK_TextureLoaded(void *ctx)
{
struct texturefence *w = ctx;
#ifdef USE_STAGING_BUFFERS
vkDestroyBuffer(vk.device, w->stagingbuffer, vkallocationcb);
vkFreeMemory(vk.device, w->stagingmemory, vkallocationcb);
#else
unsigned int i;
for (i = 0; i < w->mips; i++)
if (w->staging[i].image != VK_NULL_HANDLE)
@ -919,13 +941,23 @@ static void VK_TextureLoaded(void *ctx)
vkDestroyImage(vk.device, w->staging[i].image, vkallocationcb);
vkFreeMemory(vk.device, w->staging[i].memory, vkallocationcb);
}
#endif
}
qboolean VK_LoadTextureMips (texid_t tex, struct pendingtextureinfo *mips)
{
#ifdef USE_STAGING_BUFFERS
VkBufferCreateInfo bci = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
VkMemoryRequirements mem_reqs;
VkMemoryAllocateInfo memAllocInfo = {VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO};
void *mapdata;
#else
uint32_t y;
#endif
struct texturefence *fence;
VkCommandBuffer vkloadcmd;
vk_image_t target;
uint32_t i, y;
uint32_t i;
uint32_t blocksize;
uint32_t blockbytes;
uint32_t layers;
@ -950,6 +982,10 @@ qboolean VK_LoadTextureMips (texid_t tex, struct pendingtextureinfo *mips)
case PTI_RGBX8:
case PTI_BGRA8:
case PTI_BGRX8:
case PTI_RGBA8_SRGB:
case PTI_RGBX8_SRGB:
case PTI_BGRA8_SRGB:
case PTI_BGRX8_SRGB:
blocksize = 1; //in texels
blockbytes = 4;
break;
@ -1059,7 +1095,68 @@ qboolean VK_LoadTextureMips (texid_t tex, struct pendingtextureinfo *mips)
}
}
//create the staging images and fill them
#ifdef USE_STAGING_BUFFERS
//figure out how big our staging buffer needs to be
bci.size = 0;
for (i = 0; i < mips->mipcount; i++)
{
uint32_t blockwidth = (mips->mip[i].width+blocksize-1) / blocksize;
uint32_t blockheight = (mips->mip[i].height+blocksize-1) / blocksize;
bci.size += blockwidth*blockheight*blockbytes;
}
bci.flags = 0;
bci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
bci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
bci.queueFamilyIndexCount = 0;
bci.pQueueFamilyIndices = NULL;
//create+map the staging buffer
VkAssert(vkCreateBuffer(vk.device, &bci, vkallocationcb, &fence->stagingbuffer));
vkGetBufferMemoryRequirements(vk.device, fence->stagingbuffer, &mem_reqs);
memAllocInfo.allocationSize = mem_reqs.size;
memAllocInfo.memoryTypeIndex = vk_find_memory_require(mem_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
VkAssert(vkAllocateMemory(vk.device, &memAllocInfo, vkallocationcb, &fence->stagingmemory));
VkAssert(vkBindBufferMemory(vk.device, fence->stagingbuffer, fence->stagingmemory, 0));
VkAssert(vkMapMemory(vk.device, fence->stagingmemory, 0, bci.size, 0, &mapdata));
if (!mapdata)
Sys_Error("Unable to map staging image\n");
bci.size = 0;
for (i = 0; i < mips->mipcount; i++)
{
VkImageSubresource subres = {0};
VkBufferImageCopy region;
//figure out the number of 'blocks' in the image.
//for non-compressed formats this is just the width directly.
//for compressed formats (ie: s3tc/dxt) we need to round up to deal with npot.
uint32_t blockwidth = (mips->mip[i].width+blocksize-1) / blocksize;
uint32_t blockheight = (mips->mip[i].height+blocksize-1) / blocksize;
memcpy((char*)mapdata + bci.size, (char*)mips->mip[i].data, blockwidth*blockbytes*blockheight);
//queue up a buffer->image copy for this mip
region.bufferOffset = bci.size;
region.bufferRowLength = 0;//blockwidth*blockbytes;
region.bufferImageHeight = 0;//blockheight;
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.imageSubresource.mipLevel = i%(mips->mipcount/layers);
region.imageSubresource.baseArrayLayer = i/(mips->mipcount/layers);
region.imageSubresource.layerCount = 1;
region.imageOffset.x = 0;
region.imageOffset.y = 0;
region.imageOffset.z = 0;
region.imageExtent.width = mips->mip[i].width;
region.imageExtent.height = mips->mip[i].height;
region.imageExtent.depth = 1;
vkCmdCopyBufferToImage(vkloadcmd, fence->stagingbuffer, target.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
bci.size += blockwidth*blockheight*blockbytes;
}
vkUnmapMemory(vk.device, fence->stagingmemory);
#else
//create the staging images and fill them
for (i = 0; i < mips->mipcount; i++)
{
VkImageSubresource subres = {0};
@ -1112,6 +1209,7 @@ qboolean VK_LoadTextureMips (texid_t tex, struct pendingtextureinfo *mips)
vkCmdCopyImage(vkloadcmd, fence->staging[i].image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, target.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
}
}
#endif
//layouts are annoying. and weird.
{
@ -2029,7 +2127,7 @@ void VKVID_QueueGetRGBData (void (*gotrgbdata) (void *rgbdata, intptr_t bytest
vkCmdCopyImageToBuffer(vk.frame->cbuf, vk.frame->backbuf->colour.image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, capt->buffer, 1, &icpy);
set_image_layout(vk.frame->cbuf, vk.frame->backbuf->colour.image, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
set_image_layout(vk.frame->cbuf, vk.frame->backbuf->colour.image, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
}
char *VKVID_GetRGBInfo (int *bytestride, int *truevidwidth, int *truevidheight, enum uploadfmt *fmt)
@ -2097,7 +2195,7 @@ char *VKVID_GetRGBInfo (int *bytestride, int *truevidwidth, int *truevidheight
icpy.extent.depth = 1;
vkCmdCopyImage(fence->cbuf, vk.frame->backbuf->colour.image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, tempimage, VK_IMAGE_LAYOUT_GENERAL, 1, &icpy);
set_image_layout(fence->cbuf, vk.frame->backbuf->colour.image, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
set_image_layout(fence->cbuf, vk.frame->backbuf->colour.image, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
set_image_layout(fence->cbuf, tempimage, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL, VK_ACCESS_HOST_READ_BIT);
VK_FencedSync(fence);
@ -2902,6 +3000,12 @@ void VK_CheckTextureFormats(void)
{PTI_RGBX8, VK_FORMAT_R8G8B8A8_UNORM},
{PTI_BGRA8, VK_FORMAT_B8G8R8A8_UNORM},
{PTI_BGRX8, VK_FORMAT_B8G8R8A8_UNORM},
{PTI_RGBA8_SRGB, VK_FORMAT_R8G8B8A8_SRGB, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT},
{PTI_RGBX8_SRGB, VK_FORMAT_R8G8B8A8_SRGB, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT},
{PTI_BGRA8_SRGB, VK_FORMAT_B8G8R8A8_SRGB, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT},
{PTI_BGRX8_SRGB, VK_FORMAT_B8G8R8A8_SRGB, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT},
{PTI_RGB565, VK_FORMAT_R5G6B5_UNORM_PACK16},
{PTI_RGBA4444, VK_FORMAT_R4G4B4A4_UNORM_PACK16},
{PTI_ARGB4444, VK_FORMAT_B4G4R4A4_UNORM_PACK16},
@ -2931,7 +3035,7 @@ void VK_CheckTextureFormats(void)
for (i = 0; i < countof(texfmt); i++)
{
unsigned int need = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | texfmt[i].needextra;
unsigned int need = /*VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT |*/ texfmt[i].needextra;
VkFormatProperties fmt;
vkGetPhysicalDeviceFormatProperties(vk.gpu, texfmt[i].vulkan, &fmt);

View File

@ -84,6 +84,7 @@
VKFunc(CmdCopyImage) \
VKFunc(CmdCopyBuffer) \
VKFunc(CmdCopyImageToBuffer) \
VKFunc(CmdCopyBufferToImage) \
VKFunc(CmdBlitImage) \
VKFunc(CmdPipelineBarrier) \
VKFunc(CmdSetEvent) \
@ -312,6 +313,7 @@ extern struct vulkaninfo_s
VkFormat depthformat;
VkFormat backbufformat;
qboolean srgbcapable;
qboolean neednewswapchain;

View File

@ -287,7 +287,7 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
vid.activeapp = true;
GL_Init(GLVID_getsdlglfunction);
GL_Init(info, GLVID_getsdlglfunction);
qglViewport (0, 0, vid.pixelwidth, vid.pixelheight);