From 11e6214dafca6bd5a1a2e2846cc9607114ffea65 Mon Sep 17 00:00:00 2001 From: Spoike Date: Fri, 18 Oct 2019 08:37:38 +0000 Subject: [PATCH] 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 --- engine/client/cl_main.c | 14 +- engine/client/cl_parse.c | 28 +- engine/client/cl_screen.c | 150 ++--- engine/client/client.h | 15 +- engine/client/image.c | 727 ++++++++++++++----------- engine/client/m_download.c | 9 - engine/client/merged.h | 11 +- engine/client/pr_csqc.c | 4 +- engine/client/render.h | 19 +- engine/client/renderer.c | 4 +- engine/client/wad.c | 7 + engine/common/fs.c | 4 + engine/common/fs_zip.c | 16 +- engine/common/gl_q2bsp.c | 2 +- engine/common/net_ssl_gnutls.c | 8 +- engine/common/net_ssl_winsspi.c | 8 +- engine/common/plugin.c | 5 + engine/common/q1bsp.c | 2 +- engine/d3d/d3d11_image.c | 99 +--- engine/d3d/d3d_image.c | 53 +- engine/d3d/vid_d3d.c | 2 +- engine/d3d/vid_d3d11.c | 2 + engine/gl/gl_alias.c | 2 +- engine/gl/gl_backend.c | 4 +- engine/gl/gl_draw.c | 336 +++++++----- engine/gl/gl_rlight.c | 6 +- engine/gl/gl_rmain.c | 4 +- engine/gl/gl_rmisc.c | 2 +- engine/gl/gl_shader.c | 56 +- engine/gl/gl_warp.c | 8 +- engine/gl/glsupp.h | 20 + engine/qclib/execloop.h | 13 + engine/shaders/hlsl11/default2d.hlsl | 3 +- engine/shaders/hlsl11/defaultfill.hlsl | 3 +- engine/shaders/hlsl11/menutint.hlsl | 3 +- engine/shaders/makevulkanblob.c | 7 +- engine/vk/vk_backend.c | 85 ++- engine/vk/vk_init.c | 37 +- imgtool.c | 633 +++++++++++++++------ iqm/iqm.cpp | 1 + 40 files changed, 1418 insertions(+), 994 deletions(-) diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index bb98a872..f157155a 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -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 "); Cmd_AddCommandD ("waterfog", CL_Fog_f, "waterfog "); + Cmd_AddCommandD ("skyroomfog", CL_Fog_f, "waterfog "); 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 diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 8556ae07..4a574048 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -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 (); diff --git a/engine/client/cl_screen.c b/engine/client/cl_screen.c index b32fb41d..1ac9d3dd 100644 --- a/engine/client/cl_screen.c +++ b/engine/client/cl_screen.c @@ -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,83 +2898,83 @@ 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) + { + 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) - 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++; + BZ_Free(facedata); + break; //zomgwtfbbq } - } - */ - Q_snprintfz(filename, sizeof(filename), "textures/%s", fname); - COM_DefaultExtension (filename, ext, sizeof(filename)); + 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 - COM_DefaultExtension (filename, ".ktx", sizeof(filename)); + COM_DefaultExtension (filename, ".ktx", sizeof(filename)); #endif #ifdef IMAGEFMT_DDS - COM_DefaultExtension (filename, ".dds", sizeof(filename)); + COM_DefaultExtension (filename, ".dds", sizeof(filename)); #endif - ext = COM_GetFileExtension(filename, NULL); - if (fail) - Con_Printf("Unable to generate cubemap data\n"); + ext = COM_GetFileExtension(filename, NULL); + if (fail) + Con_Printf("Unable to generate cubemap data\n"); #ifdef IMAGEFMT_DDS - else if (!strcmp(ext, ".dds")) - { - if (Image_WriteDDSFile(filename, FS_GAMEONLY, &mips)) + else if (!strcmp(ext, ".dds")) { - FS_NativePath(filename, FS_GAMEONLY, sysname, sizeof(sysname)); - Con_Printf ("Wrote %s\n", sysname); + if (Image_WriteDDSFile(filename, FS_GAMEONLY, &mips)) + { + FS_NativePath(filename, FS_GAMEONLY, sysname, sizeof(sysname)); + Con_Printf ("Wrote %s\n", sysname); + } } - } #endif #ifdef IMAGEFMT_KTX - else if (!strcmp(ext, ".ktx")) - { - if (Image_WriteKTXFile(filename, FS_GAMEONLY, &mips)) + else if (!strcmp(ext, ".ktx")) { - FS_NativePath(filename, FS_GAMEONLY, sysname, sizeof(sysname)); - Con_Printf ("Wrote %s\n", sysname); + if (Image_WriteKTXFile(filename, FS_GAMEONLY, &mips)) + { + FS_NativePath(filename, FS_GAMEONLY, sysname, sizeof(sysname)); + Con_Printf ("Wrote %s\n", sysname); + } } - } #endif - else - Con_Printf ("%s: Unknown format %s\n", Cmd_Argv(0), filename); + 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); diff --git a/engine/client/client.h b/engine/client/client.h index 4b257a05..fef96e71 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -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. diff --git a/engine/client/image.c b/engine/client/image.c index 7ba352c4..537b851b 100644 --- a/engine/client/image.c +++ b/engine/client/image.c @@ -4695,15 +4695,53 @@ typedef struct } ktxheader_t; qboolean Image_WriteKTXFile(const char *filename, enum fs_relative fsroot, struct pendingtextureinfo *mips) { + unsigned int bb,bw,bh; vfsfile_t *file; ktxheader_t header = {{0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A}, 0x04030201/*endianness*/, 0/*type*/, 1/*typesize*/, 0/*format*/, 0/*internalformat*/, 0/*base*/, mips->mip[0].width, mips->mip[0].height, 0/*depth*/, - 0/*array elements*/, (mips->type==PTI_CUBEMAP)?6:1, mips->mipcount, 0/*kvdatasize*/}; + 0/*array elements*/, 1, mips->mipcount, 0/*kvdatasize*/}; size_t mipnum; - if (mips->type != PTI_2D && mips->type != PTI_CUBEMAP) + if (mips->type==PTI_CUBE_ARRAY) + { + if (!mips->mip[0].depth || mips->mip[0].depth % 6) + { + Con_Printf("Image_WriteKTXFile: malformed cube\n"); + return false; //malformed... + } + header.numberoffaces = 6; + header.numberofarrayelements = mips->mip[0].depth/6; + } + else if (mips->type==PTI_CUBE) + { + if (mips->mip[0].depth != 6) + { + Con_Printf("Image_WriteKTXFile: malformed cube\n"); + return false; //malformed... + } + header.numberofarrayelements = 0; + header.numberoffaces = 6; + } + else if (mips->type==PTI_2D_ARRAY) + { + if (!mips->mip[0].depth) + return false; + header.numberofarrayelements = mips->mip[0].depth; + } + else if (mips->type == PTI_3D) + header.pixeldepth = mips->mip[0].depth; + else if (mips->type == PTI_2D) + { + if (mips->mip[0].depth != 1) + return false; + } + else + { + Con_Printf("Image_WriteKTXFile: unsupported texture type\n"); return false; - header.numberofmipmaplevels /= header.numberoffaces; + } + + Image_BlockSizeForEncoding(mips->encoding, &bb, &bw, &bh); switch(mips->encoding) { @@ -4836,16 +4874,46 @@ qboolean Image_WriteKTXFile(const char *filename, enum fs_relative fsroot, struc return false; VFS_WRITE(file, &header, sizeof(header)); - for (mipnum = 0; mipnum < mips->mipcount; mipnum++) + for (mipnum = 0; mipnum < mips->mipcount; ) { - unsigned int pad = 0; - unsigned int sz = mips->mip[mipnum].datasize; - if (!(mipnum % header.numberoffaces)) - VFS_WRITE(file, &sz, 4); - - VFS_WRITE(file, mips->mip[mipnum].data, sz); - if ((sz & 3) && mips->type == PTI_CUBEMAP) - VFS_WRITE(file, &pad, 4-(sz&3)); + unsigned int sz; + //translate to blocks + unsigned int browbytes = bb * ((mips->mip[mipnum].width+bw-1)/bh); + unsigned int padbytes = (browbytes&3)?4-(browbytes&3):0; + unsigned int brows = (mips->mip[mipnum].height+bh-1)/bh; + unsigned int blayers = (mips->mip[mipnum].depth+1-1)/1; + if (mips->mip[mipnum].datasize != browbytes*brows*blayers) + { //should probably be a sys_error + Con_Printf("WriteKTX mip %u missized\n", (unsigned)mipnum); + VFS_CLOSE(file); + return false; + } + switch(mips->type) + { + case PTI_2D: + case PTI_2D_ARRAY: + case PTI_CUBE: + case PTI_CUBE_ARRAY: + sz = (browbytes+padbytes) * brows; + break; + case PTI_3D: + sz = (browbytes+padbytes) * brows * blayers; + break; + } + VFS_WRITE(file, &sz, 4); + brows *= blayers; + if (padbytes) + { + unsigned int pad = 0, y; + for (y = 0; y < brows; y++) + { + VFS_WRITE(file, mips->mip[mipnum].data + browbytes*y, browbytes); + VFS_WRITE(file, &pad, 4-(browbytes&3)); + } + } + else + VFS_WRITE(file, mips->mip[mipnum].data, browbytes*brows); + mipnum++; } VFS_CLOSE(file); @@ -4859,10 +4927,9 @@ static struct pendingtextureinfo *Image_ReadKTXFile(unsigned int flags, const ch int mipnum; int face; int datasize; - unsigned int w, h, d; + unsigned int w, h, d, f, l, browbytes,padbytes,y,rows; struct pendingtextureinfo *mips; int encoding = TF_INVALID; - qbyte *in; qbyte *fileend = filedata + filesize; unsigned int blockwidth, blockheight, blockbytes; @@ -4875,12 +4942,15 @@ static struct pendingtextureinfo *Image_ReadKTXFile(unsigned int flags, const ch if (nummips < 1) nummips = 1; - if (header->numberofarrayelements != 0) - return NULL; //don't support array textures +// if (header->numberofarrayelements != 0) +// return NULL; //don't support array textures if (header->numberoffaces == 1) ; //non-cubemap else if (header->numberoffaces == 6) { + if (header->numberofarrayelements != 0) + return NULL; //don't support array textures + if (header->pixeldepth != 0) return NULL; // if (header->numberofmipmaplevels != 1) @@ -4888,8 +4958,8 @@ static struct pendingtextureinfo *Image_ReadKTXFile(unsigned int flags, const ch } else return NULL; //don't allow weird cubemaps - if (header->pixeldepth && header->pixelwidth != header->pixeldepth && header->pixelheight != header->pixeldepth) - return NULL; //we only support 3d textures where width+height+depth are the same. too lazy to change it now. +// if (header->pixeldepth && header->pixelwidth != header->pixeldepth && header->pixelheight != header->pixeldepth) +// return NULL; //we only support 3d textures where width+height+depth are the same. too lazy to change it now. /*FIXME: validate format+type for non-compressed formats*/ switch(header->glinternalformat) @@ -5037,10 +5107,10 @@ static struct pendingtextureinfo *Image_ReadKTXFile(unsigned int flags, const ch if (header->numberofarrayelements) { header->pixeldepth = header->numberofarrayelements*6; - mips->type = PTI_CUBEMAP_ARRAY; + mips->type = PTI_CUBE_ARRAY; } else - mips->type = PTI_CUBEMAP; + mips->type = PTI_CUBE; } else { @@ -5067,48 +5137,59 @@ static struct pendingtextureinfo *Image_ReadKTXFile(unsigned int flags, const ch Image_BlockSizeForEncoding(encoding, &blockbytes, &blockwidth, &blockheight); w = header->pixelwidth; - h = header->pixelheight; - d = header->pixeldepth; - - //fixme: if (w+blockwidth-1)/blockwidth)*blockbytes MUST be a multiple of 4. - //we need to de-pad it otherwise. + h = max(1, header->pixelheight); + d = max(1, header->pixeldepth); + f = max(1, header->numberoffaces); + l = max(1, header->numberofarrayelements); for (mipnum = 0; mipnum < nummips; mipnum++) { datasize = *(int*)filedata; filedata += 4; - if (datasize != blockbytes * ((w+blockwidth-1)/blockwidth) * ((h+blockheight-1)/blockheight)) + browbytes = blockbytes * ((w+blockwidth-1)/blockwidth); + padbytes = (browbytes & 3)?4-(browbytes&3):0; + rows = ((h+blockheight-1)/blockheight)*d; + if (datasize != (browbytes+padbytes) * rows) { - Con_Printf("%s: mip %i does not match expected size\n", fname, mipnum); + Con_Printf("%s: mip %i does not match expected size (%u, required %u)\n", fname, mipnum, datasize, (browbytes+padbytes) * rows); break; } - if (filedata + datasize*header->numberoffaces > fileend) + if (filedata + datasize*f*l > fileend) { Con_Printf("%s: truncation at mip %i\n", fname, mipnum); break; } - for (face = 0; face < header->numberoffaces; face++) - { - if (mips->mipcount >= countof(mips->mip)) - break; - mips->mip[mips->mipcount].data = in = filedata; - mips->mip[mips->mipcount].datasize = datasize; - mips->mip[mips->mipcount].width = w; - mips->mip[mips->mipcount].height = h; - mips->mip[mips->mipcount].depth = d; - mips->mipcount++; + if (mips->mipcount >= countof(mips->mip)) + break; + mips->mip[mips->mipcount].width = w; + mips->mip[mips->mipcount].height = h; + mips->mip[mips->mipcount].depth = d*l*f; - filedata += datasize; - if ((datasize & 3) && mips->type == PTI_CUBEMAP) - filedata += 4-(datasize&3); + if (padbytes) + { + //gah + rows *= l*f; + mips->mip[mips->mipcount].needfree = true; + mips->mip[mips->mipcount].datasize = browbytes * rows; + mips->mip[mips->mipcount].data = BZ_Malloc(mips->mip[mips->mipcount].datasize); + for (y = 0; y < rows; y++) + memcpy(mips->mip[mips->mipcount].data + y*browbytes, filedata + y*browbytes+padbytes, browbytes); } + else + { + mips->mip[mips->mipcount].datasize = datasize * l*f; + mips->mip[mips->mipcount].data = filedata; + } + mips->mipcount++; + + filedata += datasize *l*f; + w = max(1, w>>1); h = max(1, h>>1); - if (mips->type == PTI_3D) - d = max(1, d>>1); + d = max(1, d>>1); } if (!mips->mipcount) @@ -5311,11 +5392,12 @@ static struct pendingtextureinfo *Image_ReadDDSFile(unsigned int flags, const ch int mipnum; int datasize; // int pad; - unsigned int w, h; + unsigned int w, h, d; unsigned int blockwidth, blockheight, blockbytes; struct pendingtextureinfo *mips; int encoding; int layers = 1, layer; + int ttype; ddsheader fmtheader; dds10header_t fmt10header; @@ -5327,7 +5409,8 @@ static struct pendingtextureinfo *Image_ReadDDSFile(unsigned int flags, const ch if (fmtheader.dwSize != sizeof(fmtheader)) return NULL; //corrupt/different version memset(&fmt10header, 0, sizeof(fmt10header)); - fmt10header.arraysize = 1; + + fmt10header.arraysize = (fmtheader.ddsCaps[1] & 0x200)?6:1; //cubemaps need 6 faces... nummips = fmtheader.dwMipMapCount; if (nummips < 1) @@ -5348,6 +5431,8 @@ static struct pendingtextureinfo *Image_ReadDDSFile(unsigned int flags, const ch encoding = PTI_BGRX8; else if (IsPacked(32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0)) encoding = PTI_RGBX8; + else if (IsPacked(32, 0x000003ff, 0x000ffc00, 0x3ff00000, 0xc0000000)) + encoding = PTI_A2BGR10; else { Con_Printf("Unsupported non-fourcc dds in %s\n", fname); @@ -5569,32 +5654,54 @@ static struct pendingtextureinfo *Image_ReadDDSFile(unsigned int flags, const ch if ((fmtheader.ddsCaps[1] & 0x200) && (fmtheader.ddsCaps[1] & 0xfc00) != 0xfc00) return NULL; //cubemap without all 6 faces defined. - if (fmtheader.ddsCaps[1] & 0x200000) - return NULL; //3d texture. fte internally interleaves layers on the x axis. I'll bet dds does not. Image_BlockSizeForEncoding(encoding, &blockbytes, &blockwidth, &blockheight); if (!blockbytes) return NULL; //werid/unsupported - mips = Z_Malloc(sizeof(*mips)); - mips->mipcount = 0; if (fmtheader.ddsCaps[1] & 0x200) { - layers = 6; - mips->type = PTI_CUBEMAP; + if (fmt10header.arraysize % 6) //weird number of faces. + return NULL; + + if (fmt10header.arraysize == 6) + { + ttype = PTI_CUBE; + fmtheader.dwDepth = 6; + } + else + { + ttype = PTI_CUBE_ARRAY; + fmtheader.dwDepth = fmt10header.arraysize; + } } else if (fmtheader.ddsCaps[1] & 0x200000) - mips->type = PTI_3D; + { + if (fmt10header.arraysize != 1) //no 2d arrays + return NULL; + ttype = PTI_3D; + } else - mips->type = PTI_2D; + { + if (fmt10header.arraysize == 1) + ttype = PTI_2D; + else + ttype = PTI_2D_ARRAY; + fmtheader.dwDepth = fmt10header.arraysize; + } + + mips = Z_Malloc(sizeof(*mips)); + mips->mipcount = 0; + mips->type = ttype; mips->extrafree = filedata; mips->encoding = encoding; filedata += 4+fmtheader.dwSize; - datasize = fmtheader.dwPitchOrLinearSize; w = fmtheader.dwWidth; h = fmtheader.dwHeight; + d = fmtheader.dwDepth; + for (mipnum = 0; mipnum < nummips; mipnum++) { if (mips->mipcount >= countof(mips->mip)) @@ -5602,7 +5709,7 @@ static struct pendingtextureinfo *Image_ReadDDSFile(unsigned int flags, const ch // if (datasize < 8) // datasize = pad; - datasize = ((w+blockwidth-1)/blockwidth) * ((h+blockheight-1)/blockheight) * blockbytes; + datasize = ((w+blockwidth-1)/blockwidth) * ((h+blockheight-1)/blockheight) * (d) * blockbytes; for (layer = 0; layer < layers; layer++) { @@ -5610,7 +5717,7 @@ static struct pendingtextureinfo *Image_ReadDDSFile(unsigned int flags, const ch mips->mip[mips->mipcount].datasize = datasize; mips->mip[mips->mipcount].width = w; mips->mip[mips->mipcount].height = h; - mips->mip[mips->mipcount].depth = 1; + mips->mip[mips->mipcount].depth = d; mips->mipcount++; filedata += datasize; } @@ -5630,7 +5737,7 @@ qboolean Image_WriteDDSFile(const char *filename, enum fs_relative fsroot, struc ddsheader h9={0}; unsigned int blockbytes, blockwidth, blockheight; - unsigned int arraysize = (mips->type==PTI_CUBEMAP||mips->type==PTI_CUBEMAP_ARRAY)?6:1; + unsigned int arraysize; Image_BlockSizeForEncoding(mips->encoding, &blockbytes, &blockwidth, &blockheight); @@ -5652,40 +5759,62 @@ qboolean Image_WriteDDSFile(const char *filename, enum fs_relative fsroot, struc } if (mips->mipcount > 1) h9.dwFlags |= 0x20000; //MIPMAPCOUNT - h9.dwHeight = mips->mip[0].height; h9.dwWidth = mips->mip[0].width; - h9.dwDepth = 0; - h9.dwMipMapCount = mips->mipcount/arraysize; + h9.dwHeight = mips->mip[0].height; + h9.dwDepth = mips->mip[0].depth; + h9.ddpfPixelFormat.dwSize = 32; h9.ddpfPixelFormat.dwFlags = 4/*DDPF_FOURCC*/; h9.ddpfPixelFormat.dwFourCC = ('D'<<0)|('X'<<8)|('1'<<16)|('0'<<24); h9.ddsCaps[0] = 0x1000; //TEXTURE if (mips->mipcount > 1) h9.ddsCaps[0] |= 0x8; //COMPLEX - if (mips->mipcount > arraysize) - h9.ddsCaps[0] |= 0x400000; //MIPMAP h9.ddsCaps[1] = 0; h10.miscflag = 0; - h10.arraysize = arraysize; h10.miscflags2 = 0; + h9.dwMipMapCount = mips->mipcount; + arraysize = mips->mip[0].depth; switch(mips->type) { case PTI_3D: + arraysize = 1; h9.ddsCaps[1] |= 0x200000; //VOLUME h10.resourcetype = 4; //3d break; - case PTI_CUBEMAP: - case PTI_CUBEMAP_ARRAY: - h9.ddsCaps[1] |= 0x200|0xfc00; //CUBEMAP+faces + case PTI_CUBE_ARRAY: + if (mips->mip[0].depth <= 1) //in dds arraysize=1 is NOT an array, leaving us with an ambiguity issue + return false; + h9.dwDepth = 1; + h10.resourcetype = 3; //2d + h9.ddsCaps[1] |= 0x200|0xfc00; //CUBEMAP+faces + h10.miscflag |= 4;//DDS_RESOURCE_MISC_TEXTURECUBE - otherwise they're basicaly just 2d_arrays + break; + case PTI_CUBE: + if (mips->mip[0].depth != 6) //wut?!? + return false; + h9.dwDepth = 1; + h10.resourcetype = 3; //2d + h9.ddsCaps[1] |= 0x200|0xfc00; //CUBEMAP+faces + h10.miscflag |= 4;//DDS_RESOURCE_MISC_TEXTURECUBE - otherwise they're basicaly just 2d_arrays + break; + case PTI_2D_ARRAY: + if (mips->mip[0].depth <= 1) //in dds arraysize=1 is NOT an array, leaving us with an ambiguity issue + return false; + h9.dwDepth = 1; h10.resourcetype = 3; //2d - h10.miscflag = 4;//DDS_RESOURCE_MISC_TEXTURECUBE - otherwise they're basicaly just 2d_arrays break; case PTI_2D: - case PTI_2D_ARRAY: + if (mips->mip[0].depth != 1) //wut?!? + return false; + h9.dwDepth = 1; h10.resourcetype = 3; //2d break; } + if (h9.dwMipMapCount > 1) + h9.ddsCaps[0] |= 0x400000; //MIPMAP + + h10.arraysize = arraysize; h10.dxgiformat = 0; @@ -5765,7 +5894,7 @@ qboolean Image_WriteDDSFile(const char *filename, enum fs_relative fsroot, struc case PTI_RGBA8: h10.dxgiformat = 28/*DXGI_FORMAT_R8G8B8A8_UNORM*/; break; case PTI_BGRA8_SRGB: h10.dxgiformat = 91/*DXGI_FORMAT_B8G8R8A8_UNORM_SRGB*/; break; case PTI_RGBA8_SRGB: h10.dxgiformat = 29/*DXGI_FORMAT_R8G8B8A8_UNORM_SRGB*/; break; - case PTI_L8: return false; //unsupported + case PTI_L8: return false; //unsupported, should fall back on dx9 formats. case PTI_L8A8: return false; //unsupported case PTI_L8_SRGB: return false; //unsupported case PTI_L8A8_SRGB: return false; //unsupported @@ -5783,7 +5912,7 @@ qboolean Image_WriteDDSFile(const char *filename, enum fs_relative fsroot, struc case PTI_A2BGR10: h10.dxgiformat = 24/*DXGI_FORMAT_R10G10B10A2_UNORM*/; break; case PTI_E5BGR9: h10.dxgiformat = 67/*DXGI_FORMAT_R9G9B9E5_SHAREDEXP*/; break; case PTI_B10G11R11F: h10.dxgiformat = 26/*DXGI_FORMAT_R11G11B10_FLOAT*/; break; - case PTI_P8: + case PTI_P8: return false; //unsupported, technically R8_UNORM but would load back in wrongly. case PTI_R8: h10.dxgiformat = 61/*DXGI_FORMAT_R8_UNORM*/; break; case PTI_RG8: h10.dxgiformat = 49/*DXGI_FORMAT_R8G8_UNORM*/; break; case PTI_R8_SNORM: h10.dxgiformat = 63/*DXGI_FORMAT_R8_SNORM*/; break; @@ -5809,15 +5938,17 @@ qboolean Image_WriteDDSFile(const char *filename, enum fs_relative fsroot, struc case PTI_MAX: return false; -// default: -// return; +#ifndef _DEBUG + default: //don't enable in debug builds, so we get warnings for any cases being missed. + return false; +#endif } //truncate the mip chain if they're dodgy sizes. for (mipnum = 1; mipnum < h9.dwMipMapCount; mipnum++) { - size_t m = mipnum*arraysize; - size_t p = (mipnum-1)*arraysize; + size_t m = mipnum; + size_t p = (mipnum-1); if (mips->mip[m].width != max(1,(mips->mip[p].width)>>1) || mips->mip[m].height != max(1,(mips->mip[p].height)>>1)) { @@ -5836,14 +5967,14 @@ qboolean Image_WriteDDSFile(const char *filename, enum fs_relative fsroot, struc VFS_WRITE(file, &h9, sizeof(h9)); VFS_WRITE(file, &h10, sizeof(h10)); - //our internal state uses a0m0, a1m0, a0m1, a1m1 + //our internal state uses width*height*layers for each mip level (gl-friendly). //DDS requires a0m0, a0m1, a1m0, a1m1, so reorder with two nested loops for (a = 0; a < arraysize; a++) { for (mipnum = 0; mipnum < h9.dwMipMapCount; mipnum++) { - size_t m = a + mipnum*arraysize; - VFS_WRITE(file, mips->mip[m].data, mips->mip[m].datasize); + size_t sz = mips->mip[mipnum].datasize / arraysize; + VFS_WRITE(file, mips->mip[mipnum].data + sz*a, sz); } } @@ -6025,13 +6156,13 @@ static struct pendingtextureinfo *Image_ReadBLPFile(unsigned int flags, const ch //many of these look like dupes, not really sure how they're meant to work. probably legacy. typedef enum { VMF_INVALID=-1, -// VMF_RGBA8=0, + VMF_RGBA8=0, // VMF_ABGR8=1, VMF_RGB8=2, VMF_BGR8=3, // VMF_RGB565=4, -// VMF_I8=5, -// VMF_IA8=6, + VMF_I8=5, + VMF_IA8=6, // VMF_P8=7, // VMF_A8=8, // VMF_RGB8_BS=9, @@ -6068,6 +6199,8 @@ static uploadfmt_t ImageVTF_VtfToFTE(fmtfmt_t f) return PTI_BC3_RGBA; case VMF_RGB8: return PTI_RGB8; + case VMF_RGBA8: + return PTI_RGBA8; case VMF_BGR8: return PTI_BGR8; case VMF_BGRA8: @@ -6078,6 +6211,10 @@ static uploadfmt_t ImageVTF_VtfToFTE(fmtfmt_t f) return PTI_RGBA16F; case VMF_UV88: return PTI_RG8; + case VMF_I8: + return PTI_L8; + case VMF_IA8: + return PTI_L8A8; case VMF_INVALID: return PTI_INVALID; @@ -6180,23 +6317,23 @@ static struct pendingtextureinfo *Image_ReadVTFFile(unsigned int flags, const ch //now handle the high-res image if (mips) { - mips->type = (vtf->flags & 0x4000)?PTI_CUBEMAP:PTI_2D; + mips->type = (vtf->flags & 0x4000)?PTI_CUBE:PTI_2D; mips->encoding = ImageVTF_VtfToFTE(vmffmt); Image_BlockSizeForEncoding(mips->encoding, &bb, &bw, &bh); miplevels = vtf->mipmapcount; frames = 1;//vtf->numframes; - faces = ((mips->type==PTI_CUBEMAP)?6:1); //no cubemaps yet. + faces = ((mips->type==PTI_CUBE)?6:1); //no cubemaps yet. - mips->mipcount = miplevels * frames * faces; + mips->mipcount = miplevels * frames; while (mips->mipcount > countof(mips->mip)) { if (miplevels > 1) miplevels--; else frames--; - mips->mipcount = miplevels * frames * faces; + mips->mipcount = miplevels * frames; } if (!mips->mipcount) { @@ -6214,23 +6351,20 @@ static struct pendingtextureinfo *Image_ReadVTFFile(unsigned int flags, const ch datasize = ((w+bw-1)/bw) * ((h+bh-1)/bh) * bb; for (frame = 0; frame < vtf->numframes; frame++) { - for (face = 0; face < faces; face++) + if (miplevel < miplevels) { - if (miplevel < miplevels && face < faces) - { - img = face+miplevel*faces + frame*miplevels*faces; - if (img >= countof(mips->mip)) - break; //erk? - if (filedata + datasize > end) - break; //no more data here... - mips->mip[img].width = w; - mips->mip[img].height = h; - mips->mip[img].depth = 1; - mips->mip[img].data = filedata; - mips->mip[img].datasize = datasize; - } - filedata += datasize; + img = miplevel + frame*miplevels; + if (img >= countof(mips->mip)) + break; //erk? + if (filedata + datasize > end) + break; //no more data here... + mips->mip[img].width = w; + mips->mip[img].height = h; + mips->mip[img].depth = faces; + mips->mip[img].data = filedata; + mips->mip[img].datasize = datasize*faces; } + filedata += datasize*faces; } } } @@ -7569,9 +7703,7 @@ static void Image_Tr_8888toLuminence(struct pendingtextureinfo *mips, int channe qbyte l, a; qbyte *in = mips->mip[mip].data; qbyte *out = mips->mip[mip].data; - unsigned int w = mips->mip[mip].width; - unsigned int h = mips->mip[mip].height; - unsigned int p = w*h; + unsigned int p = mips->mip[mip].width*mips->mip[mip].height*mips->mip[mip].depth; unsigned short tmp; if (!mips->mip[mip].needfree && !mips->extrafree) { @@ -7599,9 +7731,7 @@ static void Image_Tr_8888to565(struct pendingtextureinfo *mips, int bgra) { qbyte *in = mips->mip[mip].data; unsigned short *out = mips->mip[mip].data; - unsigned int w = mips->mip[mip].width; - unsigned int h = mips->mip[mip].height; - unsigned int p = w*h; + unsigned int p = mips->mip[mip].width*mips->mip[mip].height*mips->mip[mip].depth; unsigned short tmp; if (!mips->mip[mip].needfree && !mips->extrafree) { @@ -7642,9 +7772,7 @@ static void Image_Tr_8888to1555(struct pendingtextureinfo *mips, int bgra) { qbyte *in = mips->mip[mip].data; unsigned short *out = mips->mip[mip].data; - unsigned int w = mips->mip[mip].width; - unsigned int h = mips->mip[mip].height; - unsigned int p = w*h; + unsigned int p = mips->mip[mip].width*mips->mip[mip].height*mips->mip[mip].depth; unsigned short tmp; if (!mips->mip[mip].needfree && !mips->extrafree) { @@ -7685,9 +7813,7 @@ static void Image_Tr_8888to5551(struct pendingtextureinfo *mips, int bgra) { qbyte *in = mips->mip[mip].data; unsigned short *out = mips->mip[mip].data; - unsigned int w = mips->mip[mip].width; - unsigned int h = mips->mip[mip].height; - unsigned int p = w*h; + unsigned int p = mips->mip[mip].width*mips->mip[mip].height*mips->mip[mip].depth; unsigned short tmp; if (!mips->mip[mip].needfree && !mips->extrafree) { @@ -7728,9 +7854,7 @@ static void Image_Tr_8888to4444(struct pendingtextureinfo *mips, int bgra) { qbyte *in = mips->mip[mip].data; unsigned short *out = mips->mip[mip].data; - unsigned int w = mips->mip[mip].width; - unsigned int h = mips->mip[mip].height; - unsigned int p = w*h; + unsigned int p = mips->mip[mip].width*mips->mip[mip].height*mips->mip[mip].depth; unsigned short tmp; if (!mips->mip[mip].needfree && !mips->extrafree) { @@ -7771,9 +7895,7 @@ static void Image_Tr_8888toARGB4444(struct pendingtextureinfo *mips, int bgra) { qbyte *in = mips->mip[mip].data; unsigned short *out = mips->mip[mip].data; - unsigned int w = mips->mip[mip].width; - unsigned int h = mips->mip[mip].height; - unsigned int p = w*h; + unsigned int p = mips->mip[mip].width*mips->mip[mip].height*mips->mip[mip].depth; unsigned short tmp; if (!mips->mip[mip].needfree && !mips->extrafree) { @@ -7814,9 +7936,7 @@ static void Image_Tr_4X16to8888(struct pendingtextureinfo *mips, int unused) { unsigned short *in = mips->mip[mip].data; qbyte *out = mips->mip[mip].data; - unsigned int w = mips->mip[mip].width; - unsigned int h = mips->mip[mip].height; - unsigned int p = w*h*4; + unsigned int p = mips->mip[mip].width*mips->mip[mip].height*mips->mip[mip].depth*4; if (!mips->mip[mip].needfree && !mips->extrafree) { mips->mip[mip].needfree = true; @@ -7839,9 +7959,7 @@ static void Image_Tr_E5BGR9ToByte(struct pendingtextureinfo *mips, int bgr) { unsigned int *in = mips->mip[mip].data; qbyte *out = mips->mip[mip].data; - unsigned int w = mips->mip[mip].width; - unsigned int h = mips->mip[mip].height; - unsigned int p = w*h; + unsigned int p = mips->mip[mip].width*mips->mip[mip].height*mips->mip[mip].depth; if (!mips->mip[mip].needfree && !mips->extrafree) { mips->mip[mip].needfree = true; @@ -7868,9 +7986,7 @@ static void Image_Tr_E5BGR9ToFloat(struct pendingtextureinfo *mips, int dummy) { unsigned int *in = mips->mip[mip].data; float *out = mips->mip[mip].data; - unsigned int w = mips->mip[mip].width; - unsigned int h = mips->mip[mip].height; - unsigned int p = w*h; + unsigned int p = mips->mip[mip].width*mips->mip[mip].height*mips->mip[mip].depth; if (!mips->mip[mip].needfree && !mips->extrafree) { mips->mip[mip].needfree = true; @@ -7898,9 +8014,7 @@ static void Image_Tr_FloatToE5BGR9(struct pendingtextureinfo *mips, int dummy) float *in = mips->mip[mip].data; unsigned int *out = mips->mip[mip].data; float *dofree = mips->mip[mip].needfree?in:NULL; - unsigned int w = mips->mip[mip].width; - unsigned int h = mips->mip[mip].height; - unsigned int p = w*h; + unsigned int p = mips->mip[mip].width*mips->mip[mip].height*mips->mip[mip].depth; mips->mip[mip].needfree = true; mips->mip[mip].data = out = BZ_Malloc(sizeof(*out)*p); mips->mip[mip].datasize = p*sizeof(*out); @@ -7937,9 +8051,7 @@ static void Image_Tr_PackedToFloat(struct pendingtextureinfo *mips, int dummy) unsigned int *in = mips->mip[mip].data; float *out = mips->mip[mip].data; void *dofree = mips->mip[mip].needfree?in:NULL; - unsigned int w = mips->mip[mip].width; - unsigned int h = mips->mip[mip].height; - unsigned int p = w*h; + unsigned int p = mips->mip[mip].width*mips->mip[mip].height*mips->mip[mip].depth; mips->mip[mip].needfree = true; mips->mip[mip].data = out = BZ_Malloc(sizeof(*out)*p*4); mips->mip[mip].datasize = p*sizeof(*out)*4; @@ -7963,9 +8075,7 @@ static void Image_Tr_FloatToPacked(struct pendingtextureinfo *mips, int dummy) float *in = mips->mip[mip].data; unsigned int *out = mips->mip[mip].data; float *dofree = mips->mip[mip].needfree?in:NULL; - unsigned int w = mips->mip[mip].width; - unsigned int h = mips->mip[mip].height; - unsigned int p = w*h; + unsigned int p = mips->mip[mip].width*mips->mip[mip].height*mips->mip[mip].depth; mips->mip[mip].needfree = true; mips->mip[mip].data = out = BZ_Malloc(sizeof(*out)*p); mips->mip[mip].datasize = p*sizeof(*out); @@ -7989,9 +8099,7 @@ static void Image_Tr_HalfToByte(struct pendingtextureinfo *mips, int channels) int v; unsigned short *in = mips->mip[mip].data; qbyte *out = mips->mip[mip].data; - unsigned int w = mips->mip[mip].width; - unsigned int h = mips->mip[mip].height; - unsigned int p = w*h*abs(channels); + unsigned int p = mips->mip[mip].width*mips->mip[mip].height*mips->mip[mip].depth*abs(channels); if (!mips->mip[mip].needfree && !mips->extrafree) { mips->mip[mip].needfree = true; @@ -8033,9 +8141,7 @@ static void Image_Tr_RGB32FToFloat(struct pendingtextureinfo *mips, int dummy) float *in = mips->mip[mip].data; float *out = mips->mip[mip].data; float *dofree = mips->mip[mip].needfree?in:NULL; - unsigned int w = mips->mip[mip].width; - unsigned int h = mips->mip[mip].height; - unsigned int p = w*h; + unsigned int p = mips->mip[mip].width*mips->mip[mip].height*mips->mip[mip].depth; mips->mip[mip].needfree = true; mips->mip[mip].data = out = BZ_Malloc(sizeof(*out)*p*4); mips->mip[mip].datasize = p*sizeof(*out)*4; @@ -8059,9 +8165,7 @@ static void Image_Tr_HalfToFloat(struct pendingtextureinfo *mips, int channels) float *in = mips->mip[mip].data; float *out = mips->mip[mip].data; float *dofree = mips->mip[mip].needfree?in:NULL; - unsigned int w = mips->mip[mip].width; - unsigned int h = mips->mip[mip].height; - unsigned int p = w*h; + unsigned int p = mips->mip[mip].width*mips->mip[mip].height*mips->mip[mip].depth; mips->mip[mip].needfree = true; mips->mip[mip].data = out = BZ_Malloc(sizeof(*out)*p*4); mips->mip[mip].datasize = p*sizeof(*out)*4; @@ -8079,9 +8183,7 @@ static void Image_Tr_FloatToHalf(struct pendingtextureinfo *mips, int channels) { float *in = mips->mip[mip].data; unsigned short *out = mips->mip[mip].data; - unsigned int w = mips->mip[mip].width; - unsigned int h = mips->mip[mip].height; - unsigned int p = w*h*channels; + unsigned int p = mips->mip[mip].width*mips->mip[mip].height*mips->mip[mip].depth*channels; if (!mips->mip[mip].needfree && !mips->extrafree) { mips->mip[mip].needfree = true; @@ -8104,9 +8206,7 @@ static void Image_Tr_FloatToByte(struct pendingtextureinfo *mips, int channels) int v; float *in = mips->mip[mip].data; qbyte *out = mips->mip[mip].data; - unsigned int w = mips->mip[mip].width; - unsigned int h = mips->mip[mip].height; - unsigned int p = w*h*abs(channels); + unsigned int p = mips->mip[mip].width*mips->mip[mip].height*mips->mip[mip].depth*abs(channels); if (!mips->mip[mip].needfree && !mips->extrafree) { mips->mip[mip].needfree = true; @@ -8149,9 +8249,7 @@ static void Image_Tr_DropBytes(struct pendingtextureinfo *mips, int srcbitsdstbi { qbyte *in = mips->mip[mip].data; qbyte *out = mips->mip[mip].data; - unsigned int w = mips->mip[mip].width; - unsigned int h = mips->mip[mip].height; - unsigned int p = w*h; + unsigned int p = mips->mip[mip].width*mips->mip[mip].height*mips->mip[mip].depth; if (!mips->mip[mip].needfree && !mips->extrafree) { mips->mip[mip].needfree = true; @@ -8176,9 +8274,7 @@ static void Image_Tr_RG8ToRGXX8(struct pendingtextureinfo *mips, int dummy) qbyte *in = mips->mip[mip].data; qbyte *out = mips->mip[mip].data; void *dofree = mips->mip[mip].needfree?in:NULL; - unsigned int w = mips->mip[mip].width; - unsigned int h = mips->mip[mip].height; - unsigned int p = w*h; + unsigned int p = mips->mip[mip].width*mips->mip[mip].height*mips->mip[mip].depth; mips->mip[mip].needfree = true; mips->mip[mip].data = out = BZ_Malloc(sizeof(*out)*p*4); mips->mip[mip].datasize = p*sizeof(*out)*4; @@ -8201,9 +8297,7 @@ static void Image_Tr_8To10(struct pendingtextureinfo *mips, int dummy) { qbyte *in = mips->mip[mip].data; unsigned int *out = mips->mip[mip].data; - unsigned int w = mips->mip[mip].width; - unsigned int h = mips->mip[mip].height; - unsigned int p = w*h; + unsigned int p = mips->mip[mip].width*mips->mip[mip].height*mips->mip[mip].depth; if (!mips->mip[mip].needfree && !mips->extrafree) { mips->mip[mip].needfree = true; @@ -8228,9 +8322,7 @@ static void Image_Tr_10To8(struct pendingtextureinfo *mips, int dummy) { unsigned int *in = mips->mip[mip].data, v; qbyte *out = mips->mip[mip].data; - unsigned int w = mips->mip[mip].width; - unsigned int h = mips->mip[mip].height; - unsigned int p = w*h; + unsigned int p = mips->mip[mip].width*mips->mip[mip].height*mips->mip[mip].depth; if (!mips->mip[mip].needfree && !mips->extrafree) { mips->mip[mip].needfree = true; @@ -8258,9 +8350,7 @@ static void Image_Tr_Swap8888(struct pendingtextureinfo *mips, int dummy) qbyte rb, g, br, a; qbyte *in = mips->mip[mip].data; qbyte *out = mips->mip[mip].data; - unsigned int w = mips->mip[mip].width; - unsigned int h = mips->mip[mip].height; - unsigned int p = w*h; + unsigned int p = mips->mip[mip].width*mips->mip[mip].height*mips->mip[mip].depth; if (!mips->mip[mip].needfree && !mips->extrafree) { mips->mip[mip].needfree = true; @@ -10187,14 +10277,14 @@ const char *Image_FormatName(uploadfmt_t fmt) return "Unknown"; } -static pixel32_t *Image_Block_Decode(qbyte *fte_restrict in, size_t insize, int w, int h, void(*decodeblock)(qbyte *fte_restrict in, pixel32_t *fte_restrict out, int w, uploadfmt_t srcfmt), uploadfmt_t encoding) +static pixel32_t *Image_Block_Decode(qbyte *fte_restrict in, size_t insize, int w, int h, int d, void(*decodeblock)(qbyte *fte_restrict in, pixel32_t *fte_restrict out, int w, uploadfmt_t srcfmt), uploadfmt_t encoding) { #define TMPBLOCKSIZE 16u pixel32_t *ret, *out; pixel32_t tmp[TMPBLOCKSIZE*TMPBLOCKSIZE]; - int x, y, i, j; + int x, y, z, i, j; int sizediff; - int rows, columns; + int rows, columns, layers; unsigned int blockbytes, blockwidth, blockheight; Image_BlockSizeForEncoding(encoding, &blockbytes, &blockwidth, &blockheight); @@ -10202,7 +10292,7 @@ static pixel32_t *Image_Block_Decode(qbyte *fte_restrict in, size_t insize, int if (blockwidth > TMPBLOCKSIZE || blockheight > TMPBLOCKSIZE) Sys_Error("Image_Block_Decode only supports up to %u*%u blocks.\n", TMPBLOCKSIZE,TMPBLOCKSIZE); - sizediff = insize - blockbytes*((w+blockwidth-1)/blockwidth)*((h+blockheight-1)/blockheight); + sizediff = insize - blockbytes*((w+blockwidth-1)/blockwidth)*((h+blockheight-1)/blockheight)*d; if (sizediff) { Con_Printf("Image_Block_Decode: %s data size is %u, expected %u\n\n", Image_FormatName(encoding), (unsigned int)insize, (unsigned int)(insize-sizediff)); @@ -10210,56 +10300,60 @@ static pixel32_t *Image_Block_Decode(qbyte *fte_restrict in, size_t insize, int return NULL; } - ret = out = BZ_Malloc(w*h*sizeof(*out)); + ret = out = BZ_Malloc(w*h*d*sizeof(*out)); rows = h/blockheight; rows *= blockheight; columns = w/blockwidth; columns *= blockwidth; - for (y = 0; y < rows; y+=blockheight, out += w*(blockheight-1)) + layers = d; + for (z = 0; z < layers; z++) { - for (x = 0; x < columns; x+=blockwidth, in+=blockbytes, out+=blockwidth) - decodeblock(in, out, w, encoding); - if (w%blockwidth) + for (y = 0; y < rows; y+=blockheight, out += w*(blockheight-1)) { - decodeblock(in, tmp, TMPBLOCKSIZE, encoding); - for (i = 0; x < w; x++, out++, i++) + for (x = 0; x < columns; x+=blockwidth, in+=blockbytes, out+=blockwidth) + decodeblock(in, out, w, encoding); + if (w%blockwidth) { - for (j = 0; j < blockheight; j++) - out[w*j] = tmp[i+TMPBLOCKSIZE*j]; + decodeblock(in, tmp, TMPBLOCKSIZE, encoding); + for (i = 0; x < w; x++, out++, i++) + { + for (j = 0; j < blockheight; j++) + out[w*j] = tmp[i+TMPBLOCKSIZE*j]; + } + in+=blockbytes; } - in+=blockbytes; } - } - if (h%blockheight) - { //now walk along the bottom of the image - h %= blockheight; - for (x = 0; x < w; ) - { - decodeblock(in, tmp, TMPBLOCKSIZE, encoding); - i = 0; - do + if (h%blockheight) + { //now walk along the bottom of the image + h %= blockheight; + for (x = 0; x < w; ) { - if (x == w) - break; - for (y = 0; y < h; y++) - out[w*y] = tmp[i+TMPBLOCKSIZE*y]; - out++; - i++; - } while (++x % blockwidth); - in+=blockbytes; + decodeblock(in, tmp, TMPBLOCKSIZE, encoding); + i = 0; + do + { + if (x == w) + break; + for (y = 0; y < h; y++) + out[w*y] = tmp[i+TMPBLOCKSIZE*y]; + out++; + i++; + } while (++x % blockwidth); + in+=blockbytes; + } } } return ret; } -static pixel64_t *Image_Block_Decode64(qbyte *fte_restrict in, size_t insize, int w, int h, void(*decodeblock)(qbyte *fte_restrict in, pixel64_t *fte_restrict out, int w, uploadfmt_t srcfmt), uploadfmt_t encoding) +static pixel64_t *Image_Block_Decode64(qbyte *fte_restrict in, size_t insize, int w, int h, int d, void(*decodeblock)(qbyte *fte_restrict in, pixel64_t *fte_restrict out, int w, uploadfmt_t srcfmt), uploadfmt_t encoding) { #define TMPBLOCKSIZE 16u pixel64_t *ret, *out; pixel64_t tmp[TMPBLOCKSIZE*TMPBLOCKSIZE]; - int x, y, i, j; + int x, y, z, i, j; int sizediff; - int rows, columns; + int rows, columns, layers; unsigned int blockbytes, blockwidth, blockheight; Image_BlockSizeForEncoding(encoding, &blockbytes, &blockwidth, &blockheight); @@ -10267,7 +10361,7 @@ static pixel64_t *Image_Block_Decode64(qbyte *fte_restrict in, size_t insize, in if (blockwidth > TMPBLOCKSIZE || blockheight > TMPBLOCKSIZE) Sys_Error("Image_Block_Decode only supports up to %u*%u blocks.\n", TMPBLOCKSIZE,TMPBLOCKSIZE); - sizediff = insize - blockbytes*((w+blockwidth-1)/blockwidth)*((h+blockheight-1)/blockheight); + sizediff = insize - blockbytes*((w+blockwidth-1)/blockwidth)*((h+blockheight-1)/blockheight)*d; if (sizediff) { Con_Printf("Image_Block_Decode: %s data size is %u, expected %u\n\n", Image_FormatName(encoding), (unsigned int)insize, (unsigned int)(insize-sizediff)); @@ -10275,44 +10369,48 @@ static pixel64_t *Image_Block_Decode64(qbyte *fte_restrict in, size_t insize, in return NULL; } - ret = out = BZ_Malloc(w*h*sizeof(*out)); + ret = out = BZ_Malloc(w*h*d*sizeof(*out)); rows = h/blockheight; rows *= blockheight; columns = w/blockwidth; columns *= blockwidth; - for (y = 0; y < rows; y+=blockheight, out += w*(blockheight-1)) + layers = d; + for (z = 0; z < layers; z++) { - for (x = 0; x < columns; x+=blockwidth, in+=blockbytes, out+=blockwidth) - decodeblock(in, out, w, encoding); - if (w%blockwidth) + for (y = 0; y < rows; y+=blockheight, out += w*(blockheight-1)) { - decodeblock(in, tmp, TMPBLOCKSIZE, encoding); - for (i = 0; x < w; x++, out++, i++) + for (x = 0; x < columns; x+=blockwidth, in+=blockbytes, out+=blockwidth) + decodeblock(in, out, w, encoding); + if (w%blockwidth) { - for (j = 0; j < blockheight; j++) - out[w*j] = tmp[i+TMPBLOCKSIZE*j]; + decodeblock(in, tmp, TMPBLOCKSIZE, encoding); + for (i = 0; x < w; x++, out++, i++) + { + for (j = 0; j < blockheight; j++) + out[w*j] = tmp[i+TMPBLOCKSIZE*j]; + } + in+=blockbytes; } - in+=blockbytes; } - } - if (h%blockheight) - { //now walk along the bottom of the image - h %= blockheight; - for (x = 0; x < w; ) - { - decodeblock(in, tmp, TMPBLOCKSIZE, encoding); - i = 0; - do + if (h%blockheight) + { //now walk along the bottom of the image + h %= blockheight; + for (x = 0; x < w; ) { - if (x == w) - break; - for (y = 0; y < h; y++) - out[w*y] = tmp[i+TMPBLOCKSIZE*y]; - out++; - i++; - } while (++x % blockwidth); - in+=blockbytes; + decodeblock(in, tmp, TMPBLOCKSIZE, encoding); + i = 0; + do + { + if (x == w) + break; + for (y = 0; y < h; y++) + out[w*y] = tmp[i+TMPBLOCKSIZE*y]; + out++; + i++; + } while (++x % blockwidth); + in+=blockbytes; + } } } return ret; @@ -10562,12 +10660,12 @@ static qboolean Image_DecompressFormat(struct pendingtextureinfo *mips, const ch if (decodefunc64) { sz = sizeof(pixel64_t); - out = Image_Block_Decode64(mips->mip[mip].data, mips->mip[mip].datasize, mips->mip[mip].width, mips->mip[mip].height, decodefunc64, mips->encoding); + out = Image_Block_Decode64(mips->mip[mip].data, mips->mip[mip].datasize, mips->mip[mip].width, mips->mip[mip].height, mips->mip[mip].depth, decodefunc64, mips->encoding); } else { sz = sizeof(pixel32_t); - out = Image_Block_Decode(mips->mip[mip].data, mips->mip[mip].datasize, mips->mip[mip].width, mips->mip[mip].height, decodefunc, mips->encoding); + out = Image_Block_Decode(mips->mip[mip].data, mips->mip[mip].datasize, mips->mip[mip].width, mips->mip[mip].height, mips->mip[mip].depth, decodefunc, mips->encoding); } if (mips->mip[mip].needfree) BZ_Free(mips->mip[mip].data); @@ -10680,9 +10778,6 @@ void Image_ChangeFormat(struct pendingtextureinfo *mips, unsigned int flags, upl { int mip; - if (mips->type != PTI_2D) - return; //blurgh - if (flags & IF_PALETTIZE) { Image_DecompressFormat(mips, NULL); //force-decompress it, so that we can palettise it. @@ -11852,7 +11947,7 @@ struct pendingtextureinfo *Image_LoadMipsFromMemory(int flags, const char *iname } mips = Z_Malloc(sizeof(*mips)); - mips->type = (flags & IF_3DMAP)?PTI_3D:PTI_2D; + mips->type = (flags & IF_TEXTYPEMASK)>>IF_TEXTYPESHIFT; if (Image_GenMip0(mips, flags, rgbadata, NULL, imgwidth, imgheight, format, true)) { Image_GenerateMips(mips, flags); @@ -11867,7 +11962,7 @@ struct pendingtextureinfo *Image_LoadMipsFromMemory(int flags, const char *iname { struct pendingtextureinfo *mips; mips = Z_Malloc(sizeof(*mips)); - mips->type = (flags & IF_3DMAP)?PTI_3D:PTI_2D; + mips->type = (flags & IF_TEXTYPEMASK)>>IF_TEXTYPESHIFT; mips->mipcount = 1; mips->encoding = PTI_WHOLEFILE; mips->extrafree = NULL; @@ -11888,6 +11983,67 @@ struct pendingtextureinfo *Image_LoadMipsFromMemory(int flags, const char *iname return NULL; } +void *Image_FlipImage(const void *inbuffer, void *outbuffer, int *inoutwidth, int *inoutheight, int pixelbytes, qboolean flipx, qboolean flipy, qboolean flipd) +{ + int x, y, b; + qbyte *outb; + const qbyte *inb, *inr; + int inwidth = *inoutwidth; + int inheight = *inoutheight; + int rowstride = inwidth; + int colstride = 1; + + //simply return if no operation + if (!flipx && !flipy && !flipd) + memcpy(outbuffer, inbuffer, inwidth*inheight*pixelbytes); + else + { + inr = inbuffer; + outb = outbuffer; + + if (flipy) + { + inr += (inwidth*inheight-inwidth)*pixelbytes;//start on the bottom row + rowstride *= -1; //and we need to move up instead + } + if (flipx) + { + colstride *= -1; //move backwards + inr += (inwidth-1)*pixelbytes; //start at the end of the row + } + if (flipd) + { + //switch the dimensions + int tmp = inwidth; + inwidth = inheight; + inheight = tmp; + //make sure the caller gets the new dimensions + *inoutwidth = inwidth; + *inoutheight = inheight; + //switch the strides + tmp = colstride; + colstride = rowstride; + rowstride = tmp; + } + + colstride *= pixelbytes; + rowstride *= pixelbytes; + + //rows->rows, columns->columns + for (y = 0; y < inheight; y++) + { + inb = inr; //reset the input after each row, so we have truely independant row+column strides + inr += rowstride; + for (x = 0; x < inheight; x++) + { + for (b = 0; b < pixelbytes; b++) + *outb++ = inb[b]; + inb += colstride; + } + } + } + return outbuffer; +} #if !defined(NPFTE) && !defined(IMGTOOL) static int tex_extensions_count; #define tex_extensions_max 15 @@ -11915,62 +12071,6 @@ static void QDECL R_ImageExtensions_Callback(struct cvar_s *var, char *oldvalue) tex_extensions_count++; } } -static void *R_FlipImage32(void *in, int *inoutwidth, int *inoutheight, qboolean flipx, qboolean flipy, qboolean flipd) -{ - int x, y; - unsigned int *in32, *inr, *out32; - void *out; - int inwidth = *inoutwidth; - int inheight = *inoutheight; - int rowstride = inwidth; - int colstride = 1; - - //simply return if no operation - if (!flipx && !flipy && !flipd) - return in; - - inr = in; - out32 = out = BZ_Malloc(inwidth*inheight*4); - - if (flipy) - { - inr += inwidth*inheight-inwidth;//start on the bottom row - rowstride *= -1; //and we need to move up instead - } - if (flipx) - { - colstride *= -1; //move backwards - inr += inwidth-1; //start at the end of the row - } - if (flipd) - { - //switch the dimensions - int tmp = inwidth; - inwidth = inheight; - inheight = tmp; - //make sure the caller gets the new dimensions - *inoutwidth = inwidth; - *inoutheight = inheight; - //switch the strides - tmp = colstride; - colstride = rowstride; - rowstride = tmp; - } - - //rows->rows, columns->columns - for (y = 0; y < inheight; y++) - { - in32 = inr; //reset the input after each row, so we have truely independant row+column strides - inr += rowstride; - for (x = 0; x < inheight; x++) - { - *out32++ = *in32; - in32 += colstride; - } - } - BZ_Free(in); - return out; -} static struct pendingtextureinfo *Image_LoadCubemapTextureData(const char *nicename, char *subpath, unsigned int texflags) { static struct @@ -12008,18 +12108,13 @@ static struct pendingtextureinfo *Image_LoadCubemapTextureData(const char *nicen } }; int i, j, e; - struct pendingtextureinfo *mips; + struct pendingtextureinfo *mips = NULL; char fname[MAX_QPATH]; size_t filesize; int width, height; uploadfmt_t format; char *nextprefix, *prefixend; size_t prefixlen; - mips = Z_Malloc(sizeof(*mips)); - mips->type = PTI_CUBEMAP; - mips->mipcount = 6; - mips->encoding = PTI_RGBA8; - mips->extrafree = NULL; for (i = 0; i < 6; i++) { @@ -12050,23 +12145,35 @@ static struct pendingtextureinfo *Image_LoadCubemapTextureData(const char *nicen if (buf) { qboolean needsflipping = cmscheme[j][i].flipx||cmscheme[j][i].flipy||cmscheme[j][i].flipd; - if ((data = ReadRawImageFile(buf, filesize, &width, &height, &format, needsflipping, fname))) + if ((data = ReadRawImageFile(buf, filesize, &width, &height, &format, true, fname))) { extern cvar_t vid_hardwaregamma; int bb,bw,bh; Image_BlockSizeForEncoding(format, &bb, &bw, &bh); if (needsflipping && (bb!=4 || bw!=1 || bh!=1)) ; - else if (width == height && (!i || width == mips->mip[0].width)) //cubemaps must be square and all the same size (npot is fine though) + else if (width == height && (!mips || width == mips->mip[0].width)) //cubemaps must be square and all the same size (npot is fine though) { //(skies have a fallback for invalid sizes, but it'll run a bit slower) + + if (!mips) + { + mips = Z_Malloc(sizeof(*mips)); + mips->type = PTI_CUBE; + mips->mipcount = 1; + mips->encoding = PTI_RGBA8; + mips->extrafree = NULL; + mips->mip[0].datasize = width*height*4*6; + mips->mip[0].data = BZ_Malloc(mips->mip[0].datasize); + mips->mip[0].width = width; + mips->mip[0].height = height; + mips->mip[0].depth = 6;; + mips->mip[0].needfree = true; + } + if (!(texflags&IF_NOGAMMA) && !vid_hardwaregamma.value) BoostGamma(data, width, height, format); - mips->mip[i].data = R_FlipImage32(data, &width, &height, cmscheme[j][i].flipx, cmscheme[j][i].flipy, cmscheme[j][i].flipd); - mips->mip[i].datasize = (width+(bw-1))/bw * (height+(bh-1))/bh * bb; - mips->mip[i].width = width; - mips->mip[i].height = height; - mips->mip[i].depth = 1; - mips->mip[i].needfree = true; + Image_FlipImage(data, mips->mip[0].data + i*width*height*bb, &width, &height, bb, cmscheme[j][i].flipx, cmscheme[j][i].flipy, cmscheme[j][i].flipd); + BZ_Free(data); BZ_Free(buf); goto nextface; @@ -12109,7 +12216,7 @@ static qboolean Image_LoadRawTexture(texid_t tex, unsigned int flags, void *rawd { struct pendingtextureinfo *mips; mips = Z_Malloc(sizeof(*mips)); - mips->type = (flags&IF_TEXTYPE)>>IF_TEXTYPESHIFT; + mips->type = (flags&IF_TEXTYPEMASK)>>IF_TEXTYPESHIFT; if (!Image_GenMip0(mips, flags, rawdata, palettedata, imgwidth, imgheight, fmt, true)) { @@ -12408,10 +12515,12 @@ static void Image_LoadHiResTextureWorker(void *ctx, void *data, size_t a, size_t int imgwidth; int imgheight; uploadfmt_t format; + int ttype = (tex->flags & IF_TEXTYPEMASK)>>IF_TEXTYPESHIFT; - if ((tex->flags & IF_TEXTYPE) == IF_CUBEMAP) + if (ttype == PTI_CUBE) { //cubemaps require special handling because they are (normally) 6 files instead of 1. - //the exception is single-file dds cubemaps, but we don't support those. + //the exception is single-file dds/ktx/etc cubemaps. + //FIXME: handle via Image_LocateHighResTexture. for(altname = tex->ident;altname;altname = nextalt) { struct pendingtextureinfo *mips = NULL; @@ -12865,7 +12974,7 @@ void Image_Upload (texid_t tex, uploadfmt_t fmt, void *data, void *palette, in return; mips.extrafree = NULL; - mips.type = (flags & IF_3DMAP)?PTI_3D:PTI_2D; + mips.type = (flags&IF_TEXTYPEMASK)>>IF_TEXTYPESHIFT; if (!Image_GenMip0(&mips, flags, data, palette, width, height, fmt, false)) return; Image_GenerateMips(&mips, flags); @@ -13203,7 +13312,7 @@ void R_LoadNumberedLightTexture(dlight_t *dl, int cubetexnum) if (!gl_load24bit.ival) dl->cubetexture = r_nulltex; else - dl->cubetexture = Image_GetTexture(dl->cubemapname, NULL, IF_CUBEMAP, NULL, NULL, 0, 0, TF_INVALID); + dl->cubetexture = Image_GetTexture(dl->cubemapname, NULL, IF_TEXTYPE_CUBE, NULL, NULL, 0, 0, TF_INVALID); } #endif diff --git a/engine/client/m_download.c b/engine/client/m_download.c index b5f1f113..cf2b1150 100644 --- a/engine/client/m_download.c +++ b/engine/client/m_download.c @@ -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; } diff --git a/engine/client/merged.h b/engine/client/merged.h index 05ccb39b..24389f96 100644 --- a/engine/client/merged.h +++ b/engine/client/merged.h @@ -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 diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index f230f020..8fd00290 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -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; diff --git a/engine/client/render.h b/engine/client/render.h index 83406fb4..f074de0c 100644 --- a/engine/client/render.h +++ b/engine/client/render.h @@ -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<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. } diff --git a/engine/common/gl_q2bsp.c b/engine/common/gl_q2bsp.c index 48a17249..b4482ace 100644 --- a/engine/common/gl_q2bsp.c +++ b/engine/common/gl_q2bsp.c @@ -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; diff --git a/engine/common/net_ssl_gnutls.c b/engine/common/net_ssl_gnutls.c index f6d1f3d0..a3499cb5 100644 --- a/engine/common/net_ssl_gnutls.c +++ b/engine/common/net_ssl_gnutls.c @@ -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}, }; diff --git a/engine/common/net_ssl_winsspi.c b/engine/common/net_ssl_winsspi.c index c601e65c..eab9f2da 100644 --- a/engine/common/net_ssl_winsspi.c +++ b/engine/common/net_ssl_winsspi.c @@ -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} }; diff --git a/engine/common/plugin.c b/engine/common/plugin.c index de10c704..ff3b1882 100644 --- a/engine/common/plugin.c +++ b/engine/common/plugin.c @@ -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,7 +1686,10 @@ 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++) diff --git a/engine/common/q1bsp.c b/engine/common/q1bsp.c index 55a089cc..a26c99e0 100644 --- a/engine/common/q1bsp.c +++ b/engine/common/q1bsp.c @@ -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); } diff --git a/engine/d3d/d3d11_image.c b/engine/d3d/d3d11_image.c index 0a47baab..8a77ab81 100644 --- a/engine/d3d/d3d11_image.c +++ b/engine/d3d/d3d11_image.c @@ -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 { - for (i = 0; i < mips->mipcount; i++) + subresdesc = alloca(tdesc.ArraySize*mips->mipcount); + for (layer = 0; layer < tdesc.ArraySize; layer++) { - 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; + for (i = 0; i < mips->mipcount; i++) + { + 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; diff --git a/engine/d3d/d3d_image.c b/engine/d3d/d3d_image.c index 481ece5d..35945c81 100644 --- a/engine/d3d/d3d_image.c +++ b/engine/d3d/d3d_image.c @@ -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,39 +123,42 @@ 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) - { //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 (x = 0; x < rowbytes; x+=4) + 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; y < mips->mip[i].height; y+=blockheight, out += lock.Pitch, in += rowbytes) { - out[x+0] = in[x+2]; - out[x+1] = in[x+1]; - out[x+2] = in[x+0]; - out[x+3] = in[x+3]; + for (x = 0; x < rowbytes; x+=4) + { + out[x+0] = in[x+2]; + out[x+1] = in[x+1]; + out[x+2] = in[x+0]; + out[x+3] = in[x+3]; + } } } + else + { + 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) + memcpy(out, in, rowbytes); + } + IDirect3DCubeTexture9_UnlockRect(dt, i%6, i/6); } - else - { - 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) - memcpy(out, in, rowbytes); - } - IDirect3DCubeTexture9_UnlockRect(dt, i%6, i/6); } } else if (mips->type == PTI_2D) diff --git a/engine/d3d/vid_d3d.c b/engine/d3d/vid_d3d.c index 6ad46a2d..5afed7cf 100644 --- a/engine/d3d/vid_d3d.c +++ b/engine/d3d/vid_d3d.c @@ -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 } diff --git a/engine/d3d/vid_d3d11.c b/engine/d3d/vid_d3d11.c index 2d61ce18..6a06d96e 100644 --- a/engine/d3d/vid_d3d11.c +++ b/engine/d3d/vid_d3d11.c @@ -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))) diff --git a/engine/gl/gl_alias.c b/engine/gl/gl_alias.c index a1b91dce..4b8c6160 100644 --- a/engine/gl/gl_alias.c +++ b/engine/gl/gl_alias.c @@ -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) diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index 1cd9f011..3e7f230e 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -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); diff --git a/engine/gl/gl_draw.c b/engine/gl/gl_draw.c index f7371704..c7c4ba2b 100644 --- a/engine/gl/gl_draw.c +++ b/engine/gl/gl_draw.c @@ -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,147 +994,134 @@ 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) + if (compress && gl_compress.ival>1 && gl_config.formatinfo[encoding].type) + { + GLint fmt; + GLint csize; + struct pendingtextureinfo out = {mips->type}; + out.type = mips->type; + out.mipcount = mips->mipcount; + out.encoding = 0; + out.extrafree = NULL; + + qglGetTexLevelParameteriv(targ, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt); + + switch(fmt) { - GLint fmt; - GLint csize; - struct pendingtextureinfo out = {mips->type}; - out.type = mips->type; - out.mipcount = mips->mipcount; - out.encoding = 0; - out.extrafree = NULL; + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: out.encoding = PTI_BC1_RGB; break; + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: out.encoding = PTI_BC1_RGBA; break; + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: out.encoding = PTI_BC2_RGBA; break; + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: out.encoding = PTI_BC3_RGBA; break; + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: out.encoding = PTI_BC1_RGB_SRGB; break; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: out.encoding = PTI_BC1_RGBA_SRGB; break; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: out.encoding = PTI_BC2_RGBA_SRGB; break; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: out.encoding = PTI_BC3_RGBA_SRGB; break; + case GL_COMPRESSED_RED_RGTC1: out.encoding = PTI_BC4_R8; break; + case GL_COMPRESSED_SIGNED_RED_RGTC1: out.encoding = PTI_BC4_R8_SNORM; break; + case GL_COMPRESSED_RG_RGTC2: out.encoding = PTI_BC5_RG8; break; + case GL_COMPRESSED_SIGNED_RG_RGTC2: out.encoding = PTI_BC5_RG8_SNORM; break; + case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB: out.encoding = PTI_BC6_RGB_UFLOAT; break; + case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB: out.encoding = PTI_BC6_RGB_SFLOAT; break; + case GL_COMPRESSED_RGBA_BPTC_UNORM_ARB: out.encoding = PTI_BC7_RGBA; break; + case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB: out.encoding = PTI_BC7_RGBA_SRGB; break; + case GL_ETC1_RGB8_OES: out.encoding = PTI_ETC1_RGB8; break; + case GL_COMPRESSED_RGB8_ETC2: out.encoding = PTI_ETC2_RGB8; break; + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: out.encoding = PTI_ETC2_RGB8A1; break; + case GL_COMPRESSED_RGBA8_ETC2_EAC: out.encoding = PTI_ETC2_RGB8A8; break; + case GL_COMPRESSED_SRGB8_ETC2: out.encoding = PTI_ETC2_RGB8_SRGB; break; + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: out.encoding = PTI_ETC2_RGB8A1_SRGB; break; + case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: out.encoding = PTI_ETC2_RGB8A8_SRGB; break; + case GL_COMPRESSED_R11_EAC: out.encoding = PTI_EAC_R11; break; + case GL_COMPRESSED_SIGNED_R11_EAC: out.encoding = PTI_EAC_R11_SNORM; break; + case GL_COMPRESSED_RG11_EAC: out.encoding = PTI_EAC_RG11; break; + case GL_COMPRESSED_SIGNED_RG11_EAC: out.encoding = PTI_EAC_RG11_SNORM; break; + case GL_COMPRESSED_RGBA_ASTC_4x4_KHR: out.encoding = PTI_ASTC_4X4_HDR; break; //play it safe and assume hdr. + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: out.encoding = PTI_ASTC_4X4_SRGB; break; + case GL_COMPRESSED_RGBA_ASTC_5x4_KHR: out.encoding = PTI_ASTC_5X4_HDR; break; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: out.encoding = PTI_ASTC_5X4_SRGB; break; + case GL_COMPRESSED_RGBA_ASTC_5x5_KHR: out.encoding = PTI_ASTC_5X5_HDR; break; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: out.encoding = PTI_ASTC_5X5_SRGB; break; + case GL_COMPRESSED_RGBA_ASTC_6x5_KHR: out.encoding = PTI_ASTC_6X5_HDR; break; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: out.encoding = PTI_ASTC_6X5_SRGB; break; + case GL_COMPRESSED_RGBA_ASTC_6x6_KHR: out.encoding = PTI_ASTC_6X6_HDR; break; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: out.encoding = PTI_ASTC_6X6_SRGB; break; + case GL_COMPRESSED_RGBA_ASTC_8x5_KHR: out.encoding = PTI_ASTC_8X5_HDR; break; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: out.encoding = PTI_ASTC_8X5_SRGB; break; + case GL_COMPRESSED_RGBA_ASTC_8x6_KHR: out.encoding = PTI_ASTC_8X6_HDR; break; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: out.encoding = PTI_ASTC_8X6_SRGB; break; + case GL_COMPRESSED_RGBA_ASTC_10x5_KHR: out.encoding = PTI_ASTC_10X5_HDR; break; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: out.encoding = PTI_ASTC_10X5_SRGB; break; + case GL_COMPRESSED_RGBA_ASTC_10x6_KHR: out.encoding = PTI_ASTC_10X6_HDR; break; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: out.encoding = PTI_ASTC_10X6_SRGB; break; + case GL_COMPRESSED_RGBA_ASTC_8x8_KHR: out.encoding = PTI_ASTC_8X8_HDR; break; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: out.encoding = PTI_ASTC_8X8_SRGB; break; + case GL_COMPRESSED_RGBA_ASTC_10x8_KHR: out.encoding = PTI_ASTC_10X8_HDR; break; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: out.encoding = PTI_ASTC_10X8_SRGB; break; + case GL_COMPRESSED_RGBA_ASTC_10x10_KHR: out.encoding = PTI_ASTC_10X10_HDR; break; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: out.encoding = PTI_ASTC_10X10_SRGB; break; + case GL_COMPRESSED_RGBA_ASTC_12x10_KHR: out.encoding = PTI_ASTC_12X10_HDR; break; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: out.encoding = PTI_ASTC_12X10_SRGB; break; + case GL_COMPRESSED_RGBA_ASTC_12x12_KHR: out.encoding = PTI_ASTC_12X12_HDR; break; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: out.encoding = PTI_ASTC_12X12_SRGB; break; + } - qglGetTexLevelParameteriv(targ, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt); - - switch(fmt) + if (out.encoding) + { + for (i = 0; i < nummips; i++) { - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: out.encoding = PTI_BC1_RGB; break; - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: out.encoding = PTI_BC1_RGBA; break; - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: out.encoding = PTI_BC2_RGBA; break; - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: out.encoding = PTI_BC3_RGBA; break; - case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: out.encoding = PTI_BC1_RGB_SRGB; break; - case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: out.encoding = PTI_BC1_RGBA_SRGB; break; - case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: out.encoding = PTI_BC2_RGBA_SRGB; break; - case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: out.encoding = PTI_BC3_RGBA_SRGB; break; - case GL_COMPRESSED_RED_RGTC1: out.encoding = PTI_BC4_R8; break; - case GL_COMPRESSED_SIGNED_RED_RGTC1: out.encoding = PTI_BC4_R8_SNORM; break; - case GL_COMPRESSED_RG_RGTC2: out.encoding = PTI_BC5_RG8; break; - case GL_COMPRESSED_SIGNED_RG_RGTC2: out.encoding = PTI_BC5_RG8_SNORM; break; - case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB: out.encoding = PTI_BC6_RGB_UFLOAT; break; - case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB: out.encoding = PTI_BC6_RGB_SFLOAT; break; - case GL_COMPRESSED_RGBA_BPTC_UNORM_ARB: out.encoding = PTI_BC7_RGBA; break; - case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB: out.encoding = PTI_BC7_RGBA_SRGB; break; - case GL_ETC1_RGB8_OES: out.encoding = PTI_ETC1_RGB8; break; - case GL_COMPRESSED_RGB8_ETC2: out.encoding = PTI_ETC2_RGB8; break; - case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: out.encoding = PTI_ETC2_RGB8A1; break; - case GL_COMPRESSED_RGBA8_ETC2_EAC: out.encoding = PTI_ETC2_RGB8A8; break; - case GL_COMPRESSED_SRGB8_ETC2: out.encoding = PTI_ETC2_RGB8_SRGB; break; - case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: out.encoding = PTI_ETC2_RGB8A1_SRGB; break; - case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: out.encoding = PTI_ETC2_RGB8A8_SRGB; break; - case GL_COMPRESSED_R11_EAC: out.encoding = PTI_EAC_R11; break; - case GL_COMPRESSED_SIGNED_R11_EAC: out.encoding = PTI_EAC_R11_SNORM; break; - case GL_COMPRESSED_RG11_EAC: out.encoding = PTI_EAC_RG11; break; - case GL_COMPRESSED_SIGNED_RG11_EAC: out.encoding = PTI_EAC_RG11_SNORM; break; - case GL_COMPRESSED_RGBA_ASTC_4x4_KHR: out.encoding = PTI_ASTC_4X4_HDR; break; //play it safe and assume hdr. - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: out.encoding = PTI_ASTC_4X4_SRGB; break; - case GL_COMPRESSED_RGBA_ASTC_5x4_KHR: out.encoding = PTI_ASTC_5X4_HDR; break; - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: out.encoding = PTI_ASTC_5X4_SRGB; break; - case GL_COMPRESSED_RGBA_ASTC_5x5_KHR: out.encoding = PTI_ASTC_5X5_HDR; break; - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: out.encoding = PTI_ASTC_5X5_SRGB; break; - case GL_COMPRESSED_RGBA_ASTC_6x5_KHR: out.encoding = PTI_ASTC_6X5_HDR; break; - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: out.encoding = PTI_ASTC_6X5_SRGB; break; - case GL_COMPRESSED_RGBA_ASTC_6x6_KHR: out.encoding = PTI_ASTC_6X6_HDR; break; - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: out.encoding = PTI_ASTC_6X6_SRGB; break; - case GL_COMPRESSED_RGBA_ASTC_8x5_KHR: out.encoding = PTI_ASTC_8X5_HDR; break; - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: out.encoding = PTI_ASTC_8X5_SRGB; break; - case GL_COMPRESSED_RGBA_ASTC_8x6_KHR: out.encoding = PTI_ASTC_8X6_HDR; break; - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: out.encoding = PTI_ASTC_8X6_SRGB; break; - case GL_COMPRESSED_RGBA_ASTC_10x5_KHR: out.encoding = PTI_ASTC_10X5_HDR; break; - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: out.encoding = PTI_ASTC_10X5_SRGB; break; - case GL_COMPRESSED_RGBA_ASTC_10x6_KHR: out.encoding = PTI_ASTC_10X6_HDR; break; - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: out.encoding = PTI_ASTC_10X6_SRGB; break; - case GL_COMPRESSED_RGBA_ASTC_8x8_KHR: out.encoding = PTI_ASTC_8X8_HDR; break; - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: out.encoding = PTI_ASTC_8X8_SRGB; break; - case GL_COMPRESSED_RGBA_ASTC_10x8_KHR: out.encoding = PTI_ASTC_10X8_HDR; break; - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: out.encoding = PTI_ASTC_10X8_SRGB; break; - case GL_COMPRESSED_RGBA_ASTC_10x10_KHR: out.encoding = PTI_ASTC_10X10_HDR; break; - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: out.encoding = PTI_ASTC_10X10_SRGB; break; - case GL_COMPRESSED_RGBA_ASTC_12x10_KHR: out.encoding = PTI_ASTC_12X10_HDR; break; - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: out.encoding = PTI_ASTC_12X10_SRGB; break; - case GL_COMPRESSED_RGBA_ASTC_12x12_KHR: out.encoding = PTI_ASTC_12X12_HDR; break; - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: out.encoding = PTI_ASTC_12X12_SRGB; break; - } - - if (out.encoding) - { - for (i = 0; i < nummips; i++) + 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 { - if (tex->flags & IF_TEXTYPE) - { //cubemap face - targface = cubeface[i%countof(cubeface)]; - j = i/countof(cubeface); - } - 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,21 +1130,21 @@ 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) - { - out.mipcount = i; - Image_WriteKTXFile(va("textures/%s.ktx", tex->ident), FS_GAMEONLY, &out); - } - while (i-- > 0) - if (out.mip[i].needfree) - BZ_Free(out.mip[i].data); } + + if (i) + { + out.mipcount = i; + Image_WriteKTXFile(va("textures/%s.ktx", tex->ident), FS_GAMEONLY, &out); + } + while (i-- > 0) + if (out.mip[i].needfree) + BZ_Free(out.mip[i].data); } -#endif } +#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); diff --git a/engine/gl/gl_rlight.c b/engine/gl/gl_rlight.c index 9f660b48..cd708d21 100644 --- a/engine/gl/gl_rlight.c +++ b/engine/gl/gl_rlight.c @@ -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; } diff --git a/engine/gl/gl_rmain.c b/engine/gl/gl_rmain.c index afb802d4..c0213f63 100644 --- a/engine/gl/gl_rmain.c +++ b/engine/gl/gl_rmain.c @@ -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 } diff --git a/engine/gl/gl_rmisc.c b/engine/gl/gl_rmisc.c index 4f67d451..7bfffbc3 100644 --- a/engine/gl/gl_rmisc.c +++ b/engine/gl/gl_rmisc.c @@ -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); diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index 98f94a08..fef2a9e9 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -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":"", diff --git a/engine/gl/gl_warp.c b/engine/gl/gl_warp.c index b3efe918..d54ced28 100644 --- a/engine/gl/gl_warp.c +++ b/engine/gl/gl_warp.c @@ -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); diff --git a/engine/gl/glsupp.h b/engine/gl/glsupp.h index 17492fa9..47ad17f9 100644 --- a/engine/gl/glsupp.h +++ b/engine/gl/glsupp.h @@ -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 diff --git a/engine/qclib/execloop.h b/engine/qclib/execloop.h index 3fda280b..7bfd3ac0 100644 --- a/engine/qclib/execloop.h +++ b/engine/qclib/execloop.h @@ -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; diff --git a/engine/shaders/hlsl11/default2d.hlsl b/engine/shaders/hlsl11/default2d.hlsl index e893f0ce..1ce8527c 100644 --- a/engine/shaders/hlsl11/default2d.hlsl +++ b/engine/shaders/hlsl11/default2d.hlsl @@ -36,4 +36,5 @@ struct v2f #endif return t_t0.Sample(s_t0, inp.tc) * inp.vcol; } -#endif \ No newline at end of file +#endif + diff --git a/engine/shaders/hlsl11/defaultfill.hlsl b/engine/shaders/hlsl11/defaultfill.hlsl index f09650e7..da34a71b 100644 --- a/engine/shaders/hlsl11/defaultfill.hlsl +++ b/engine/shaders/hlsl11/defaultfill.hlsl @@ -26,4 +26,5 @@ struct v2f { return inp.vcol; } -#endif \ No newline at end of file +#endif + diff --git a/engine/shaders/hlsl11/menutint.hlsl b/engine/shaders/hlsl11/menutint.hlsl index d72bbe9e..cd77eddd 100644 --- a/engine/shaders/hlsl11/menutint.hlsl +++ b/engine/shaders/hlsl11/menutint.hlsl @@ -42,4 +42,5 @@ struct v2f return texcolor * inp.vcol; } -#endif \ No newline at end of file +#endif + diff --git a/engine/shaders/makevulkanblob.c b/engine/shaders/makevulkanblob.c index 7caef291..d6a896a0 100644 --- a/engine/shaders/makevulkanblob.c +++ b/engine/shaders/makevulkanblob.c @@ -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"); diff --git a/engine/vk/vk_backend.c b/engine/vk/vk_backend.c index cbdf9d56..1a3517ed 100644 --- a/engine/vk/vk_backend.c +++ b/engine/vk/vk_backend.c @@ -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); diff --git a/engine/vk/vk_init.c b/engine/vk/vk_init.c index 81b846f8..4c784f31 100644 --- a/engine/vk/vk_init.c +++ b/engine/vk/vk_init.c @@ -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.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}, diff --git a/imgtool.c b/imgtool.c index 2c0bf440..a2e3a061 100644 --- a/imgtool.c +++ b/imgtool.c @@ -333,19 +333,24 @@ static void ImgTool_SetupPalette(void) static void ImgTool_FreeMips(struct pendingtextureinfo *mips) { size_t i; - for (i = 0; i < mips->mipcount; i++) - if (mips->mip[i].needfree) - BZ_Free(mips->mip[i].data); - if (mips->extrafree) - BZ_Free(mips->extrafree); - BZ_Free(mips); + if (mips) + { + for (i = 0; i < mips->mipcount; i++) + if (mips->mip[i].needfree) + BZ_Free(mips->mip[i].data); + if (mips->extrafree) + BZ_Free(mips->extrafree); + BZ_Free(mips); + } } 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,38 +509,74 @@ 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++) { - tmp.mip[0] = mips->mip[m]; - tmp.mip[0].needfree = false; - (void)tmp; - - if (canktx) + qbyte *srcdata = mips->mip[m].data; + size_t srcsize = mips->mip[m].datasize; + if (mips->type == PTI_3D) { -#ifdef IMAGEFMT_KTX - if (!Image_WriteKTXFile(raw, FS_SYSTEM, &tmp)) -#endif - break; + layers = 1; + d = mips->mip[m].depth; + tmp.type = PTI_2D; } 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)) -#endif - break; + layers = mips->mip[m].depth; + d = 1; + tmp.type = PTI_2D; } - - system(command); - - fdata = FS_LoadMallocFile(comp, &fsize); - 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 && - ImgTool_ASTCToLDR(ret->encoding) == ImgTool_ASTCToLDR(targfmt)) + for (l = 0; l < layers; l++) { - mips->mip[m] = ret->mip[0]; - continue; + 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) + { + #ifdef IMAGEFMT_KTX + if (!Image_WriteKTXFile(raw, FS_SYSTEM, &tmp)) + #endif + break; + } + else + { + #ifdef AVAIL_PNGLIB + 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; + } + + system(command); + + fdata = FS_LoadMallocFile(comp, &fsize); + 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 == 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; } - break; + if (l != layers) + break; } mips->encoding = targfmt; @@ -567,139 +609,357 @@ 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) + if (in) { - in = Image_LoadMipsFromMemory(args->flags|(allowcompressed?0:IF_NOMIPMAP), inname, inname, indata, fsize); - if (in) + if (!(args->flags & IF_NOMIPMAP) && in->mipcount == 1) + Image_GenerateMips(in, args->flags); + + if (args->mipnum >= in->mipcount) { - printf("%s: %s, %i*%i, %i mips\n", inname, Image_FormatName(in->encoding), in->mip[0].width, in->mip[0].height, in->mipcount); + ImgTool_FreeMips(in); + Con_Printf("%s: Requested output mip number was out of bounds %i >= %i\n", outname, args->mipnum, in->mipcount); + return; + } + for (k = 0; k < args->mipnum; k++) + { + if (in->mip[k].needfree) + BZ_Free(in->mip[k].data); + } + in->mipcount -= k; + memmove(in->mip, &in->mip[k], sizeof(in->mip[0])*in->mipcount); - if (!(args->flags & IF_NOMIPMAP) && in->mipcount == 1) - Image_GenerateMips(in, args->flags); + if (args->newpixelformat != PTI_INVALID && (args->newpixelformat < PTI_BC1_RGB || allowcompressed) && ImgTool_ConvertPixelFormat(args, inname, in)) + printf("\t(Converted to %s)\n", Image_FormatName(in->encoding)); - if (args->mipnum >= in->mipcount) - { - ImgTool_FreeMips(in); - Con_Printf("%s: Requested output mip number was out of bounds %i >= %i\n", outname, args->mipnum, in->mipcount); - return; - } - for (k = 0; k < args->mipnum; k++) - { - if (in->mip[k].needfree) - BZ_Free(in->mip[k].data); - } - in->mipcount -= k; - memmove(in->mip, &in->mip[k], sizeof(in->mip[0])*in->mipcount); + if (!in->mipcount) + { + ImgTool_FreeMips(in); + printf("%s: unable to convert any mips\n", inname); + return; + } - if (args->newpixelformat != PTI_INVALID && (args->newpixelformat < PTI_BC1_RGB || allowcompressed) && ImgTool_ConvertPixelFormat(args, inname, in)) - printf("\t(Converted to %s)\n", Image_FormatName(in->encoding)); - - if (!in->mipcount) - { - ImgTool_FreeMips(in); - printf("%s: unable to convert any mips\n", inname); - return; - } - - if (0) - ; + if (0) + ; #ifdef IMAGEFMT_KTX - else if (!strcmp(outext, ".ktx")) + else if (!strcmp(outext, ".ktx")) + { + if (!Image_WriteKTXFile(outname, FS_SYSTEM, in)) + Con_Printf("%s(%s): Write failed\n", outname, Image_FormatName(in->encoding)); + } +#endif +#ifdef IMAGEFMT_DDS + else if (!strcmp(outext, ".dds")) + { + if (!Image_WriteDDSFile(outname, FS_SYSTEM, in)) + Con_Printf("%s(%s): Write failed\n", outname, Image_FormatName(in->encoding)); + } +#endif + else + { + int bb,bw,bh; + + 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")) { - if (!Image_WriteKTXFile(outname, FS_SYSTEM, in)) +#ifdef AVAIL_PNGLIB + //force the format, because we can. + for (k = 0; k < PTI_MAX; k++) + sh_config.texfmt[k] = + (k == PTI_RGBA8) || (k == PTI_RGBX8) || + (k == PTI_BGRA8) || (k == PTI_BGRX8) || + (k == PTI_LLLA8) || (k == PTI_LLLX8) || + (k == PTI_RGBA16) || + (k == PTI_L8) || (k == PTI_L8A8) || + /*(k == PTI_L16) ||*/ + (k == PTI_BGR8) || (k == PTI_BGR8) || + 0; + if (!sh_config.texfmt[in->encoding]) + { + 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); + if (!Image_WritePNG(outname, FS_SYSTEM, 0, &in->mip[0].data, 1, in->mip[0].width*bb, in->mip[0].width, in->mip[0].height, in->encoding, false)) +#endif Con_Printf("%s(%s): Write failed\n", outname, Image_FormatName(in->encoding)); } #endif -#ifdef IMAGEFMT_DDS - else if (!strcmp(outext, ".dds")) +#ifdef IMAGEFMT_TGA + else if (!strcmp(outext, ".tga")) { - if (!Image_WriteDDSFile(outname, FS_SYSTEM, in)) + for (k = 0; k < PTI_MAX; k++) + sh_config.texfmt[k] = + (k == PTI_RGBA8) || (k == PTI_RGBX8) || + (k == PTI_BGRA8) || (k == PTI_BGRX8) || + (k == PTI_LLLA8) || (k == PTI_LLLX8) || + (k == PTI_RGBA16F) || (k == PTI_R16F) || //half-float tgas is a format extension, but allow it. + (k == PTI_L8) || (k == PTI_L8A8) || + /*(k == PTI_L16) ||*/ + (k == PTI_BGR8) || (k == PTI_BGR8) || + 0; + if (!sh_config.texfmt[in->encoding]) + { + 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); + if (!WriteTGA(outname, FS_SYSTEM, in->mip[0].data, in->mip[0].width*bb, in->mip[0].width, in->mip[0].height, in->encoding)) Con_Printf("%s(%s): Write failed\n", outname, Image_FormatName(in->encoding)); } #endif else - { - int bb,bw,bh; - - if (0) - ; -#ifdef IMAGEFMT_PNG - else if (!strcmp(outext, ".png")) - { -#ifdef AVAIL_PNGLIB - //force the format, because we can. - for (k = 0; k < PTI_MAX; k++) - sh_config.texfmt[k] = - (k == PTI_RGBA8) || (k == PTI_RGBX8) || - (k == PTI_BGRA8) || (k == PTI_BGRX8) || - (k == PTI_LLLA8) || (k == PTI_LLLX8) || - (k == PTI_RGBA16) || - (k == PTI_L8) || (k == PTI_L8A8) || - /*(k == PTI_L16) ||*/ - (k == PTI_BGR8) || (k == PTI_BGR8) || - 0; - if (!sh_config.texfmt[in->encoding]) - { - Image_ChangeFormat(in, args->flags&~IF_PREMULTIPLYALPHA, PTI_INVALID, inname); - printf("\t(Exporting as %s)\n", Image_FormatName(in->encoding)); - } - Image_BlockSizeForEncoding(in->encoding, &bb, &bw,&bh); - if (!Image_WritePNG(outname, FS_SYSTEM, 0, &in->mip[0].data, 1, in->mip[0].width*bb, in->mip[0].width, in->mip[0].height, in->encoding, false)) -#endif - Con_Printf("%s(%s): Write failed\n", outname, Image_FormatName(in->encoding)); - } -#endif -#ifdef IMAGEFMT_TGA - else if (!strcmp(outext, ".tga")) - { - for (k = 0; k < PTI_MAX; k++) - sh_config.texfmt[k] = - (k == PTI_RGBA8) || (k == PTI_RGBX8) || - (k == PTI_BGRA8) || (k == PTI_BGRX8) || - (k == PTI_LLLA8) || (k == PTI_LLLX8) || - (k == PTI_RGBA16F) || (k == PTI_R16F) || //half-float tgas is a format extension, but allow it. - (k == PTI_L8) || (k == PTI_L8A8) || - /*(k == PTI_L16) ||*/ - (k == PTI_BGR8) || (k == PTI_BGR8) || - 0; - if (!sh_config.texfmt[in->encoding]) - { - Image_ChangeFormat(in, args->flags&~IF_PREMULTIPLYALPHA, PTI_INVALID, inname); - printf("\t(Exporting as %s)\n", Image_FormatName(in->encoding)); - } - Image_BlockSizeForEncoding(in->encoding, &bb, &bw,&bh); - if (!WriteTGA(outname, FS_SYSTEM, in->mip[0].data, in->mip[0].width*bb, in->mip[0].width, in->mip[0].height, in->encoding)) - Con_Printf("%s(%s): Write failed\n", outname, Image_FormatName(in->encoding)); - } -#endif - else - 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); - - ImgTool_FreeMips(in); + Con_Printf("%s: Unknown output file format\n", outname); } - else - printf("%s: unsupported format\n", inname); + + 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: 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 - { - if (mode == mode_info) - ImgTool_Info(&args, argv[u]); - else if (mode == mode_convert) - { - if (u+1 < argc) - { - ImgTool_Convert(&args, argv[u], argv[u+1]); - u++; - } - } - 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++; - } - } - } + argv[files++] = argv[u]; } - return 0; + + 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 && files > 1 && args.textype>=0) //overwrite input + { + 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 + { + //-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 && 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; } diff --git a/iqm/iqm.cpp b/iqm/iqm.cpp index e93266be..28c69b45 100644 --- a/iqm/iqm.cpp +++ b/iqm/iqm.cpp @@ -4523,6 +4523,7 @@ template 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"