Add explicit skyroom fog.

Changed how cubemaps are held in memory, making all images basically just 3d textures.
Don't start up at all if no game data is found.


git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5570 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2019-10-18 08:37:38 +00:00
parent 371909fb30
commit 11e6214daf
40 changed files with 1418 additions and 994 deletions

View file

@ -1798,8 +1798,9 @@ void CL_ClearState (qboolean gamestart)
// wipe the entire cl structure
memset (&cl, 0, sizeof(cl));
CL_ResetFog(0);
CL_ResetFog(1);
CL_ResetFog(FOGTYPE_AIR);
CL_ResetFog(FOGTYPE_WATER);
CL_ResetFog(FOGTYPE_SKYROOM);
cl.protocol_qw = PROTOCOL_VERSION_QW; //until we get an svc_serverdata
cl.allocated_client_slots = QWMAX_CLIENTS;
@ -4341,12 +4342,14 @@ void CL_Fog_f(void)
{
int ftype;
if (!Q_strcasecmp(Cmd_Argv(0), "waterfog"))
ftype = 1;
ftype = FOGTYPE_WATER;
else if (!Q_strcasecmp(Cmd_Argv(0), "skyroomfog"))
ftype = FOGTYPE_SKYROOM;
else //fog
ftype = 0;
ftype = FOGTYPE_AIR;
if ((cl.fog_locked && !Cmd_FromGamecode() && !cls.allow_cheats) || Cmd_Argc() <= 1)
{
static const char *fognames[]={"fog","waterfog"};
static const char *fognames[FOGTYPE_COUNT]={"fog","waterfog","skyroomfog"};
if (Cmd_ExecLevel != RESTRICT_INSECURE)
Con_Printf("Current %s %f (r:%f g:%f b:%f, a:%f bias:%f)\n", fognames[ftype], cl.fog[ftype].density, cl.fog[ftype].colour[0], cl.fog[ftype].colour[1], cl.fog[ftype].colour[2], cl.fog[ftype].alpha, cl.fog[ftype].depthbias);
}
@ -4905,6 +4908,7 @@ void CL_Init (void)
Cmd_AddCommandD ("fog", CL_Fog_f, "fog <density> <red> <green> <blue> <alpha> <depthbias>");
Cmd_AddCommandD ("waterfog", CL_Fog_f, "waterfog <density> <red> <green> <blue> <alpha> <depthbias>");
Cmd_AddCommandD ("skyroomfog", CL_Fog_f, "waterfog <density> <red> <green> <blue> <alpha> <depthbias>");
Cmd_AddCommandD ("skygroup", CL_Skygroup_f, "Provides a way to associate a skybox name with a series of maps, so that the requested skybox will override on a per-map basis.");
//
// Windows commands

View file

@ -8205,16 +8205,16 @@ void CLNQ_ParseServerMessage (void)
//case svcneh_fog:
if (CPNQ_IS_BJP || cls.protocol_nq == CPNQ_NEHAHRA)
{
CL_ResetFog(0);
CL_ResetFog(FOGTYPE_AIR);
if (MSG_ReadByte())
{
cl.fog[0].density = MSG_ReadFloat();
cl.fog[0].colour[0] = SRGBf(MSG_ReadByte()/255.0f);
cl.fog[0].colour[1] = SRGBf(MSG_ReadByte()/255.0f);
cl.fog[0].colour[2] = SRGBf(MSG_ReadByte()/255.0f);
cl.fog[0].time += 0.25; //change fairly fast, but not instantly
cl.fog[FOGTYPE_AIR].density = MSG_ReadFloat();
cl.fog[FOGTYPE_AIR].colour[0] = SRGBf(MSG_ReadByte()/255.0f);
cl.fog[FOGTYPE_AIR].colour[1] = SRGBf(MSG_ReadByte()/255.0f);
cl.fog[FOGTYPE_AIR].colour[2] = SRGBf(MSG_ReadByte()/255.0f);
cl.fog[FOGTYPE_AIR].time += 0.25; //change fairly fast, but not instantly
}
cl.fog_locked = !!cl.fog[0].density;
cl.fog_locked = !!cl.fog[FOGTYPE_AIR].density;
}
else
{
@ -8338,13 +8338,13 @@ void CLNQ_ParseServerMessage (void)
Cmd_ExecuteString("bf", RESTRICT_SERVER);
break;
case svcfitz_fog:
CL_ResetFog(0);
cl.fog[0].density = MSG_ReadByte()/255.0f;
cl.fog[0].colour[0] = SRGBf(MSG_ReadByte()/255.0f);
cl.fog[0].colour[1] = SRGBf(MSG_ReadByte()/255.0f);
cl.fog[0].colour[2] = SRGBf(MSG_ReadByte()/255.0f);
cl.fog[0].time += ((unsigned short)MSG_ReadShort()) / 100.0;
cl.fog_locked = !!cl.fog[0].density;
CL_ResetFog(FOGTYPE_AIR);
cl.fog[FOGTYPE_AIR].density = MSG_ReadByte()/255.0f;
cl.fog[FOGTYPE_AIR].colour[0] = SRGBf(MSG_ReadByte()/255.0f);
cl.fog[FOGTYPE_AIR].colour[1] = SRGBf(MSG_ReadByte()/255.0f);
cl.fog[FOGTYPE_AIR].colour[2] = SRGBf(MSG_ReadByte()/255.0f);
cl.fog[FOGTYPE_AIR].time += ((unsigned short)MSG_ReadShort()) / 100.0;
cl.fog_locked = !!cl.fog[FOGTYPE_AIR].density;
break;
case svcfitz_spawnbaseline2:
i = MSGCL_ReadEntity ();

View file

@ -2829,55 +2829,6 @@ static void SCR_ScreenShot_VR_f(void)
VectorClear(r_refdef.eyeoffset);
}
//flips an image so that the result is always top-down
static void *SCR_ScreenShot_FixStride(void *buffer, unsigned int fbwidth, unsigned int fbheight, int *stride, uploadfmt_t fmt, qboolean horizontalflip, qboolean verticalflip)
{
unsigned int bb, bw, bh;
Image_BlockSizeForEncoding(fmt, &bb, &bw, &bh);
if (bw == 1 && bh == 1)
{
if (horizontalflip)
{
int y, x, p;
char *bad = buffer;
char *in = buffer, *out;
buffer = out = BZ_Malloc(fbwidth*fbheight*bb);
if (*stride < 0)
in += fbwidth*bb*(fbheight-1);
for (y = 0; y < fbheight; y++, in += *stride, out += fbwidth*bb)
{
for (x = 0; x < fbwidth*bb; x+=bb)
{
for (p = 0; p < bb; p++)
out[x+p] = in[(fbwidth-1)*bb-x+p];
}
}
BZ_Free(bad);
*stride = fbwidth*bb;
}
if (verticalflip && bh == 1)
*stride = -*stride;
if (*stride != fbwidth*bw)
{
unsigned int y;
char *tofree = buffer;
char *out = BZ_Malloc(fbwidth*fbheight*bb);
char *in = buffer;
buffer = out;
if (*stride < 0)
in += fbwidth*bb*(fbheight-1); //the memory pointer always starts at the lowest address regardless of bottom-up state.
for (y = 0; y < fbheight; y++, in += *stride, out += fbwidth*bb)
{
memcpy(out, in, fbwidth*bb);
}
BZ_Free(tofree);
*stride = fbwidth*bb;
}
}
return buffer;
}
void SCR_ScreenShot_Cubemap_f(void)
{
void *buffer;
@ -2889,6 +2840,7 @@ void SCR_ScreenShot_Cubemap_f(void)
int i, firstside;
char olddrawviewmodel[64]; //hack, so we can set r_drawviewmodel to 0 so that it doesn't appear in screenshots even if the csqc is generating new data.
vec3_t oldangles;
void *facedata;
struct pendingtextureinfo mips;
static const struct
{
@ -2946,50 +2898,49 @@ void SCR_ScreenShot_Cubemap_f(void)
if (!strcmp(ext, ".ktx") || !strcmp(ext, ".dds"))
{
qboolean fail = false;
mips.type = PTI_CUBEMAP;
mips.type = PTI_CUBE;
mips.encoding = 0;
mips.extrafree = NULL;
mips.mipcount = 6;
bb=0;
for (i = 0; i < 6; i++)
{
VectorCopy(sides[i].angle, cl.playerview->simangles);
VectorCopy(cl.playerview->simangles, cl.playerview->viewangles);
mips.mip[i].data = SCR_ScreenShot_Capture(fbwidth, fbheight, &stride, &fmt, true);
if (!mips.mip[i].data)
fail = true;
facedata = SCR_ScreenShot_Capture(fbwidth, fbheight, &stride, &fmt, true);
if (!facedata)
break;
if (!i)
mips.encoding = fmt;
else if (fmt != mips.encoding || fbwidth != mips.mip[0].width || fbheight != mips.mip[0].height)
fail = true; //zomgwtfbbq
mips.mip[i].data = SCR_ScreenShot_FixStride(mips.mip[i].data, fbwidth, fbheight, &stride, fmt, sides[i].horizontalflip, sides[i].verticalflip);
Image_BlockSizeForEncoding(fmt, &bb, &bw, &bh);
mips.mip[i].datasize = bb*((fbwidth+bw-1)/bw)*((fbheight+bh-1)/bh);
mips.mip[i].width = fbwidth;
mips.mip[i].height = fbheight;
mips.mip[i].depth = 0;
mips.mip[i].needfree = true;
}
/*FIXME:
while (!fail && (w > 1 || h > 1))
{ //warning: d3d is different
w = max(1,w>>1);
h = max(1,h>>1);
if (mips.mipcount+6 > countof(mips.mip))
break; //erk! how big was the original image?!?
for (i = 0; i < 6; i++)
{
mips.mip[mips.mipcount] = GenerateMip(mips.mip[mips.mipcount-6]);
mips.mipcount++;
Image_BlockSizeForEncoding(fmt, &bb, &bw, &bh);
if (bw != 1 || bh != 1)
{ //erk, no block compression here...
BZ_Free(facedata);
break; //zomgwtfbbq
}
}
*/
mips.mip[0].datasize = bb*((fbwidth+bw-1)/bw)*((fbheight+bh-1)/bh);
mips.mip[0].width = fbwidth;
mips.mip[0].height = fbheight;
mips.mip[0].depth = 6;
mips.mip[0].datasize *= mips.mip[0].depth;
mips.mip[0].data = BZ_Malloc(mips.mip[0].datasize);
mips.mip[0].needfree = true;
mips.encoding = fmt;
}
else if (fmt != mips.encoding || fbwidth != mips.mip[0].width || fbheight != mips.mip[0].height)
{
BZ_Free(facedata);
break; //zomgwtfbbq
}
Image_FlipImage(facedata, mips.mip[0].data + i*mips.mip[0].datasize/6, &fbwidth, &fbheight, bb, sides[i].horizontalflip, sides[i].verticalflip, false);
BZ_Free(facedata);
}
if (i == 6)
{
Q_snprintfz(filename, sizeof(filename), "textures/%s", fname);
COM_DefaultExtension (filename, ext, sizeof(filename));
#ifdef IMAGEFMT_KTX
@ -3023,6 +2974,7 @@ void SCR_ScreenShot_Cubemap_f(void)
#endif
else
Con_Printf ("%s: Unknown format %s\n", Cmd_Argv(0), filename);
}
while (i-- > 0)
if (mips.mip[i].needfree)
BZ_Free(mips.mip[i].data);

View file

@ -621,6 +621,15 @@ typedef struct {
entity_state_t *entstate;
} lerpents_t;
enum
{
FOGTYPE_AIR,
FOGTYPE_WATER,
FOGTYPE_SKYROOM,
FOGTYPE_COUNT
};
//state associated with each player 'seat' (one for each splitscreen client)
//note that this doesn't include networking inputlog info.
struct playerview_s
@ -908,9 +917,9 @@ typedef struct
float skyrotate;
vec3_t skyaxis;
qboolean fog_locked;
fogstate_t fog[2]; //0 = air, 1 = water. if water has no density fall back on air.
fogstate_t oldfog[2];
qboolean fog_locked; //FIXME: make bitmask
fogstate_t fog[FOGTYPE_COUNT]; //0 = air, 1 = water. if water has no density fall back on air.
fogstate_t oldfog[FOGTYPE_COUNT];
char levelname[40]; // for display on solo scoreboard
char *windowtitle; // fully overrides the window caption.

File diff suppressed because it is too large Load diff

View file

@ -750,15 +750,6 @@ static qboolean PM_ParsePackageList(vfsfile_t *f, int parseflags, const char *ur
else
subprefix = com_token;
#if defined(HAVE_LEGACY) && defined(WEBCLIENT)
//hack. I'm trying to retire the self-signed cert on [fte.]triptohell.info
if (!strcmp(url, "https://triptohell.info/downloadables.php") || !strcmp(url, "https://fte.triptohell.info/downloadables.php"))
{
Q_strncpyz(url, "https://updates.triptohell.info/downloadables.php", sizeof(url));
forcewrite = true;
}
#endif
PM_AddSubList(url, subprefix, (parseflags & DPF_ENABLED)?true:false, (parseflags&DPF_TRUSTED));
continue;
}

View file

@ -295,11 +295,12 @@ struct pendingtextureinfo
{
enum
{
PTI_2D,
PTI_3D,
PTI_CUBEMAP, //mips are packed (to make d3d11 happy)
PTI_2D_ARRAY, //looks like a 3d texture, but depth doesn't change with mips.
PTI_CUBEMAP_ARRAY, //looks like PTI_2D_ARRAY, with depth*6
//formats are all w*h*(d||l)
PTI_2D, //w*h*1
PTI_3D, //w*h*d - only format which actually changes mip depths
PTI_CUBE, //w*h*6
PTI_2D_ARRAY, //w*h*layers
PTI_CUBE_ARRAY, //w*h*(layers*6)
} type;
uploadfmt_t encoding; //0

View file

@ -1179,7 +1179,7 @@ static void QCBUILTIN PF_R_DynamicLight_Set(pubprogfuncs_t *prinst, struct globa
s = PR_GetStringOfs(prinst, OFS_PARM2);
Q_strncpyz(l->cubemapname, s, sizeof(l->cubemapname));
if (*l->cubemapname)
l->cubetexture = R_LoadReplacementTexture(l->cubemapname, "", IF_CUBEMAP, NULL, 0, 0, TF_INVALID);
l->cubetexture = R_LoadReplacementTexture(l->cubemapname, "", IF_TEXTYPE_CUBE, NULL, 0, 0, TF_INVALID);
else
l->cubetexture = r_nulltex;
break;
@ -1366,7 +1366,7 @@ static void PF_R_DynamicLight_AddInternal(pubprogfuncs_t *prinst, struct globalv
dl->style = style;
Q_strncpyz(dl->cubemapname, cubemapname, sizeof(dl->cubemapname));
if (*dl->cubemapname)
dl->cubetexture = R_LoadReplacementTexture(dl->cubemapname, "", IF_CUBEMAP, NULL, 0, 0, TF_INVALID);
dl->cubetexture = R_LoadReplacementTexture(dl->cubemapname, "", IF_TEXTYPE_CUBE, NULL, 0, 0, TF_INVALID);
else
dl->cubetexture = r_nulltex;

View file

@ -205,7 +205,6 @@ typedef struct
float glslpad1; //w_fog[1].z
float glslpad2; //w_fog[1].w
// float alpha;
// float start;
// float end;
// float height;
@ -421,15 +420,16 @@ enum imageflags
IF_NOPICMIP = 1<<7,
IF_NOALPHA = 1<<8, /*hint rather than requirement*/
IF_NOGAMMA = 1<<9, /*do not apply texture-based gamma*/
IF_3DMAP = 1<<10, /*waning - don't test directly*/
IF_CUBEMAP = 1<<11, /*waning - don't test directly*/
IF_2DARRAY = IF_3DMAP|IF_CUBEMAP,
IF_TEXTYPE = (1<<10) | (1<<11), /*0=2d, 1=3d, 2=cubeface, 3=2d array texture*/
IF_TEXTYPESHIFT = 10, /*0=2d, 1=3d, 2=cubeface, 3=array*/
IF_MIPCAP = 1<<12, //allow the use of d_mipcap
IF_PREMULTIPLYALPHA = 1<<13, //rgb *= alpha
IF_TEXTYPEMASK = (1<<10) | (1<<11) | (1<<12), /*0=2d, 1=3d, 2=cubeface, 3=2d array texture*/
#define IF_TEXTYPESHIFT 10
#define IF_TEXTYPE_2D (PTI_2D<<IF_TEXTYPESHIFT)
#define IF_TEXTYPE_3D (PTI_3D<<IF_TEXTYPESHIFT)
#define IF_TEXTYPE_CUBE (PTI_CUBE<<IF_TEXTYPESHIFT)
#define IF_TEXTYPE_2D_ARRAY (PTI_2D_ARRAY<<IF_TEXTYPESHIFT)
#define IF_TEXTYPE_CUBE_ARRAY (PTI_CUBE_ARRAY<<IF_TEXTYPESHIFT)
IF_MIPCAP = 1<<13, //allow the use of d_mipcap
IF_PREMULTIPLYALPHA = 1<<14, //rgb *= alpha
IF_UNUSED14 = 1<<14, //
IF_UNUSED15 = 1<<15, //
IF_UNUSED16 = 1<<16, //
IF_UNUSED17 = 1<<17, //
@ -477,6 +477,7 @@ qboolean Image_FormatHasAlpha(uploadfmt_t encoding);
image_t *Image_LoadTexture (const char *identifier, int width, int height, uploadfmt_t fmt, void *data, unsigned int flags);
struct pendingtextureinfo *Image_LoadMipsFromMemory(int flags, const char *iname, const char *fname, qbyte *filedata, int filesize);
void Image_ChangeFormat(struct pendingtextureinfo *mips, unsigned int flags, uploadfmt_t origfmt, const char *imagename);
void *Image_FlipImage(const void *inbuffer, void *outbuffer, int *inoutwidth, int *inoutheight, int pixelbytes, qboolean flipx, qboolean flipy, qboolean flipd);
#ifdef D3D8QUAKE
void D3D8_Set2D (void);

View file

@ -128,8 +128,8 @@ cvar_t r_drawflat = CVARAF ("r_drawflat", "0", "gl_textureless",
CVAR_ARCHIVE | CVAR_SEMICHEAT | CVAR_RENDERERCALLBACK | CVAR_SHADERSYSTEM);
cvar_t r_lightmap = CVARF ("r_lightmap", "0",
CVAR_ARCHIVE | CVAR_SEMICHEAT | CVAR_RENDERERCALLBACK | CVAR_SHADERSYSTEM);
cvar_t r_wireframe = CVARAFD ("r_wireframe", "0",
"r_showtris", CVAR_CHEAT, "Developer feature where everything is drawn with wireframe over the top. Only active where cheats are permitted.");
cvar_t r_wireframe = CVARAFD ("r_showtris", "0",
"r_wireframe", CVAR_CHEAT, "Developer feature where everything is drawn with wireframe over the top. Only active where cheats are permitted.");
cvar_t r_outline = CVARD ("gl_outline", "0", "Draw some stylised outlines.");
cvar_t r_outline_width = CVARD ("gl_outline_width", "2", "The width of those outlines.");
cvar_t r_wireframe_smooth = CVAR ("r_wireframe_smooth", "0");

View file

@ -860,6 +860,13 @@ void Mod_ParseInfoFromEntityLump(model_t *wmodel) //actually, this should be in
Cbuf_AddText(key, RESTRICT_INSECURE);
Cbuf_AddText("\n", RESTRICT_INSECURE);
}
else if (!strcmp("skyroomfog", key)) //q1 extension. FIXME: should be made temporary.
{
memcpy(key, "skyroomfog ", 11);
Q_strncpyz(key+11, token, sizeof(key)-11);
Cbuf_AddText(key, RESTRICT_INSECURE);
Cbuf_AddText("\n", RESTRICT_INSECURE);
}
else if (!strncmp("cvar_", key, 5)) //override cvars so mappers don't end up hacking cvars and fucking over configs (at least in other engines).
{
cvar_t *var = Cvar_FindVar(key+5);

View file

@ -5706,6 +5706,10 @@ qboolean FS_ChangeGame(ftemanifest_t *man, qboolean allowreloadconfigs, qboolean
}
if (!man)
{
#ifdef _WIN32
if (!fixedbasedir)
Sys_Error("No recognised game data found in working directory.\n");
#endif
man = FS_Manifest_Parse(NULL,
"FTEManifestVer 1\n"
"game \"\"\n"

View file

@ -1285,9 +1285,9 @@ static vfsfile_t *QDECL FSZIP_OpenVFS(searchpathfuncs_t *handle, flocation_t *lo
return NULL;
}
#ifdef AVAIL_ZLIB
if (flags & ZFL_DEFLATED)
{
#ifdef AVAIL_ZLIB
#ifdef ZIPCRYPT
//FIXME: Cvar_Get is not threadsafe, and nor is accessing the cvar...
char *password = (flags & ZFL_WEAKENCRYPT)?Cvar_Get("fs_zip_password", "thisispublic", 0, "Filesystem")->string:NULL;
@ -1296,6 +1296,9 @@ static vfsfile_t *QDECL FSZIP_OpenVFS(searchpathfuncs_t *handle, flocation_t *lo
#endif
vfsz->decompress = FSZIP_Deflate_Init(zip, vfsz->startpos, datasize, vfsz->length, pf->name, password, pf->crc);
if (!vfsz->decompress)
#else
Con_Printf("%s:%s: zlib not supported\n", COM_SkipPath(zip->filename), pf->name);
#endif
{
/*
windows explorer tends to use deflate64 on large files, which zlib and thus we, do not support, thus this is a 'common' failure path
@ -1305,10 +1308,9 @@ static vfsfile_t *QDECL FSZIP_OpenVFS(searchpathfuncs_t *handle, flocation_t *lo
return NULL;
}
}
#endif
#ifdef AVAIL_BZLIB
if (flags & ZFL_BZIP2)
{
#ifdef AVAIL_BZLIB
#ifdef ZIPCRYPT
//FIXME: Cvar_Get is not threadsafe, and nor is accessing the cvar...
char *password = (flags & ZFL_WEAKENCRYPT)?Cvar_Get("fs_zip_password", "thisispublic", 0, "Filesystem")->string:NULL;
@ -1317,6 +1319,9 @@ static vfsfile_t *QDECL FSZIP_OpenVFS(searchpathfuncs_t *handle, flocation_t *lo
#endif
vfsz->decompress = FSZIP_BZip2_Init(zip, vfsz->startpos, datasize, vfsz->length, pf->name, password, pf->crc);
if (!vfsz->decompress)
#else
Con_Printf("%s:%s: libbz2 not supported\n", COM_SkipPath(zip->filename), pf->name);
#endif
{
/*
windows explorer tends to use deflate64 on large files, which zlib and thus we, do not support, thus this is a 'common' failure path
@ -1326,7 +1331,6 @@ static vfsfile_t *QDECL FSZIP_OpenVFS(searchpathfuncs_t *handle, flocation_t *lo
return NULL;
}
}
#endif
if (Sys_LockMutex(zip->mutex))
{
@ -1554,14 +1558,10 @@ static qboolean FSZIP_ValidateLocalHeader(zipfile_t *zip, zpackfile_t *zfile, qo
if (local.cmethod == 0)
return (zfile->flags & (ZFL_STORED|ZFL_CORRUPT|ZFL_DEFLATED|ZFL_BZIP2)) == ZFL_STORED;
#ifdef AVAIL_ZLIB
if (local.cmethod == 8)
return (zfile->flags & (ZFL_STORED|ZFL_CORRUPT|ZFL_DEFLATED|ZFL_BZIP2)) == ZFL_DEFLATED;
#endif
#ifdef AVAIL_BZLIB
if (local.cmethod == 12)
return (zfile->flags & (ZFL_STORED|ZFL_CORRUPT|ZFL_DEFLATED|ZFL_BZIP2)) == ZFL_BZIP2;
#endif
return false; //some other method that we don't know.
}

View file

@ -7196,7 +7196,7 @@ qbyte *CM_ClusterPVS (model_t *mod, int cluster, pvsbuffer_t *buffer, pvsmerge_t
}
else
{
if (merge != PVM_REPLACE)
if (merge != PVM_MERGE)
memset (buffer->buffer, 0, (mod->numclusters+7)>>3);
}
return buffer->buffer;

View file

@ -456,16 +456,16 @@ static qboolean QDECL SSL_CloseFile(vfsfile_t *vfs)
}
static const qbyte updates_triptohell_certdata[962] = "\x30\x82\x03\xbe\x30\x82\x02\xa6\xa0\x03\x02\x01\x02\x02\x09\x00\xf4\x4e\x13\x08\x32\x85\xb5\x19\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x30\x74\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x4b\x31\x10\x30\x0e\x06\x03\x55\x04\x08\x0c\x07\x45\x6e\x67\x6c\x61\x6e\x64\x31\x0f\x30\x0d\x06\x03\x55\x04\x07\x0c\x06\x4c\x6f\x6e\x64\x6f\x6e\x31\x0e\x30\x0c\x06\x03\x55\x04\x0a\x0c\x05\x46\x54\x45\x51\x57\x31\x10\x30\x0e\x06\x03\x55\x04\x0b\x0c\x07\x55\x70\x64\x61\x74\x65\x73\x31\x20\x30\x1e\x06\x03\x55\x04\x03\x0c\x17\x75\x70\x64\x61\x74\x65\x73\x2e\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x1e\x17\x0d\x31\x39\x30\x35\x33\x31\x31\x30\x30\x39\x31\x39\x5a\x17\x0d\x32\x39\x30\x35\x32\x38\x31\x30\x30\x39\x31\x39\x5a\x30\x74\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x4b\x31\x10\x30\x0e\x06\x03\x55\x04\x08\x0c\x07\x45\x6e\x67\x6c\x61\x6e\x64\x31\x0f\x30\x0d\x06\x03\x55\x04\x07\x0c\x06\x4c\x6f\x6e\x64\x6f\x6e\x31\x0e\x30\x0c\x06\x03\x55\x04\x0a\x0c\x05\x46\x54\x45\x51\x57\x31\x10\x30\x0e\x06\x03\x55\x04\x0b\x0c\x07\x55\x70\x64\x61\x74\x65\x73\x31\x20\x30\x1e\x06\x03\x55\x04\x03\x0c\x17\x75\x70\x64\x61\x74\x65\x73\x2e\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xaa\xb5\x9c\xcc\xe8\xbd\xad\x1c\x7f\x6b\x1c\xc9\x04\xe6\x2c\x10\xac\x99\xeb\x67\x0b\x9c\x24\xb8\x90\x77\xde\xaa\x44\xa2\x15\x31\x61\x52\x4d\xeb\x8f\x56\xb8\xaf\xc1\x2f\x66\xdd\x55\x8d\xd6\xec\xc3\xa4\x93\x8c\x86\xeb\xaf\x89\x17\x19\x2e\x6c\xc2\xd4\xf9\x92\xac\x2e\x73\x99\x56\xf2\xc3\xc4\x14\x56\x4a\x0d\xbe\x51\xc9\x8f\x4e\x92\x20\x2b\xae\x05\x0c\x7e\x87\xa5\x02\xe1\xc0\x7d\x71\xa7\x38\x72\x47\x3f\x31\x07\x90\xb0\x6d\xcf\xae\xb6\xdb\xeb\x39\xaa\x5f\xb4\x6f\x0c\x63\x2a\x21\x65\x36\xaa\x6b\xac\x97\xb6\xbe\x20\xa4\x87\x36\xbf\x35\xc5\xa6\x31\xe4\x9d\x85\xf3\xae\x8f\x6b\xf8\x59\x75\x0f\xb5\x5d\x31\x40\x39\x2e\xea\x48\x65\xdf\x91\xe3\x06\xfb\xb2\xec\xdc\xd0\x90\x94\xd6\x68\x4d\x62\x25\x9a\x3d\xc3\x74\x17\x7d\x0e\xe2\x1e\x34\xbf\x02\x85\xc4\x40\x88\x91\xeb\xe0\xf5\x92\x56\x42\x4f\xa6\x4c\x17\x88\xb2\x89\xd2\xec\x60\x54\x97\x20\x0a\xca\xf0\xd1\x33\x3f\x5b\x66\xb7\x8a\x42\x72\x67\xc9\x47\x83\xb3\xd4\x1e\xa8\x44\xbf\x5a\x1a\x85\x79\xee\xf8\x80\xde\x19\x1d\xc5\xdd\x50\x42\x10\x17\xb7\xc3\xd4\xf1\xcb\x8a\xb8\x71\x55\x31\x02\x03\x01\x00\x01\xa3\x53\x30\x51\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\x2c\x68\x81\x8f\x40\x8c\x40\x42\x9f\xbd\xc5\x0b\x36\xfb\xe2\x76\xeb\x8d\xb4\xf3\x30\x1f\x06\x03\x55\x1d\x23\x04\x18\x30\x16\x80\x14\x2c\x68\x81\x8f\x40\x8c\x40\x42\x9f\xbd\xc5\x0b\x36\xfb\xe2\x76\xeb\x8d\xb4\xf3\x30\x0f\x06\x03\x55\x1d\x13\x01\x01\xff\x04\x05\x30\x03\x01\x01\xff\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x03\x82\x01\x01\x00\x0c\x01\x35\x32\xb8\xe7\x96\xba\x3e\x53\x8c\x78\x41\xab\x9b\x7f\xe2\x7a\x80\x5a\xc9\x88\x06\x29\x28\xf9\x50\x7f\xcc\xb6\xcc\x34\x03\x45\x32\x79\x63\xe7\xde\x9c\x46\x29\xf4\xaf\x32\x72\x26\x11\xa0\x7b\x52\x23\x0a\xd5\x51\x91\x79\xf2\x50\x61\x80\x72\x40\xe7\x85\xb0\x13\x1d\x98\xdb\x14\x23\x59\xa4\xbc\xe9\xe0\x1b\xc0\x38\x33\x96\xbc\xbb\x56\x47\xcc\xbd\xe8\x40\x49\xdf\xaa\x64\x7e\x29\xe5\x9d\x40\xa5\x1a\x5c\x45\x1f\x5a\x77\x59\xfe\x7a\xb8\xf8\x4d\xc4\x9b\x31\xe6\x08\xc4\x95\xfa\x91\x8f\x91\x9f\x3c\xc4\x82\xb9\xf1\x6d\xa8\xa6\xc4\x09\xb1\xe9\xa8\x60\x9b\xaa\x4c\x79\xf0\x99\xb8\xad\x63\xb1\xe4\xc0\xaf\xf0\xdf\xc9\x33\x53\x4d\x09\xe4\x3f\x8d\x9e\x38\xc6\x93\xff\xcc\x91\x46\x7e\x67\x28\x61\xaa\xc7\x0b\xe2\xd8\x8c\xe4\xec\x8d\x44\xe7\x6a\x14\x78\x91\x7d\xec\xc7\x07\xed\xc9\x58\xdb\x35\xd4\x70\x06\x06\x39\x8d\x4b\x80\x2c\xb6\xa8\x79\x5c\x94\x15\x6c\x34\x06\x5c\xd7\xc5\x42\xc0\x72\x01\x71\x07\xf5\x25\x6a\xd0\x24\x86\xcd\x1b\x21\x07\xae\x40\xf8\xc1\xe4\x23\x0d\xa0\xc0\x23\xf0\x07\xba\xdc\x34\x5d\x47\xcf\x4b\x7b\xd5\x5d";
static const qbyte fte_triptohell_certdata[917] = "\x30\x82\x03\x91\x30\x82\x02\x79\xa0\x03\x02\x01\x02\x02\x09\x00\xb5\x71\x47\x8d\x5e\x66\xf1\xd9\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x30\x5f\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x11\x30\x0f\x06\x03\x55\x04\x07\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x0c\x30\x0a\x06\x03\x55\x04\x0a\x0c\x03\x46\x54\x45\x31\x1c\x30\x1a\x06\x03\x55\x04\x03\x0c\x13\x66\x74\x65\x2e\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x1e\x17\x0d\x31\x34\x31\x32\x32\x35\x30\x30\x35\x38\x31\x34\x5a\x17\x0d\x31\x37\x30\x33\x30\x34\x30\x30\x35\x38\x31\x34\x5a\x30\x5f\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x11\x30\x0f\x06\x03\x55\x04\x07\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x0c\x30\x0a\x06\x03\x55\x04\x0a\x0c\x03\x46\x54\x45\x31\x1c\x30\x1a\x06\x03\x55\x04\x03\x0c\x13\x66\x74\x65\x2e\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xdd\xb8\x7c\x69\x3d\x63\x95\xe3\x88\x15\xfd\xad\x93\x5e\x6b\x97\xfb\x74\xba\x1f\x83\x33\xe5\x8a\x8d\x8f\xb0\xbf\xf9\xd3\xa1\x2c\x65\x53\xa7\xef\xd3\x0f\xdc\x03\x60\x0a\x40\xef\xa8\xef\x3f\xb3\xd9\x8d\x31\x39\x12\x8a\xd8\x0e\x24\x8f\xe5\x58\x26\x86\x4c\x76\x6c\x59\x9a\xab\xea\x1c\x3d\xfb\x62\x62\xad\xaf\xd6\x00\x33\x76\x2d\xbb\xeb\xe8\xec\xb4\x76\x4f\xb0\xbe\xcf\xf0\x46\x94\x40\x02\x99\xd4\xb2\x71\x71\xd6\xf5\x1f\xc3\x4f\x1e\x1e\xb4\x0d\x82\x49\xc4\xa2\xdc\xae\x6f\x4e\x3a\xf9\x0e\xdd\xf4\xd2\x53\xe3\xe7\x7d\x58\x79\xf4\xce\x1f\x6c\xac\x81\x8c\x8c\xe1\x03\x5b\x22\x56\x92\x19\x4f\x74\xc0\x36\x41\xac\x1b\xfa\x9e\xf7\x2a\x0f\xd6\x4b\xcc\x9a\xca\x67\x87\xb7\x95\xdf\xb7\xd4\x7d\x8c\xcc\xa9\x25\xde\xdd\x8c\x1b\xd7\x32\xf2\x84\x25\x46\x7b\x10\x55\xf9\x80\xfd\x5d\xad\xab\xf9\x4c\x1f\xc0\xa5\xd1\x3f\x01\x86\x4d\xfa\x57\xab\x7a\x6d\xec\xf1\xdb\xf4\xad\xf2\x33\xcd\xa0\xed\xfe\x1b\x27\x55\x56\xba\x8c\x47\x70\x16\xd5\x75\x17\x8e\x80\xaa\x49\x5e\x93\x83\x1d\x6f\x1f\x2c\xf7\xa7\x64\xe6\x2e\x88\x8e\xff\x70\x5a\x41\x52\xae\x93\x02\x03\x01\x00\x01\xa3\x50\x30\x4e\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\x4e\x76\x4a\xce\x7b\x45\x14\x39\xeb\x9c\x28\x56\xb5\x7b\x8a\x18\x6f\x22\x17\x82\x30\x1f\x06\x03\x55\x1d\x23\x04\x18\x30\x16\x80\x14\x4e\x76\x4a\xce\x7b\x45\x14\x39\xeb\x9c\x28\x56\xb5\x7b\x8a\x18\x6f\x22\x17\x82\x30\x0c\x06\x03\x55\x1d\x13\x04\x05\x30\x03\x01\x01\xff\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x03\x82\x01\x01\x00\x48\x22\x65\xed\x2e\xc5\xed\xbb\xe9\x40\x6c\x80\xc4\x63\x19\xd1\x00\xb4\x30\x34\x17\x7c\x7c\xbd\x1b\xc5\xa9\x43\x0c\x92\x6e\xd6\x2d\x11\x6c\x0d\xa6\xda\x30\xe9\xf7\x46\x7b\x01\xe4\x53\x23\xae\x88\xd1\xf2\xed\xca\x84\x06\x19\x97\xb9\x06\xfb\xda\xec\x72\x2d\x15\x20\xd2\x8f\x66\xad\xb5\xdd\x4b\x4f\xdf\x7e\xaf\xa3\x6c\x7f\x53\x32\x8f\xe2\x19\x5c\x44\x98\x86\x31\xee\xb4\x03\xe7\x27\xa1\x83\xab\xc3\xce\xb4\x9a\x01\xbe\x8c\x64\x2e\x2b\xe3\x4e\x55\xdf\x95\xeb\x16\x87\xbd\xfa\x11\xa2\x3e\x38\x92\x97\x36\xe9\x65\x60\xf3\xac\x68\x44\xb3\x51\x54\x3a\x42\xa8\x98\x9b\xee\x1b\x9e\x79\x6a\xaf\xc0\xbe\x41\xc4\xb1\x96\x42\xd9\x94\xef\x49\x5b\xbe\x2d\x04\xb9\xfb\x92\xbb\xdc\x0e\x29\xfd\xee\xa9\x68\x09\xf9\x9f\x69\x8b\x3d\xe1\x4b\xee\x24\xf9\xfe\x02\x3a\x0a\xb8\xcd\x6c\x07\x43\xa9\x4a\xe7\x03\x34\x2e\x72\xa7\x81\xaa\x40\xa9\x98\x5d\x97\xee\x2a\x99\xc6\x8f\xe8\x6f\x98\xa2\x85\xc9\x0d\x04\x19\x43\x6a\xd3\xc7\x15\x4c\x4b\xbc\xa5\xb8\x9f\x38\xf3\x43\x83\x0c\xef\x97\x6e\xa6\x20\xde\xc5\xd3\x1e\x3e\x5d\xcd\x58\x3d\x5c\x55\x7a\x90\x94";
static const qbyte triptohell_certdata[933] = "\x30\x82\x03\xa1\x30\x82\x02\x89\xa0\x03\x02\x01\x02\x02\x09\x00\xea\xb7\x13\xcf\x55\xe5\xe8\x8c\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x30\x67\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x11\x30\x0f\x06\x03\x55\x04\x07\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x18\x30\x16\x06\x03\x55\x04\x0a\x0c\x0f\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x31\x18\x30\x16\x06\x03\x55\x04\x03\x0c\x0f\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x1e\x17\x0d\x31\x34\x31\x32\x32\x35\x30\x30\x35\x38\x33\x37\x5a\x17\x0d\x31\x37\x30\x33\x30\x34\x30\x30\x35\x38\x33\x37\x5a\x30\x67\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x11\x30\x0f\x06\x03\x55\x04\x07\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x18\x30\x16\x06\x03\x55\x04\x0a\x0c\x0f\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x31\x18\x30\x16\x06\x03\x55\x04\x03\x0c\x0f\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xd8\x77\x62\xf6\x74\xa7\x75\xde\xda\x09\xae\x9e\x76\x7a\xc6\x2a\xcf\x9a\xbe\xc6\xb9\x6d\xe2\xca\x0f\x2d\x95\xb8\x89\x93\xf7\x50\x64\x92\x7d\x95\x34\xe4\x6e\xef\x52\x56\xef\x13\x9a\x3a\xae\x84\x5b\x57\x82\x04\x86\x74\xbd\x4e\x38\x32\x56\x00\xd6\x34\x9c\x23\xd6\x81\x8e\x29\x77\x45\x61\x20\xdf\x28\xf8\xe5\x61\x83\xec\xe6\xa0\x1a\x75\xa8\x3b\x53\x6f\xc4\x09\x61\x66\x3a\xf0\x81\xbf\x2c\xf5\x8e\xf1\xe2\x35\xe4\x24\x7f\x16\xcc\xce\x60\xa2\x42\x6e\xc2\x3a\x29\x75\x6c\x79\xb0\x99\x9c\xe2\xfe\x27\x32\xb6\xf7\x0d\x71\xfd\x62\x9d\x54\x7c\x40\xb2\xf5\xa0\xa4\x25\x31\x8d\x65\xfd\x3f\x3b\x9b\x7e\x84\x74\x17\x3c\x1f\xec\x50\xcf\x75\xb8\x5c\xca\xfc\x0f\xe8\x47\xd8\x64\xec\x5f\x6c\x45\x9a\x55\x49\x97\x3f\xcb\x49\x34\x71\x0a\x12\x13\xbc\x3d\x53\x81\x17\x9a\x92\x44\x91\x07\xc2\xef\x6d\x64\x86\x5d\xfd\x67\xd5\x99\x38\x95\x46\x74\x6d\xb6\xbf\x29\xc9\x5b\xac\xb1\x46\xd6\x9e\x57\x5c\x7b\x24\x91\xf4\x7c\xe4\x01\x31\x8c\xec\x79\x94\xb7\x3f\xd2\x93\x6d\xe2\x69\xbe\x61\x44\x2e\x8f\x1a\xdc\xa8\x97\xf5\x81\x8e\x0c\xe1\x00\xf2\x71\x51\xf3\x02\x03\x01\x00\x01\xa3\x50\x30\x4e\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\x18\xb2\x6b\x63\xcc\x17\x54\xf6\xf0\xb6\x9e\x62\xa4\x35\xcf\x47\x74\x13\x29\xbf\x30\x1f\x06\x03\x55\x1d\x23\x04\x18\x30\x16\x80\x14\x18\xb2\x6b\x63\xcc\x17\x54\xf6\xf0\xb6\x9e\x62\xa4\x35\xcf\x47\x74\x13\x29\xbf\x30\x0c\x06\x03\x55\x1d\x13\x04\x05\x30\x03\x01\x01\xff\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x03\x82\x01\x01\x00\x7f\x24\x18\x8a\x79\xee\xf9\xeb\xed\x29\x1e\x21\x15\x8a\x53\xc9\xb7\xec\x30\xc4\x85\x9f\x45\x85\x26\x36\xb7\x07\xf3\xf1\xff\x3b\x89\x05\x0a\xd4\x30\x68\x31\x68\x33\xdd\xf6\x58\xa3\x85\x9f\x49\x50\x76\x9a\xc5\x79\x13\xe1\x4d\x67\x0c\xf3\x92\xf0\x1d\x02\x1f\xc4\x5c\xd4\xa1\x0c\x57\xdf\x46\x84\x43\x9f\xb0\xe2\x91\x62\xa8\xe0\x86\x0d\x47\xe1\xd9\x60\x01\xc4\xe0\xda\x6f\x06\x0a\xad\x38\xf3\x66\x68\xc5\xe2\x66\x3e\x47\x83\x65\x64\xcd\xff\xf3\xbb\xa7\xfa\x23\xf1\x82\x5e\x06\x6a\x91\x37\x51\xcd\xb9\x95\x20\x89\xff\xa1\x54\xb2\x76\xcf\x8e\xe1\xcd\x13\x93\x13\xd1\xda\x0d\x0d\xbc\x0f\xd5\x11\x26\xd6\xaf\x60\x0f\x4d\x8a\x4f\x28\xee\x6c\xf1\x99\xdc\xed\x16\xdc\x87\x26\xfd\x23\x8a\xb8\xb0\x20\x0e\xe2\x32\xf5\x8e\xb0\x65\x98\x13\xb8\x4b\x39\x7c\x8c\x98\xa2\x29\x75\x48\x3a\x89\xf9\x61\x77\x6c\x2d\x84\x41\x40\x17\xa6\x50\xc5\x09\x63\x10\xe7\x09\xd4\x5c\xdd\x0e\x71\x16\xaf\xb1\x32\xe4\xc0\xe6\xea\xfd\x26\x55\x07\x40\x95\x84\x48\x62\x04\x10\x92\xb2\xd9\x27\xfb\x8a\xf3\x7c\xe6\xfe\xd4\xfc\xa6\x33\x79\x01\x5c\xc3\x1f\x80\xa8\xf3";
//static const qbyte fte_triptohell_certdata[917] = "\x30\x82\x03\x91\x30\x82\x02\x79\xa0\x03\x02\x01\x02\x02\x09\x00\xb5\x71\x47\x8d\x5e\x66\xf1\xd9\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x30\x5f\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x11\x30\x0f\x06\x03\x55\x04\x07\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x0c\x30\x0a\x06\x03\x55\x04\x0a\x0c\x03\x46\x54\x45\x31\x1c\x30\x1a\x06\x03\x55\x04\x03\x0c\x13\x66\x74\x65\x2e\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x1e\x17\x0d\x31\x34\x31\x32\x32\x35\x30\x30\x35\x38\x31\x34\x5a\x17\x0d\x31\x37\x30\x33\x30\x34\x30\x30\x35\x38\x31\x34\x5a\x30\x5f\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x11\x30\x0f\x06\x03\x55\x04\x07\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x0c\x30\x0a\x06\x03\x55\x04\x0a\x0c\x03\x46\x54\x45\x31\x1c\x30\x1a\x06\x03\x55\x04\x03\x0c\x13\x66\x74\x65\x2e\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xdd\xb8\x7c\x69\x3d\x63\x95\xe3\x88\x15\xfd\xad\x93\x5e\x6b\x97\xfb\x74\xba\x1f\x83\x33\xe5\x8a\x8d\x8f\xb0\xbf\xf9\xd3\xa1\x2c\x65\x53\xa7\xef\xd3\x0f\xdc\x03\x60\x0a\x40\xef\xa8\xef\x3f\xb3\xd9\x8d\x31\x39\x12\x8a\xd8\x0e\x24\x8f\xe5\x58\x26\x86\x4c\x76\x6c\x59\x9a\xab\xea\x1c\x3d\xfb\x62\x62\xad\xaf\xd6\x00\x33\x76\x2d\xbb\xeb\xe8\xec\xb4\x76\x4f\xb0\xbe\xcf\xf0\x46\x94\x40\x02\x99\xd4\xb2\x71\x71\xd6\xf5\x1f\xc3\x4f\x1e\x1e\xb4\x0d\x82\x49\xc4\xa2\xdc\xae\x6f\x4e\x3a\xf9\x0e\xdd\xf4\xd2\x53\xe3\xe7\x7d\x58\x79\xf4\xce\x1f\x6c\xac\x81\x8c\x8c\xe1\x03\x5b\x22\x56\x92\x19\x4f\x74\xc0\x36\x41\xac\x1b\xfa\x9e\xf7\x2a\x0f\xd6\x4b\xcc\x9a\xca\x67\x87\xb7\x95\xdf\xb7\xd4\x7d\x8c\xcc\xa9\x25\xde\xdd\x8c\x1b\xd7\x32\xf2\x84\x25\x46\x7b\x10\x55\xf9\x80\xfd\x5d\xad\xab\xf9\x4c\x1f\xc0\xa5\xd1\x3f\x01\x86\x4d\xfa\x57\xab\x7a\x6d\xec\xf1\xdb\xf4\xad\xf2\x33\xcd\xa0\xed\xfe\x1b\x27\x55\x56\xba\x8c\x47\x70\x16\xd5\x75\x17\x8e\x80\xaa\x49\x5e\x93\x83\x1d\x6f\x1f\x2c\xf7\xa7\x64\xe6\x2e\x88\x8e\xff\x70\x5a\x41\x52\xae\x93\x02\x03\x01\x00\x01\xa3\x50\x30\x4e\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\x4e\x76\x4a\xce\x7b\x45\x14\x39\xeb\x9c\x28\x56\xb5\x7b\x8a\x18\x6f\x22\x17\x82\x30\x1f\x06\x03\x55\x1d\x23\x04\x18\x30\x16\x80\x14\x4e\x76\x4a\xce\x7b\x45\x14\x39\xeb\x9c\x28\x56\xb5\x7b\x8a\x18\x6f\x22\x17\x82\x30\x0c\x06\x03\x55\x1d\x13\x04\x05\x30\x03\x01\x01\xff\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x03\x82\x01\x01\x00\x48\x22\x65\xed\x2e\xc5\xed\xbb\xe9\x40\x6c\x80\xc4\x63\x19\xd1\x00\xb4\x30\x34\x17\x7c\x7c\xbd\x1b\xc5\xa9\x43\x0c\x92\x6e\xd6\x2d\x11\x6c\x0d\xa6\xda\x30\xe9\xf7\x46\x7b\x01\xe4\x53\x23\xae\x88\xd1\xf2\xed\xca\x84\x06\x19\x97\xb9\x06\xfb\xda\xec\x72\x2d\x15\x20\xd2\x8f\x66\xad\xb5\xdd\x4b\x4f\xdf\x7e\xaf\xa3\x6c\x7f\x53\x32\x8f\xe2\x19\x5c\x44\x98\x86\x31\xee\xb4\x03\xe7\x27\xa1\x83\xab\xc3\xce\xb4\x9a\x01\xbe\x8c\x64\x2e\x2b\xe3\x4e\x55\xdf\x95\xeb\x16\x87\xbd\xfa\x11\xa2\x3e\x38\x92\x97\x36\xe9\x65\x60\xf3\xac\x68\x44\xb3\x51\x54\x3a\x42\xa8\x98\x9b\xee\x1b\x9e\x79\x6a\xaf\xc0\xbe\x41\xc4\xb1\x96\x42\xd9\x94\xef\x49\x5b\xbe\x2d\x04\xb9\xfb\x92\xbb\xdc\x0e\x29\xfd\xee\xa9\x68\x09\xf9\x9f\x69\x8b\x3d\xe1\x4b\xee\x24\xf9\xfe\x02\x3a\x0a\xb8\xcd\x6c\x07\x43\xa9\x4a\xe7\x03\x34\x2e\x72\xa7\x81\xaa\x40\xa9\x98\x5d\x97\xee\x2a\x99\xc6\x8f\xe8\x6f\x98\xa2\x85\xc9\x0d\x04\x19\x43\x6a\xd3\xc7\x15\x4c\x4b\xbc\xa5\xb8\x9f\x38\xf3\x43\x83\x0c\xef\x97\x6e\xa6\x20\xde\xc5\xd3\x1e\x3e\x5d\xcd\x58\x3d\x5c\x55\x7a\x90\x94";
//static const qbyte triptohell_certdata[933] = "\x30\x82\x03\xa1\x30\x82\x02\x89\xa0\x03\x02\x01\x02\x02\x09\x00\xea\xb7\x13\xcf\x55\xe5\xe8\x8c\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x30\x67\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x11\x30\x0f\x06\x03\x55\x04\x07\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x18\x30\x16\x06\x03\x55\x04\x0a\x0c\x0f\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x31\x18\x30\x16\x06\x03\x55\x04\x03\x0c\x0f\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x1e\x17\x0d\x31\x34\x31\x32\x32\x35\x30\x30\x35\x38\x33\x37\x5a\x17\x0d\x31\x37\x30\x33\x30\x34\x30\x30\x35\x38\x33\x37\x5a\x30\x67\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x11\x30\x0f\x06\x03\x55\x04\x07\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x18\x30\x16\x06\x03\x55\x04\x0a\x0c\x0f\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x31\x18\x30\x16\x06\x03\x55\x04\x03\x0c\x0f\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xd8\x77\x62\xf6\x74\xa7\x75\xde\xda\x09\xae\x9e\x76\x7a\xc6\x2a\xcf\x9a\xbe\xc6\xb9\x6d\xe2\xca\x0f\x2d\x95\xb8\x89\x93\xf7\x50\x64\x92\x7d\x95\x34\xe4\x6e\xef\x52\x56\xef\x13\x9a\x3a\xae\x84\x5b\x57\x82\x04\x86\x74\xbd\x4e\x38\x32\x56\x00\xd6\x34\x9c\x23\xd6\x81\x8e\x29\x77\x45\x61\x20\xdf\x28\xf8\xe5\x61\x83\xec\xe6\xa0\x1a\x75\xa8\x3b\x53\x6f\xc4\x09\x61\x66\x3a\xf0\x81\xbf\x2c\xf5\x8e\xf1\xe2\x35\xe4\x24\x7f\x16\xcc\xce\x60\xa2\x42\x6e\xc2\x3a\x29\x75\x6c\x79\xb0\x99\x9c\xe2\xfe\x27\x32\xb6\xf7\x0d\x71\xfd\x62\x9d\x54\x7c\x40\xb2\xf5\xa0\xa4\x25\x31\x8d\x65\xfd\x3f\x3b\x9b\x7e\x84\x74\x17\x3c\x1f\xec\x50\xcf\x75\xb8\x5c\xca\xfc\x0f\xe8\x47\xd8\x64\xec\x5f\x6c\x45\x9a\x55\x49\x97\x3f\xcb\x49\x34\x71\x0a\x12\x13\xbc\x3d\x53\x81\x17\x9a\x92\x44\x91\x07\xc2\xef\x6d\x64\x86\x5d\xfd\x67\xd5\x99\x38\x95\x46\x74\x6d\xb6\xbf\x29\xc9\x5b\xac\xb1\x46\xd6\x9e\x57\x5c\x7b\x24\x91\xf4\x7c\xe4\x01\x31\x8c\xec\x79\x94\xb7\x3f\xd2\x93\x6d\xe2\x69\xbe\x61\x44\x2e\x8f\x1a\xdc\xa8\x97\xf5\x81\x8e\x0c\xe1\x00\xf2\x71\x51\xf3\x02\x03\x01\x00\x01\xa3\x50\x30\x4e\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\x18\xb2\x6b\x63\xcc\x17\x54\xf6\xf0\xb6\x9e\x62\xa4\x35\xcf\x47\x74\x13\x29\xbf\x30\x1f\x06\x03\x55\x1d\x23\x04\x18\x30\x16\x80\x14\x18\xb2\x6b\x63\xcc\x17\x54\xf6\xf0\xb6\x9e\x62\xa4\x35\xcf\x47\x74\x13\x29\xbf\x30\x0c\x06\x03\x55\x1d\x13\x04\x05\x30\x03\x01\x01\xff\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x03\x82\x01\x01\x00\x7f\x24\x18\x8a\x79\xee\xf9\xeb\xed\x29\x1e\x21\x15\x8a\x53\xc9\xb7\xec\x30\xc4\x85\x9f\x45\x85\x26\x36\xb7\x07\xf3\xf1\xff\x3b\x89\x05\x0a\xd4\x30\x68\x31\x68\x33\xdd\xf6\x58\xa3\x85\x9f\x49\x50\x76\x9a\xc5\x79\x13\xe1\x4d\x67\x0c\xf3\x92\xf0\x1d\x02\x1f\xc4\x5c\xd4\xa1\x0c\x57\xdf\x46\x84\x43\x9f\xb0\xe2\x91\x62\xa8\xe0\x86\x0d\x47\xe1\xd9\x60\x01\xc4\xe0\xda\x6f\x06\x0a\xad\x38\xf3\x66\x68\xc5\xe2\x66\x3e\x47\x83\x65\x64\xcd\xff\xf3\xbb\xa7\xfa\x23\xf1\x82\x5e\x06\x6a\x91\x37\x51\xcd\xb9\x95\x20\x89\xff\xa1\x54\xb2\x76\xcf\x8e\xe1\xcd\x13\x93\x13\xd1\xda\x0d\x0d\xbc\x0f\xd5\x11\x26\xd6\xaf\x60\x0f\x4d\x8a\x4f\x28\xee\x6c\xf1\x99\xdc\xed\x16\xdc\x87\x26\xfd\x23\x8a\xb8\xb0\x20\x0e\xe2\x32\xf5\x8e\xb0\x65\x98\x13\xb8\x4b\x39\x7c\x8c\x98\xa2\x29\x75\x48\x3a\x89\xf9\x61\x77\x6c\x2d\x84\x41\x40\x17\xa6\x50\xc5\x09\x63\x10\xe7\x09\xd4\x5c\xdd\x0e\x71\x16\xaf\xb1\x32\xe4\xc0\xe6\xea\xfd\x26\x55\x07\x40\x95\x84\x48\x62\x04\x10\x92\xb2\xd9\x27\xfb\x8a\xf3\x7c\xe6\xfe\xd4\xfc\xa6\x33\x79\x01\x5c\xc3\x1f\x80\xa8\xf3";
static struct
{
char *hostname;
unsigned int datasize;
const qbyte *data;
} knowncerts[] = {
{"triptohell.info", sizeof(triptohell_certdata), triptohell_certdata},
{"fte.triptohell.info", sizeof(fte_triptohell_certdata), fte_triptohell_certdata},
// {"triptohell.info", sizeof(triptohell_certdata), triptohell_certdata},
// {"fte.triptohell.info", sizeof(fte_triptohell_certdata), fte_triptohell_certdata},
{"updates.triptohell.info", sizeof(updates_triptohell_certdata), updates_triptohell_certdata},
};

View file

@ -387,8 +387,8 @@ static void SSPI_Encode(sslfile_t *f)
//these are known sites that use self-signed certificates, or are special enough that we don't trust corporate networks to hack in their own certificate authority for a proxy/mitm
//old static const qbyte triptohell_certdata[933] = "\x30\x82\x03\xa1\x30\x82\x02\x89\xa0\x03\x02\x01\x02\x02\x09\x00\x8b\xd0\x05\x63\x62\xd1\x6a\xe3\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x05\x05\x00\x30\x67\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x42\x44\x31\x0c\x30\x0a\x06\x03\x55\x04\x08\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x07\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x0a\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x0b\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x03\x0c\x03\x42\x61\x64\x31\x12\x30\x10\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x09\x01\x16\x03\x42\x61\x64\x30\x1e\x17\x0d\x31\x34\x31\x32\x32\x34\x32\x32\x34\x32\x34\x37\x5a\x17\x0d\x32\x34\x31\x32\x32\x31\x32\x32\x34\x32\x34\x37\x5a\x30\x67\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x42\x44\x31\x0c\x30\x0a\x06\x03\x55\x04\x08\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x07\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x0a\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x0b\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x03\x0c\x03\x42\x61\x64\x31\x12\x30\x10\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x09\x01\x16\x03\x42\x61\x64\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xaf\x10\x33\xfa\x39\xf5\xae\x2c\x91\x0e\x20\xe6\x3c\x5c\x7c\x1e\xeb\x16\x50\x2f\x05\x30\xfe\x67\xee\xa9\x00\x54\xd9\x4a\x86\xe6\xba\x80\xfb\x1a\x80\x08\x7e\x7b\x13\xe5\x1a\x18\xc9\xd4\x70\xbd\x5d\xc4\x38\xef\x64\xf1\x90\x2c\x53\x49\x93\x24\x36\x3e\x11\x59\x69\xa6\xdf\x37\xb2\x54\x82\x28\x3e\xdd\x30\x75\xa0\x18\xd8\xe1\xf5\x52\x73\x12\x5b\x37\x68\x1c\x59\xbd\x8c\x73\x66\x47\xbc\xcb\x9c\xfe\x38\x92\x8f\x74\xe9\xd1\x2f\x96\xd2\x5d\x6d\x11\x59\xb2\xdc\xbd\x8c\x37\x5b\x22\x76\x98\xe7\xbe\x08\xef\x1e\x99\xc4\xa9\x77\x2c\x9c\x0e\x08\x3c\x8e\xab\x97\x0c\x6a\xd7\x03\xab\xfd\x4a\x1e\x95\xb2\xc2\x9c\x3a\x16\x65\xd7\xaf\x45\x5f\x6e\xe7\xce\x51\xba\xa0\x60\x43\x0e\x07\xc5\x0b\x0a\x82\x05\x26\xc4\x92\x0a\x27\x5b\xfc\x57\x6c\xdf\xe2\x54\x8a\xef\x38\xf1\xf8\xc4\xf8\x51\x16\x27\x1f\x78\x89\x7c\x5b\xd7\x53\xcd\x9b\x54\x2a\xe6\x71\xee\xe4\x56\x2e\xa4\x09\x1a\x61\xf7\x0f\x97\x22\x94\xd7\xef\x21\x6c\xe6\x81\xfb\x54\x5f\x09\x92\xac\xd2\x7c\xab\xd5\xa9\x81\xf4\xc9\xb7\xd6\xbf\x68\xf8\x4f\xdc\xf3\x60\xa3\x3b\x29\x92\x9e\xdd\xa2\xa3\x02\x03\x01\x00\x01\xa3\x50\x30\x4e\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\x19\xed\xd0\x7b\x16\xaf\xb5\x0c\x9a\xe8\xd3\x46\x2e\x3c\x64\x29\xb6\xc1\x73\x5a\x30\x1f\x06\x03\x55\x1d\x23\x04\x18\x30\x16\x80\x14\x19\xed\xd0\x7b\x16\xaf\xb5\x0c\x9a\xe8\xd3\x46\x2e\x3c\x64\x29\xb6\xc1\x73\x5a\x30\x0c\x06\x03\x55\x1d\x13\x04\x05\x30\x03\x01\x01\xff\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x05\x05\x00\x03\x82\x01\x01\x00\x62\xa7\x26\xeb\xd4\x03\x29\x9c\x09\x33\x69\x7a\x9c\x65\x68\xec\x4c\xb9\x06\xeb\x1e\x51\x6f\x78\x20\xdc\xf6\x44\x5e\x06\x6e\x53\x87\x73\xe6\x14\x15\xb9\x17\x74\x67\xe0\x4e\x48\x38\xbc\x1c\xbd\xd0\xad\xd6\xbd\x8c\xf0\x3a\xe0\x13\x73\x19\xad\x8b\x79\x68\x67\x65\x9b\x7a\x4c\x81\xfb\xd9\x92\x77\x89\xb5\xb0\x53\xb0\xa5\xf7\x2d\x8e\x29\x60\x31\xd1\x9b\x2f\x63\x8a\x5f\x64\xc1\x61\xd5\xb7\xdf\x70\x3b\x2b\xf6\x1a\x96\xb9\xa7\x08\xca\x87\xa6\x8c\x60\xca\x6e\xd7\xee\xba\xef\x89\x0b\x93\xd5\xfd\xfc\x14\xba\xef\x27\xba\x90\x11\x90\xf7\x25\x70\xe7\x4e\xf4\x9c\x13\x27\xc1\xa7\x8e\xd9\x66\x43\x72\x20\x5b\xe1\x5c\x73\x74\xf5\x33\xf2\xa5\xf6\xe1\xd5\xac\xf3\x67\x5c\xe7\xd4\x0a\x8d\x91\x73\x03\x3e\x9d\xbc\x96\xc3\x0c\xdb\xd5\x77\x6e\x76\x44\x69\xaf\x24\x0f\x4f\x8b\x47\x36\x8b\xc3\xd6\x36\xdd\x26\x5a\x9c\xdd\x9c\x43\xee\x29\x43\xdd\x75\x2f\x19\x52\xfc\x1d\x24\x9c\x13\x29\x99\xa0\x6d\x7a\x95\xcc\xa0\x58\x86\xd8\xc5\xb9\xa3\xc2\x3d\x64\x1d\x85\x8a\xca\x53\x55\x8e\x9a\x6d\xc9\x91\x73\xf4\xe1\xe1\xa4\x9b\x76\xfc\x7f\x63\xc2\xb9\x23";
static const qbyte updates_triptohell_certdata[962] = "\x30\x82\x03\xbe\x30\x82\x02\xa6\xa0\x03\x02\x01\x02\x02\x09\x00\xf4\x4e\x13\x08\x32\x85\xb5\x19\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x30\x74\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x4b\x31\x10\x30\x0e\x06\x03\x55\x04\x08\x0c\x07\x45\x6e\x67\x6c\x61\x6e\x64\x31\x0f\x30\x0d\x06\x03\x55\x04\x07\x0c\x06\x4c\x6f\x6e\x64\x6f\x6e\x31\x0e\x30\x0c\x06\x03\x55\x04\x0a\x0c\x05\x46\x54\x45\x51\x57\x31\x10\x30\x0e\x06\x03\x55\x04\x0b\x0c\x07\x55\x70\x64\x61\x74\x65\x73\x31\x20\x30\x1e\x06\x03\x55\x04\x03\x0c\x17\x75\x70\x64\x61\x74\x65\x73\x2e\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x1e\x17\x0d\x31\x39\x30\x35\x33\x31\x31\x30\x30\x39\x31\x39\x5a\x17\x0d\x32\x39\x30\x35\x32\x38\x31\x30\x30\x39\x31\x39\x5a\x30\x74\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x4b\x31\x10\x30\x0e\x06\x03\x55\x04\x08\x0c\x07\x45\x6e\x67\x6c\x61\x6e\x64\x31\x0f\x30\x0d\x06\x03\x55\x04\x07\x0c\x06\x4c\x6f\x6e\x64\x6f\x6e\x31\x0e\x30\x0c\x06\x03\x55\x04\x0a\x0c\x05\x46\x54\x45\x51\x57\x31\x10\x30\x0e\x06\x03\x55\x04\x0b\x0c\x07\x55\x70\x64\x61\x74\x65\x73\x31\x20\x30\x1e\x06\x03\x55\x04\x03\x0c\x17\x75\x70\x64\x61\x74\x65\x73\x2e\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xaa\xb5\x9c\xcc\xe8\xbd\xad\x1c\x7f\x6b\x1c\xc9\x04\xe6\x2c\x10\xac\x99\xeb\x67\x0b\x9c\x24\xb8\x90\x77\xde\xaa\x44\xa2\x15\x31\x61\x52\x4d\xeb\x8f\x56\xb8\xaf\xc1\x2f\x66\xdd\x55\x8d\xd6\xec\xc3\xa4\x93\x8c\x86\xeb\xaf\x89\x17\x19\x2e\x6c\xc2\xd4\xf9\x92\xac\x2e\x73\x99\x56\xf2\xc3\xc4\x14\x56\x4a\x0d\xbe\x51\xc9\x8f\x4e\x92\x20\x2b\xae\x05\x0c\x7e\x87\xa5\x02\xe1\xc0\x7d\x71\xa7\x38\x72\x47\x3f\x31\x07\x90\xb0\x6d\xcf\xae\xb6\xdb\xeb\x39\xaa\x5f\xb4\x6f\x0c\x63\x2a\x21\x65\x36\xaa\x6b\xac\x97\xb6\xbe\x20\xa4\x87\x36\xbf\x35\xc5\xa6\x31\xe4\x9d\x85\xf3\xae\x8f\x6b\xf8\x59\x75\x0f\xb5\x5d\x31\x40\x39\x2e\xea\x48\x65\xdf\x91\xe3\x06\xfb\xb2\xec\xdc\xd0\x90\x94\xd6\x68\x4d\x62\x25\x9a\x3d\xc3\x74\x17\x7d\x0e\xe2\x1e\x34\xbf\x02\x85\xc4\x40\x88\x91\xeb\xe0\xf5\x92\x56\x42\x4f\xa6\x4c\x17\x88\xb2\x89\xd2\xec\x60\x54\x97\x20\x0a\xca\xf0\xd1\x33\x3f\x5b\x66\xb7\x8a\x42\x72\x67\xc9\x47\x83\xb3\xd4\x1e\xa8\x44\xbf\x5a\x1a\x85\x79\xee\xf8\x80\xde\x19\x1d\xc5\xdd\x50\x42\x10\x17\xb7\xc3\xd4\xf1\xcb\x8a\xb8\x71\x55\x31\x02\x03\x01\x00\x01\xa3\x53\x30\x51\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\x2c\x68\x81\x8f\x40\x8c\x40\x42\x9f\xbd\xc5\x0b\x36\xfb\xe2\x76\xeb\x8d\xb4\xf3\x30\x1f\x06\x03\x55\x1d\x23\x04\x18\x30\x16\x80\x14\x2c\x68\x81\x8f\x40\x8c\x40\x42\x9f\xbd\xc5\x0b\x36\xfb\xe2\x76\xeb\x8d\xb4\xf3\x30\x0f\x06\x03\x55\x1d\x13\x01\x01\xff\x04\x05\x30\x03\x01\x01\xff\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x03\x82\x01\x01\x00\x0c\x01\x35\x32\xb8\xe7\x96\xba\x3e\x53\x8c\x78\x41\xab\x9b\x7f\xe2\x7a\x80\x5a\xc9\x88\x06\x29\x28\xf9\x50\x7f\xcc\xb6\xcc\x34\x03\x45\x32\x79\x63\xe7\xde\x9c\x46\x29\xf4\xaf\x32\x72\x26\x11\xa0\x7b\x52\x23\x0a\xd5\x51\x91\x79\xf2\x50\x61\x80\x72\x40\xe7\x85\xb0\x13\x1d\x98\xdb\x14\x23\x59\xa4\xbc\xe9\xe0\x1b\xc0\x38\x33\x96\xbc\xbb\x56\x47\xcc\xbd\xe8\x40\x49\xdf\xaa\x64\x7e\x29\xe5\x9d\x40\xa5\x1a\x5c\x45\x1f\x5a\x77\x59\xfe\x7a\xb8\xf8\x4d\xc4\x9b\x31\xe6\x08\xc4\x95\xfa\x91\x8f\x91\x9f\x3c\xc4\x82\xb9\xf1\x6d\xa8\xa6\xc4\x09\xb1\xe9\xa8\x60\x9b\xaa\x4c\x79\xf0\x99\xb8\xad\x63\xb1\xe4\xc0\xaf\xf0\xdf\xc9\x33\x53\x4d\x09\xe4\x3f\x8d\x9e\x38\xc6\x93\xff\xcc\x91\x46\x7e\x67\x28\x61\xaa\xc7\x0b\xe2\xd8\x8c\xe4\xec\x8d\x44\xe7\x6a\x14\x78\x91\x7d\xec\xc7\x07\xed\xc9\x58\xdb\x35\xd4\x70\x06\x06\x39\x8d\x4b\x80\x2c\xb6\xa8\x79\x5c\x94\x15\x6c\x34\x06\x5c\xd7\xc5\x42\xc0\x72\x01\x71\x07\xf5\x25\x6a\xd0\x24\x86\xcd\x1b\x21\x07\xae\x40\xf8\xc1\xe4\x23\x0d\xa0\xc0\x23\xf0\x07\xba\xdc\x34\x5d\x47\xcf\x4b\x7b\xd5\x5d";
static const qbyte fte_triptohell_certdata[917] = "\x30\x82\x03\x91\x30\x82\x02\x79\xa0\x03\x02\x01\x02\x02\x09\x00\xb5\x71\x47\x8d\x5e\x66\xf1\xd9\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x30\x5f\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x11\x30\x0f\x06\x03\x55\x04\x07\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x0c\x30\x0a\x06\x03\x55\x04\x0a\x0c\x03\x46\x54\x45\x31\x1c\x30\x1a\x06\x03\x55\x04\x03\x0c\x13\x66\x74\x65\x2e\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x1e\x17\x0d\x31\x34\x31\x32\x32\x35\x30\x30\x35\x38\x31\x34\x5a\x17\x0d\x31\x37\x30\x33\x30\x34\x30\x30\x35\x38\x31\x34\x5a\x30\x5f\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x11\x30\x0f\x06\x03\x55\x04\x07\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x0c\x30\x0a\x06\x03\x55\x04\x0a\x0c\x03\x46\x54\x45\x31\x1c\x30\x1a\x06\x03\x55\x04\x03\x0c\x13\x66\x74\x65\x2e\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xdd\xb8\x7c\x69\x3d\x63\x95\xe3\x88\x15\xfd\xad\x93\x5e\x6b\x97\xfb\x74\xba\x1f\x83\x33\xe5\x8a\x8d\x8f\xb0\xbf\xf9\xd3\xa1\x2c\x65\x53\xa7\xef\xd3\x0f\xdc\x03\x60\x0a\x40\xef\xa8\xef\x3f\xb3\xd9\x8d\x31\x39\x12\x8a\xd8\x0e\x24\x8f\xe5\x58\x26\x86\x4c\x76\x6c\x59\x9a\xab\xea\x1c\x3d\xfb\x62\x62\xad\xaf\xd6\x00\x33\x76\x2d\xbb\xeb\xe8\xec\xb4\x76\x4f\xb0\xbe\xcf\xf0\x46\x94\x40\x02\x99\xd4\xb2\x71\x71\xd6\xf5\x1f\xc3\x4f\x1e\x1e\xb4\x0d\x82\x49\xc4\xa2\xdc\xae\x6f\x4e\x3a\xf9\x0e\xdd\xf4\xd2\x53\xe3\xe7\x7d\x58\x79\xf4\xce\x1f\x6c\xac\x81\x8c\x8c\xe1\x03\x5b\x22\x56\x92\x19\x4f\x74\xc0\x36\x41\xac\x1b\xfa\x9e\xf7\x2a\x0f\xd6\x4b\xcc\x9a\xca\x67\x87\xb7\x95\xdf\xb7\xd4\x7d\x8c\xcc\xa9\x25\xde\xdd\x8c\x1b\xd7\x32\xf2\x84\x25\x46\x7b\x10\x55\xf9\x80\xfd\x5d\xad\xab\xf9\x4c\x1f\xc0\xa5\xd1\x3f\x01\x86\x4d\xfa\x57\xab\x7a\x6d\xec\xf1\xdb\xf4\xad\xf2\x33\xcd\xa0\xed\xfe\x1b\x27\x55\x56\xba\x8c\x47\x70\x16\xd5\x75\x17\x8e\x80\xaa\x49\x5e\x93\x83\x1d\x6f\x1f\x2c\xf7\xa7\x64\xe6\x2e\x88\x8e\xff\x70\x5a\x41\x52\xae\x93\x02\x03\x01\x00\x01\xa3\x50\x30\x4e\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\x4e\x76\x4a\xce\x7b\x45\x14\x39\xeb\x9c\x28\x56\xb5\x7b\x8a\x18\x6f\x22\x17\x82\x30\x1f\x06\x03\x55\x1d\x23\x04\x18\x30\x16\x80\x14\x4e\x76\x4a\xce\x7b\x45\x14\x39\xeb\x9c\x28\x56\xb5\x7b\x8a\x18\x6f\x22\x17\x82\x30\x0c\x06\x03\x55\x1d\x13\x04\x05\x30\x03\x01\x01\xff\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x03\x82\x01\x01\x00\x48\x22\x65\xed\x2e\xc5\xed\xbb\xe9\x40\x6c\x80\xc4\x63\x19\xd1\x00\xb4\x30\x34\x17\x7c\x7c\xbd\x1b\xc5\xa9\x43\x0c\x92\x6e\xd6\x2d\x11\x6c\x0d\xa6\xda\x30\xe9\xf7\x46\x7b\x01\xe4\x53\x23\xae\x88\xd1\xf2\xed\xca\x84\x06\x19\x97\xb9\x06\xfb\xda\xec\x72\x2d\x15\x20\xd2\x8f\x66\xad\xb5\xdd\x4b\x4f\xdf\x7e\xaf\xa3\x6c\x7f\x53\x32\x8f\xe2\x19\x5c\x44\x98\x86\x31\xee\xb4\x03\xe7\x27\xa1\x83\xab\xc3\xce\xb4\x9a\x01\xbe\x8c\x64\x2e\x2b\xe3\x4e\x55\xdf\x95\xeb\x16\x87\xbd\xfa\x11\xa2\x3e\x38\x92\x97\x36\xe9\x65\x60\xf3\xac\x68\x44\xb3\x51\x54\x3a\x42\xa8\x98\x9b\xee\x1b\x9e\x79\x6a\xaf\xc0\xbe\x41\xc4\xb1\x96\x42\xd9\x94\xef\x49\x5b\xbe\x2d\x04\xb9\xfb\x92\xbb\xdc\x0e\x29\xfd\xee\xa9\x68\x09\xf9\x9f\x69\x8b\x3d\xe1\x4b\xee\x24\xf9\xfe\x02\x3a\x0a\xb8\xcd\x6c\x07\x43\xa9\x4a\xe7\x03\x34\x2e\x72\xa7\x81\xaa\x40\xa9\x98\x5d\x97\xee\x2a\x99\xc6\x8f\xe8\x6f\x98\xa2\x85\xc9\x0d\x04\x19\x43\x6a\xd3\xc7\x15\x4c\x4b\xbc\xa5\xb8\x9f\x38\xf3\x43\x83\x0c\xef\x97\x6e\xa6\x20\xde\xc5\xd3\x1e\x3e\x5d\xcd\x58\x3d\x5c\x55\x7a\x90\x94";
static const qbyte triptohell_certdata[933] = "\x30\x82\x03\xa1\x30\x82\x02\x89\xa0\x03\x02\x01\x02\x02\x09\x00\xea\xb7\x13\xcf\x55\xe5\xe8\x8c\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x30\x67\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x11\x30\x0f\x06\x03\x55\x04\x07\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x18\x30\x16\x06\x03\x55\x04\x0a\x0c\x0f\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x31\x18\x30\x16\x06\x03\x55\x04\x03\x0c\x0f\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x1e\x17\x0d\x31\x34\x31\x32\x32\x35\x30\x30\x35\x38\x33\x37\x5a\x17\x0d\x31\x37\x30\x33\x30\x34\x30\x30\x35\x38\x33\x37\x5a\x30\x67\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x11\x30\x0f\x06\x03\x55\x04\x07\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x18\x30\x16\x06\x03\x55\x04\x0a\x0c\x0f\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x31\x18\x30\x16\x06\x03\x55\x04\x03\x0c\x0f\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xd8\x77\x62\xf6\x74\xa7\x75\xde\xda\x09\xae\x9e\x76\x7a\xc6\x2a\xcf\x9a\xbe\xc6\xb9\x6d\xe2\xca\x0f\x2d\x95\xb8\x89\x93\xf7\x50\x64\x92\x7d\x95\x34\xe4\x6e\xef\x52\x56\xef\x13\x9a\x3a\xae\x84\x5b\x57\x82\x04\x86\x74\xbd\x4e\x38\x32\x56\x00\xd6\x34\x9c\x23\xd6\x81\x8e\x29\x77\x45\x61\x20\xdf\x28\xf8\xe5\x61\x83\xec\xe6\xa0\x1a\x75\xa8\x3b\x53\x6f\xc4\x09\x61\x66\x3a\xf0\x81\xbf\x2c\xf5\x8e\xf1\xe2\x35\xe4\x24\x7f\x16\xcc\xce\x60\xa2\x42\x6e\xc2\x3a\x29\x75\x6c\x79\xb0\x99\x9c\xe2\xfe\x27\x32\xb6\xf7\x0d\x71\xfd\x62\x9d\x54\x7c\x40\xb2\xf5\xa0\xa4\x25\x31\x8d\x65\xfd\x3f\x3b\x9b\x7e\x84\x74\x17\x3c\x1f\xec\x50\xcf\x75\xb8\x5c\xca\xfc\x0f\xe8\x47\xd8\x64\xec\x5f\x6c\x45\x9a\x55\x49\x97\x3f\xcb\x49\x34\x71\x0a\x12\x13\xbc\x3d\x53\x81\x17\x9a\x92\x44\x91\x07\xc2\xef\x6d\x64\x86\x5d\xfd\x67\xd5\x99\x38\x95\x46\x74\x6d\xb6\xbf\x29\xc9\x5b\xac\xb1\x46\xd6\x9e\x57\x5c\x7b\x24\x91\xf4\x7c\xe4\x01\x31\x8c\xec\x79\x94\xb7\x3f\xd2\x93\x6d\xe2\x69\xbe\x61\x44\x2e\x8f\x1a\xdc\xa8\x97\xf5\x81\x8e\x0c\xe1\x00\xf2\x71\x51\xf3\x02\x03\x01\x00\x01\xa3\x50\x30\x4e\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\x18\xb2\x6b\x63\xcc\x17\x54\xf6\xf0\xb6\x9e\x62\xa4\x35\xcf\x47\x74\x13\x29\xbf\x30\x1f\x06\x03\x55\x1d\x23\x04\x18\x30\x16\x80\x14\x18\xb2\x6b\x63\xcc\x17\x54\xf6\xf0\xb6\x9e\x62\xa4\x35\xcf\x47\x74\x13\x29\xbf\x30\x0c\x06\x03\x55\x1d\x13\x04\x05\x30\x03\x01\x01\xff\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x03\x82\x01\x01\x00\x7f\x24\x18\x8a\x79\xee\xf9\xeb\xed\x29\x1e\x21\x15\x8a\x53\xc9\xb7\xec\x30\xc4\x85\x9f\x45\x85\x26\x36\xb7\x07\xf3\xf1\xff\x3b\x89\x05\x0a\xd4\x30\x68\x31\x68\x33\xdd\xf6\x58\xa3\x85\x9f\x49\x50\x76\x9a\xc5\x79\x13\xe1\x4d\x67\x0c\xf3\x92\xf0\x1d\x02\x1f\xc4\x5c\xd4\xa1\x0c\x57\xdf\x46\x84\x43\x9f\xb0\xe2\x91\x62\xa8\xe0\x86\x0d\x47\xe1\xd9\x60\x01\xc4\xe0\xda\x6f\x06\x0a\xad\x38\xf3\x66\x68\xc5\xe2\x66\x3e\x47\x83\x65\x64\xcd\xff\xf3\xbb\xa7\xfa\x23\xf1\x82\x5e\x06\x6a\x91\x37\x51\xcd\xb9\x95\x20\x89\xff\xa1\x54\xb2\x76\xcf\x8e\xe1\xcd\x13\x93\x13\xd1\xda\x0d\x0d\xbc\x0f\xd5\x11\x26\xd6\xaf\x60\x0f\x4d\x8a\x4f\x28\xee\x6c\xf1\x99\xdc\xed\x16\xdc\x87\x26\xfd\x23\x8a\xb8\xb0\x20\x0e\xe2\x32\xf5\x8e\xb0\x65\x98\x13\xb8\x4b\x39\x7c\x8c\x98\xa2\x29\x75\x48\x3a\x89\xf9\x61\x77\x6c\x2d\x84\x41\x40\x17\xa6\x50\xc5\x09\x63\x10\xe7\x09\xd4\x5c\xdd\x0e\x71\x16\xaf\xb1\x32\xe4\xc0\xe6\xea\xfd\x26\x55\x07\x40\x95\x84\x48\x62\x04\x10\x92\xb2\xd9\x27\xfb\x8a\xf3\x7c\xe6\xfe\xd4\xfc\xa6\x33\x79\x01\x5c\xc3\x1f\x80\xa8\xf3";
//static const qbyte fte_triptohell_certdata[917] = "\x30\x82\x03\x91\x30\x82\x02\x79\xa0\x03\x02\x01\x02\x02\x09\x00\xb5\x71\x47\x8d\x5e\x66\xf1\xd9\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x30\x5f\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x11\x30\x0f\x06\x03\x55\x04\x07\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x0c\x30\x0a\x06\x03\x55\x04\x0a\x0c\x03\x46\x54\x45\x31\x1c\x30\x1a\x06\x03\x55\x04\x03\x0c\x13\x66\x74\x65\x2e\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x1e\x17\x0d\x31\x34\x31\x32\x32\x35\x30\x30\x35\x38\x31\x34\x5a\x17\x0d\x31\x37\x30\x33\x30\x34\x30\x30\x35\x38\x31\x34\x5a\x30\x5f\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x11\x30\x0f\x06\x03\x55\x04\x07\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x0c\x30\x0a\x06\x03\x55\x04\x0a\x0c\x03\x46\x54\x45\x31\x1c\x30\x1a\x06\x03\x55\x04\x03\x0c\x13\x66\x74\x65\x2e\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xdd\xb8\x7c\x69\x3d\x63\x95\xe3\x88\x15\xfd\xad\x93\x5e\x6b\x97\xfb\x74\xba\x1f\x83\x33\xe5\x8a\x8d\x8f\xb0\xbf\xf9\xd3\xa1\x2c\x65\x53\xa7\xef\xd3\x0f\xdc\x03\x60\x0a\x40\xef\xa8\xef\x3f\xb3\xd9\x8d\x31\x39\x12\x8a\xd8\x0e\x24\x8f\xe5\x58\x26\x86\x4c\x76\x6c\x59\x9a\xab\xea\x1c\x3d\xfb\x62\x62\xad\xaf\xd6\x00\x33\x76\x2d\xbb\xeb\xe8\xec\xb4\x76\x4f\xb0\xbe\xcf\xf0\x46\x94\x40\x02\x99\xd4\xb2\x71\x71\xd6\xf5\x1f\xc3\x4f\x1e\x1e\xb4\x0d\x82\x49\xc4\xa2\xdc\xae\x6f\x4e\x3a\xf9\x0e\xdd\xf4\xd2\x53\xe3\xe7\x7d\x58\x79\xf4\xce\x1f\x6c\xac\x81\x8c\x8c\xe1\x03\x5b\x22\x56\x92\x19\x4f\x74\xc0\x36\x41\xac\x1b\xfa\x9e\xf7\x2a\x0f\xd6\x4b\xcc\x9a\xca\x67\x87\xb7\x95\xdf\xb7\xd4\x7d\x8c\xcc\xa9\x25\xde\xdd\x8c\x1b\xd7\x32\xf2\x84\x25\x46\x7b\x10\x55\xf9\x80\xfd\x5d\xad\xab\xf9\x4c\x1f\xc0\xa5\xd1\x3f\x01\x86\x4d\xfa\x57\xab\x7a\x6d\xec\xf1\xdb\xf4\xad\xf2\x33\xcd\xa0\xed\xfe\x1b\x27\x55\x56\xba\x8c\x47\x70\x16\xd5\x75\x17\x8e\x80\xaa\x49\x5e\x93\x83\x1d\x6f\x1f\x2c\xf7\xa7\x64\xe6\x2e\x88\x8e\xff\x70\x5a\x41\x52\xae\x93\x02\x03\x01\x00\x01\xa3\x50\x30\x4e\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\x4e\x76\x4a\xce\x7b\x45\x14\x39\xeb\x9c\x28\x56\xb5\x7b\x8a\x18\x6f\x22\x17\x82\x30\x1f\x06\x03\x55\x1d\x23\x04\x18\x30\x16\x80\x14\x4e\x76\x4a\xce\x7b\x45\x14\x39\xeb\x9c\x28\x56\xb5\x7b\x8a\x18\x6f\x22\x17\x82\x30\x0c\x06\x03\x55\x1d\x13\x04\x05\x30\x03\x01\x01\xff\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x03\x82\x01\x01\x00\x48\x22\x65\xed\x2e\xc5\xed\xbb\xe9\x40\x6c\x80\xc4\x63\x19\xd1\x00\xb4\x30\x34\x17\x7c\x7c\xbd\x1b\xc5\xa9\x43\x0c\x92\x6e\xd6\x2d\x11\x6c\x0d\xa6\xda\x30\xe9\xf7\x46\x7b\x01\xe4\x53\x23\xae\x88\xd1\xf2\xed\xca\x84\x06\x19\x97\xb9\x06\xfb\xda\xec\x72\x2d\x15\x20\xd2\x8f\x66\xad\xb5\xdd\x4b\x4f\xdf\x7e\xaf\xa3\x6c\x7f\x53\x32\x8f\xe2\x19\x5c\x44\x98\x86\x31\xee\xb4\x03\xe7\x27\xa1\x83\xab\xc3\xce\xb4\x9a\x01\xbe\x8c\x64\x2e\x2b\xe3\x4e\x55\xdf\x95\xeb\x16\x87\xbd\xfa\x11\xa2\x3e\x38\x92\x97\x36\xe9\x65\x60\xf3\xac\x68\x44\xb3\x51\x54\x3a\x42\xa8\x98\x9b\xee\x1b\x9e\x79\x6a\xaf\xc0\xbe\x41\xc4\xb1\x96\x42\xd9\x94\xef\x49\x5b\xbe\x2d\x04\xb9\xfb\x92\xbb\xdc\x0e\x29\xfd\xee\xa9\x68\x09\xf9\x9f\x69\x8b\x3d\xe1\x4b\xee\x24\xf9\xfe\x02\x3a\x0a\xb8\xcd\x6c\x07\x43\xa9\x4a\xe7\x03\x34\x2e\x72\xa7\x81\xaa\x40\xa9\x98\x5d\x97\xee\x2a\x99\xc6\x8f\xe8\x6f\x98\xa2\x85\xc9\x0d\x04\x19\x43\x6a\xd3\xc7\x15\x4c\x4b\xbc\xa5\xb8\x9f\x38\xf3\x43\x83\x0c\xef\x97\x6e\xa6\x20\xde\xc5\xd3\x1e\x3e\x5d\xcd\x58\x3d\x5c\x55\x7a\x90\x94";
//static const qbyte triptohell_certdata[933] = "\x30\x82\x03\xa1\x30\x82\x02\x89\xa0\x03\x02\x01\x02\x02\x09\x00\xea\xb7\x13\xcf\x55\xe5\xe8\x8c\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x30\x67\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x11\x30\x0f\x06\x03\x55\x04\x07\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x18\x30\x16\x06\x03\x55\x04\x0a\x0c\x0f\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x31\x18\x30\x16\x06\x03\x55\x04\x03\x0c\x0f\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x1e\x17\x0d\x31\x34\x31\x32\x32\x35\x30\x30\x35\x38\x33\x37\x5a\x17\x0d\x31\x37\x30\x33\x30\x34\x30\x30\x35\x38\x33\x37\x5a\x30\x67\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x11\x30\x0f\x06\x03\x55\x04\x07\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x18\x30\x16\x06\x03\x55\x04\x0a\x0c\x0f\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x31\x18\x30\x16\x06\x03\x55\x04\x03\x0c\x0f\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xd8\x77\x62\xf6\x74\xa7\x75\xde\xda\x09\xae\x9e\x76\x7a\xc6\x2a\xcf\x9a\xbe\xc6\xb9\x6d\xe2\xca\x0f\x2d\x95\xb8\x89\x93\xf7\x50\x64\x92\x7d\x95\x34\xe4\x6e\xef\x52\x56\xef\x13\x9a\x3a\xae\x84\x5b\x57\x82\x04\x86\x74\xbd\x4e\x38\x32\x56\x00\xd6\x34\x9c\x23\xd6\x81\x8e\x29\x77\x45\x61\x20\xdf\x28\xf8\xe5\x61\x83\xec\xe6\xa0\x1a\x75\xa8\x3b\x53\x6f\xc4\x09\x61\x66\x3a\xf0\x81\xbf\x2c\xf5\x8e\xf1\xe2\x35\xe4\x24\x7f\x16\xcc\xce\x60\xa2\x42\x6e\xc2\x3a\x29\x75\x6c\x79\xb0\x99\x9c\xe2\xfe\x27\x32\xb6\xf7\x0d\x71\xfd\x62\x9d\x54\x7c\x40\xb2\xf5\xa0\xa4\x25\x31\x8d\x65\xfd\x3f\x3b\x9b\x7e\x84\x74\x17\x3c\x1f\xec\x50\xcf\x75\xb8\x5c\xca\xfc\x0f\xe8\x47\xd8\x64\xec\x5f\x6c\x45\x9a\x55\x49\x97\x3f\xcb\x49\x34\x71\x0a\x12\x13\xbc\x3d\x53\x81\x17\x9a\x92\x44\x91\x07\xc2\xef\x6d\x64\x86\x5d\xfd\x67\xd5\x99\x38\x95\x46\x74\x6d\xb6\xbf\x29\xc9\x5b\xac\xb1\x46\xd6\x9e\x57\x5c\x7b\x24\x91\xf4\x7c\xe4\x01\x31\x8c\xec\x79\x94\xb7\x3f\xd2\x93\x6d\xe2\x69\xbe\x61\x44\x2e\x8f\x1a\xdc\xa8\x97\xf5\x81\x8e\x0c\xe1\x00\xf2\x71\x51\xf3\x02\x03\x01\x00\x01\xa3\x50\x30\x4e\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\x18\xb2\x6b\x63\xcc\x17\x54\xf6\xf0\xb6\x9e\x62\xa4\x35\xcf\x47\x74\x13\x29\xbf\x30\x1f\x06\x03\x55\x1d\x23\x04\x18\x30\x16\x80\x14\x18\xb2\x6b\x63\xcc\x17\x54\xf6\xf0\xb6\x9e\x62\xa4\x35\xcf\x47\x74\x13\x29\xbf\x30\x0c\x06\x03\x55\x1d\x13\x04\x05\x30\x03\x01\x01\xff\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x03\x82\x01\x01\x00\x7f\x24\x18\x8a\x79\xee\xf9\xeb\xed\x29\x1e\x21\x15\x8a\x53\xc9\xb7\xec\x30\xc4\x85\x9f\x45\x85\x26\x36\xb7\x07\xf3\xf1\xff\x3b\x89\x05\x0a\xd4\x30\x68\x31\x68\x33\xdd\xf6\x58\xa3\x85\x9f\x49\x50\x76\x9a\xc5\x79\x13\xe1\x4d\x67\x0c\xf3\x92\xf0\x1d\x02\x1f\xc4\x5c\xd4\xa1\x0c\x57\xdf\x46\x84\x43\x9f\xb0\xe2\x91\x62\xa8\xe0\x86\x0d\x47\xe1\xd9\x60\x01\xc4\xe0\xda\x6f\x06\x0a\xad\x38\xf3\x66\x68\xc5\xe2\x66\x3e\x47\x83\x65\x64\xcd\xff\xf3\xbb\xa7\xfa\x23\xf1\x82\x5e\x06\x6a\x91\x37\x51\xcd\xb9\x95\x20\x89\xff\xa1\x54\xb2\x76\xcf\x8e\xe1\xcd\x13\x93\x13\xd1\xda\x0d\x0d\xbc\x0f\xd5\x11\x26\xd6\xaf\x60\x0f\x4d\x8a\x4f\x28\xee\x6c\xf1\x99\xdc\xed\x16\xdc\x87\x26\xfd\x23\x8a\xb8\xb0\x20\x0e\xe2\x32\xf5\x8e\xb0\x65\x98\x13\xb8\x4b\x39\x7c\x8c\x98\xa2\x29\x75\x48\x3a\x89\xf9\x61\x77\x6c\x2d\x84\x41\x40\x17\xa6\x50\xc5\x09\x63\x10\xe7\x09\xd4\x5c\xdd\x0e\x71\x16\xaf\xb1\x32\xe4\xc0\xe6\xea\xfd\x26\x55\x07\x40\x95\x84\x48\x62\x04\x10\x92\xb2\xd9\x27\xfb\x8a\xf3\x7c\xe6\xfe\xd4\xfc\xa6\x33\x79\x01\x5c\xc3\x1f\x80\xa8\xf3";
static struct
{
wchar_t *hostname;
@ -397,8 +397,8 @@ static struct
//FIXME: include expiry information
//FIXME: add alternative when one is about to expire
} knowncerts[] = {
{L"triptohell.info", sizeof(triptohell_certdata), triptohell_certdata},
{L"fte.triptohell.info", sizeof(fte_triptohell_certdata), fte_triptohell_certdata},
// {L"triptohell.info", sizeof(triptohell_certdata), triptohell_certdata},
// {L"fte.triptohell.info", sizeof(fte_triptohell_certdata), fte_triptohell_certdata},
{L"updates.triptohell.info", sizeof(updates_triptohell_certdata), updates_triptohell_certdata},
{NULL}
};

View file

@ -1664,6 +1664,7 @@ void Plug_List_f(void)
char rootpath[MAX_OSPATH];
unsigned int u;
plugin_t *plug;
Con_Printf("Loaded plugins:\n");
for (plug = plugs; plug; plug = plug->next)
Con_Printf("^[^2%s\\type\\plug_close %s\\^]: loaded\n", plug->filename, plug->name);
@ -1674,6 +1675,7 @@ void Plug_List_f(void)
while ((mssuck=strchr(binarypath, '\\')))
*mssuck = '/';
#endif
Con_Printf("Scanning for plugins at %s:\n", binarypath);
Sys_EnumerateFiles(binarypath, PLUGINPREFIX"*" ARCH_DL_POSTFIX, Plug_List_Print, binarypath, NULL);
}
if (FS_NativePath("", FS_ROOT, rootpath, sizeof(rootpath)))
@ -1684,8 +1686,11 @@ void Plug_List_f(void)
*mssuck = '/';
#endif
if (strcmp(binarypath, rootpath))
{
Con_Printf("Scanning for plugins at %s:\n", rootpath);
Sys_EnumerateFiles(rootpath, PLUGINPREFIX"*" ARCH_DL_POSTFIX, Plug_List_Print, rootpath, NULL);
}
}
for (u = 0; staticplugins[u].name; u++)
Plug_List_Print(staticplugins[u].name, 0, 0, "", NULL);

View file

@ -2452,7 +2452,7 @@ void BSPX_LoadEnvmaps(model_t *mod, bspx_header_t *bspx, void *mod_base)
out[i].cubesize = LittleLong(in[i].cubesize);
Q_snprintfz(imagename, sizeof(imagename), "textures/env/%s_%i_%i_%i", base, (int)mod->envmaps[i].origin[0], (int)mod->envmaps[i].origin[1], (int)mod->envmaps[i].origin[2]);
out[i].image = Image_GetTexture(imagename, NULL, IF_CUBEMAP|IF_NOREPLACE, NULL, NULL, out[i].cubesize, out[i].cubesize, PTI_INVALID);
out[i].image = Image_GetTexture(imagename, NULL, IF_TEXTYPE_CUBE|IF_NOREPLACE, NULL, NULL, out[i].cubesize, out[i].cubesize, PTI_INVALID);
}

View file

@ -36,92 +36,21 @@ void D3D11_DestroyTexture (texid_t tex)
tex->ptr = NULL;
}
#if 0
static void Upload_Texture_32(ID3D11Texture2D *tex, unsigned int *data, int datawidth, int dataheight, unsigned int flags)
{
int x, y;
unsigned int *dest;
// unsigned char swapbuf[4];
// unsigned char swapbuf2[4];
D3D11_MAPPED_SUBRESOURCE lock;
D3D11_TEXTURE2D_DESC desc;
if (!tex)
return;
desc.Width = 0;
desc.Height = 0;
ID3D11Texture2D_GetDesc(tex, &desc);
#if 0
if (width == desc.Width && height == desc.Height)
{
ID3D11DeviceContext_UpdateSubresource(d3ddevctx, (ID3D11Resource*)tex, 0, NULL, data, width*4, width*height*4);
return;
}
Con_Printf("Wrong size!\n");
return;
#else
if (FAILED(ID3D11DeviceContext_Map(d3ddevctx, (ID3D11Resource*)tex, 0, D3D11_MAP_WRITE_DISCARD, 0, &lock)))
{
Con_Printf("Dynamic texture update failed\n");
return;
}
if (datawidth == desc.Width && dataheight == desc.Height)
{
for (y = 0; y < dataheight; y++)
{
dest = (unsigned int *)((char *)lock.pData + lock.RowPitch*y);
for (x = 0; x < datawidth; x++)
{
// *(unsigned int*)swapbuf2 = *(unsigned int*)swapbuf = data[x];
// swapbuf[0] = swapbuf2[2];
// swapbuf[2] = swapbuf2[0];
dest[x] = data[x];//*(unsigned int*)swapbuf;
}
data += datawidth;
}
}
else
{
int x, y;
int iny;
unsigned int *row, *inrow;
for (y = 0; y < desc.Height; y++)
{
row = (unsigned int*)((char *)lock.pData + lock.RowPitch*y);
iny = (y * dataheight) / desc.Height;
inrow = data + datawidth*iny;
for (x = 0; x < desc.Width; x++)
{
//*(unsigned int*)swapbuf2 = *(unsigned int*)swapbuf = inrow[(x * width)/desc.Width];
//swapbuf[0] = swapbuf2[2];
//swapbuf[2] = swapbuf2[0];
row[x] = inrow[(x * datawidth)/desc.Width];//*(unsigned int*)swapbuf;
}
}
}
ID3D11DeviceContext_Unmap(d3ddevctx, (ID3D11Resource*)tex, 0);
#endif
}
#endif
qboolean D3D11_LoadTextureMips(image_t *tex, const struct pendingtextureinfo *mips)
{
unsigned int blockbytes, blockwidth, blockheight;
HRESULT hr;
D3D11_TEXTURE2D_DESC tdesc = {0};
D3D11_SUBRESOURCE_DATA subresdesc[sizeof(mips->mip) / sizeof(mips->mip[0])];
int i;
D3D11_SUBRESOURCE_DATA *subresdesc;
int i, layer;
if (!sh_config.texfmt[mips->encoding])
{
Con_Printf("Texture encoding %i not supported by d3d11\n", mips->encoding);
return false;
}
if (mips->type != (tex->flags & IF_TEXTYPEMASK)>>IF_TEXTYPESHIFT)
return false;
tdesc.Width = mips->mip[0].width;
tdesc.Height = mips->mip[0].height;
@ -141,7 +70,7 @@ qboolean D3D11_LoadTextureMips(image_t *tex, const struct pendingtextureinfo *mi
tdesc.CPUAccessFlags = 0;
}
if (mips->type == PTI_CUBEMAP)
if (mips->type == PTI_CUBE)
{
tdesc.ArraySize *= 6;
tdesc.MiscFlags |= D3D11_RESOURCE_MISC_TEXTURECUBE;
@ -391,19 +320,26 @@ qboolean D3D11_LoadTextureMips(image_t *tex, const struct pendingtextureinfo *mi
if (!mips->mip[0].data)
{
subresdesc = alloca(sizeof(*subresdesc));
subresdesc[0].pSysMem = NULL;
subresdesc[0].SysMemPitch = 0;
subresdesc[0].SysMemSlicePitch = 0;
//one mip, but no data. happens with rendertargets
tdesc.MipLevels = 1;
}
else
{
subresdesc = alloca(tdesc.ArraySize*mips->mipcount);
for (layer = 0; layer < tdesc.ArraySize; layer++)
{
for (i = 0; i < mips->mipcount; i++)
{
subresdesc[i].pSysMem = mips->mip[i].data;
subresdesc[i].SysMemPitch = ((mips->mip[i].width+blockwidth-1)/blockwidth) * blockbytes;
subresdesc[i].SysMemSlicePitch = mips->mip[i].datasize;
subresdesc[i+layer*mips->mipcount].SysMemPitch = ((mips->mip[i].width+blockwidth-1)/blockwidth) * blockbytes;
subresdesc[i+layer*mips->mipcount].SysMemSlicePitch = subresdesc[i].SysMemPitch * ((mips->mip[i].width+blockheight-1)/blockheight);
subresdesc[i+layer*mips->mipcount].pSysMem = mips->mip[i].data + subresdesc[i+layer*mips->mipcount].SysMemSlicePitch*layer;
}
tdesc.MipLevels = i/tdesc.ArraySize;
}
tdesc.MipLevels = mips->mipcount;
}
D3D11_DestroyTexture(tex);
@ -437,6 +373,7 @@ void D3D11_UploadLightmap(lightmapinfo_t *lm)
default:
case PTI_A2BGR10:
case PTI_E5BGR9:
case PTI_B10G11R11F:
case PTI_RGBA16F:
case PTI_RGBA32F:
mips.encoding = lm->fmt;

View file

@ -106,12 +106,16 @@ qboolean D3D9_LoadTextureMips(image_t *tex, const struct pendingtextureinfo *mip
if (fmt == D3DFMT_UNKNOWN)
return false;
if (mips->type != ((tex->flags&IF_TEXTYPEMASK)>>IF_TEXTYPESHIFT))
return false;
Image_BlockSizeForEncoding(mips->encoding, &blockbytes, &blockwidth, &blockheight);
if (!pD3DDev9)
return false; //can happen on errors
if (mips->type == PTI_CUBEMAP)
if (mips->type == PTI_CUBE)
{
unsigned int face;
IDirect3DCubeTexture9 *dt;
if (FAILED(IDirect3DDevice9_CreateCubeTexture(pD3DDev9, mips->mip[0].width, mips->mipcount/6, 0, fmt, D3DPOOL_MANAGED, &dt, NULL)))
return false;
@ -119,22 +123,24 @@ qboolean D3D9_LoadTextureMips(image_t *tex, const struct pendingtextureinfo *mip
for (i = 0; i < mips->mipcount; i++)
{
IDirect3DCubeTexture9_GetLevelDesc(dt, i/6, &desc);
IDirect3DCubeTexture9_GetLevelDesc(dt, i, &desc);
if (mips->mip[i].height != desc.Height || mips->mip[i].width != desc.Width)
{
IDirect3DCubeTexture9_Release(dt);
return false;
}
IDirect3DCubeTexture9_LockRect(dt, i%6, i/6, &lock, NULL, D3DLOCK_NOSYSLOCK|D3DLOCK_DISCARD);
//can't do it in one go. pitch might contain padding or be upside down.
if (!mips->mip[i].data)
;
else if (swap)
continue;
for (face = 0, in = mips->mip[i].data; face < mips->mip[i].depth; face++)
{
IDirect3DCubeTexture9_LockRect(dt, face, i, &lock, NULL, D3DLOCK_NOSYSLOCK|D3DLOCK_DISCARD);
//can't do it in one go. pitch might contain padding or be upside down.
if (swap)
{ //only works for blockbytes=4
size_t rowbytes = ((mips->mip[i].width+blockwidth-1)/blockwidth)*blockbytes;
for (y = 0, out = lock.pBits, in = mips->mip[i].data; y < mips->mip[i].height; y+=blockheight, out += lock.Pitch, in += rowbytes)
for (y = 0, out = lock.pBits; y < mips->mip[i].height; y+=blockheight, out += lock.Pitch, in += rowbytes)
{
for (x = 0; x < rowbytes; x+=4)
{
@ -154,6 +160,7 @@ qboolean D3D9_LoadTextureMips(image_t *tex, const struct pendingtextureinfo *mip
IDirect3DCubeTexture9_UnlockRect(dt, i%6, i/6);
}
}
}
else if (mips->type == PTI_2D)
{
IDirect3DTexture9 *dt;

View file

@ -1265,7 +1265,7 @@ static void (D3D9_R_RenderView) (void)
if (!r_refdef.globalfog.density)
{
int fogtype = ((r_refdef.flags & RDF_UNDERWATER) && cl.fog[1].density)?1:0;
int fogtype = ((r_refdef.flags & RDF_UNDERWATER) && cl.fog[FOGTYPE_WATER].density)?FOGTYPE_WATER:FOGTYPE_AIR;
CL_BlendFog(&r_refdef.globalfog, &cl.oldfog[fogtype], realtime, &cl.fog[fogtype]);
r_refdef.globalfog.density /= 64; //FIXME
}

View file

@ -895,6 +895,8 @@ static qboolean initD3D11Device(HWND hWnd, rendererstate_t *info, PFN_D3D11_CREA
sh_config.texfmt[PTI_A2BGR10] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D) && !!(support & D3D11_FORMAT_SUPPORT_RENDER_TARGET);
if (SUCCEEDED(ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, &support)))
sh_config.texfmt[PTI_E5BGR9] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
if (SUCCEEDED(ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_R11G11B10_FLOAT, &support)))
sh_config.texfmt[PTI_B10G11R11F] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
if (SUCCEEDED(ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_R16G16B16A16_FLOAT, &support)))
sh_config.texfmt[PTI_RGBA16F] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D) && !!(support & D3D11_FORMAT_SUPPORT_RENDER_TARGET);
if (SUCCEEDED(ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_R32G32B32A32_FLOAT, &support)))

View file

@ -2939,7 +2939,7 @@ void BE_GenModelBatches(batch_t **batches, const dlight_t *dl, unsigned int bemo
}
}
if (cl_numstris)
if (cl_numstris && !(r_refdef.flags & RDF_DISABLEPARTICLES))
BE_GenPolyBatches(batches);
while(orig_numstris < cl_numstris)

View file

@ -5624,7 +5624,7 @@ void GLBE_RenderToTextureUpdate2d(qboolean destchanged)
shaderstate.tex_sourcedepth = R2D_RT_GetTexture(r_refdef.rt_depth.texname, &width, &height);
if (*r_refdef.nearenvmap.texname)
shaderstate.tex_reflectcube = Image_GetTexture(r_refdef.nearenvmap.texname, NULL, IF_CUBEMAP, NULL, NULL, 0, 0, TF_INVALID);
shaderstate.tex_reflectcube = Image_GetTexture(r_refdef.nearenvmap.texname, NULL, IF_TEXTYPE_CUBE, NULL, NULL, 0, 0, TF_INVALID);
else
shaderstate.tex_reflectcube = r_nulltex;
}
@ -5844,7 +5844,7 @@ int GLBE_FBO_Update(fbostate_t *state, unsigned int enables, texid_t *destcol, i
for (i = 0; i < mrt; i++)
{
if ((destcol[i]->flags & IF_TEXTYPE) == IF_CUBEMAP)
if ((destcol[i]->flags & IF_TEXTYPEMASK) == IF_TEXTYPE_CUBE)
{
//fixme: we should probably support whole-cubemap rendering for shadowmaps or something.
qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT+i, GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + layer, destcol[i]->num, 0);

View file

@ -276,20 +276,28 @@ void GL_SetupFormats(void)
glfmtc(PTI_ARGB4444, GL_RGBA4, GL_RGBA, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV, tc_srgba8);
glfmtc(PTI_ARGB1555, GL_RGB5_A1, GL_RGBA, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV, tc_rgba1);
}
if (gl_config_gles || ver > 4.1) //rgb565 was a gles thing, desktop gl just has a 555 internal format despite the 565 data...
if (gl_config_gles || ver >= 4.1) //rgb565 was a gles thing, desktop gl just has a 555 internal format despite the 565 data...
glfmtc(PTI_RGB565, GL_RGB565, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, tc_rgb);
else
glfmtc(PTI_RGB565, GL_RGB5, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, tc_rgb);
glfmt(PTI_RGB8, GL_RGB8, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE);
if (!gl_config_nofixedfunc)
{ //if we have fixed function, then we still have proper support. the driver can emulate with swizzles if it wants.
glfmtc(PTI_L8, GL_LUMINANCE8, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, tc_ru);
glfmtc(PTI_L8A8, GL_LUMINANCE8_ALPHA8,GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, tc_rgu);
glfmtc(PTI_L8, GL_LUMINANCE8, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0);
glfmtc(PTI_L8A8, GL_LUMINANCE8_ALPHA8,GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0);
if (ver >= 2.1)
{
glfmtc(PTI_L8, GL_SLUMINANCE8_EXT, GL_SLUMINANCE_EXT, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0);
glfmtc(PTI_L8A8,GL_SLUMINANCE8_ALPHA8_EXT,GL_SLUMINANCE_ALPHA_EXT, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0);
}
}
else if (ver >= 3.3)
{ //can emulate them with swizzles.
glfmtsw(PTI_L8, GL_R8, GL_RED, GL_RED, GL_UNSIGNED_BYTE, tc_ru, GL_RED, GL_RED, GL_RED, GL_ONE);
glfmtsw(PTI_L8A8, GL_RG8, GL_RG, GL_RG, GL_UNSIGNED_BYTE, tc_rgu, GL_RED, GL_RED, GL_RED, GL_GREEN);
if (GL_CheckExtension("GL_EXT_texture_sRGB_R8"))
glfmtsw(PTI_L8_SRGB,GL_SR8_EXT, GL_RED, GL_RED, GL_UNSIGNED_BYTE, 0, GL_RED, GL_RED, GL_RED, GL_ONE);
//can't do PTI_L8A8_SRGB with RG - either its all linear or the alpha is srgb, both are wrong.
}
}
@ -717,7 +725,7 @@ qboolean GL_LoadTextureMips(texid_t tex, const struct pendingtextureinfo *mips)
GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
};
int targ, targface;
int targ;
int i, j, ifmt;
int nummips = mips->mipcount;
uploadfmt_t encoding = mips->encoding;
@ -725,7 +733,7 @@ qboolean GL_LoadTextureMips(texid_t tex, const struct pendingtextureinfo *mips)
qboolean storage = true;
unsigned int bb, bw, bh;
int levels = 0, genlevels;
int layers = 1;
int ttype = (tex->flags & IF_TEXTYPEMASK)>>IF_TEXTYPESHIFT;
if (gl_config.gles)
{
@ -739,27 +747,30 @@ qboolean GL_LoadTextureMips(texid_t tex, const struct pendingtextureinfo *mips)
encoding = PTI_BGRA8;
}
switch((tex->flags & IF_TEXTYPE) >> IF_TEXTYPESHIFT)
if (ttype != mips->type)
return false;
switch(ttype)
{
default:
case 0:
return false;
case PTI_2D:
targ = GL_TEXTURE_2D;
layers = 1;
break;
case 1:
case PTI_3D:
targ = GL_TEXTURE_3D;
layers = 1;
break;
case 2:
case PTI_CUBE:
targ = GL_TEXTURE_CUBE_MAP_ARB;
layers = 1*6;
break;
case 3:
case PTI_CUBE_ARRAY:
targ = GL_TEXTURE_CUBE_MAP_ARRAY_ARB;
break;
case PTI_2D_ARRAY:
targ = GL_TEXTURE_2D_ARRAY;
layers = 1; //TODO
break;
}
genlevels = levels = mips->mipcount / layers;
genlevels = levels = mips->mipcount;
if (!(tex->flags & IF_NOMIPMAP) && sh_config.can_genmips && gl_config.formatinfo[encoding].type && genlevels == 1 && mips->mip[0].data && mips->encoding != PTI_P8)
{
while ((mips->mip[0].width>>genlevels) || (mips->mip[0].height>>genlevels))
@ -811,7 +822,7 @@ qboolean GL_LoadTextureMips(texid_t tex, const struct pendingtextureinfo *mips)
qglTexParameteri(targ, GL_TEXTURE_WRAP_R, GL_REPEAT);
}
if (targ == GL_TEXTURE_2D && nummips > 1)
if (ttype != PTI_3D && nummips > 1)
{ //npot mipmapped textures are awkward.
//opengl floors.
for (i = 1; i < nummips; i++)
@ -867,7 +878,7 @@ qboolean GL_LoadTextureMips(texid_t tex, const struct pendingtextureinfo *mips)
compress = !!gl_compress.ival;
else
compress = false;
if (compress & gl_config.formatinfo[encoding].cformat)
if (compress && gl_config.formatinfo[encoding].cformat)
ifmt = gl_config.formatinfo[encoding].cformat;
else
ifmt = gl_config.formatinfo[encoding].sizedformat;
@ -913,9 +924,47 @@ qboolean GL_LoadTextureMips(texid_t tex, const struct pendingtextureinfo *mips)
qglPixelStorei(GL_UNPACK_ALIGNMENT, bb);
}
if (targ == GL_TEXTURE_3D || targ == GL_TEXTURE_2D_ARRAY)
if (ttype == PTI_CUBE)
{
if (qglTexStorage2D && storage)
{
qglTexStorage2D(targ, genlevels, ifmt, mips->mip[0].width, mips->mip[0].height);
for (i = 0; i < nummips; i++)
{
size_t sz = mips->mip[i].datasize / mips->mip[i].depth;
if (!mips->mip[i].data) //already specified by gltexstorage, don't bother wiping it or anything.
continue;
for (j = 0; j < min(6, mips->mip[i].depth); j++)
{
if (gl_config.formatinfo[encoding].type)
qglTexSubImage2D (cubeface[j], i, 0, 0, mips->mip[i].width, mips->mip[i].height, gl_config.formatinfo[encoding].format, gl_config.formatinfo[encoding].type, mips->mip[i].data + sz*j);
else
qglCompressedTexSubImage2D (cubeface[j], i, 0, 0, mips->mip[i].width, mips->mip[i].height, ifmt, sz, mips->mip[i].data + sz*j);
}
}
}
else
{
for (i = 0; i < nummips; i++)
{
size_t sz = mips->mip[i].datasize / mips->mip[i].depth;
if (!mips->mip[i].data) //already specified by gltexstorage, don't bother wiping it or anything.
continue;
for (j = 0; j < min(6, mips->mip[i].depth); j++)
{
if (gl_config.formatinfo[encoding].type)
qglTexImage2D (cubeface[j], i, ifmt, mips->mip[i].width, mips->mip[i].height, 0, gl_config.formatinfo[encoding].format, gl_config.formatinfo[encoding].type, mips->mip[i].data + sz*j);
else
qglCompressedTexImage2D (cubeface[j], i, ifmt, mips->mip[i].width, mips->mip[i].height, 0, sz, mips->mip[i].data + sz*j);
}
}
}
if (genlevels > levels)
qglGenerateMipmap(targ);
}
else if (ttype == PTI_3D || ttype == PTI_2D_ARRAY || ttype == PTI_CUBE_ARRAY)
{
//FIXME: support array textures properly
if (qglTexStorage3D && storage)
{
qglTexStorage3D(targ, genlevels, ifmt, mips->mip[0].width, mips->mip[0].height, mips->mip[0].depth);
@ -945,58 +994,40 @@ qboolean GL_LoadTextureMips(texid_t tex, const struct pendingtextureinfo *mips)
if (genlevels > levels)
qglGenerateMipmap(targ);
}
else
else if (ttype == PTI_2D)
{
if (qglTexStorage2D && storage)
{ //FIXME: destroy the old texture
{
qglTexStorage2D(targ, genlevels, ifmt, mips->mip[0].width, mips->mip[0].height);
for (i = 0; i < nummips; i++)
{
if (tex->flags & IF_TEXTYPE)
{ //cubemap face
targface = cubeface[i%countof(cubeface)];
j = i/countof(cubeface);
}
else
{ //2d
targface = targ;
j = i;
}
if (!mips->mip[i].data) //already specified by gltexstorage, don't bother wiping it or anything.
continue;
if (gl_config.formatinfo[encoding].type)
qglTexSubImage2D (targface, j, 0, 0, mips->mip[i].width, mips->mip[i].height, gl_config.formatinfo[encoding].format, gl_config.formatinfo[encoding].type, mips->mip[i].data);
qglTexSubImage2D (targ, i, 0, 0, mips->mip[i].width, mips->mip[i].height, gl_config.formatinfo[encoding].format, gl_config.formatinfo[encoding].type, mips->mip[i].data);
else
qglCompressedTexSubImage2D (targface, j, 0, 0, mips->mip[i].width, mips->mip[i].height, ifmt, mips->mip[i].datasize, mips->mip[i].data);
qglCompressedTexSubImage2D (targ, i, 0, 0, mips->mip[i].width, mips->mip[i].height, ifmt, mips->mip[i].datasize, mips->mip[i].data);
}
}
else
{
for (i = 0; i < nummips; i++)
{
if (tex->flags & IF_TEXTYPE)
{ //cubemap face
targface = cubeface[i%countof(cubeface)];
j = i/countof(cubeface);
}
else
{ //2d
targface = targ;
j = i;
}
if (gl_config.formatinfo[encoding].type)
qglTexImage2D (targface, j, ifmt, mips->mip[i].width, mips->mip[i].height, 0, gl_config.formatinfo[encoding].format, gl_config.formatinfo[encoding].type, mips->mip[i].data);
qglTexImage2D (targ, i, ifmt, mips->mip[i].width, mips->mip[i].height, 0, gl_config.formatinfo[encoding].format, gl_config.formatinfo[encoding].type, mips->mip[i].data);
else
qglCompressedTexImage2D (targface, j, ifmt, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data);
qglCompressedTexImage2D (targ, i, ifmt, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data);
}
}
if (genlevels > levels)
qglGenerateMipmap(targ);
}
else
{
//erk!
}
#ifdef IMAGEFMT_KTX
if (compress && gl_compress.ival>1 && gl_config.formatinfo[encoding].type)
@ -1074,18 +1105,23 @@ qboolean GL_LoadTextureMips(texid_t tex, const struct pendingtextureinfo *mips)
{
for (i = 0; i < nummips; i++)
{
if (tex->flags & IF_TEXTYPE)
{ //cubemap face
targface = cubeface[i%countof(cubeface)];
j = i/countof(cubeface);
if (ttype == PTI_CUBE)
{ //gl's cubemaps are annoying
qglGetTexLevelParameteriv(cubeface[0], i, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, &csize);
if (!csize)
break; //some kind of error. the gpu didn't store it?
out.mip[i].datasize = csize;
out.mip[i].data = BZ_Malloc(csize*6);
out.mip[i].needfree = true;
out.mip[i].width = mips->mip[i].width;
out.mip[i].height = mips->mip[i].height;
out.mip[i].depth = 6;
for (j = 0; j < 6; j++)
qglGetCompressedTexImage(targ, j, out.mip[i].data + csize*j);
}
else
{ //2d
targface = targ;
j = i;
}
qglGetTexLevelParameteriv(targface, j, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, &csize);
{
qglGetTexLevelParameteriv(targ, i, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, &csize);
if (!csize)
break; //some kind of error. the gpu didn't store it?
out.mip[i].datasize = csize;
@ -1094,7 +1130,8 @@ qboolean GL_LoadTextureMips(texid_t tex, const struct pendingtextureinfo *mips)
out.mip[i].width = mips->mip[i].width;
out.mip[i].height = mips->mip[i].height;
out.mip[i].depth = mips->mip[i].depth;
qglGetCompressedTexImage(targ, j, out.mip[i].data);
qglGetCompressedTexImage(targ, i, out.mip[i].data);
}
}
if (i)
@ -1108,7 +1145,6 @@ qboolean GL_LoadTextureMips(texid_t tex, const struct pendingtextureinfo *mips)
}
}
#endif
}
return true;
}
@ -1138,17 +1174,25 @@ void GL_UpdateFiltering(image_t *imagelist, int filtermip[3], int filterpic[3],
{
if (img->status != TEX_LOADED)
continue;
switch((img->flags & IF_TEXTYPE) >> IF_TEXTYPESHIFT)
switch((img->flags & IF_TEXTYPEMASK) >> IF_TEXTYPESHIFT)
{
case 0:
case PTI_2D:
targ = GL_TEXTURE_2D;
break;
case 1:
case PTI_3D:
targ = GL_TEXTURE_3D;
break;
default:
case PTI_CUBE:
targ = GL_TEXTURE_CUBE_MAP_ARB;
break;
case PTI_CUBE_ARRAY:
targ = GL_TEXTURE_CUBE_MAP_ARRAY_ARB;
break;
case PTI_2D_ARRAY:
targ = GL_TEXTURE_2D_ARRAY;
break;
default:
continue;
}
GL_MTBind(0, targ, img);

View file

@ -1356,7 +1356,7 @@ qboolean R_LoadRTLights(void)
Q_strncpyz(dl->cubemapname, cubename, sizeof(dl->cubemapname));
if (*dl->cubemapname)
dl->cubetexture = R_LoadReplacementTexture(dl->cubemapname, "", IF_CUBEMAP, NULL, 0, 0, TF_INVALID);
dl->cubetexture = R_LoadReplacementTexture(dl->cubemapname, "", IF_TEXTYPE_CUBE, NULL, 0, 0, TF_INVALID);
else
dl->cubetexture = r_nulltex;
@ -1634,7 +1634,7 @@ static int R_EditLight(dlight_t *dl, const char *cmd, int argc, const char *x, c
{
Q_strncpyz(dl->cubemapname, x, sizeof(dl->cubemapname));
if (*dl->cubemapname)
dl->cubetexture = R_LoadReplacementTexture(dl->cubemapname, "", IF_CUBEMAP, NULL, 0, 0, TF_INVALID);
dl->cubetexture = R_LoadReplacementTexture(dl->cubemapname, "", IF_TEXTYPE_CUBE, NULL, 0, 0, TF_INVALID);
else
dl->cubetexture = r_nulltex;
}
@ -2077,7 +2077,7 @@ static void R_EditLights_PasteInfo_f(void)
//just in case its from a different map...
if (*dl->cubemapname)
dl->cubetexture = R_LoadReplacementTexture(dl->cubemapname, "", IF_CUBEMAP, NULL, 0, 0, TF_INVALID);
dl->cubetexture = R_LoadReplacementTexture(dl->cubemapname, "", IF_TEXTYPE_CUBE, NULL, 0, 0, TF_INVALID);
else
dl->cubetexture = r_nulltex;
}

View file

@ -1671,7 +1671,7 @@ qboolean R_RenderScene_Cubemap(void)
{
if (!TEXVALID(scenepp_postproc_cube))
{
scenepp_postproc_cube = Image_CreateTexture("***fish***", NULL, IF_CUBEMAP|IF_RENDERTARGET|IF_CLAMP|IF_LINEAR);
scenepp_postproc_cube = Image_CreateTexture("***fish***", NULL, IF_TEXTYPE_CUBE|IF_RENDERTARGET|IF_CLAMP|IF_LINEAR);
qglGenTextures(1, &scenepp_postproc_cube->num);
}
else
@ -1910,7 +1910,7 @@ void GLR_RenderView (void)
if (!r_refdef.globalfog.density)
{
int fogtype = ((r_refdef.flags & RDF_UNDERWATER) && cl.fog[1].density)?1:0;
int fogtype = ((r_refdef.flags & RDF_UNDERWATER) && cl.fog[FOGTYPE_WATER].density)?FOGTYPE_WATER:FOGTYPE_AIR;
CL_BlendFog(&r_refdef.globalfog, &cl.oldfog[fogtype], realtime, &cl.fog[fogtype]);
r_refdef.globalfog.density /= 64; //FIXME
}

View file

@ -81,7 +81,7 @@ texid_t GenerateNormalisationCubeMap(void)
int i, j;
normalisationCubeMap = Image_CreateTexture("normalisationcubemap", NULL, IF_CUBEMAP);
normalisationCubeMap = Image_CreateTexture("normalisationcubemap", NULL, IF_TEXTYPE_CUBE);
qglGenTextures(1, &normalisationCubeMap->num);
GL_MTBind(0, GL_TEXTURE_CUBE_MAP_ARB, normalisationCubeMap);

View file

@ -726,20 +726,30 @@ static int Shader_SetImageFlags(parsestate_t *parsestate, shaderpass_t *pass, ch
*name += 8;
flags |= IF_PREMULTIPLYALPHA;
}
else if (!Q_strnicmp(*name, "$3d:", 4))
else if (!Q_strnicmp(*name, "$2d:", 4))
{
*name+=4;
flags = (flags&~IF_TEXTYPE) | IF_3DMAP;
}
else if (!Q_strnicmp(*name, "$cube:", 6))
{
*name+=6;
flags = (flags&~IF_TEXTYPE) | IF_CUBEMAP;
flags = (flags&~IF_TEXTYPEMASK) | IF_TEXTYPE_2D;
}
else if (!Q_strnicmp(*name, "$2darray:", 9))
{
*name+=9;
flags = (flags&~IF_TEXTYPE) | IF_2DARRAY;
flags = (flags&~IF_TEXTYPEMASK) | IF_TEXTYPE_2D_ARRAY;
}
else if (!Q_strnicmp(*name, "$3d:", 4))
{
*name+=4;
flags = (flags&~IF_TEXTYPEMASK) | IF_TEXTYPE_3D;
}
else if (!Q_strnicmp(*name, "$cube:", 6))
{
*name+=6;
flags = (flags&~IF_TEXTYPEMASK) | IF_TEXTYPE_CUBE;
}
else if (!Q_strnicmp(*name, "$cubearray:", 11))
{
*name+=11;
flags = (flags&~IF_TEXTYPEMASK) | IF_TEXTYPE_CUBE_ARRAY;
}
else if (!Q_strnicmp(*name, "$srgb:", 6))
{
@ -1390,7 +1400,7 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
int cvartypes[64];
size_t cvarcount = 0, i;
extern cvar_t gl_specular, gl_specular_power;
qboolean cantess; //not forced.
qboolean cantess = false; //not forced.
char prescript[8192];
size_t offset = 0;
#endif
@ -2322,7 +2332,7 @@ static void Shader_HLSL11ProgramName (parsestate_t *ps, char **ptr)
static void Shader_ReflectCube(parsestate_t *ps, char **ptr)
{
char *token = Shader_ParseSensString(ptr);
unsigned int flags = Shader_SetImageFlags (ps, ps->pass, &token, IF_CUBEMAP);
unsigned int flags = Shader_SetImageFlags (ps, ps->pass, &token, IF_TEXTYPE_CUBE);
ps->s->defaulttextures->reflectcube = Shader_FindImage(ps, token, flags);
}
static void Shader_ReflectMask(parsestate_t *ps, char **ptr)
@ -2930,17 +2940,20 @@ static void Shaderpass_Map (parsestate_t *ps, char **ptr)
flags = Shader_SetImageFlags (ps, pass, &token, 0);
if (!Shaderpass_MapGen(ps, pass, token))
{
switch((flags & IF_TEXTYPE) >> IF_TEXTYPESHIFT)
switch((flags & IF_TEXTYPEMASK) >> IF_TEXTYPESHIFT)
{
case 0:
case PTI_2D:
pass->texgen = T_GEN_SINGLEMAP;
break;
case 1:
case PTI_3D:
pass->texgen = T_GEN_3DMAP;
break;
default:
case PTI_CUBE:
pass->texgen = T_GEN_CUBEMAP;
break;
default:
pass->texgen = T_GEN_SINGLEMAP;
break;
}
if (pass->tcgen == TC_GEN_UNSPECIFIED)
@ -3033,22 +3046,23 @@ static void Shaderpass_ClampMap (parsestate_t *ps, char **ptr)
pass->tcgen = TC_GEN_BASE;
pass->anim_frames[0] = Shader_FindImage (ps, token, flags);
switch((flags & IF_TEXTYPE) >> IF_TEXTYPESHIFT)
switch((flags & IF_TEXTYPEMASK) >> IF_TEXTYPESHIFT)
{
case 0:
default:
case PTI_2D:
pass->texgen = T_GEN_SINGLEMAP;
break;
case 1:
case PTI_3D:
pass->texgen = T_GEN_3DMAP;
break;
default:
case PTI_CUBE:
pass->texgen = T_GEN_CUBEMAP;
break;
}
if (!TEXVALID(pass->anim_frames[0]))
{
if (flags & (IF_3DMAP | IF_CUBEMAP))
if ((flags & IF_TEXTYPEMASK)!=IF_TEXTYPE_2D)
pass->anim_frames[0] = r_nulltex;
else
pass->anim_frames[0] = missing_texture;
@ -3767,7 +3781,7 @@ static void Shaderpass_CubeMap(parsestate_t *ps, char **ptr)
if (pass->tcgen == TC_GEN_UNSPECIFIED)
pass->tcgen = TC_GEN_SKYBOX;
pass->texgen = T_GEN_CUBEMAP;
pass->anim_frames[0] = Shader_FindImage(ps, token, IF_CUBEMAP);
pass->anim_frames[0] = Shader_FindImage(ps, token, IF_TEXTYPE_CUBE);
if (!TEXVALID(pass->anim_frames[0]))
{
@ -7380,7 +7394,7 @@ static void Shader_DecomposeSubPassMap(char *o, shader_t *s, char *name, texid_t
(flags&IF_NOPICMIP)?" nopicmip":"",
(flags&IF_NOALPHA)?" noalpha":"",
(flags&IF_NOGAMMA)?" noalpha":"",
(flags&IF_TEXTYPE)?" non-2d":"",
(flags&IF_TEXTYPEMASK)?" non-2d":"",
(flags&IF_MIPCAP)?"":" nomipcap",
(flags&IF_PREMULTIPLYALPHA)?" premultiply":"",

View file

@ -76,7 +76,7 @@ void R_SetSky(const char *sky)
{
texnums_t tex;
memset(&tex, 0, sizeof(tex));
tex.reflectcube = R_LoadHiResTexture(sky, "env:gfx/env", IF_LOADNOW|IF_CUBEMAP|IF_CLAMP);
tex.reflectcube = R_LoadHiResTexture(sky, "env:gfx/env", IF_LOADNOW|IF_TEXTYPE_CUBE|IF_CLAMP);
if (tex.reflectcube->width)
{
forcedsky = R_RegisterShader(va("skybox_%s", sky), 0, "{\nsort sky\nprogram defaultskybox\n{\ndepthwrite\nmap \"$cube:$reflectcube\"\ntcgen skybox\n}\nsurfaceparm nodlight\nsurfaceparm sky\n}");
@ -154,6 +154,12 @@ qboolean R_DrawSkyroom(shader_t *skyshader)
r_refdef.forcedvis = NULL;
r_refdef.areabitsknown = false; //recalculate areas clientside.
if (cl.fog[FOGTYPE_SKYROOM].density)
{
CL_BlendFog(&r_refdef.globalfog, &cl.oldfog[FOGTYPE_SKYROOM], realtime, &cl.fog[FOGTYPE_SKYROOM]);
r_refdef.globalfog.density/=64;
}
/*work out where the camera should be (use the same angles)*/
VectorCopy(r_refdef.skyroom_pos, r_refdef.vieworg);
VectorCopy(r_refdef.skyroom_pos, r_refdef.pvsorigin);

View file

@ -143,6 +143,17 @@ extern qlpSelTexFUNC qglClientActiveTextureARB;
#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C
#endif
#ifndef GL_ARB_texture_cube_map_array
#define GL_ARB_texture_cube_map_array 1
#define GL_TEXTURE_CUBE_MAP_ARRAY_ARB 0x9009
#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB 0x900A
#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB 0x900B
#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C
#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D
#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E
#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F
#endif /* GL_ARB_texture_cube_map_array */
#ifndef GL_TEXTURE_2D_ARRAY //gl 3.0 or GL_EXT_texture_array
#define GL_TEXTURE_2D_ARRAY 0x8C1A
#endif
@ -682,6 +693,15 @@ typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
#endif /* GL_EXT_texture_sRGB */
#ifndef GL_EXT_texture_sRGB_R8
#define GL_EXT_texture_sRGB_R8
#define GL_SR8_EXT 0x8FBD
#endif
#ifndef GL_EXT_texture_sRGB_RG8
#define GL_EXT_texture_sRGB_RG8
#define GL_SRG8_EXT 0x8FBE
#endif
#ifndef GL_RGB9_E5
#define GL_RGB9_E5 0x8C3D /*opengl 3.0*/
#endif

View file

@ -1217,6 +1217,19 @@ reeval:
OPC->_float = (OPA->_float / OPB->_int);
break;
case OP_MOD_I:
OPC->_int = (OPA->_int % OPB->_int);
break;
case OP_MOD_F:
OPC->_float = OPA->_float - OPB->_float*(int)(OPA->_float/OPB->_float);
break;
case OP_MOD_V:
OPC->_vector[0] = OPA->_vector[0] - OPB->_vector[0]*(int)(OPA->_vector[0]/OPB->_vector[0]);
OPC->_vector[1] = OPA->_vector[1] - OPB->_vector[1]*(int)(OPA->_vector[1]/OPB->_vector[1]);
OPC->_vector[2] = OPA->_vector[2] - OPB->_vector[2]*(int)(OPA->_vector[2]/OPB->_vector[2]);
break;
case OP_AND_I:
OPC->_int = (OPA->_int && OPB->_int);
break;

View file

@ -37,3 +37,4 @@ struct v2f
return t_t0.Sample(s_t0, inp.tc) * inp.vcol;
}
#endif

View file

@ -27,3 +27,4 @@ struct v2f
return inp.vcol;
}
#endif

View file

@ -43,3 +43,4 @@ struct v2f
return texcolor * inp.vcol;
}
#endif

View file

@ -246,11 +246,11 @@ int generatevulkanblobs(struct blobheader *blob, size_t maxblobsize, const char
//batch
else if (!strcasecmp(arg, "lightmap"))
blob->defaulttextures |= 1u<<12;
else if (!strcasecmp(arg, "deluxmap"))
else if (!strcasecmp(arg, "deluxemap") || !strcasecmp(arg, "deluxmap"))
blob->defaulttextures |= 1u<<13;
else if (!strcasecmp(arg, "lightmaps"))
blob->defaulttextures |= 1u<<12 | 1u<<14 | 1u<<15 | 1u<<16;
else if (!strcasecmp(arg, "deluxmaps"))
else if (!strcasecmp(arg, "deluxemaps") || !strcasecmp(arg, "deluxmaps"))
blob->defaulttextures |= 1u<<13 | 1u<<17 | 1u<<18 | 1u<<19;
//shader pass
@ -310,7 +310,7 @@ int generatevulkanblobs(struct blobheader *blob, size_t maxblobsize, const char
//batch
"uniform sampler2D s_lightmap;\n#define s_lightmap0 s_lightmap\n",
"uniform sampler2D s_deluxmap;\n#define s_deluxmap0 s_deluxmap\n",
"uniform sampler2D s_deluxemap;\n#define s_deluxemap0 s_deluxemap\n",
"uniform sampler2D s_lightmap1;\n",
"uniform sampler2D s_lightmap2;\n",
"uniform sampler2D s_lightmap3;\n",
@ -320,6 +320,7 @@ int generatevulkanblobs(struct blobheader *blob, size_t maxblobsize, const char
};
int binding = 2;
inheader = 0;
fprintf(temp, "#define s_deluxmap s_deluxemap\n");
fprintf(temp, "#define OFFSETMAPPING (cvar_r_glsl_offsetmapping>0)\n");
fprintf(temp, "#define SPECULAR (cvar_gl_specular>0)\n");
fprintf(temp, "#ifdef FRAGMENT_SHADER\n");

View file

@ -1675,8 +1675,9 @@ static texid_t SelectPassTexture(const shaderpass_t *pass)
{
switch(pass->texgen)
{
#ifndef _DEBUG
default:
#endif
case T_GEN_DIFFUSE:
return shaderstate.curtexnums->base;
case T_GEN_NORMALMAP:
@ -1695,6 +1696,22 @@ static texid_t SelectPassTexture(const shaderpass_t *pass)
return shaderstate.curtexnums->loweroverlay;
case T_GEN_FULLBRIGHT:
return shaderstate.curtexnums->fullbright;
case T_GEN_PALETTED:
return shaderstate.curtexnums->paletted;
case T_GEN_REFLECTCUBE:
if (TEXLOADED(shaderstate.curtexnums->reflectcube))
return shaderstate.curtexnums->reflectcube;
else if (shaderstate.curbatch->envmap)
return shaderstate.curbatch->envmap;
else
return r_nulltex; //FIXME
case T_GEN_REFLECTMASK:
return shaderstate.curtexnums->reflectmask;
case T_GEN_OCCLUSION:
return shaderstate.curtexnums->occlusion;
case T_GEN_DISPLACEMENT:
return shaderstate.curtexnums->displacement;
case T_GEN_ANIMMAP:
return pass->anim_frames[(int)(pass->anim_fps * shaderstate.curtime) % pass->anim_numframes];
case T_GEN_3DMAP:
@ -1755,7 +1772,18 @@ static texid_t SelectPassTexture(const shaderpass_t *pass)
case T_GEN_SOURCECUBE: //used for render-to-texture targets
return r_nulltex;
case T_GEN_GBUFFER0:
case T_GEN_GBUFFER1:
case T_GEN_GBUFFER2:
case T_GEN_GBUFFER3:
case T_GEN_GBUFFER4:
case T_GEN_GBUFFER5:
case T_GEN_GBUFFER6:
case T_GEN_GBUFFER7:
return r_nulltex;
}
return r_nulltex;
}
static void T_Gen_CurrentRender(void)
@ -2208,7 +2236,7 @@ static void BE_GenerateColourMods(unsigned int vertcount, const shaderpass_t *pa
else
{ //we can't use the vbo due to gaps that we don't want to have to deal with
//we can at least ensure that the data is written in one go to aid cpu cache.
vec4_t *map;
vec4_t *fte_restrict map;
unsigned int mno;
map = VKBE_AllocateBufferSpace(DB_VBO, vertcount * sizeof(vec4_t), buffer, offset);
if (m->colors4f_array[0])
@ -2240,7 +2268,7 @@ static void BE_GenerateColourMods(unsigned int vertcount, const shaderpass_t *pa
}
else
{
vec4_t *map;
vec4_t *fte_restrict map;
unsigned int mno;
map = VKBE_AllocateBufferSpace(DB_VBO, vertcount * sizeof(vec4_t), buffer, offset);
for (mno = 0; mno < shaderstate.nummeshes; mno++)
@ -3166,6 +3194,7 @@ static qboolean BE_SetupMeshProgram(program_t *p, shaderpass_t *pass, unsigned i
VkWriteDescriptorSet descs[MAX_TMUS], *desc = descs;
VkDescriptorImageInfo imgs[MAX_TMUS], *img = imgs;
unsigned int i;
texid_t t;
//why do I keep wanting to write 'desk'? its quite annoying.
//light / scene
@ -3192,7 +3221,15 @@ static qboolean BE_SetupMeshProgram(program_t *p, shaderpass_t *pass, unsigned i
if (p->defaulttextures & (1u<<8))
BE_SetupTextureDescriptor(shaderstate.curtexnums->paletted, r_blackimage, set, descs, desc++, img++);
if (p->defaulttextures & (1u<<9))
BE_SetupTextureDescriptor(shaderstate.curtexnums->reflectcube, r_blackimage, set, descs, desc++, img++);
{
if (shaderstate.curtexnums && TEXLOADED(shaderstate.curtexnums->reflectcube))
t = shaderstate.curtexnums->reflectcube;
else if (shaderstate.curbatch->envmap)
t = shaderstate.curbatch->envmap;
else
t = r_nulltex; //FIXME
BE_SetupTextureDescriptor(t, r_blackimage, set, descs, desc++, img++);
}
if (p->defaulttextures & (1u<<10))
BE_SetupTextureDescriptor(shaderstate.curtexnums->reflectmask, r_whiteimage, set, descs, desc++, img++);
if (p->defaulttextures & (1u<<11))
@ -3361,7 +3398,7 @@ static void BE_DrawMeshChain_Internal(void)
}
else
{
index_t *map;
index_t *fte_restrict map;
VkBuffer buf;
unsigned int i;
VkDeviceSize offset;
@ -3385,7 +3422,7 @@ static void BE_DrawMeshChain_Internal(void)
}
else
{ /*we're going to be using dynamic array stuff here, so generate an index array list that has no vertex gaps*/
index_t *map;
index_t *fte_restrict map;
VkBuffer buf;
unsigned int i;
VkDeviceSize offset;
@ -3422,7 +3459,7 @@ static void BE_DrawMeshChain_Internal(void)
}
else
{
vecV_t *map;
vecV_t *fte_restrict map;
const mesh_t *m;
unsigned int mno;
unsigned int i;
@ -3508,16 +3545,13 @@ static void BE_DrawMeshChain_Internal(void)
}
else
{
vec2_t *map;
vec2_t *lmmap;
const mesh_t *m;
unsigned int mno;
unsigned int i;
if (shaderstate.meshlist[0]->normals_array[0])
{
vec4_t *map;
map = VKBE_AllocateBufferSpace(DB_VBO, vertcount * sizeof(vec3_t), &vertexbuffers[VK_BUFF_NORM], &vertexoffsets[VK_BUFF_NORM]);
vec4_t *fte_restrict map = VKBE_AllocateBufferSpace(DB_VBO, vertcount * sizeof(vec3_t), &vertexbuffers[VK_BUFF_NORM], &vertexoffsets[VK_BUFF_NORM]);
for (mno = 0; mno < shaderstate.nummeshes; mno++)
{
m = shaderstate.meshlist[mno];
@ -3533,8 +3567,7 @@ static void BE_DrawMeshChain_Internal(void)
if (shaderstate.meshlist[0]->snormals_array[0])
{
vec4_t *map;
map = VKBE_AllocateBufferSpace(DB_VBO, vertcount * sizeof(vec3_t), &vertexbuffers[VK_BUFF_SDIR], &vertexoffsets[VK_BUFF_SDIR]);
vec4_t *fte_restrict map = VKBE_AllocateBufferSpace(DB_VBO, vertcount * sizeof(vec3_t), &vertexbuffers[VK_BUFF_SDIR], &vertexoffsets[VK_BUFF_SDIR]);
for (mno = 0; mno < shaderstate.nummeshes; mno++)
{
m = shaderstate.meshlist[mno];
@ -3550,8 +3583,7 @@ static void BE_DrawMeshChain_Internal(void)
if (shaderstate.meshlist[0]->tnormals_array[0])
{
vec4_t *map;
map = VKBE_AllocateBufferSpace(DB_VBO, vertcount * sizeof(vec3_t), &vertexbuffers[VK_BUFF_TDIR], &vertexoffsets[VK_BUFF_TDIR]);
vec4_t *fte_restrict map = VKBE_AllocateBufferSpace(DB_VBO, vertcount * sizeof(vec3_t), &vertexbuffers[VK_BUFF_TDIR], &vertexoffsets[VK_BUFF_TDIR]);
for (mno = 0; mno < shaderstate.nummeshes; mno++)
{
m = shaderstate.meshlist[mno];
@ -3567,8 +3599,7 @@ static void BE_DrawMeshChain_Internal(void)
if (shaderstate.meshlist[0]->colors4f_array[0])
{
vec4_t *map;
map = VKBE_AllocateBufferSpace(DB_VBO, vertcount * sizeof(vec4_t), &vertexbuffers[VK_BUFF_COL], &vertexoffsets[VK_BUFF_COL]);
vec4_t *fte_restrict map = VKBE_AllocateBufferSpace(DB_VBO, vertcount * sizeof(vec4_t), &vertexbuffers[VK_BUFF_COL], &vertexoffsets[VK_BUFF_COL]);
for (mno = 0; mno < shaderstate.nummeshes; mno++)
{
m = shaderstate.meshlist[mno];
@ -3578,8 +3609,7 @@ static void BE_DrawMeshChain_Internal(void)
}
else if (shaderstate.meshlist[0]->colors4b_array)
{
vec4_t *map;
map = VKBE_AllocateBufferSpace(DB_VBO, vertcount * sizeof(vec4_t), &vertexbuffers[VK_BUFF_COL], &vertexoffsets[VK_BUFF_COL]);
vec4_t *fte_restrict map = VKBE_AllocateBufferSpace(DB_VBO, vertcount * sizeof(vec4_t), &vertexbuffers[VK_BUFF_COL], &vertexoffsets[VK_BUFF_COL]);
for (mno = 0; mno < shaderstate.nummeshes; mno++)
{
m = shaderstate.meshlist[mno];
@ -3592,8 +3622,7 @@ static void BE_DrawMeshChain_Internal(void)
}
else
{ //FIXME: use some predefined buffer
vec4_t *map;
map = VKBE_AllocateBufferSpace(DB_VBO, vertcount * sizeof(vec4_t), &vertexbuffers[VK_BUFF_COL], &vertexoffsets[VK_BUFF_COL]);
vec4_t *fte_restrict map = VKBE_AllocateBufferSpace(DB_VBO, vertcount * sizeof(vec4_t), &vertexbuffers[VK_BUFF_COL], &vertexoffsets[VK_BUFF_COL]);
for (i = 0; i < vertcount; i++)
{
Vector4Set(map[i], 1, 1, 1, 1);
@ -3602,8 +3631,8 @@ static void BE_DrawMeshChain_Internal(void)
if (shaderstate.meshlist[0]->lmst_array[0])
{
map = VKBE_AllocateBufferSpace(DB_VBO, vertcount * sizeof(vec2_t), &vertexbuffers[VK_BUFF_TC], &vertexoffsets[VK_BUFF_TC]);
lmmap = VKBE_AllocateBufferSpace(DB_VBO, vertcount * sizeof(vec2_t), &vertexbuffers[VK_BUFF_LMTC], &vertexoffsets[VK_BUFF_LMTC]);
vec2_t *fte_restrict map = VKBE_AllocateBufferSpace(DB_VBO, vertcount * sizeof(vec2_t), &vertexbuffers[VK_BUFF_TC], &vertexoffsets[VK_BUFF_TC]);
vec2_t *fte_restrict lmmap = VKBE_AllocateBufferSpace(DB_VBO, vertcount * sizeof(vec2_t), &vertexbuffers[VK_BUFF_LMTC], &vertexoffsets[VK_BUFF_LMTC]);
for (mno = 0; mno < shaderstate.nummeshes; mno++)
{
m = shaderstate.meshlist[mno];
@ -3615,7 +3644,7 @@ static void BE_DrawMeshChain_Internal(void)
}
else
{
map = VKBE_AllocateBufferSpace(DB_VBO, vertcount * sizeof(vec2_t), &vertexbuffers[VK_BUFF_TC], &vertexoffsets[VK_BUFF_TC]);
vec2_t *fte_restrict map = VKBE_AllocateBufferSpace(DB_VBO, vertcount * sizeof(vec2_t), &vertexbuffers[VK_BUFF_TC], &vertexoffsets[VK_BUFF_TC]);
for (mno = 0; mno < shaderstate.nummeshes; mno++)
{
m = shaderstate.meshlist[mno];
@ -4329,13 +4358,13 @@ void VKBE_SetupLightCBuffer(dlight_t *l, vec3_t colour)
//also updates the entity constant buffer
static void BE_RotateForEntity (const entity_t *e, const model_t *mod)
static void BE_RotateForEntity (const entity_t *fte_restrict e, const model_t *fte_restrict mod)
{
int i;
float modelmatrix[16];
float *m = modelmatrix;
float *proj;
vkcbuf_entity_t *cbe = VKBE_AllocateBufferSpace(DB_UBO, (sizeof(*cbe) + 0x0ff) & ~0xff, &shaderstate.ubo_entity.buffer, &shaderstate.ubo_entity.offset);
vkcbuf_entity_t *fte_restrict cbe = VKBE_AllocateBufferSpace(DB_UBO, (sizeof(*cbe) + 0x0ff) & ~0xff, &shaderstate.ubo_entity.buffer, &shaderstate.ubo_entity.offset);
shaderstate.ubo_entity.range = sizeof(*cbe);
shaderstate.curentity = e;
@ -5877,7 +5906,7 @@ struct vk_shadowbuffer *VKBE_GenerateShadowBuffer(vecV_t *verts, int numverts, i
if (istemp)
{
struct vk_shadowbuffer *buf = &tempbuf;
void *map;
void *fte_restrict map;
map = VKBE_AllocateBufferSpace(DB_VBO, sizeof(*verts)*numverts, &buf->vbuffer, &buf->voffset);
memcpy(map, verts, sizeof(*verts)*numverts);
@ -5893,7 +5922,7 @@ struct vk_shadowbuffer *VKBE_GenerateShadowBuffer(vecV_t *verts, int numverts, i
//FIXME: these buffers should really be some subsection of a larger buffer
struct vk_shadowbuffer *buf = BZ_Malloc(sizeof(*buf));
struct stagingbuf vbuf;
void *map;
void *fte_restrict map;
buf->isstatic = true;
map = VKBE_CreateStagingBuffer(&vbuf, sizeof(*verts) * numverts, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);

View file

@ -1495,7 +1495,7 @@ vk_image_t VK_CreateTexture2DArray(uint32_t width, uint32_t height, uint32_t lay
if (format == VK_FORMAT_UNDEFINED) //no default case means warnings for unsupported formats above.
Sys_Error("VK_CreateTexture2DArray: Unsupported image encoding: %u(%s)\n", encoding, Image_FormatName(encoding));
ici.flags = (ret.type==PTI_CUBEMAP)?VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT:0;
ici.flags = (ret.type==PTI_CUBE)?VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT:0;
ici.imageType = VK_IMAGE_TYPE_2D;
ici.format = format;
ici.extent.width = width;
@ -1527,7 +1527,7 @@ vk_image_t VK_CreateTexture2DArray(uint32_t width, uint32_t height, uint32_t lay
{
default:
return ret;
case PTI_CUBEMAP:
case PTI_CUBE:
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_CUBE;
break;
case PTI_2D:
@ -1806,23 +1806,20 @@ qboolean VK_LoadTextureMips (texid_t tex, const struct pendingtextureinfo *mips)
case PTI_2D:
if (!mipcount || mips->mip[0].width == 0 || mips->mip[0].height == 0 || mips->mip[0].depth != 1)
return false;
layers = 1;
break;
case PTI_2D_ARRAY:
if (!mipcount || mips->mip[0].width == 0 || mips->mip[0].height == 0 || mips->mip[0].depth == 0)
return false;
layers = 1;
break;
case PTI_CUBEMAP: //unfortunately, these use separate layers (yay gl compat)
if (!mipcount || mips->mip[0].width == 0 || mips->mip[0].height == 0 || mips->mip[0].depth != 1)
case PTI_CUBE:
if (!mipcount || mips->mip[0].width == 0 || mips->mip[0].height == 0 || mips->mip[0].depth != 6)
return false;
layers = 6;
break;
default:
return false;
}
layers *= mips->mip[0].depth;
layers = mips->mip[0].depth;
if (layers == 1 && mipcount > 1)
{ //npot mipmapped textures are awkward.
@ -1880,7 +1877,7 @@ qboolean VK_LoadTextureMips (texid_t tex, const struct pendingtextureinfo *mips)
imgbarrier.image = target.image;
imgbarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imgbarrier.subresourceRange.baseMipLevel = 0;
imgbarrier.subresourceRange.levelCount = mipcount/layers;
imgbarrier.subresourceRange.levelCount = mipcount;
imgbarrier.subresourceRange.baseArrayLayer = 0;
imgbarrier.subresourceRange.layerCount = layers;
imgbarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
@ -1910,7 +1907,7 @@ qboolean VK_LoadTextureMips (texid_t tex, const struct pendingtextureinfo *mips)
imgbarrier.image = target.image;
imgbarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imgbarrier.subresourceRange.baseMipLevel = 0;
imgbarrier.subresourceRange.levelCount = mipcount/layers;
imgbarrier.subresourceRange.levelCount = mipcount;
imgbarrier.subresourceRange.baseArrayLayer = 0;
imgbarrier.subresourceRange.layerCount = layers;
imgbarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
@ -1976,18 +1973,9 @@ qboolean VK_LoadTextureMips (texid_t tex, const struct pendingtextureinfo *mips)
region.bufferRowLength = blockswidth*blockwidth;
region.bufferImageHeight = blocksheight*blockheight;
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
if (mips->type == PTI_CUBEMAP)
{
region.imageSubresource.mipLevel = i%(mipcount/layers);
region.imageSubresource.baseArrayLayer = i/(mipcount/layers);
region.imageSubresource.layerCount = mips->mip[i].depth;
}
else
{
region.imageSubresource.mipLevel = i;
region.imageSubresource.baseArrayLayer = 0;
region.imageSubresource.layerCount = mips->mip[i].depth;
}
region.imageOffset.x = 0;
region.imageOffset.y = 0;
region.imageOffset.z = 0;
@ -2011,7 +1999,7 @@ qboolean VK_LoadTextureMips (texid_t tex, const struct pendingtextureinfo *mips)
imgbarrier.image = target.image;
imgbarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imgbarrier.subresourceRange.baseMipLevel = 0;
imgbarrier.subresourceRange.levelCount = mipcount/layers;
imgbarrier.subresourceRange.levelCount = mipcount;
imgbarrier.subresourceRange.baseArrayLayer = 0;
imgbarrier.subresourceRange.layerCount = layers;
imgbarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
@ -2639,7 +2627,7 @@ void VK_R_RenderView (void)
if (!r_refdef.globalfog.density)
{
int fogtype = ((r_refdef.flags & RDF_UNDERWATER) && cl.fog[1].density)?1:0;
int fogtype = ((r_refdef.flags & RDF_UNDERWATER) && cl.fog[FOGTYPE_WATER].density)?FOGTYPE_WATER:FOGTYPE_AIR;
CL_BlendFog(&r_refdef.globalfog, &cl.oldfog[fogtype], realtime, &cl.fog[fogtype]);
r_refdef.globalfog.density /= 64; //FIXME
}
@ -4120,6 +4108,7 @@ void VK_CheckTextureFormats(void)
{PTI_BGRX8_SRGB, VK_FORMAT_B8G8R8A8_SRGB, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT|VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT},
{PTI_E5BGR9, VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT|VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT},
{PTI_B10G11R11F, VK_FORMAT_B10G11R11_UFLOAT_PACK32, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT|VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT},
{PTI_A2BGR10, VK_FORMAT_A2B10G10R10_UNORM_PACK32, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT|VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT},
{PTI_RGB565, VK_FORMAT_R5G6B5_UNORM_PACK16, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_RGBA4444, VK_FORMAT_R4G4B4A4_UNORM_PACK16, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},

395
imgtool.c
View file

@ -333,6 +333,8 @@ static void ImgTool_SetupPalette(void)
static void ImgTool_FreeMips(struct pendingtextureinfo *mips)
{
size_t i;
if (mips)
{
for (i = 0; i < mips->mipcount; i++)
if (mips->mip[i].needfree)
BZ_Free(mips->mip[i].data);
@ -340,12 +342,15 @@ static void ImgTool_FreeMips(struct pendingtextureinfo *mips)
BZ_Free(mips->extrafree);
BZ_Free(mips);
}
}
sh_config_t sh_config;
viddef_t vid;
static const char *imagetypename[] = {"2D", "3D", "Cube", "2DArray", "CubemapArray", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"};
struct opts_s
{
int textype;
unsigned int flags; //image flags to use (affects how textures get interpreted a little)
unsigned int mipnum; //when exporting to a mipless format, this is the mip level that is actually written. default 0.
uploadfmt_t newpixelformat; //try to convert to this pixel format on export.
@ -407,6 +412,7 @@ static qboolean ImgTool_ConvertPixelFormat(struct opts_s *args, const char *inna
int bb,bw,bh;
qboolean canktx = false;
uploadfmt_t targfmt = args->newpixelformat;
int d,l, layers;
//force it to bc1 if bc2 or bc3 with no alpha channel.
if ((targfmt == PTI_BC2_RGBA || targfmt == PTI_BC3_RGBA) && !Image_FormatHasAlpha(mips->encoding))
@ -503,8 +509,28 @@ static qboolean ImgTool_ConvertPixelFormat(struct opts_s *args, const char *inna
Image_BlockSizeForEncoding(mips->encoding, &bb, &bw, &bh);
for (m = 0; m < mips->mipcount; m++)
{
qbyte *srcdata = mips->mip[m].data;
size_t srcsize = mips->mip[m].datasize;
if (mips->type == PTI_3D)
{
layers = 1;
d = mips->mip[m].depth;
tmp.type = PTI_2D;
}
else
{
layers = mips->mip[m].depth;
d = 1;
tmp.type = PTI_2D;
}
for (l = 0; l < layers; l++)
{
Con_DPrintf("Compressing %s mip %u, layer %u\n", inname, (unsigned)m, l);
tmp.mip[0] = mips->mip[m];
tmp.mip[0].needfree = false;
tmp.mip[0].depth = d;
tmp.mip[0].datasize = srcsize/layers;
tmp.mip[0].data = srcdata + l * tmp.mip[0].datasize;
(void)tmp;
if (canktx)
@ -517,7 +543,7 @@ static qboolean ImgTool_ConvertPixelFormat(struct opts_s *args, const char *inna
else
{
#ifdef AVAIL_PNGLIB
if (!Image_WritePNG(raw, FS_SYSTEM, 0, &mips->mip[m].data, 1, mips->mip[m].width*bb, mips->mip[m].width, mips->mip[m].height, mips->encoding, false))
if (!Image_WritePNG(raw, FS_SYSTEM, 0, &tmp.mip[0].data, 1, tmp.mip[0].width*bb, tmp.mip[0].width, tmp.mip[0].height, tmp.encoding, false))
#endif
break;
}
@ -528,14 +554,30 @@ static qboolean ImgTool_ConvertPixelFormat(struct opts_s *args, const char *inna
ret = Image_LoadMipsFromMemory(IF_NOMIPMAP, comp, comp, fdata, fsize);
if (ret && ret->mip[0].width == mips->mip[m].width &&
ret->mip[0].height == mips->mip[m].height &&
ret->mip[0].depth == mips->mip[m].depth &&
ret->mip[0].depth == d &&
ImgTool_ASTCToLDR(ret->encoding) == ImgTool_ASTCToLDR(targfmt))
{
if (layers == 1) //just copy it over. FIXME: memory leak
mips->mip[m] = ret->mip[0];
else
{
if (!l)
{
mips->mip[m].datasize = ret->mip[0].datasize * layers;
mips->mip[m].data = BZ_Malloc(mips->mip[m].datasize);
mips->mip[m].needfree = true;
}
else if (ret->mip[0].datasize != mips->mip[m].datasize/layers)
break; //erk..?
memcpy(mips->mip[m].data + l * ret->mip[0].datasize, ret->mip[0].data, ret->mip[0].datasize);
}
continue;
}
break;
}
if (l != layers)
break;
}
mips->encoding = targfmt;
mips->mipcount = m;
@ -567,25 +609,249 @@ const char *COM_GetFileExtension (const char *in, const char *term)
}
return "";
}
static void ImgTool_Convert(struct opts_s *args, const char *inname, const char *outname)
static struct pendingtextureinfo *ImgTool_Read(struct opts_s *args, const char *inname)
{
qbyte *indata;
size_t fsize, k;
size_t fsize;
struct pendingtextureinfo *in;
indata = FS_LoadMallocFile(inname, &fsize);
if (!indata)
printf("%s: unable to read\n", inname);
else
{
in = Image_LoadMipsFromMemory(args->flags, inname, inname, indata, fsize);
if (!in)
{
printf("%s: unsupported format\n", inname);
BZ_Free(indata);
}
else
{
printf("%s: %s %s, %i*%i, %i mips\n", inname, imagetypename[in->type], Image_FormatName(in->encoding), in->mip[0].width, in->mip[0].height, in->mipcount);
return in;
}
}
return NULL;
}
static struct pendingtextureinfo *ImgTool_Combine(struct opts_s *args, const char **namelist, unsigned int filecount)
{
struct pendingtextureinfo *r, *t;
unsigned int i;
unsigned int layers = 0;
unsigned int j = 0;
struct
{
const char *fname;
struct pendingtextureinfo *in;
} *srcs, *tmpsrcs;
if (args->textype == PTI_3D)
args->flags |= IF_NOMIPMAP; //generate any mipmaps after...
srcs = alloca(sizeof(*srcs)*filecount);
for (i = 0, j = 0; i < filecount; i++)
{
srcs[j].in = t = ImgTool_Read(args, namelist[i]);
if (srcs[j].in)
{
if (!j)
{
//get the image loader to massage pixel formats...
memset(sh_config.texfmt, 0, sizeof(sh_config.texfmt));
sh_config.texfmt[srcs[j].in->encoding] = true;
}
else if (!t->mipcount || !t->mip[0].data)
{
Con_Printf("%s: no valid image data\n", namelist[i]);
ImgTool_FreeMips(srcs[j].in);
continue;
}
else if (t->encoding != srcs[0].in->encoding)
{
Con_Printf("%s: mismatched pixel format, (%s not %s) cannot combine\n", namelist[i], Image_FormatName(t->encoding), Image_FormatName(srcs[0].in->encoding));
ImgTool_FreeMips(srcs[j].in);
continue;
}
else if (t->type == PTI_CUBE && t->mip[0].depth != 6)
{
Con_Printf("%s: incorrect cubemap data\n", namelist[i]);
ImgTool_FreeMips(srcs[j].in);
continue;
}
else if (srcs[0].in->mip[0].width != t->mip[0].width || srcs[0].in->mip[0].height != t->mip[0].height)
{
Con_Printf("%s: incorrect image size\n", namelist[i]);
ImgTool_FreeMips(srcs[j].in);
continue;
}
else if (t->mip[0].depth == 0)
{
Con_Printf("%s: no layers\n", namelist[i]);
ImgTool_FreeMips(srcs[j].in);
continue;
}
layers += t->mip[0].depth;
srcs[j++].fname = namelist[i];
}
}
filecount = j;
//FIXME: reorder input images to handle ft/bk/lt/rt/up/dn, and flip+rotate+etc to match quake
if (args->textype == PTI_CUBE)
{
int facetype[6];
static const struct {qboolean flipx, flipy, flipd;} skyboxflips[] ={
{true, false, true},
{false, true, true},
{true, true, false},
{false, false, false},
{true, false, true},
{true, false, true}
};
for (i = 0; i < 6; i++)
facetype[i] = 0;
for (i = 0; i < filecount; i++)
{
const char *ex = COM_GetFileExtension(srcs[i].fname, NULL);
if (ex && ex-srcs[i].fname > 2 && srcs[i].in->mip[0].depth == 1)
{
if (!strncasecmp(ex-2, "rt", 2))
facetype[0] = -i-1;
else if (!strncasecmp(ex-2, "lf", 2))
facetype[1] = -i-1;
else if (!strncasecmp(ex-2, "ft", 2))
facetype[2] = -i-1;
else if (!strncasecmp(ex-2, "bk", 2))
facetype[3] = -i-1;
else if (!strncasecmp(ex-2, "up", 2))
facetype[4] = -i-1;
else if (!strncasecmp(ex-2, "dn", 2))
facetype[5] = -i-1;
else if (!strncasecmp(ex-2, "px", 2))
facetype[0] = i+1;
else if (!strncasecmp(ex-2, "nx", 2))
facetype[1] = i+1;
else if (!strncasecmp(ex-2, "py", 2))
facetype[2] = i+1;
else if (!strncasecmp(ex-2, "ny", 2))
facetype[3] = i+1;
else if (!strncasecmp(ex-2, "pz", 2))
facetype[4] = i+1;
else if (!strncasecmp(ex-2, "nz", 2))
facetype[5] = i+1;
}
}
if (facetype[0] && facetype[1] && facetype[2] && facetype[3] && facetype[4] && facetype[5])
{
Con_Printf("Reordering images to match cubemap\n");
tmpsrcs = alloca(sizeof(*tmpsrcs)*filecount);
memcpy(tmpsrcs, srcs, sizeof(*tmpsrcs)*filecount);
for (i = 0; i < 6; i++)
{
if (facetype[i] < 0)
{ //flip to match legacy skyboxes
unsigned bb,bw,bh;
srcs[i] = tmpsrcs[-facetype[i]-1];
t = srcs[i].in;
Image_BlockSizeForEncoding(t->encoding, &bb,&bw,&bh);
if (bw == 1 && bh == 1)
{
for (j = 0; j < t->mipcount; j++)
{
void *data = Image_FlipImage(t->mip[j].data, BZ_Malloc(t->mip[j].datasize), &t->mip[j].width, &t->mip[j].height, bb, skyboxflips[i].flipx, skyboxflips[i].flipy, skyboxflips[i].flipd);
if (t->mip[j].needfree)
Z_Free(t->mip[j].data);
t->mip[j].data = data;
t->mip[j].needfree = true;
}
}
}
else
srcs[i] = tmpsrcs[facetype[i]-1];
}
}
else
Con_Printf("WARNING: Cubemap ordering unknown!\n");
}
if (!filecount)
Con_Printf("no valid input files\n");
else if (!layers)
Con_Printf("Images must have at least one layer\n");
else if (args->textype == PTI_2D && layers != 1)
Con_Printf("2D images must have one layer exactly, sorry\n");
else if (args->textype == PTI_CUBE && layers != 6)
Con_Printf("Cubemaps must have 6 layers exactly\n");
else if (args->textype == PTI_CUBE_ARRAY && layers % 6)
Con_Printf("Cubemap arrays must have a multiple of 6 layers exactly\n");
else
{
t = srcs[0].in;
r = Z_Malloc(sizeof(*t));
r->type = args->textype;
r->extrafree = NULL;
r->encoding = t->encoding;
if (args->textype == PTI_3D)
r->mipcount = 1;
else
r->mipcount = t->mipcount;
for (j = 0; j < t->mipcount; j++)
{
r->mip[j].datasize = t->mip[j].datasize*layers;
r->mip[j].width = t->mip[j].width;
r->mip[j].height = t->mip[j].height;
r->mip[j].depth = 0;
r->mip[j].needfree = true;
r->mip[j].data = BZ_Malloc(r->mip[j].datasize);
}
for (i = 0, j = 0; i < filecount; i++)
{
t = srcs[i].in;
if (!t)
{
ImgTool_FreeMips(r);
return NULL;
}
for (j = 0; j < r->mipcount; j++)
{
if (r->mip[j].width != t->mip[j].width || r->mip[j].height != t->mip[j].height || t->mip[j].depth != 1)
{
Con_Printf("%s: mismatched mipmap sizes\n", namelist[i]);
continue;
}
memcpy(r->mip[j].data + t->mip[j].datasize*r->mip[j].depth, t->mip[j].data, t->mip[j].datasize);
r->mip[j].depth++;
}
}
for (i = 0; i < filecount; i++)
ImgTool_FreeMips(srcs[i].in);
printf("%s: %s %s, %i*%i, %i mips\n", "combined", imagetypename[r->type], Image_FormatName(r->encoding), r->mip[0].width, r->mip[0].height, r->mipcount);
return r;
}
for (i = 0; i < filecount; i++)
ImgTool_FreeMips(srcs[i].in);
return NULL;
}
static void ImgTool_Convert(struct opts_s *args, struct pendingtextureinfo *in, const char *inname, const char *outname)
{
size_t k;
const char *outext = COM_GetFileExtension(outname, NULL);
qboolean allowcompressed = false;
if (!strcmp(outext, ".dds") || !strcmp(outext, ".ktx"))
allowcompressed = true;
indata = FS_LoadMallocFile(inname, &fsize);
if (indata)
{
in = Image_LoadMipsFromMemory(args->flags|(allowcompressed?0:IF_NOMIPMAP), inname, inname, indata, fsize);
if (in)
{
printf("%s: %s, %i*%i, %i mips\n", inname, Image_FormatName(in->encoding), in->mip[0].width, in->mip[0].height, in->mipcount);
if (!(args->flags & IF_NOMIPMAP) && in->mipcount == 1)
Image_GenerateMips(in, args->flags);
@ -633,8 +899,8 @@ static void ImgTool_Convert(struct opts_s *args, const char *inname, const char
{
int bb,bw,bh;
if (0)
;
if (in->type != PTI_2D)
Con_Printf("%s: Unable to write %s file to 2d image format\n", outname, imagetypename[in->type]);
#ifdef IMAGEFMT_PNG
else if (!strcmp(outext, ".png"))
{
@ -652,7 +918,7 @@ static void ImgTool_Convert(struct opts_s *args, const char *inname, const char
0;
if (!sh_config.texfmt[in->encoding])
{
Image_ChangeFormat(in, args->flags&~IF_PREMULTIPLYALPHA, PTI_INVALID, inname);
Image_ChangeFormat(in, args->flags&~IF_PREMULTIPLYALPHA, PTI_INVALID, outname);
printf("\t(Exporting as %s)\n", Image_FormatName(in->encoding));
}
Image_BlockSizeForEncoding(in->encoding, &bb, &bw,&bh);
@ -676,7 +942,7 @@ static void ImgTool_Convert(struct opts_s *args, const char *inname, const char
0;
if (!sh_config.texfmt[in->encoding])
{
Image_ChangeFormat(in, args->flags&~IF_PREMULTIPLYALPHA, PTI_INVALID, inname);
Image_ChangeFormat(in, args->flags&~IF_PREMULTIPLYALPHA, PTI_INVALID, outname);
printf("\t(Exporting as %s)\n", Image_FormatName(in->encoding));
}
Image_BlockSizeForEncoding(in->encoding, &bb, &bw,&bh);
@ -688,18 +954,12 @@ static void ImgTool_Convert(struct opts_s *args, const char *inname, const char
Con_Printf("%s: Unknown output file format\n", outname);
}
// printf("%s: %s, %i*%i, %i mips\n", outname, Image_FormatName(in->encoding), in->mip[0].width, in->mip[0].height, in->mipcount);
// for (m = 0; m < in->mipcount; m++)
// printf("\t%u: %i*%i*%i, %u\n", (unsigned)m, in->mip[m].width, in->mip[m].height, in->mip[m].depth, (unsigned)in->mip[m].datasize);
printf("%s: %s %s, %i*%i, %i mips\n", outname, imagetypename[in->type], Image_FormatName(in->encoding), in->mip[0].width, in->mip[0].height, in->mipcount);
for (k = 0; k < in->mipcount; k++)
printf("\t%u: %i*%i*%i, %u\n", (unsigned)k, in->mip[k].width, in->mip[k].height, in->mip[k].depth, (unsigned)in->mip[k].datasize);
ImgTool_FreeMips(in);
}
else
printf("%s: unsupported format\n", inname);
}
else
printf("%s: unable to read\n", inname);
fflush(stdout);
}
static void ImgTool_Info(struct opts_s *args, const char *inname)
@ -718,7 +978,7 @@ static void ImgTool_Info(struct opts_s *args, const char *inname)
printf("%s: unsupported format\n", inname);
else
{
printf("%s: %s, %i*%i, %i mips\n", inname, Image_FormatName(in->encoding), in->mip[0].width, in->mip[0].height, in->mipcount);
printf("%s: %s %s, %i*%i, %i mips\n", inname, imagetypename[in->type], Image_FormatName(in->encoding), in->mip[0].width, in->mip[0].height, in->mipcount);
for (m = 0; m < in->mipcount; m++)
printf("\t%u: %i*%i*%i, %u\n", (unsigned)m, in->mip[m].width, in->mip[m].height, in->mip[m].depth, (unsigned)in->mip[m].datasize);
@ -865,7 +1125,7 @@ static void ImgTool_TreeConvert(struct opts_s *args, const char *srcpath, const
processedfiles++;
// Con_Printf("Image file %s -> %s\n", file, dest);
FS_CreatePath(dest, FS_SYSTEM);
ImgTool_Convert(args, file, dest);
ImgTool_Convert(args, ImgTool_Read(args, file), file, dest);
}
else
{
@ -1062,13 +1322,16 @@ int main(int argc, const char **argv)
mode_genwad3,
} mode = mode_info;
size_t u, f;
qboolean nomoreopts = false;
struct opts_s args;
size_t files = 0;
for (u = 1; u < countof(sh_config.texfmt); u++)
sh_config.texfmt[u] = true;
args.flags = 0;
args.newpixelformat = PTI_INVALID;
args.mipnum = 0;
args.textype = -1;
sh_config.texture2d_maxsize = 1u<<31;
sh_config.texture3d_maxsize = 1u<<31;
@ -1088,9 +1351,11 @@ int main(int argc, const char **argv)
for (u = 1; u < argc; u++)
{
if (*argv[u] == '-')
if (*argv[u] == '-' && !nomoreopts)
{
if (!strcmp(argv[u], "-?") || !strcmp(argv[u], "--help"))
if (!strcmp(argv[u], "--"))
nomoreopts = true;
else if (!strcmp(argv[u], "-?") || !strcmp(argv[u], "--help"))
{
showhelp:
Con_Printf("show info : %s -i *.ktx\n", argv[0]);
@ -1135,26 +1400,36 @@ showhelp:
// else
// Con_DPrintf(" --%-16s %5.3g-bpp (unsupported)\n", Image_FormatName(f), 8*(float)bb/(bw*bh));
}
break;
return EXIT_SUCCESS;
}
else if (!strcmp(argv[u], "-c") || !strcmp(argv[u], "--convert"))
else if (!files && (!strcmp(argv[u], "-c") || !strcmp(argv[u], "--convert")))
mode = mode_convert;
else if (!strcmp(argv[u], "-d") || !strcmp(argv[u], "--decompress"))
else if (!files && (!strcmp(argv[u], "-d") || !strcmp(argv[u], "--decompress")))
{ //remove any (weird) gpu formats
for (f = PTI_BC1_RGB; f < PTI_ASTC_LAST; f++)
sh_config.texfmt[f] = false;
mode = mode_convert;
}
else if (!strcmp(argv[u], "-r") || !strcmp(argv[u], "--auto"))
else if (!files && (!strcmp(argv[u], "-r") || !strcmp(argv[u], "--auto")))
mode = mode_autotree;
else if (!strcmp(argv[u], "-i") || !strcmp(argv[u], "--info"))
else if (!files && (!strcmp(argv[u], "-i") || !strcmp(argv[u], "--info")))
mode = mode_info;
else if (!strcmp(argv[u], "-w") || !strcmp(argv[u], "--genwad3"))
else if (!files && (!strcmp(argv[u], "-w") || !strcmp(argv[u], "--genwad3")))
mode = mode_genwad3;
else if (!strcmp(argv[u], "-w") || !strcmp(argv[u], "--genwad2"))
else if (!files && (!strcmp(argv[u], "-w") || !strcmp(argv[u], "--genwad2")))
mode = mode_genwad2;
else if (!strcmp(argv[u], "-w") || !strcmp(argv[u], "--genwadx"))
else if (!files && (!strcmp(argv[u], "-w") || !strcmp(argv[u], "--genwadx")))
mode = mode_genwadx;
else if (!strcmp(argv[u], "--2d"))
args.textype = PTI_2D;
else if (!strcmp(argv[u], "--3d"))
args.textype = PTI_3D;
else if (!strcmp(argv[u], "--cube"))
args.textype = PTI_CUBE;
else if (!strcmp(argv[u], "--2darray"))
args.textype = PTI_2D_ARRAY;
else if (!strcmp(argv[u], "--cubearray"))
args.textype = PTI_CUBE_ARRAY;
else if (!strcmp(argv[u], "--nomips") )
args.flags |= IF_NOMIPMAP;
else if (!strcmp(argv[u], "--mips"))
@ -1193,36 +1468,36 @@ showhelp:
Con_Printf("Unknown arg %s\n", argv[u]);
goto showhelp;
}
argv[u] = NULL;
}
else
{
argv[files++] = argv[u];
}
if (mode == mode_info)
{ //just print info about each listed file.
for (u = 0; u < files; u++)
ImgTool_Info(&args, argv[u]);
else if (mode == mode_convert)
}
else if (mode == mode_convert && files > 1 && args.textype>=0) //overwrite input
{
if (u+1 < argc)
files--;
ImgTool_Convert(&args, ImgTool_Combine(&args, argv, files), "combined", argv[files]);
}
else if (mode == mode_convert && files == 1 && args.textype<0) //overwrite input
ImgTool_Convert(&args, ImgTool_Read(&args, argv[u]), argv[u], argv[u]);
else if (mode == mode_convert && !(files&1) && args.textype<0) //list of pairs
{
ImgTool_Convert(&args, argv[u], argv[u+1]);
u++;
//-c src1 dst1 src2 dst2
for (u = 0; u+1 < files; u+=2)
ImgTool_Convert(&args, ImgTool_Read(&args, argv[u]), argv[u], argv[u+1]);
}
}
else if (mode == mode_autotree)
{
if (u+1 < argc)
{
ImgTool_TreeConvert(&args, argv[u], argv[u+1]);
u++;
}
}
else if (mode == mode_genwad2 || mode == mode_genwad3 || mode == mode_genwadx)
{
if (u+1 < argc)
{
ImgTool_WadConvert(&args, argv[u], argv[u+1], mode-mode_genwadx);
u++;
}
}
}
}
return 0;
else if (mode == mode_autotree && files == 2)
ImgTool_TreeConvert(&args, argv[0], argv[1]);
else if ((mode == mode_genwad2 || mode == mode_genwad3 || mode == mode_genwadx) && files == 2)
ImgTool_WadConvert(&args, argv[0], argv[1], mode-mode_genwadx);
else
return EXIT_FAILURE;
return EXIT_SUCCESS;
}

View file

@ -4523,6 +4523,7 @@ template<int md16> bool writemdl(const char *filename)
void help(bool exitstatus = EXIT_SUCCESS)
{
fprintf(exitstatus != EXIT_SUCCESS ? stderr : stdout,
"-- FTE's Fork of Lee Salzman's iqm exporter --\n"
"Usage:\n"
"\n"
"./iqm cmdfile.cmd\n"