bugfixes:

hexen2 players now have colourmaps again. doesn't crash with rgb player colours.
hexen2 colour previews now work (as well as they did in actual hexen2, anyway)
fix possible issue with 'bad type - needs fixing'
color command now longer omits 0 values when displaying.
readded support for all hexen2 palette lookup types.
fixed some hexen2 image positions.
using premultiplied alpha for pics as an easy fix for hexen2's various ugly halos.
the checkerboard texture is back!
fix q1 maps that have more than 32k clipplanes.
new features:
when associated with mdl etc file extensions, now opens up the modelviewer. also potentially changes gamedir (this applies to bsps too).
multiplayer setup menu now supports selecting rgb colours (lower colour remains with the 14 team colours). press shift for the normal/hue colour selection instead. 
attempt to use bgra for texture uploads by default where available. reimplement possible support for 16bit textures.
attempt to implement gamepad support for web port. untested, but should be completeish.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4764 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2014-10-11 19:39:45 +00:00
parent 71f4fe99e0
commit 97579ebfbb
52 changed files with 1185 additions and 372 deletions

View file

@ -3471,6 +3471,7 @@ void CL_LinkPacketEntities (void)
else if (state->colormap > 0 && state->colormap <= cl.allocated_client_slots)
{
ent->playerindex = state->colormap-1;
ent->h2playerclass = cl.players[ent->playerindex].h2playerclass;
ent->topcolour = cl.players[ent->playerindex].ttopcolor;
ent->bottomcolour = cl.players[ent->playerindex].tbottomcolor;
}
@ -4697,6 +4698,10 @@ void CL_LinkViewModel(void)
plnum = r_refdef.playerview->playernum;
plstate = &cl.inframes[parsecountmod].playerstate[plnum];
/* ent.topcolour = TOP_DEFAULT;//cl.players[plnum].ttopcolor;
ent.bottomcolour = cl.players[plnum].tbottomcolor;
ent.h2playerclass = cl.players[plnum].h2playerclass;
*/
CLQ1_AddPowerupShell(V_AddEntity(&ent), true, plstate?plstate->effects:0);
if (alpha < 1 && qrenderer == QR_OPENGL)

View file

@ -1550,7 +1550,7 @@ void CL_SendCmd (double frametime, qboolean mainloop)
CL_ProxyMenuHooks();
if (cls.demoplayback != DPB_NONE || !cls.state)
if (cls.demoplayback != DPB_NONE || cls.state <= ca_demostart)
{
cursor_active = false;
if (!cls.state || cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)

View file

@ -1625,9 +1625,13 @@ void CL_Color_f (void)
if (Cmd_Argc() == 1)
{
Con_TPrintf ("\"color\" is \"%s %s\"\n",
Info_ValueForKey (cls.userinfo[pnum], "topcolor"),
Info_ValueForKey (cls.userinfo[pnum], "bottomcolor") );
char *t = Info_ValueForKey (cls.userinfo[pnum], "topcolor");
char *b = Info_ValueForKey (cls.userinfo[pnum], "bottomcolor");
if (!*t)
t = "0";
if (!*b)
b = "0";
Con_TPrintf ("\"color\" is \"%s %s\"\n", t, b);
Con_TPrintf ("usage: color <0xRRGGBB> [0xRRGGBB]\n");
return;
}
@ -3880,10 +3884,11 @@ void Host_RunFileNotify(struct dl_download *dl)
#define HRF_MANIFEST (1<<13)
#define HRF_BSP (1<<14)
#define HRF_PACKAGE (1<<15)
#define HRF_MODEL (1<<16)
#define HRF_ACTION (HRF_OVERWRITE|HRF_NOOVERWRITE|HRF_ABORT)
#define HRF_DEMO (HRF_DEMO_MVD|HRF_DEMO_QWD|HRF_DEMO_DM2|HRF_DEMO_DEM)
#define HRF_FILETYPES (HRF_DEMO|HRF_QTVINFO|HRF_MANIFEST|HRF_BSP|HRF_PACKAGE)
#define HRF_FILETYPES (HRF_DEMO|HRF_QTVINFO|HRF_MANIFEST|HRF_BSP|HRF_PACKAGE|HRF_MODEL)
typedef struct {
unsigned int flags;
vfsfile_t *srcfile;
@ -4024,6 +4029,8 @@ static qboolean isurl(char *url)
return /*!strncmp(url, "data:", 5) || */!strncmp(url, "http://", 7) || !strncmp(url, "https://", 8);
}
qboolean FS_FixupGamedirForExternalFile(char *input, char *filename, size_t fnamelen);
void Host_DoRunFile(hrf_t *f)
{
char qname[MAX_QPATH];
@ -4078,22 +4085,25 @@ void Host_DoRunFile(hrf_t *f)
//if we get here, we have no mime type to give us any clues.
COM_FileExtension(f->fname, ext, sizeof(ext));
if (!strcmp(ext, "qwd"))
if (!Q_strcasecmp(ext, "qwd"))
f->flags |= HRF_DEMO_QWD;
else if (!strcmp(ext, "mvd"))
else if (!Q_strcasecmp(ext, "mvd"))
f->flags |= HRF_DEMO_MVD;
else if (!strcmp(ext, "dm2"))
else if (!Q_strcasecmp(ext, "dm2"))
f->flags |= HRF_DEMO_DM2;
else if (!strcmp(ext, "dem"))
else if (!Q_strcasecmp(ext, "dem"))
f->flags |= HRF_DEMO_DEM;
else if (!strcmp(ext, "qtv"))
else if (!Q_strcasecmp(ext, "qtv"))
f->flags |= HRF_QTVINFO;
else if (!strcmp(ext, "fmf"))
else if (!Q_strcasecmp(ext, "fmf"))
f->flags |= HRF_MANIFEST;
else if (!strcmp(ext, "bsp"))
else if (!Q_strcasecmp(ext, "bsp"))
f->flags |= HRF_BSP;
else if (!strcmp(ext, "pak") || !strcmp(ext, "pk3"))
else if (!Q_strcasecmp(ext, "pak") || !Q_strcasecmp(ext, "pk3") || !Q_strcasecmp(ext, "pk4") || !Q_strcasecmp(ext, "wad"))
f->flags |= HRF_PACKAGE;
else if (!Q_strcasecmp(ext, "mdl") || !Q_strcasecmp(ext, "md2") || !Q_strcasecmp(ext, "md3") || !Q_strcasecmp(ext, "iqm")
|| !Q_strcasecmp(ext, "psk") || !Q_strcasecmp(ext, "zym") || !Q_strcasecmp(ext, "dpm") || !Q_strcasecmp(ext, "spr") || !Q_strcasecmp(ext, "spr2"))
f->flags |= HRF_MODEL;
//if we still don't know what it is, give up.
if (!(f->flags & HRF_FILETYPES))
@ -4111,7 +4121,8 @@ void Host_DoRunFile(hrf_t *f)
if (f->flags & HRF_DEMO)
{
//play directly via system path, no prompts needed
Cbuf_AddText(va("playdemo \"#%s\"\n", f->fname), RESTRICT_LOCAL);
FS_FixupGamedirForExternalFile(f->fname, loadcommand, sizeof(loadcommand));
Cbuf_AddText(va("playdemo \"%s\"\n", loadcommand), RESTRICT_LOCAL);
f->flags |= HRF_ABORT;
Host_DoRunFile(f);
@ -4121,9 +4132,18 @@ void Host_DoRunFile(hrf_t *f)
{
char shortname[MAX_QPATH];
COM_StripExtension(COM_SkipPath(f->fname), shortname, sizeof(shortname));
snprintf(qname, sizeof(qname), "maps/%s.bsp", shortname);
if (FS_FixupGamedirForExternalFile(f->fname, qname, sizeof(qname)) && !Q_strncasecmp(qname, "maps/", 5))
{
COM_StripExtension(qname+5, loadcommand, sizeof(loadcommand));
Cbuf_AddText(va("map \"%s\"\n", loadcommand), RESTRICT_LOCAL);
f->flags |= HRF_ABORT;
Host_DoRunFile(f);
return;
}
snprintf(loadcommand, sizeof(loadcommand), "map \"%s\"\n", shortname);
snprintf(displayname, sizeof(displayname), "map: %s", shortname);
snprintf(qname, sizeof(qname), "maps/%s.bsp", shortname);
}
else if (f->flags & HRF_PACKAGE)
{
@ -4175,6 +4195,14 @@ void Host_DoRunFile(hrf_t *f)
}
}
}
else if (f->flags & HRF_MODEL)
{
FS_FixupGamedirForExternalFile(f->fname, loadcommand, sizeof(loadcommand));
Cbuf_AddText(va("modelviewer \"%s\"\n", loadcommand), RESTRICT_LOCAL);
f->flags |= HRF_ABORT;
Host_DoRunFile(f);
return;
}
else if (!(f->flags & HRF_QTVINFO))
{
Con_Printf("Host_DoRunFile: filetype not handled\n");

View file

@ -1,5 +1,5 @@
#include "quakedef.h"
#include "glquake.h"
#include "shader.h"
//FIXME
texid_t GL_FindTextureFallback (const char *identifier, unsigned int flags, void *fallback, int fallbackwidth, int fallbackheight, uploadfmt_t fallbackfmt);
@ -2743,7 +2743,7 @@ static struct
{2, "override/%s%s", 1} /*tenebrae compatibility*/
};
static void Image_MipMap (qbyte *in, int inwidth, int inheight, qbyte *out, int outwidth, int outheight)
static void Image_MipMap8888 (qbyte *in, int inwidth, int inheight, qbyte *out, int outwidth, int outheight)
{
int i, j;
qbyte *inrow;
@ -2806,37 +2806,40 @@ static void Image_GenerateMips(struct pendingtextureinfo *mips, unsigned int fla
if (mips->type != PTI_2D)
return; //blurgh
if (flags & IF_NOMIPMAP)
return;
switch(mips->encoding)
{
case PTI_RGBA8:
case PTI_RGBX8:
case PTI_BGRA8:
case PTI_BGRX8:
for (mip = 1; mip < 32; mip++)
{
mips->mip[mip].width = mips->mip[mip-1].width >> 1;
mips->mip[mip].height = mips->mip[mip-1].height >> 1;
if (mips->mip[mip].width < 1 && mips->mip[mip].height < 1)
break;
if (mips->mip[mip].width < 1)
mips->mip[mip].width = 1;
if (mips->mip[mip].height < 1)
mips->mip[mip].height = 1;
mips->mip[mip].datasize = ((mips->mip[mip].width+3)&~3) * mips->mip[mip].height*4;
mips->mip[mip].data = BZ_Malloc(mips->mip[mip].datasize);
mips->mip[mip].needfree = true;
Image_MipMap8888(mips->mip[mip-1].data, mips->mip[mip-1].width, mips->mip[mip-1].height, mips->mip[mip].data, mips->mip[mip].width, mips->mip[mip].height);
mips->mipcount = mip+1;
}
break;
case PTI_RGBA4444:
case PTI_RGB565:
case PTI_RGBA5551:
return; //convert to 16bit afterwards. always mipmap at 8 bit, to try to preserve what little precision there is.
default:
return; //not supported.
}
if (flags & IF_NOMIPMAP)
return;
for (mip = 1; mip < 32; mip++)
{
mips->mip[mip].width = mips->mip[mip-1].width >> 1;
mips->mip[mip].height = mips->mip[mip-1].height >> 1;
if (mips->mip[mip].width < 1 && mips->mip[mip].height < 1)
break;
if (mips->mip[mip].width < 1)
mips->mip[mip].width = 1;
if (mips->mip[mip].height < 1)
mips->mip[mip].height = 1;
mips->mip[mip].datasize = ((mips->mip[mip].width+3)&~3) * mips->mip[mip].height*4;
mips->mip[mip].data = BZ_Malloc(mips->mip[mip].datasize);
mips->mip[mip].needfree = true;
Image_MipMap(mips->mip[mip-1].data, mips->mip[mip-1].width, mips->mip[mip-1].height, mips->mip[mip].data, mips->mip[mip].width, mips->mip[mip].height);
mips->mipcount = mip+1;
}
}
//stolen from DP
@ -3071,12 +3074,12 @@ static unsigned int * Image_GenerateNormalMap(qbyte *pixels, unsigned int *nmap,
static void Image_RoundDimensions(int *scaled_width, int *scaled_height, unsigned int flags)
{
if (r_config.texture_non_power_of_two) //NPOT is a simple extension that relaxes errors.
if (sh_config.texture_non_power_of_two) //NPOT is a simple extension that relaxes errors.
{
//lax form
TRACE(("dbg: GL_RoundDimensions: GL_ARB_texture_non_power_of_two\n"));
}
else if ((flags & IF_CLAMP) && (flags & IF_NOMIPMAP) && r_config.texture_non_power_of_two_pic)
else if ((flags & IF_CLAMP) && (flags & IF_NOMIPMAP) && sh_config.texture_non_power_of_two_pic)
{
//more strict form
TRACE(("dbg: GL_RoundDimensions: GL_OES_texture_npot\n"));
@ -3091,7 +3094,7 @@ static void Image_RoundDimensions(int *scaled_width, int *scaled_height, unsigne
;
/*round npot textures down if we're running on an embedded system*/
if (r_config.npot_rounddown)
if (sh_config.npot_rounddown)
{
if (*scaled_width != width)
*scaled_width >>= 1;
@ -3114,12 +3117,12 @@ static void Image_RoundDimensions(int *scaled_width, int *scaled_height, unsigne
TRACE(("dbg: GL_RoundDimensions: %f\n", gl_max_size.value));
if (r_config.maxtexturesize)
if (sh_config.texture_maxsize)
{
if (*scaled_width > r_config.maxtexturesize)
*scaled_width = r_config.maxtexturesize;
if (*scaled_height > r_config.maxtexturesize)
*scaled_height = r_config.maxtexturesize;
if (*scaled_width > sh_config.texture_maxsize)
*scaled_width = sh_config.texture_maxsize;
if (*scaled_height > sh_config.texture_maxsize)
*scaled_height = sh_config.texture_maxsize;
}
if (!(flags & IF_UIPIC))
{
@ -3138,6 +3141,221 @@ static void Image_RoundDimensions(int *scaled_width, int *scaled_height, unsigne
*scaled_height = 1;
}
//may operate in place
static void Image_8888to565(qbyte *in, unsigned short *out, unsigned int w, unsigned int h, qboolean bgra)
{
unsigned int p = w*h;
unsigned short tmp;
if (bgra)
{
while(p-->0)
{
tmp = ((*in++>>3) << 0);//b
tmp |= ((*in++>>2) << 5);//g
tmp |= ((*in++>>3) << 11);//r
in++;
*out++ = tmp;
}
}
else
{
while(p-->0)
{
tmp = ((*in++>>3) << 11);//r
tmp |= ((*in++>>2) << 5);//g
tmp |= ((*in++>>3) << 0);//b
in++;
*out++ = tmp;
}
}
}
//may operate in place
static void Image_8888to1555(qbyte *in, unsigned short *out, unsigned int w, unsigned int h, qboolean bgra)
{
unsigned int p = w*h;
unsigned short tmp;
if (bgra)
{
while(p-->0)
{
tmp = ((*in++>>3) << 0);//b
tmp |= ((*in++>>3) << 5);//g
tmp |= ((*in++>>3) << 10);//r
tmp |= ((*in++>>7) << 15);//a
*out++ = tmp;
}
}
else
{
while(p-->0)
{
tmp = ((*in++>>3) << 10);//r
tmp |= ((*in++>>3) << 5);//g
tmp |= ((*in++>>3) << 0);//b
tmp |= ((*in++>>7) << 15);//a
*out++ = tmp;
}
}
}
//may operate in place
static void Image_8888to5551(qbyte *in, unsigned short *out, unsigned int w, unsigned int h, qboolean bgra)
{
unsigned int p = w*h;
unsigned short tmp;
if (bgra)
{
while(p-->0)
{
tmp = ((*in++>>3) << 1);//b
tmp |= ((*in++>>3) << 6);//g
tmp |= ((*in++>>3) << 11);//r
tmp |= ((*in++>>7) << 0);//a
*out++ = tmp;
}
}
else
{
while(p-->0)
{
tmp = ((*in++>>3) << 11);//r
tmp |= ((*in++>>3) << 6);//g
tmp |= ((*in++>>3) << 1);//b
tmp |= ((*in++>>7) << 0);//a
*out++ = tmp;
}
}
}
//may operate in place
static void Image_8888to4444(qbyte *in, unsigned short *out, unsigned int w, unsigned int h, qboolean bgra)
{
unsigned int p = w*h;
unsigned short tmp;
if (bgra)
{
while(p-->0)
{
tmp = ((*in++>>4) << 4);//b
tmp |= ((*in++>>4) << 8);//g
tmp |= ((*in++>>4) << 12);//r
tmp |= ((*in++>>4) << 0);//a
*out++ = tmp;
}
}
else
{
while(p-->0)
{
tmp = ((*in++>>4) << 12);//r
tmp |= ((*in++>>4) << 8);//g
tmp |= ((*in++>>4) << 4);//b
tmp |= ((*in++>>4) << 0);//a
*out++ = tmp;
}
}
}
//may operate in place
static void Image_8888toARGB4444(qbyte *in, unsigned short *out, unsigned int w, unsigned int h, qboolean bgra)
{
unsigned int p = w*h;
unsigned short tmp;
if (bgra)
{
while(p-->0)
{
tmp = ((*in++>>4) << 0);//b
tmp |= ((*in++>>4) << 4);//g
tmp |= ((*in++>>4) << 8);//r
tmp |= ((*in++>>4) << 12);//a
*out++ = tmp;
}
}
else
{
while(p-->0)
{
tmp = ((*in++>>4) << 8);//r
tmp |= ((*in++>>4) << 4);//g
tmp |= ((*in++>>4) << 0);//b
tmp |= ((*in++>>4) << 12);//a
*out++ = tmp;
}
}
}
static void Image_ChangeFormat(struct pendingtextureinfo *mips, uploadfmt_t origfmt)
{
int mip;
if (mips->type != PTI_2D)
return; //blurgh
//if that format isn't supported/desired, try converting it.
if (sh_config.texfmt[PTI_RGBX8])
return;
//should we just use 5551 always?
if (mips->encoding == PTI_RGBX8 || mips->encoding == PTI_BGRX8)
{
/*if (0)
{ //prevent discolouration.
if (sh_config.texfmt[PTI_RGBA5551])
{
for (mip = 0; mip < mips->mipcount; mip++)
Image_8888to5551(mips->mip[mip].data, mips->mip[mip].data, mips->mip[mip].width, mips->mip[mip].height, mips->encoding == PTI_BGRX8);
mips->encoding = PTI_RGBA5551;
}
else
{
for (mip = 0; mip < mips->mipcount; mip++)
Image_8888to1555(mips->mip[mip].data, mips->mip[mip].data, mips->mip[mip].width, mips->mip[mip].height, mips->encoding == PTI_BGRX8);
mips->encoding = PTI_ARGB1555;
}
}
else*/
{
for (mip = 0; mip < mips->mipcount; mip++)
Image_8888to565(mips->mip[mip].data, mips->mip[mip].data, mips->mip[mip].width, mips->mip[mip].height, mips->encoding == PTI_BGRX8);
mips->encoding = PTI_RGB565;
}
}
else if (mips->encoding == PTI_RGBA8 || mips->encoding == PTI_BGRA8)
{
if (origfmt == TF_TRANS8 || origfmt == TF_TRANS8_FULLBRIGHT || origfmt == TF_H2_TRANS8_0 || !(sh_config.texfmt[PTI_RGBA4444] || sh_config.texfmt[PTI_ARGB4444]))
{ //1-bit alpha is okay for these textures.
if (sh_config.texfmt[PTI_RGBA5551])
{
for (mip = 0; mip < mips->mipcount; mip++)
Image_8888to5551(mips->mip[mip].data, mips->mip[mip].data, mips->mip[mip].width, mips->mip[mip].height, mips->encoding == PTI_BGRA8);
mips->encoding = PTI_RGBA5551;
}
else
{
for (mip = 0; mip < mips->mipcount; mip++)
Image_8888to1555(mips->mip[mip].data, mips->mip[mip].data, mips->mip[mip].width, mips->mip[mip].height, mips->encoding == PTI_BGRA8);
mips->encoding = PTI_ARGB1555;
}
}
else
{
if (sh_config.texfmt[PTI_RGBA4444])
{
for (mip = 0; mip < mips->mipcount; mip++)
Image_8888to4444(mips->mip[mip].data, mips->mip[mip].data, mips->mip[mip].width, mips->mip[mip].height, mips->encoding == PTI_BGRA8);
mips->encoding = PTI_RGBA4444;
}
else
{
for (mip = 0; mip < mips->mipcount; mip++)
Image_8888toARGB4444(mips->mip[mip].data, mips->mip[mip].data, mips->mip[mip].width, mips->mip[mip].height, mips->encoding == PTI_BGRA8);
mips->encoding = PTI_ARGB4444;
}
}
}
}
//resamples and depalettes as required
static qboolean Image_GenMip0(struct pendingtextureinfo *mips, unsigned int flags, void *rawdata, void *palettedata, int imgwidth, int imgheight, uploadfmt_t fmt, qboolean freedata)
{
@ -3169,27 +3387,17 @@ static qboolean Image_GenMip0(struct pendingtextureinfo *mips, unsigned int flag
mips->encoding = PTI_BGRA8;
break;
case TF_SOLID8:
mips->encoding = PTI_RGBX8;
rgbadata = BZ_Malloc(imgwidth * imgheight*4);
for (i = 0; i < imgwidth * imgheight; i++)
{
rgbadata[i] = d_8to24rgbtable[((qbyte*)rawdata)[i]];
if (sh_config.texfmt[PTI_BGRX8])
{ //bgra8 is typically faster when supported.
mips->encoding = PTI_BGRX8;
for (i = 0; i < imgwidth * imgheight; i++)
rgbadata[i] = d_8to24bgrtable[((qbyte*)rawdata)[i]];
}
if (freedata)
BZ_Free(rawdata);
freedata = true;
break;
case TF_H2_TRANS8_0:
mips->encoding = PTI_RGBX8;
rgbadata = BZ_Malloc(imgwidth * imgheight*4);
for (i = 0; i < imgwidth * imgheight; i++)
else
{
if (((qbyte*)rawdata)[i] == 0)
{
rgbadata[i] = 0;
mips->encoding = PTI_RGBA8;
}
else
mips->encoding = PTI_RGBX8;
for (i = 0; i < imgwidth * imgheight; i++)
rgbadata[i] = d_8to24rgbtable[((qbyte*)rawdata)[i]];
}
if (freedata)
@ -3197,21 +3405,25 @@ static qboolean Image_GenMip0(struct pendingtextureinfo *mips, unsigned int flag
freedata = true;
break;
case TF_TRANS8:
mips->encoding = PTI_RGBX8;
rgbadata = BZ_Malloc(imgwidth * imgheight*4);
for (i = 0; i < imgwidth * imgheight; i++)
case TF_H2_TRANS8_0:
{
if (((qbyte*)rawdata)[i] == 0xff)
qbyte ref = (fmt==TF_H2_TRANS8_0)?0:0xff;
mips->encoding = PTI_RGBX8;
rgbadata = BZ_Malloc(imgwidth * imgheight*4);
for (i = 0; i < imgwidth * imgheight; i++)
{
rgbadata[i] = 0;
mips->encoding = PTI_RGBA8;
if (((qbyte*)rawdata)[i] == ref)
{//fixme: blend non-0xff neighbours. no, just use premultiplied alpha instead, where it matters.
rgbadata[i] = 0;
mips->encoding = PTI_RGBA8;
}
else
rgbadata[i] = d_8to24rgbtable[((qbyte*)rawdata)[i]];
}
else
rgbadata[i] = d_8to24rgbtable[((qbyte*)rawdata)[i]];
if (freedata)
BZ_Free(rawdata);
freedata = true;
}
if (freedata)
BZ_Free(rawdata);
freedata = true;
break;
case TF_TRANS8_FULLBRIGHT:
mips->encoding = PTI_RGBA8;
@ -3289,6 +3501,7 @@ static qboolean Image_GenMip0(struct pendingtextureinfo *mips, unsigned int flag
freedata = true;
break;
#ifdef HEXEN2
case TF_H2_T7G1: /*8bit data, odd indexes give greyscale transparence*/
mips->encoding = PTI_RGBA8;
rgbadata = BZ_Malloc(imgwidth * imgheight*4);
@ -3307,8 +3520,22 @@ static qboolean Image_GenMip0(struct pendingtextureinfo *mips, unsigned int flag
BZ_Free(rawdata);
freedata = true;
break;
// case TF_H2_T4A4: /*8bit data, weird packing*/
// break;
case TF_H2_T4A4: /*8bit data, weird packing*/
mips->encoding = PTI_RGBA8;
rgbadata = BZ_Malloc(imgwidth * imgheight*4);
for (i = 0; i < imgwidth * imgheight; i++)
{
static const int ColorIndex[16] = {0, 31, 47, 63, 79, 95, 111, 127, 143, 159, 175, 191, 199, 207, 223, 231};
static const unsigned ColorPercent[16] = {25, 51, 76, 102, 114, 127, 140, 153, 165, 178, 191, 204, 216, 229, 237, 247};
qbyte p = ((qbyte*)rawdata)[i];
rgbadata[i] = d_8to24rgbtable[ColorIndex[p>>4]] & 0x00ffffff;
rgbadata[i] |= ( int )ColorPercent[p&15] << 24;
}
if (freedata)
BZ_Free(rawdata);
freedata = true;
break;
#endif
}
if (flags & IF_NOALPHA)
@ -3321,15 +3548,24 @@ static qboolean Image_GenMip0(struct pendingtextureinfo *mips, unsigned int flag
case PTI_BGRA8:
mips->encoding = PTI_RGBX8;
break;
case PTI_RGBA4444:
case PTI_RGBA5551:
break; //erk
case PTI_S3RGBA1: //mostly compatible, but I don't want to push it.
case PTI_S3RGBA3:
case PTI_S3RGBA5:
//erk. meh.
break;
case PTI_RGB565:
case PTI_RGBX8:
case PTI_BGRX8:
case PTI_S3RGB1:
break;
case PTI_DEPTH16:
case PTI_DEPTH24:
case PTI_DEPTH32:
case PTI_DEPTH24_8:
break;
}
//FIXME: fill alpha channel with 255?
}
@ -3400,6 +3636,7 @@ static qboolean Image_LoadRawTexture(texid_t tex, unsigned int flags, void *rawd
return false;
}
Image_GenerateMips(mips, flags);
Image_ChangeFormat(mips, fmt);
tex->width = imgwidth;
tex->height = imgheight;
@ -3756,7 +3993,7 @@ void Image_LoadHiResTextureWorker(void *ctx, void *data, size_t a, size_t b)
/*still failed? attempt to load quake lmp files, which have no real format id (hence why they're not above)*/
Q_strncpyz(fname, nicename, sizeof(fname));
COM_DefaultExtension(fname, ".lmp", sizeof(fname));
if ((buf = COM_LoadFile (fname, 5, &fsize)))
if (!(tex->flags & IF_NOPCX) && (buf = COM_LoadFile (fname, 5, &fsize)))
{
if (Image_LoadTextureFromMemory(tex, tex->flags, nicename, fname, buf, fsize))
return;
@ -3875,13 +4112,17 @@ image_t *Image_GetTexture(const char *identifier, const char *subpath, unsigned
tex = Image_FindTexture(identifier, subpath, flags);
if (tex)
{
if (!fallbackdata || tex->status != TEX_FAILED)
{
#ifdef LOADERTHREAD
Sys_UnlockMutex(com_resourcemutex);
Sys_UnlockMutex(com_resourcemutex);
#endif
return tex; //already exists
return tex; //already exists
}
tex->flags = flags;
}
tex = Image_CreateTexture_Internal(identifier, subpath, flags);
else
tex = Image_CreateTexture_Internal(identifier, subpath, flags);
tex->status = TEX_LOADING;
if (fallbackdata)
@ -3950,6 +4191,8 @@ void Image_Upload (texid_t tex, uploadfmt_t fmt, void *data, void *palette, in
mips.type = (flags & IF_3DMAP)?PTI_3D:PTI_2D;
if (!Image_GenMip0(&mips, flags, data, palette, width, height, fmt, false))
return;
Image_GenerateMips(&mips, flags);
Image_ChangeFormat(&mips, fmt);
rf->IMG_LoadTextureMips(tex, &mips);
tex->status = TEX_LOADED;
}

View file

@ -47,6 +47,7 @@ int CL_TargettedSplit(qboolean nowrap);
//specific events for the system-specific input code to call. may be called outside the main thread (so long as you don't call these simultaneously - ie: use a mutex or only one input thread).
void IN_KeyEvent(int devid, int down, int keycode, int unicode); //don't use IN_KeyEvent for mice if you ever use abs mice...
void IN_MouseMove(int devid, int abs, float x, float y, float z, float size);
void IN_JoystickAxisEvent(int devid, int axis, float value);
//system-specific functions
void INS_Move (float *movements, int pnum);

View file

@ -90,27 +90,60 @@ menu_t *currentmenu;
menu_t *firstmenu;
menuoption_t *M_NextSelectableItem(menu_t *m, menuoption_t *old);
#ifdef HEXEN2
//this function is so fucked up.
//firstly, the source image uses 0 for transparent instead of 255. this means we need special handling. *sigh*.
//secondly we have to avoid sampling too much of the image, because i chars seem to have stray white pixels in them
//thirdly, we hard-code (by eye) the space between chars, which should be different for any character pair.
//but we're lazy so we don't consider the next char. italic fonts are annoying like that. feel free to refudge it.
void Draw_Hexen2BigFontString(int x, int y, const char *text)
{
int c;
int sx, sy;
mpic_t *p;
unsigned int hack; //FIXME: threads can't cope
hack = d_8to24rgbtable[0];
d_8to24rgbtable[0] = 0;
p = R2D_SafeCachePic ("gfx/menu/bigfont.lmp");
d_8to24rgbtable[0] = hack;
p = R_RegisterShader ("gfx/menu/bigfont.lmp", SUF_2D,
"{\n"
"if $nofixed\n"
"program default2d\n"
"endif\n"
"affine\n"
"nomipmaps\n"
"{\n"
"clampmap $diffuse\n"
"rgbgen vertex\n"
"alphagen vertex\n"
"blendfunc gl_one gl_one_minus_src_alpha\n"
"}\n"
"sort additive\n"
"}\n");
if (!p->defaulttextures.base)
{
void *file;
qofs_t fsize = FS_LoadFile("gfx/menu/bigfont.lmp", &file);
if (file)
{
unsigned int w = ((unsigned int*)file)[0];
unsigned int h = ((unsigned int*)file)[1];
p->defaulttextures.base = R_LoadReplacementTexture("gfx/menu/bigfont.lmp", NULL, IF_NOPCX|IF_PREMULTIPLYALPHA|IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP|IF_CLAMP, (qbyte*)file+8, w, h, TF_H2_TRANS8_0);
FS_FreeFile(file); //got image data
}
else
p->defaulttextures.base = R_LoadHiResTexture("gfx/menu/bigfont.lmp", NULL, IF_PREMULTIPLYALPHA|IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP|IF_CLAMP);
}
while(*text)
{
if (*text >= 'a' && *text <= 'z')
c = *text++;
if (c >= 'a' && c <= 'z')
{
sx = ((*text-'a')%8)*20;
sy = ((*text-'a')/8)*20;
sx = ((c-'a')%8)*20;
sy = ((c-'a')/8)*20;
}
else if (*text >= 'A' && *text <= 'Z')
else if (c >= 'A' && c <= 'Z')
{
sx = ((*text-'A')%8)*20;
sy = ((*text-'A')/8)*20;
c = c - 'A' + 'a';
sx = ((c-'a')%8)*20;
sy = ((c-'a')/8)*20;
}
else// if (*text <= ' ')
{
@ -118,11 +151,41 @@ void Draw_Hexen2BigFontString(int x, int y, const char *text)
sy=-1;
}
if(sx>=0)
R2D_SubPic(x, y, 20, 20, p, sx, sy, 20*8, 20*4);
x+=20;
text++;
R2D_SubPic(x, y, 18, 20, p, sx, sy, 20*8, 20*4);
switch(c)
{
case 'a': x+=15; break;
case 'b': x+=15; break;
case 'c': x+=15; break;
case 'd': x+=15; break;
case 'e': x+=15; break;
case 'f': x+=15; break;
case 'g': x+=15; break;
case 'h': x+=15; break;
case 'i': x+=10; break;
case 'j': x+=15; break;
case 'k': x+=18; break;
case 'l': x+=15; break;
case 'm': x+=18; break;
case 'n': x+=15; break;
case 'o': x+=15; break;
case 'p': x+=15; break;
case 'q': x+=18; break;
case 'r': x+=18; break;
case 's': x+=13; break;
case 't': x+=15; break;
case 'u': x+=15; break;
case 'v': x+=12; break;
case 'w': x+=15; break;
case 'x': x+=18; break;
case 'y': x+=15; break;
case 'z': x+=18; break;
default: x+=20; break;
}
}
}
#endif
mpic_t *QBigFontWorks(void)
{

View file

@ -123,14 +123,15 @@ typedef struct {
int ticlass;
#endif
menucombo_t *modeledit;
int topcolour;
int lowercolour;
unsigned int topcolour;
unsigned int lowercolour;
int tiwidth, tiheight;
qbyte translationimage[128*128];
} setupmenu_t;
qboolean ApplySetupMenu (union menuoption_s *option,struct menu_s *menu, int key)
{
char bot[64], top[64];
setupmenu_t *info = menu->data;
if (key != K_ENTER && key != K_KP_ENTER)
return false;
@ -142,52 +143,130 @@ qboolean ApplySetupMenu (union menuoption_s *option,struct menu_s *menu, int key
if (info->classedit)
Cvar_SetValue(Cvar_FindVar("cl_playerclass"), info->classedit->selectedoption+1);
#endif
Cbuf_AddText(va("color %i %i\n", info->lowercolour, info->topcolour), RESTRICT_LOCAL);
if (info->lowercolour >= 16)
Q_snprintfz(bot, sizeof(bot), "0x%x", info->lowercolour&0xffffff);
else
Q_snprintfz(bot, sizeof(bot), "%i", info->lowercolour);
if (info->topcolour >= 16)
Q_snprintfz(top, sizeof(top), "0x%x", info->topcolour&0xffffff);
else
Q_snprintfz(top, sizeof(top), "%i", info->topcolour);
Cbuf_AddText(va("color %s %s\n", bot, top), RESTRICT_LOCAL);
S_LocalSound ("misc/menu2.wav");
M_RemoveMenu(menu);
return true;
}
qboolean SetupMenuColour (union menuoption_s *option,struct menu_s *menu, int key)
{
setupmenu_t *info = menu->data;
if (*option->button.text == 'T')
{
if (key == K_ENTER || key == K_KP_ENTER || key == K_RIGHTARROW)
{
info->topcolour ++;
if (info->topcolour>=14)
info->topcolour=0;
S_LocalSound ("misc/menu2.wav");
return true;
}
if (key == K_LEFTARROW)
{
info->topcolour --;
if (info->topcolour<=0)
info->topcolour=13;
S_LocalSound ("misc/menu2.wav");
return true;
}
//http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c
static void rgbtohsv(unsigned int rgb, vec3_t result)
{
int r = (rgb>>16)&0xff, g = (rgb>>8)&0xff, b = (rgb>>0)&0xff;
float maxc = max(r, max(g, b)), minc = min(r, min(g, b));
float h, s, l = (maxc + minc) / 2;
float d = maxc - minc;
if (maxc)
s = d / maxc;
else
s = 0;
if(maxc == minc)
{
h = 0; // achromatic
}
else
{
if (key == K_ENTER || key == K_KP_ENTER || key == K_RIGHTARROW)
if (maxc == r)
h = (g - b) / d + ((g < b) ? 6 : 0);
else if (maxc == g)
h = (b - r) / d + 2;
else
h = (r - g) / d + 4;
h /= 6;
}
result[0] = h;
result[1] = s;
result[2] = l;
};
//http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c
static unsigned int hsvtorgb(float inh, float s, float v)
{
int r, g, b;
float h = inh - (int)floor(inh);
int i = h * 6;
float f = h * 6 - i;
float p = v * (1 - s);
float q = v * (1 - f * s);
float t = v * (1 - (1 - f) * s);
switch(i)
{
default:
case 0: r = v*0xff, g = t*0xff, b = p*0xff; break;
case 1: r = q*0xff, g = v*0xff, b = p*0xff; break;
case 2: r = p*0xff, g = v*0xff, b = t*0xff; break;
case 3: r = p*0xff, g = q*0xff, b = v*0xff; break;
case 4: r = t*0xff, g = p*0xff, b = v*0xff; break;
case 5: r = v*0xff, g = p*0xff, b = q*0xff; break;
}
return 0xff000000 | (r<<16)|(g<<8)|(b<<0);
};
qboolean SetupMenuColour (union menuoption_s *option,struct menu_s *menu, int key)
{
extern qboolean keydown[K_MAX];
setupmenu_t *info = menu->data;
unsigned int *ptr = (*option->button.text == 'T')?&info->topcolour:&info->lowercolour;
//okay, this is a bit weird.
//fte supports rgb colours, but we only allow hue to be chosen via the menu (people picking pure black are annoying, also conversions and precisions limit us)
//for NQ compat, we stick to old-skool values (so we don't end up with far too many teams)
//but we give the top free reign.
//unless they hold shift, in which case it switches around
//this allows for whatever you want
if (key == K_ENTER || key == K_KP_ENTER || key == K_RIGHTARROW)
{
if ((keydown[K_LSHIFT] || keydown[K_RSHIFT]) ^ (ptr == &info->topcolour))
{
info->lowercolour ++;
if (info->lowercolour>=14)
info->lowercolour=0;
S_LocalSound ("misc/menu2.wav");
return true;
vec3_t hsv;
rgbtohsv(*ptr, hsv);
*ptr = hsvtorgb(hsv[0]+1/128.0, 1, 1);//hsv[1], hsv[2]);
}
if (key == K_LEFTARROW)
else
{
info->lowercolour --;
if (info->lowercolour<=0)
info->lowercolour=13;
S_LocalSound ("misc/menu2.wav");
return true;
if (*ptr >= 13 || *ptr >= 16)
*ptr = 0;
else
*ptr += 1;
}
S_LocalSound ("misc/menu2.wav");
return true;
}
if (key == K_DEL)
{
*ptr = 0;
S_LocalSound ("misc/menu2.wav");
return true;
}
if (key == K_LEFTARROW)
{
if ((keydown[K_LSHIFT] || keydown[K_RSHIFT]) ^ (ptr == &info->topcolour))
{
vec3_t hsv;
rgbtohsv(*ptr, hsv);
*ptr = hsvtorgb(hsv[0]-1/128.0, 1, 1);//hsv[1], hsv[2]);
}
else
{
if (*ptr==0 || *ptr >= 16)
*ptr=12;
else
*ptr -= 1;
}
S_LocalSound ("misc/menu2.wav");
return true;
}
return false;
}
@ -285,6 +364,7 @@ void MSetup_TransDraw (int x, int y, menucustom_t *option, menu_t *menu)
mpic_t *p;
void *f;
qboolean reloadtimage = false;
unsigned int pc = 0;
if (info->skinedit && info->skinedit->modified)
{
@ -292,10 +372,14 @@ void MSetup_TransDraw (int x, int y, menucustom_t *option, menu_t *menu)
reloadtimage = true;
}
#ifdef HEXEN2
if (info->classedit && info->classedit->selectedoption != info->ticlass)
if (info->classedit)
{
info->ticlass = info->classedit->selectedoption;
reloadtimage = true;
if (info->classedit->selectedoption != info->ticlass)
{
info->ticlass = info->classedit->selectedoption;
reloadtimage = true;
}
pc = info->ticlass+1;
}
#endif
@ -327,10 +411,10 @@ void MSetup_TransDraw (int x, int y, menucustom_t *option, menu_t *menu)
R2D_ImageColours(1,1,1,1);
p = R2D_SafeCachePic ("gfx/bigbox.lmp");
if (p)
if (R_GetShaderSizes(p, NULL, NULL, false)>0)
R2D_ScalePic (x-12, y-8, 72, 72, p);
M_BuildTranslationTable(info->topcolour, info->lowercolour, translationTable);
M_BuildTranslationTable(pc, info->topcolour, info->lowercolour, translationTable);
R2D_TransPicTranslate (x, y, info->tiwidth, info->tiheight, info->translationimage, translationTable);
}
@ -390,10 +474,6 @@ void M_Menu_Setup_f (void)
menu = M_CreateMenu(sizeof(setupmenu_t));
info = menu->data;
MC_AddPicture(menu, 16, 4, 32, 144, "gfx/qplaque.lmp");
MC_AddCenterPicture(menu, 4, 24, "gfx/p_multi.lmp");
// MC_AddPicture(menu, 72, 32, Draw_CachePic ("gfx/mp_menu.lmp") );
menu->selecteditem = (menuoption_t*)
@ -417,7 +497,12 @@ void M_Menu_Setup_f (void)
}
else
#endif
{
MC_AddPicture(menu, 16, 4, 32, 144, "gfx/qplaque.lmp");
MC_AddCenterPicture(menu, 4, 24, "gfx/p_multi.lmp");
(info->skinedit = MC_AddEdit(menu, 64, 160, 72, "Your skin", skin.string));
}
ci = MC_AddCustom(menu, 172+32, 88, NULL, 0);
ci->draw = MSetup_TransDraw;

View file

@ -183,11 +183,10 @@ void M_PrintWhite (int cx, int cy, qbyte *str)
Draw_FunString(cx + ((vid.width - 320)>>1), cy, str);
}
void M_BuildTranslationTable(int top, int bottom, unsigned int *translationTable)
void M_BuildTranslationTable(unsigned int pc, unsigned int top, unsigned int bottom, unsigned int *translationTable)
{
int j;
#ifdef HEXEN2
int pc = Cvar_Get("cl_playerclass", "1", 0, "Hexen2")->value;
if (h2playertranslations && pc)
{
int i;
@ -200,9 +199,33 @@ void M_BuildTranslationTable(int top, int bottom, unsigned int *translationTable
for(i=0;i<255;i++)
{
if (bottom > 0 && (colorB[i] != 255))
translationTable[i] = d_8to24rgbtable[sourceB[i]] | 0xff000000;
{
if (bottom >= 16)
{
unsigned int v = d_8to24rgbtable[colorB[i]];
v = max(max((v>>0)&0xff, (v>>8)&0xff), (v>>16)&0xff);
*((unsigned char*)&translationTable[i]+0) = (((bottom&0xff0000)>>16)*v)>>8;
*((unsigned char*)&translationTable[i]+1) = (((bottom&0x00ff00)>> 8)*v)>>8;
*((unsigned char*)&translationTable[i]+2) = (((bottom&0x0000ff)>> 0)*v)>>8;
*((unsigned char*)&translationTable[i]+3) = 0xff;
}
else
translationTable[i] = d_8to24rgbtable[sourceB[i]] | 0xff000000;
}
else if (top > 0 && (colorA[i] != 255))
translationTable[i] = d_8to24rgbtable[sourceA[i]] | 0xff000000;
{
if (top >= 16)
{
unsigned int v = d_8to24rgbtable[colorA[i]];
v = max(max((v>>0)&0xff, (v>>8)&0xff), (v>>16)&0xff);
*((unsigned char*)&translationTable[i]+0) = (((top&0xff0000)>>16)*v)>>8;
*((unsigned char*)&translationTable[i]+1) = (((top&0x00ff00)>> 8)*v)>>8;
*((unsigned char*)&translationTable[i]+2) = (((top&0x0000ff)>> 0)*v)>>8;
*((unsigned char*)&translationTable[i]+3) = 0xff;
}
else
translationTable[i] = d_8to24rgbtable[sourceA[i]] | 0xff000000;
}
else
translationTable[i] = d_8to24rgbtable[i] | 0xff000000;
}

View file

@ -442,7 +442,7 @@ void M_DrawServers(void);
void M_SListKey(int key);
//drawing funcs
void M_BuildTranslationTable(int top, int bottom, unsigned int *translationTable);
void M_BuildTranslationTable(unsigned int pc, unsigned int top, unsigned int bottom, unsigned int *translationTable);
void M_DrawCharacter (int cx, int line, unsigned int num);
void M_Print (int cx, int cy, qbyte *str);
void M_PrintWhite (int cx, int cy, qbyte *str);

View file

@ -258,15 +258,28 @@ struct pendingtextureinfo
} type;
enum
{
//these formats are specified as direct byte access
PTI_RGBA8, //rgba byte ordering
PTI_RGBX8, //rgb pad byte ordering
PTI_BGRA8, //alpha channel
PTI_BGRX8, //no alpha channel
//these formats are specified in native endian order
PTI_RGB565, //16bit alphaless format.
PTI_RGBA4444, //16bit format (gl)
PTI_ARGB4444, //16bit format (d3d)
PTI_RGBA5551, //16bit alpha format (gl).
PTI_ARGB1555, //16bit alpha format (d3d).
//compressed formats
PTI_S3RGB1,
PTI_S3RGBA1,
PTI_S3RGBA3,
PTI_S3RGBA5
PTI_S3RGBA5,
//depth formats
PTI_DEPTH16,
PTI_DEPTH24,
PTI_DEPTH32,
PTI_DEPTH24_8
#define PTI_MAX PTI_DEPTH24_8+1
} encoding; //0
int mipcount;
struct

View file

@ -175,8 +175,8 @@ void R2D_Init(void)
nogloss[i] = glossval;
nonorm[i] = normval;
}
missing_texture = R_LoadHiResTexture("no_texture", NULL, IF_NEAREST);
if (!TEXVALID(missing_texture))
missing_texture = R_LoadHiResTexture("no_texture", NULL, IF_NEAREST|IF_NOWORKER);
if (!TEXLOADED(missing_texture))
missing_texture = R_LoadTexture8("no_texture", 16, 16, (unsigned char*)r_notexture_mip + r_notexture_mip->offsets[0], IF_NOALPHA|IF_NOGAMMA, 0);
missing_texture_gloss = R_LoadTexture("no_texture_gloss", 4, 4, TF_RGBA32, (unsigned char*)nogloss, IF_NOGAMMA);
missing_texture_normal = R_LoadTexture("no_texture_normal", 4, 4, TF_RGBA32, (unsigned char*)nonorm, IF_NOGAMMA);
@ -194,12 +194,13 @@ void R2D_Init(void)
"map $diffuse\n"
"}\n"
"}\n");
if (!TEXVALID(draw_backtile->defaulttextures.base))
draw_backtile->defaulttextures.base = R_LoadHiResTexture("gfx/backtile", NULL, IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP);
if (!TEXVALID(draw_backtile->defaulttextures.base))
draw_backtile->defaulttextures.base = R_LoadHiResTexture("gfx/menu/backtile", NULL, IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP);
if (!TEXVALID(draw_backtile->defaulttextures.base))
draw_backtile->defaulttextures.base = R_LoadHiResTexture("pics/backtile", NULL, IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP);
TEXDOWAIT(draw_backtile->defaulttextures.base);
if (!TEXLOADED(draw_backtile->defaulttextures.base))
draw_backtile->defaulttextures.base = R_LoadHiResTexture("gfx/backtile", NULL, IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP|IF_NOWORKER);
if (!TEXLOADED(draw_backtile->defaulttextures.base))
draw_backtile->defaulttextures.base = R_LoadHiResTexture("gfx/menu/backtile", NULL, IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP|IF_NOWORKER);
if (!TEXLOADED(draw_backtile->defaulttextures.base))
draw_backtile->defaulttextures.base = R_LoadHiResTexture("pics/backtile", NULL, IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP|IF_NOWORKER);
shader_draw_fill = R_RegisterShader("fill_opaque", SUF_NONE,
"{\n"

View file

@ -359,7 +359,7 @@ enum imageflags
/*WARNING: If the above are changed, be sure to change shader pass flags*/
IF_NOPICMIP = 1<<5,
IF_NOALPHA = 1<<6,
IF_NOALPHA = 1<<6, /*hint rather than requirement*/
IF_NOGAMMA = 1<<7,
IF_3DMAP = 1<<8, /*waning - don't test directly*/
IF_CUBEMAP = 1<<9, /*waning - don't test directly*/

View file

@ -30,6 +30,7 @@ qboolean vid_isfullscreen;
#define SCREENOPTIONS "Screen Options"
unsigned int d_8to24rgbtable[256];
unsigned int d_8to24bgrtable[256];
extern int gl_anisotropy_factor;
@ -989,8 +990,10 @@ void R_GenPaletteLookup(void)
pal += 3;
d_8to24rgbtable[i] = (255<<24) + (r<<0) + (g<<8) + (b<<16);
d_8to24bgrtable[i] = (255<<24) + (b<<0) + (g<<8) + (r<<16);
}
d_8to24rgbtable[255] &= 0xffffff; // 255 is transparent
d_8to24bgrtable[255] &= 0xffffff; // 255 is transparent
}
qboolean R_ApplyRenderer (rendererstate_t *newr)

View file

@ -834,6 +834,7 @@ void Sbar_Start (void) //if one of these fails, skip the entire status bar.
}
#ifdef HEXEN2
sbar_hexen2 = false;
if (W_SafeGetLumpName("tinyfont"))
sbar_hexen2 = true;
// if (sb_nums[0][0] && sb_nums[0][0]->width < 13)

View file

@ -66,6 +66,7 @@ FIXME: a capture device would be useful (voice chat).
#ifdef FTE_TARGET_WEB //emscripten sucks.
AL_API void (AL_APIENTRY alSpeedOfSound)( ALfloat value ) {}
#define alGetError() alGetError(NULL)
#endif
#else

View file

@ -3258,6 +3258,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
return 0;
}
/*
GetModuleFileName(NULL, cwd, sizeof(cwd)-1);
for (e = cwd+strlen(cwd)-1; e >= cwd; e--)
{
@ -3267,7 +3268,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
break;
}
}
*/
}
}

View file

@ -83,6 +83,7 @@ typedef struct
extern viddef_t vid; // global video state
extern unsigned int d_8to24rgbtable[256];
extern unsigned int d_8to24bgrtable[256];
#ifdef GLQUAKE
//called when gamma ramps need to be reapplied

View file

@ -1309,6 +1309,9 @@ void V_CalcRefdef (playerview_t *pv)
vec3_t camorg, camdir;
trace_t tr;
float len;
//r_refdef.viewangles[0] += chase_pitch.value;
//r_refdef.viewangles[1] += chase_yaw.value;
//r_refdef.viewangles[2] += chase_roll.value;
AngleVectors(r_refdef.viewangles, axis[0], axis[1], axis[2]);
VectorScale(axis[0], -chase_back.value, camdir);
VectorMA(camdir, -chase_up.value, pv->gravitydir, camdir);

View file

@ -629,15 +629,13 @@ void Mod_ParseInfoFromEntityLump(model_t *wmodel, char *data, char *mapname) //a
}
else if (!strcmp("fog", key)) //q1 extension. FIXME: should be made temporary.
{
int oel = Cmd_ExecLevel;
void CL_Fog_f(void);
key[0] = 'f';
key[1] = ' ';
Q_strncpyz(key+2, token, sizeof(key)-2);
Cmd_TokenizeString(key, false, false);
Cmd_ExecLevel=RESTRICT_LOCAL;
CL_Fog_f();
Cmd_ExecLevel=oel;
key[1] = 'o';
key[2] = 'g';
key[3] = ' ';
Q_strncpyz(key+4, token, sizeof(key)-4);
Cbuf_AddText(key, RESTRICT_INSECURE);
}
else if (!strncmp("cvar_", key, 5)) //override cvars so mappers don't end up hacking cvars and fucking over configs (at least in other engines).
{

View file

@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// cmd.c -- Quake script command processing module
#include "quakedef.h"
#include "fs.h"
cvar_t rcon_level = SCVAR("rcon_level", "20");
cvar_t cmd_maxbuffersize = SCVAR("cmd_maxbuffersize", "65536");
@ -185,6 +186,11 @@ void Cbuf_Init (void)
cmd_text[level].waitattime = -1;
}
static void Cbuf_WorkerAddText(void *ctx, void *data, size_t a, size_t b)
{
Cbuf_AddText(data, a);
Z_Free(data);
}
/*
============
Cbuf_AddText
@ -196,6 +202,12 @@ void Cbuf_AddText (const char *text, int level)
{
int l;
if (!Sys_IsThread(NULL))
{
COM_AddWork(0, Cbuf_WorkerAddText, NULL, Z_StrDup(text), level, 0);
return;
}
if (level > sizeof(cmd_text)/sizeof(cmd_text[0]) || level < 0)
{
Con_Printf("Bad execution level\n");
@ -509,6 +521,10 @@ void Cmd_Exec_f (void)
{
char *f, *s;
char name[256];
flocation_t loc;
qboolean untrusted;
vfsfile_t *file;
size_t l;
if (Cmd_Argc () != 2)
{
@ -528,18 +544,27 @@ void Cmd_Exec_f (void)
else
Q_strncpyz(name, Cmd_Argv(1), sizeof(name));
if (!qofs_Error(FS_LoadFile(name, (void **)&f)))
;
else if (!qofs_Error(FS_LoadFile(va("%s.cfg", name), (void **)&f)))
;
else
if (!FS_FLocateFile(name, FSLFRT_IFFOUND, &loc) && !FS_FLocateFile(va("%s.cfg", name), FSLFRT_IFFOUND, &loc))
{
Con_TPrintf ("couldn't exec %s\n",name);
Con_TPrintf ("couldn't exec %s\n", name);
return;
}
file = FS_OpenReadLocation(&loc);
if (!file)
{
Con_TPrintf ("couldn't exec %s. check permissions.\n", name);
return;
}
if (cl_warncmd.ival || developer.ival)
Con_TPrintf ("execing %s\n",name);
l = VFS_GETLEN(file);
f = BZ_Malloc(l+1);
f[l] = 0;
VFS_READ(file, f, l);
VFS_CLOSE(file);
untrusted = !!(loc.search->flags&SPF_UNTRUSTED);
s = f;
if (s[0] == '\xef' && s[1] == '\xbb' && s[2] == '\xbf')
{
@ -554,13 +579,13 @@ void Cmd_Exec_f (void)
int cfgdepth = COM_FDepthFile(name, true);
int defdepth = COM_FDepthFile("default.cfg", true);
if (defdepth < cfgdepth)
Cbuf_InsertText("exec default.cfg\n", ((Cmd_FromGamecode() || com_file_untrusted) ? RESTRICT_INSECURE : Cmd_ExecLevel), false);
Cbuf_InsertText("exec default.cfg\n", ((Cmd_FromGamecode() || untrusted) ? RESTRICT_INSECURE : Cmd_ExecLevel), false);
}
// don't execute anything if it was from server (either the stuffcmd/localcmd, or the file)
if (!strcmp(name, "default.cfg") && !(Cmd_FromGamecode() || com_file_untrusted))
Cbuf_InsertText ("\ncvar_lockdefaults 1\n", ((Cmd_FromGamecode() || com_file_untrusted) ? RESTRICT_INSECURE : Cmd_ExecLevel), false);
Cbuf_InsertText (s, ((Cmd_FromGamecode() || com_file_untrusted) ? RESTRICT_INSECURE : Cmd_ExecLevel), true);
FS_FreeFile(f);
if (!strcmp(name, "default.cfg") && !(Cmd_FromGamecode() || untrusted))
Cbuf_InsertText ("\ncvar_lockdefaults 1\n", ((Cmd_FromGamecode() || untrusted) ? RESTRICT_INSECURE : Cmd_ExecLevel), false);
Cbuf_InsertText (s, ((Cmd_FromGamecode() || untrusted) ? RESTRICT_INSECURE : Cmd_ExecLevel), true);
BZ_Free(f);
}

View file

@ -3251,12 +3251,17 @@ qboolean QDECL Mod_LoadQ1Model (model_t *mod, void *buffer, size_t fsize)
//skins
skinstart = (daliasskintype_t *)((char*)pq1inmodel+hdrsize);
#ifdef HEXEN2
if( mod->flags & MFH2_TRANSPARENT )
skintranstype = TF_H2_T7G1; //hexen2
else if( mod->flags & MFH2_HOLEY )
else
#endif
if( mod->flags & MFH2_HOLEY )
skintranstype = TF_H2_TRANS8_0; //hexen2
#ifdef HEXEN2
else if( mod->flags & MFH2_SPECIAL_TRANS )
skintranstype = TF_H2_T4A4; //hexen2
#endif
else
skintranstype = TF_SOLID8;

View file

@ -336,8 +336,6 @@ char *VARGS va(const char *format, ...) LIKEPRINTF(1);
//============================================================================
extern qboolean com_file_copyprotected;
extern qboolean com_file_untrusted;
struct cache_user_s;
extern char com_gamepath[MAX_OSPATH];
@ -365,6 +363,22 @@ void COM_WriteFile (const char *filename, const void *data, int len);
#define qofs_Error(o) ((o) == ~0ul)
#endif
typedef struct searchpathfuncs_s searchpathfuncs_t;
typedef struct searchpath_s
{
searchpathfuncs_t *handle;
unsigned int flags;
char logicalpath[MAX_OSPATH]; //printable hunam-readable location of the package. generally includes a system path, including nested packages.
char purepath[256]; //server tracks the path used to load them so it can tell the client
int crc_check; //client sorts packs according to this checksum
int crc_reply; //client sends a different crc back to the server, for the paks it's actually loaded.
int orderkey; //used to check to see if the paths were actually changed or not.
struct searchpath_s *next;
struct searchpath_s *nextpure;
} searchpath_t;
typedef struct {
struct searchpath_s *search; //used to say which filesystem driver to open the file from
int index; //used by the filesystem driver as a simple reference to the file
@ -405,7 +419,6 @@ typedef struct vfsfile_s
char dbgname[MAX_QPATH];
#endif
} vfsfile_t;
typedef struct searchpathfuncs_s searchpathfuncs_t;
#define VFS_CLOSE(vf) ((vf)->Close(vf))
#define VFS_TELL(vf) ((vf)->Tell(vf))

View file

@ -679,6 +679,8 @@ cvar_t *Cvar_SetCore (cvar_t *var, const char *value, qboolean force)
{ //fixme: force should probably be a latch bitmask
char *latch=NULL;
COM_AssertMainThread("Cvar_SetCore");
if (!var)
return NULL;

View file

@ -161,10 +161,6 @@ char pubgamedirfile[MAX_OSPATH]; //like gamedirfile, but not set to the fte-only
//the various COM_LoadFiles set these on return
qboolean com_file_copyprotected;//file should not be available for download.
qboolean com_file_untrusted; //file was downloaded inside a package
char com_gamepath[MAX_OSPATH]; //c:\games\quake
char com_homepath[MAX_OSPATH]; //c:\users\foo\my docs\fte\quake
qboolean com_homepathenabled;
@ -490,23 +486,6 @@ ftemanifest_t *FS_Manifest_Parse(const char *fname, const char *data)
//======================================================================================================
typedef struct searchpath_s
{
searchpathfuncs_t *handle;
unsigned int flags;
char logicalpath[MAX_OSPATH]; //printable hunam-readable location of the package. generally includes a system path, including nested packages.
char purepath[256]; //server tracks the path used to load them so it can tell the client
int crc_check; //client sorts packs according to this checksum
int crc_reply; //client sends a different crc back to the server, for the paks it's actually loaded.
int orderkey; //used to check to see if the paths were actually changed or not.
struct searchpath_s *next;
struct searchpath_s *nextpure;
} searchpath_t;
static ftemanifest_t *fs_manifest; //currently active manifest.
static searchpath_t *com_searchpaths;
static searchpath_t *com_purepaths;
@ -945,9 +924,6 @@ int FS_FLocateFile(const char *filename, FSLF_ReturnType_e returntype, flocation
search->flags |= fs_referencetype;
}
loc->search = search;
com_file_copyprotected = !!(search->flags & SPF_COPYPROTECTED);
com_file_untrusted = !!(search->flags & SPF_UNTRUSTED);
break;
}
}
@ -970,8 +946,6 @@ int FS_FLocateFile(const char *filename, FSLF_ReturnType_e returntype, flocation
search->flags |= fs_referencetype;
}
loc->search = search;
com_file_copyprotected = !!(search->flags & SPF_COPYPROTECTED);
com_file_untrusted = !!(search->flags & SPF_UNTRUSTED);
break;
}
}
@ -1455,8 +1429,6 @@ vfsfile_t *FS_OpenVFS(const char *filename, const char *mode, enum fs_relative r
if (loc.search)
{
com_file_copyprotected = !!(loc.search->flags & SPF_COPYPROTECTED);
com_file_untrusted = !!(loc.search->flags & SPF_UNTRUSTED);
return VFS_Filter(filename, loc.search->handle->OpenVFS(loc.search->handle, &loc, mode));
}
@ -1474,8 +1446,6 @@ vfsfile_t *FS_OpenReadLocation(flocation_t *location)
{
if (location->search)
{
com_file_copyprotected = !!(location->search->flags & SPF_COPYPROTECTED);
com_file_untrusted = !!(location->search->flags & SPF_UNTRUSTED);
return VFS_Filter(NULL, location->search->handle->OpenVFS(location->search->handle, location, "rb"));
}
return NULL;
@ -3974,6 +3944,113 @@ void FS_EnumerateKnownGames(qboolean (*callback)(void *usr, ftemanifest_t *man),
}
}
//attempts to find a new basedir for 'input', changing to it as appropriate
//returns fixed up filename relative to the new gamedir.
//input must be an absolute path.
qboolean FS_FixupGamedirForExternalFile(char *input, char *filename, size_t fnamelen)
{
char syspath[MAX_OSPATH];
char gamepath[MAX_OSPATH];
void *iterator;
char *sep,*bs;
char *src = NULL;
Q_strncpyz(filename, input, fnamelen);
iterator = NULL;
while(COM_IteratePaths(&iterator, syspath, sizeof(syspath), gamepath, sizeof(gamepath)))
{
if (!Q_strncasecmp(syspath, filename, strlen(syspath)))
{
src = filename+strlen(syspath);
memmove(filename, src, strlen(src)+1);
break;
}
}
if (!src)
{
for(;;)
{
sep = strchr(filename, '\\');
if (sep)
*sep = '/';
else
break;
}
for (sep = NULL;;)
{
bs = sep;
sep = strrchr(filename, '/');
if (bs)
*bs = '/';
if (sep)
{
int game;
*sep = 0;
if (strchr(filename, '/')) //make sure there's always at least one /
{
char temp[MAX_OSPATH];
Q_snprintfz(temp, sizeof(temp), "%s/", filename);
game = FS_IdentifyDefaultGameFromDir(temp);
if (game != -1)
{
static char newbase[MAX_OSPATH];
if (!host_parms.basedir || strcmp(host_parms.basedir, filename))
{
Con_Printf("switching basedir+game to %s for %s\n", filename, input);
Q_strncpyz(newbase, filename, sizeof(newbase));
host_parms.basedir = newbase;
FS_ChangeGame(FS_GenerateLegacyManifest(NULL, 0, true, game), true);
}
*sep = '/';
sep = NULL;
src = filename+strlen(host_parms.basedir);
memmove(filename, src, strlen(src)+1);
break;
}
}
}
else
break;
}
if (sep)
*sep = '/';
}
if (!src && host_parms.binarydir && !Q_strncasecmp(host_parms.binarydir, filename, strlen(host_parms.binarydir)))
{
src = filename+strlen(host_parms.binarydir);
memmove(filename, src, strlen(src)+1);
}
if (!src && host_parms.basedir && !Q_strncasecmp(host_parms.basedir, filename, strlen(host_parms.basedir)))
{
src = filename+strlen(host_parms.basedir);
memmove(filename, src, strlen(src)+1);
}
if (!src)
{
Q_snprintfz(filename, fnamelen, "#%s", input);
return false;
}
if (*filename == '/' || *filename == '\\')
memmove(filename, filename+1, strlen(filename+1)+1);
sep = strchr(filename, '/');
bs = strchr(filename, '\\');
if (bs && (!sep || bs < sep))
sep = bs;
if (sep)
{
Con_Printf("switching gamedir for %s\n", filename);
*sep = 0;
COM_Gamedir(filename);
memmove(filename, sep+1, strlen(sep+1)+1);
return true;
}
Q_snprintfz(filename, fnamelen, "#%s", input);
return false;
}
void FS_ChangeGame_f(void)
{
int i;

View file

@ -173,7 +173,7 @@ int NetadrToSockadr (netadr_t *a, struct sockaddr_qstorage *s)
return sizeof(struct sockaddr_ipx);
#endif
default:
Sys_Error("Bad type - needs fixing");
Sys_Error("NetadrToSockadr: Bad type %i", a->type);
return 0;
}
}

View file

@ -133,13 +133,31 @@ qboolean D3D11_LoadTextureMips(image_t *tex, struct pendingtextureinfo *mips)
else if (mips->type == PTI_3D)
return false; //nyi
//d3d11.1 formats
#define DXGI_FORMAT_B4G4R4A4_UNORM 115
switch(mips->encoding)
{
case PTI_RGBA8:
tdesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
default:
return false;
case PTI_RGB565:
tdesc.Format = DXGI_FORMAT_B5G6R5_UNORM;
break;
case PTI_RGBX8:
tdesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; //d3d11 has no alphaless format. be sure to proprly disable alpha in the shader.
// case PTI_RGBA5551:
// tdesc.Format = DXGI_FORMAT_A1B5G5R5_UNORM;
// break;
case PTI_ARGB1555:
tdesc.Format = DXGI_FORMAT_B5G5R5A1_UNORM;
break;
case PTI_RGBA4444:
tdesc.Format = DXGI_FORMAT_B4G4R4A4_UNORM;
break;
// case PTI_ARGB4444:
// tdesc.Format = DXGI_FORMAT_A4B4G4R4_UNORM;
// break;
case PTI_RGBA8:
case PTI_RGBX8: //d3d11 has no alphaless format. be sure to proprly disable alpha in the shader.
tdesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
break;
case PTI_BGRA8:
tdesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;

View file

@ -535,8 +535,6 @@ qboolean D3D11Shader_Init(unsigned int flevel)
{NULL,NULL}
};
memset(&sh_config, 0, sizeof(sh_config));
for (ver = 47; ver >= 33; ver--)
{
shaderlib = Sys_LoadLibrary(va("D3dcompiler_%i.dll", ver), (ver>=40)?funcsnew:funcsold);
@ -565,7 +563,6 @@ qboolean D3D11Shader_Init(unsigned int flevel)
sh_config.pCreateProgram = D3D11Shader_CreateProgram;
sh_config.pProgAutoFields = NULL;
sh_config.texture_non_power_of_two = true;
sh_config.tex_env_combine = 1;
sh_config.nv_tex_env_combine4 = 1;
sh_config.env_add = 1;

View file

@ -8,78 +8,6 @@
#include <d3d9.h>
extern LPDIRECT3DDEVICE9 pD3DDev9;
static void Upload_Texture_32(LPDIRECT3DTEXTURE9 tex, unsigned int *data, int width, int height, unsigned int flags)
{
int x, y;
unsigned int *dest;
unsigned char swapbuf[4];
unsigned char swapbuf2[4];
D3DLOCKED_RECT lock;
D3DSURFACE_DESC desc;
IDirect3DTexture9_GetLevelDesc(tex, 0, &desc);
IDirect3DTexture9_LockRect(tex, 0, &lock, NULL, D3DLOCK_NOSYSLOCK);
if (width == desc.Width && height == desc.Height)
{
for (y = 0; y < height; y++)
{
dest = (unsigned int *)((char *)lock.pBits + lock.Pitch*y);
for (x = 0; x < width; x++)
{
*(unsigned int*)swapbuf2 = *(unsigned int*)swapbuf = data[x];
swapbuf[0] = swapbuf2[2];
swapbuf[2] = swapbuf2[0];
dest[x] = *(unsigned int*)swapbuf;
}
data += width;
}
}
else
{
int x, y;
int iny;
unsigned int *row, *inrow;
for (y = 0; y < desc.Height; y++)
{
row = (unsigned int*)((char *)lock.pBits + lock.Pitch*y);
iny = (y * height) / desc.Height;
inrow = data + width*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] = *(unsigned int*)swapbuf;
}
}
}
#if 0 //D3DUSAGE_AUTOGENMIPMAP so this isn't needed
if (!(flags & IF_NOMIPMAP))
{
int max = IDirect3DTexture9_GetLevelCount(tex);
for (i = 1; i < max; i++)
{
width = desc.Width;
height = desc.Height;
data = lock.pBits;
IDirect3DTexture9_LockRect(tex, i, &lock, NULL, D3DLOCK_NOSYSLOCK|D3DLOCK_DISCARD);
IDirect3DTexture9_GetLevelDesc(tex, i, &desc);
D3D_MipMap(lock.pBits, desc.Width, desc.Height, data, width, height);
IDirect3DTexture9_UnlockRect(tex, i-1);
}
IDirect3DTexture9_UnlockRect(tex, i-1);
}
else
#endif
IDirect3DTexture9_UnlockRect(tex, 0);
}
void D3D9_DestroyTexture (texid_t tex)
{
if (!tex)
@ -99,14 +27,33 @@ qboolean D3D9_LoadTextureMips(image_t *tex, struct pendingtextureinfo *mips)
D3DSURFACE_DESC desc;
IDirect3DTexture9 *dt;
qboolean swap = false;
unsigned int pixelsize = 4;
switch(mips->encoding)
{
case PTI_RGB565:
pixelsize = 2;
fmt = D3DFMT_R5G6B5;
break;
case PTI_RGBA4444://not supported on d3d9
return false;
case PTI_ARGB4444:
pixelsize = 2;
fmt = D3DFMT_A4R4G4B4;
break;
case PTI_RGBA5551://not supported on d3d9
return false;
case PTI_ARGB1555:
pixelsize = 2;
fmt = D3DFMT_A1R5G5B5;
break;
case PTI_RGBA8:
// fmt = D3DFMT_A8B8G8R8; /*how do we check
fmt = D3DFMT_A8R8G8B8;
swap = true;
break;
case PTI_RGBX8:
// fmt = D3DFMT_X8B8G8R8;
fmt = D3DFMT_X8R8G8B8;
swap = true;
break;
@ -119,9 +66,15 @@ qboolean D3D9_LoadTextureMips(image_t *tex, struct pendingtextureinfo *mips)
//too lazy to support these for now
case PTI_S3RGB1:
case PTI_S3RGBA1:
case PTI_S3RGBA1: //d3d doesn't distinguish between these
// fmt = D3DFMT_DXT1;
// break;
case PTI_S3RGBA3:
// fmt = D3DFMT_DXT3;
// break;
case PTI_S3RGBA5:
// fmt = D3DFMT_DXT5;
// break;
return false;
default: //no idea
@ -158,8 +111,8 @@ qboolean D3D9_LoadTextureMips(image_t *tex, struct pendingtextureinfo *mips)
}
else
{
for (y = 0, out = lock.pBits, in = mips->mip[i].data; y < mips->mip[i].height; y++, out += lock.Pitch, in += mips->mip[i].width*4)
memcpy(out, in, mips->mip[i].width*4);
for (y = 0, out = lock.pBits, in = mips->mip[i].data; y < mips->mip[i].height; y++, out += lock.Pitch, in += mips->mip[i].width*pixelsize)
memcpy(out, in, mips->mip[i].width*pixelsize);
}
IDirect3DTexture9_UnlockRect(dt, i);
}

View file

@ -351,6 +351,8 @@ void D3D9Shader_DeleteProg(program_t *prog, unsigned int permu)
void D3D9Shader_Init(void)
{
D3DCAPS9 caps;
dllfunction_t funcs[] =
{
{(void**)&pD3DXCompileShader, "D3DXCompileShader"},
@ -378,9 +380,22 @@ void D3D9Shader_Init(void)
sh_config.pProgAutoFields = D3D9Shader_ProgAutoFields;
sh_config.texture_non_power_of_two = 0;
sh_config.texture_non_power_of_two_pic = 0;
sh_config.tex_env_combine = 1;
sh_config.nv_tex_env_combine4 = 1;
sh_config.env_add = 1;
//FIXME: check caps
sh_config.texfmt[PTI_RGBX8] = true; //fixme: shouldn't support
sh_config.texfmt[PTI_RGBA8] = true; //fixme: shouldn't support
sh_config.texfmt[PTI_BGRX8] = true;
sh_config.texfmt[PTI_BGRA8] = true;
sh_config.texfmt[PTI_RGB565] = true;
sh_config.texfmt[PTI_ARGB1555] = true;
sh_config.texfmt[PTI_ARGB4444] = true;
IDirect3DDevice9_GetDeviceCaps(pD3DDev9, &caps);
sh_config.texture_maxsize = min(caps.MaxTextureWidth, caps.MaxTextureHeight);
}
#endif

View file

@ -657,6 +657,7 @@ static qboolean D3D11_VID_Init(rendererstate_t *info, unsigned char *palette)
#else
static qboolean initD3D11Device(HWND hWnd, rendererstate_t *info, PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN func, IDXGIAdapter *adapt)
{
UINT support;
int flags = 0;//= D3D11_CREATE_DEVICE_SINGLETHREADED;
D3D_DRIVER_TYPE drivertype;
DXGI_SWAP_CHAIN_DESC scd;
@ -740,17 +741,35 @@ static qboolean initD3D11Device(HWND hWnd, rendererstate_t *info, PFN_D3D11_CREA
{
}
r_config.texture_non_power_of_two = flevel>=D3D_FEATURE_LEVEL_10_0; //npot MUST be supported on all d3d10+ cards.
r_config.texture_non_power_of_two_pic = true; //always supported in d3d11, supposedly.
r_config.npot_rounddown = false;
memset(&sh_config, 0, sizeof(sh_config));
sh_config.texture_non_power_of_two = flevel>=D3D_FEATURE_LEVEL_10_0; //npot MUST be supported on all d3d10+ cards.
sh_config.texture_non_power_of_two_pic = true; //always supported in d3d11, supposedly, even with d3d9 devices.
sh_config.npot_rounddown = false;
if (flevel>=D3D_FEATURE_LEVEL_11_0)
r_config.maxtexturesize = 16384;
sh_config.texture_maxsize = 16384;
else if (flevel>=D3D_FEATURE_LEVEL_10_0)
r_config.maxtexturesize = 8192;
sh_config.texture_maxsize = 8192;
else if (flevel>=D3D_FEATURE_LEVEL_9_3)
r_config.maxtexturesize = 4096;
sh_config.texture_maxsize = 4096;
else
r_config.maxtexturesize = 2048;
sh_config.texture_maxsize = 2048;
//11.1 formats
#define DXGI_FORMAT_B4G4R4A4_UNORM 115
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_B5G6R5_UNORM, &support); sh_config.texfmt[PTI_RGB565] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_B5G5R5A1_UNORM, &support); sh_config.texfmt[PTI_ARGB1555] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_B4G4R4A4_UNORM, &support); sh_config.texfmt[PTI_ARGB4444] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_R8G8B8A8_UNORM, &support); sh_config.texfmt[PTI_RGBA8] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_B8G8R8A8_UNORM, &support); sh_config.texfmt[PTI_BGRA8] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_B8G8R8X8_UNORM, &support); sh_config.texfmt[PTI_BGRX8] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC1_UNORM, &support); sh_config.texfmt[PTI_S3RGBA1] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC2_UNORM, &support); sh_config.texfmt[PTI_S3RGBA3] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC3_UNORM, &support); sh_config.texfmt[PTI_S3RGBA5] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
//these formats are not officially supported as specified, but noone cares
sh_config.texfmt[PTI_RGBX8] = sh_config.texfmt[PTI_RGBA8];
sh_config.texfmt[PTI_S3RGB1] = sh_config.texfmt[PTI_S3RGBA1];
vid.numpages = scd.BufferCount;
if (!D3D11Shader_Init(flevel))

View file

@ -630,7 +630,6 @@ Global
{74542CA7-48C1-4664-9007-66F751131EA3}.Release|Win32.Build.0 = Release|Win32
{74542CA7-48C1-4664-9007-66F751131EA3}.Release|x64.ActiveCfg = Release|Win32
{75D91BDE-CC30-4C53-BF33-5F69EF13A61B}.D3DDebug|Win32.ActiveCfg = Debug|Win32
{75D91BDE-CC30-4C53-BF33-5F69EF13A61B}.D3DDebug|Win32.Build.0 = Debug|Win32
{75D91BDE-CC30-4C53-BF33-5F69EF13A61B}.D3DDebug|x64.ActiveCfg = Debug|Win32
{75D91BDE-CC30-4C53-BF33-5F69EF13A61B}.D3DRelease|Win32.ActiveCfg = Release|Win32
{75D91BDE-CC30-4C53-BF33-5F69EF13A61B}.D3DRelease|Win32.Build.0 = Release|Win32

View file

@ -751,7 +751,7 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e
}
if (!original)
{
if (skins->numframes && skins->frame[subframe].texels)
if (skins && skins->numframes && skins->frame[subframe].texels)
{
original = skins->frame[subframe].texels;
inwidth = skins->skinwidth;
@ -764,8 +764,16 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e
inheight = 0;
}
}
tinwidth = skins->skinwidth;
tinheight = skins->skinheight;
if (skins)
{
tinwidth = skins->skinwidth;
tinheight = skins->skinheight;
}
else
{
tinwidth = inwidth;
tinheight = inheight;
}
if (original)
{
int i, j;
@ -835,9 +843,33 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e
{
translate32[i] = d_8to24rgbtable[i];
if (tc > 0 && (colorA[i] != 255))
translate32[i] = d_8to24rgbtable[sourceA[i]];
{
if (tc >= 16)
{
unsigned int v = d_8to24rgbtable[colorA[i]];
v = max(max((v>>0)&0xff, (v>>8)&0xff), (v>>16)&0xff);
*((unsigned char*)&translate32[i]+0) = (((tc&0xff0000)>>16)*v)>>8;
*((unsigned char*)&translate32[i]+1) = (((tc&0x00ff00)>> 8)*v)>>8;
*((unsigned char*)&translate32[i]+2) = (((tc&0x0000ff)>> 0)*v)>>8;
*((unsigned char*)&translate32[i]+3) = 0xff;
}
else
translate32[i] = d_8to24rgbtable[sourceA[i]];
}
if (bc > 0 && (colorB[i] != 255))
translate32[i] = d_8to24rgbtable[sourceB[i]];
{
if (bc >= 16)
{
unsigned int v = d_8to24rgbtable[colorB[i]];
v = max(max((v>>0)&0xff, (v>>8)&0xff), (v>>16)&0xff);
*((unsigned char*)&translate32[i]+0) = (((bc&0xff0000)>>16)*v)>>8;
*((unsigned char*)&translate32[i]+1) = (((bc&0x00ff00)>> 8)*v)>>8;
*((unsigned char*)&translate32[i]+2) = (((bc&0x0000ff)>> 0)*v)>>8;
*((unsigned char*)&translate32[i]+3) = 0xff;
}
else
translate32[i] = d_8to24rgbtable[sourceB[i]];
}
}
translate32[0] = 0;
}

View file

@ -1010,7 +1010,7 @@ static void T_Gen_CurrentRender(int tmu)
if (r_refdef.recurse)
return;
if (gl_config.texture_non_power_of_two_limited)
if (sh_config.texture_non_power_of_two_pic)
{
vwidth = pwidth;
vheight = pheight;
@ -3044,7 +3044,7 @@ static void BE_Program_Set_Attributes(const program_t *prog, unsigned int perm,
break;
case SP_RENDERTEXTURESCALE:
if (gl_config.texture_non_power_of_two_limited)
if (sh_config.texture_non_power_of_two_pic)
{
param4[0] = 1;
param4[1] = 1;

View file

@ -181,7 +181,7 @@ qboolean R_CanBloom(void)
return false;
if (!gl_config.arb_shader_objects)
return false;
if (!gl_config.texture_non_power_of_two_limited)
if (!sh_config.texture_non_power_of_two_pic)
return false;
return true;

View file

@ -59,9 +59,6 @@ Draw_Init
*/
void GLDraw_Init (void)
{
r_config.maxtexturesize = 256;
qglGetIntegerv(GL_MAX_TEXTURE_SIZE, &r_config.maxtexturesize);
R2D_Init();
TRACE(("dbg: GLDraw_ReInit: GL_BeginRendering\n"));
@ -277,6 +274,18 @@ qboolean GL_LoadTextureMips(texid_t tex, struct pendingtextureinfo *mips)
int targ, targface;
int i, j;
if (gl_config.gles)
{
//gles requires that the internal format must match format
//this means we can't specify 24.0 modes with a 24.8 datatype.
//arguably we shouldn't do this anyway, but there are differences that q3 shaders can notice.
//fixme: move elsewhere?
if (mips->encoding == PTI_RGBX8)
mips->encoding = PTI_RGBA8;
if (mips->encoding == PTI_BGRX8)
mips->encoding = PTI_BGRA8;
}
if (!tex->num)
qglGenTextures(1, &tex->num);
@ -335,6 +344,15 @@ qboolean GL_LoadTextureMips(texid_t tex, struct pendingtextureinfo *mips)
default:
qglTexImage3D(targface, i, GL_RGBA, size, size, size, 0, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, mips->mip[i].data);
break;
case PTI_RGBA4444:
qglTexImage3D(targface, i, GL_RGBA, size, size, size, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, mips->mip[i].data);
break;
case PTI_RGBA5551:
qglTexImage3D(targface, i, GL_RGBA, size, size, size, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, mips->mip[i].data);
break;
case PTI_RGB565:
qglTexImage3D(targface, i, GL_RGB, size, size, size, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, mips->mip[i].data);
break;
}
if (mips->mip[i].needfree)
@ -358,6 +376,7 @@ qboolean GL_LoadTextureMips(texid_t tex, struct pendingtextureinfo *mips)
}
switch(mips->encoding)
{
//32bit formats
case PTI_RGBX8:
qglTexImage2D(targface, j, GL_RGB, mips->mip[i].width, mips->mip[i].height, 0, GL_RGBA, GL_UNSIGNED_BYTE, mips->mip[i].data);
break;
@ -371,6 +390,23 @@ qboolean GL_LoadTextureMips(texid_t tex, struct pendingtextureinfo *mips)
default:
qglTexImage2D(targface, j, GL_RGBA, mips->mip[i].width, mips->mip[i].height, 0, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, mips->mip[i].data);
break;
//16bit formats
case PTI_RGBA4444:
qglTexImage2D(targface, j, GL_RGBA, mips->mip[i].width, mips->mip[i].height, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, mips->mip[i].data);
break;
case PTI_RGBA5551:
qglTexImage2D(targface, j, GL_RGBA, mips->mip[i].width, mips->mip[i].height, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, mips->mip[i].data);
break;
case PTI_ARGB4444:
qglTexImage2D(targface, j, GL_RGBA, mips->mip[i].width, mips->mip[i].height, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV, mips->mip[i].data);
break;
case PTI_ARGB1555:
qglTexImage2D(targface, j, GL_RGBA, mips->mip[i].width, mips->mip[i].height, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV, mips->mip[i].data);
break;
case PTI_RGB565:
qglTexImage2D(targface, j, GL_RGB, mips->mip[i].width, mips->mip[i].height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, mips->mip[i].data);
break;
//compressed formats
case PTI_S3RGB1:
qglCompressedTexImage2DARB(targface, j, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, mips->mip[i].width, mips->mip[i].height, 0, mips->mip[i].datasize, mips->mip[i].data);
break;

View file

@ -3553,8 +3553,7 @@ static qboolean Mod_LoadLeafs (model_t *loadmodel, qbyte *mod_base, lump_t *l, i
p = LittleLong(in->contents);
out->contents = p;
out->firstmarksurface = loadmodel->marksurfaces +
(unsigned short)LittleShort(in->firstmarksurface);
out->firstmarksurface = loadmodel->marksurfaces + (unsigned short)LittleShort(in->firstmarksurface);
out->nummarksurfaces = (unsigned short)LittleShort(in->nummarksurfaces);
p = LittleLong(in->visofs);
@ -3878,8 +3877,14 @@ qboolean Mod_LoadClipnodes (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboo
for (i=0 ; i<count ; i++, out++, ins++)
{
out->planenum = LittleLong(ins->planenum);
out->children[0] = LittleShort(ins->children[0]);
out->children[1] = LittleShort(ins->children[1]);
out->children[0] = (unsigned short)LittleShort(ins->children[0]);
out->children[1] = (unsigned short)LittleShort(ins->children[1]);
//if these 'overflow', then they're meant to refer to contents instead, and should be negative
if (out->children[0] >= count)
out->children[0] -= 0x10000;
if (out->children[1] >= count)
out->children[1] -= 0x10000;
}
}

View file

@ -73,7 +73,10 @@ void R_AnimateLight (void)
{
int v1, v2, vd;
if (!cl_lightstyle[j].length)
{
d_lightstylevalue[j] = 256;
continue;
}
if (cl_lightstyle[j].map[0] == '=')
{
@ -401,6 +404,9 @@ void R_GenDlightBatches(batch_t *batches[])
int i, j, sort;
dlight_t *l;
batch_t *b;
if (!r_lightprepass.ival)
return;
if (!lpplight_shader)
lpplight_shader = R_RegisterShader("lpp_light", SUF_NONE,
"{\n"

View file

@ -1303,7 +1303,7 @@ static void R_RenderMotionBlur(void)
shader_t *shader;
//figure out the size of our texture.
if (gl_config.texture_non_power_of_two_limited)
if (sh_config.texture_non_power_of_two_pic)
{ //we can use any size, supposedly
vwidth = vid.pixelwidth;
vheight = vid.pixelheight;
@ -1618,7 +1618,7 @@ void GLR_RenderView (void)
}
//disable stuff if its simply not supported.
if (dofbo || !gl_config.arb_shader_objects || !gl_config.ext_framebuffer_objects || !gl_config.texture_non_power_of_two_limited)
if (dofbo || !gl_config.arb_shader_objects || !gl_config.ext_framebuffer_objects || !sh_config.texture_non_power_of_two_pic)
r_refdef.flags &= ~(RDF_ALLPOSTPROC); //block all of this stuff

View file

@ -43,7 +43,6 @@ static qboolean shader_rescan_needed;
static char **saveshaderbody;
sh_config_t sh_config;
r_config_t r_config;
//cvars that affect shader generation
cvar_t r_vertexlight = CVARFD("r_vertexlight", "0", CVAR_SHADERSYSTEM, "Hack loaded shaders to remove detail pass and lightmap sampling for faster rendering.");
@ -1266,7 +1265,10 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
if (!sh_config.pValidateProgram(prog, name, p, (p & PERMUTATION_SKELETAL)?true:onefailed, blobfile))
{
if (!(p & PERMUTATION_SKELETAL))
{
onefailed = true; //don't flag it if skeletal failed.
continue;
}
if (!p)
break;
}
@ -3973,11 +3975,7 @@ void QDECL R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader)
if (r_loadbumpmapping)
{
if (!TEXVALID(tn->bump))
tn->bump = R_LoadHiResTexture(va("%s_norm", imagename), subpath, IF_NOALPHA);
if (!TEXVALID(tn->bump))
tn->bump = R_LoadHiResTexture(va("%s_bump", imagename), subpath, IF_NOALPHA);
if (!TEXVALID(tn->bump))
tn->bump = R_LoadHiResTexture(va("normalmaps/%s", imagename), subpath, IF_NOALPHA);
tn->bump = R_LoadHiResTexture(va("%s_norm", imagename), subpath, IF_TRYBUMP);
}
TEXASSIGN(shader->defaulttextures.bump, tn->bump);
}
@ -4740,13 +4738,13 @@ void Shader_Default2D(const char *shortname, shader_t *s, const void *genargs)
"clampmap $diffuse\n"
"rgbgen vertex\n"
"alphagen vertex\n"
"blendfunc gl_src_alpha gl_one_minus_src_alpha\n"
"blendfunc gl_one gl_one_minus_src_alpha\n"
"}\n"
"sort additive\n"
"}\n"
);
TEXASSIGN(s->defaulttextures.base, R_LoadHiResTexture(s->name, NULL, IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP|IF_CLAMP));
TEXASSIGN(s->defaulttextures.base, R_LoadHiResTexture(s->name, NULL, IF_PREMULTIPLYALPHA|IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP|IF_CLAMP));
}
qboolean Shader_ReadShaderTerms(shader_t *s, char **shadersource, int parsemode, int *conddepth, int maxconddepth, int *cond)
@ -5341,6 +5339,13 @@ int R_GetShaderSizes(shader_t *shader, int *width, int *height, qboolean blockti
break;
}
}
if (i == shader->numpasses)
{ //this shader has no textures from which to source a width and height
if (!shader->width)
shader->width = 64;
if (!shader->height)
shader->height = 64;
}
}
if (shader->width && shader->height)
{

View file

@ -603,21 +603,20 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
//geforcefx apparently software emulates it, so gl<3 is bad.
if (GL_CheckExtension("GL_ARB_texture_non_power_of_two"))
{
gl_config.texture_non_power_of_two = true;
sh_config.texture_non_power_of_two = true;
//gles2 has limited npot as standard, which is sufficient to make the hud not look like poo. lets use it.
if ((gl_config.gles && gl_config.glversion >= 2) || gl_config.texture_non_power_of_two)
gl_config.texture_non_power_of_two_limited = true;
r_config.texture_non_power_of_two_pic = true;
if ((gl_config.gles && gl_config.glversion >= 2) || sh_config.texture_non_power_of_two)
sh_config.texture_non_power_of_two_pic = true;
}
else if (GL_CheckExtension("GL_OES_texture_npot"))
{
r_config.texture_non_power_of_two = false;
r_config.texture_non_power_of_two_pic = true;
sh_config.texture_non_power_of_two = false;
sh_config.texture_non_power_of_two_pic = true;
}
else
{
r_config.texture_non_power_of_two = false;
r_config.texture_non_power_of_two_pic = false;
sh_config.texture_non_power_of_two = false;
sh_config.texture_non_power_of_two_pic = false;
}
// if (GL_CheckExtension("GL_SGIS_generate_mipmap")) //a suprising number of implementations have this broken.
@ -1659,6 +1658,8 @@ GLhandleARB GLSlang_ValidateProgram(GLhandleARB program, const char *name, qbool
char *nullconstants = NULL;
GLint linked;
if (!program)
return (GLhandleARB)0;
qglGetProgramParameteriv_(program, GL_OBJECT_LINK_STATUS_ARB, &linked);
if(!linked)
@ -2072,6 +2073,8 @@ void GL_Init(void *(*getglfunction) (char *name))
gl_version = qglGetString (GL_VERSION);
Con_SafePrintf ("GL_VERSION: %s\n", gl_version);
memset(&sh_config, 0, sizeof(sh_config));
GL_CheckExtensions (getglfunction);
if ((gl_config.gles && gl_config.glversion >= 3) || (!gl_config.gles && gl_config.glversion >= 2))
@ -2124,11 +2127,29 @@ void GL_Init(void *(*getglfunction) (char *name))
qglGetError(); /*suck up the invalid operation error for non-debug contexts*/
#endif
sh_config.texture_maxsize = 256; //early minidrivers might not implement this, but anything else should.
qglGetIntegerv(GL_MAX_TEXTURE_SIZE, &sh_config.texture_maxsize);
//always supported
sh_config.texfmt[PTI_RGBA8] = true;
if (GL_CheckExtension("GL_EXT_texture_compression_s3tc"))
{
sh_config.texfmt[PTI_S3RGB1] = true;
sh_config.texfmt[PTI_S3RGBA1] = true;
sh_config.texfmt[PTI_S3RGBA3] = true;
sh_config.texfmt[PTI_S3RGBA5] = true;
}
memset(&sh_config, 0, sizeof(sh_config));
if (gl_config.gles)
{
sh_config.texfmt[PTI_RGBX8] = sh_config.texfmt[PTI_RGBA8]; //FIXME: this is faked with PTI_RGBA8
sh_config.texfmt[PTI_RGB565] = !gl_config.webgl_ie; //ie sucks and doesn't support things that webgl requires it to support.
sh_config.texfmt[PTI_RGBA4444] = !gl_config.webgl_ie;
sh_config.texfmt[PTI_RGBA5551] = !gl_config.webgl_ie;
sh_config.texfmt[PTI_BGRA8] = false;
sh_config.texfmt[PTI_BGRX8] = sh_config.texfmt[PTI_BGRA8];
sh_config.minver = 100;
sh_config.maxver = 110;
sh_config.blobpath = "gles/%s.blob";
@ -2137,6 +2158,27 @@ void GL_Init(void *(*getglfunction) (char *name))
}
else
{
sh_config.texfmt[PTI_RGBX8] = true; //proper support
//these require stuff like GL_UNSIGNED_SHORT_5_5_5_1 etc, which needs gl 1.2+
if (gl_config.glversion >= 1.2)
{
//16bit formats
sh_config.texfmt[PTI_RGB565] = true;
sh_config.texfmt[PTI_RGBA4444] = true;
sh_config.texfmt[PTI_RGBA5551] = true;
//bgr formats
if (GL_CheckExtension("GL_EXT_bgra"))
{
//32bit formats
sh_config.texfmt[PTI_BGRX8] = true;
sh_config.texfmt[PTI_BGRA8] = true;
//16bit formats
sh_config.texfmt[PTI_ARGB4444] = true;
sh_config.texfmt[PTI_ARGB1555] = true;
}
}
sh_config.minver = gl_config.arb_shader_objects?110:0;
sh_config.maxver = gl_config.arb_shader_objects?gl_config.maxglslversion:0;
sh_config.blobpath = "glsl/%s.blob";
@ -2144,7 +2186,6 @@ void GL_Init(void *(*getglfunction) (char *name))
sh_config.shadernamefmt = "%s_glsl";
}
sh_config.texture_non_power_of_two = gl_config.texture_non_power_of_two;
sh_config.progs_supported = gl_config.arb_shader_objects;
sh_config.progs_required = gl_config_nofixedfunc;

View file

@ -60,15 +60,6 @@ typedef struct builddata_s
void ModBrush_LoadGLStuff(void *ctx, void *data, size_t a, size_t b); //data === builddata_t
//optional features common to all renderers, so I don't have to check to see which one it is all the time.
typedef struct {
qboolean texture_non_power_of_two; //all npot is okay
qboolean texture_non_power_of_two_pic; //npot only works with clamp-to-edge mipless images.
qboolean npot_rounddown; //memory limited systems can say that they want to use less ram.
int maxtexturesize; //biggest image size supported
} r_config_t;
extern r_config_t r_config;
#ifdef GLQUAKE
#if defined(ANDROID) /*FIXME: actually just to use standard GLES headers instead of full GL*/
#if 1
@ -226,8 +217,6 @@ typedef struct {
qboolean arb_texture_env_dot3;
qboolean arb_texture_cube_map;
qboolean texture_non_power_of_two; //full npot support.
qboolean texture_non_power_of_two_limited; //mipless,clamped npot works, but generic npot doesn't.
qboolean arb_texture_compression;
// qboolean arb_fragment_program;

View file

@ -52,6 +52,12 @@ extern qlpMTex2FUNC qglMultiTexCoord2fARB;
#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 /*opengl 1.2*/
#endif
#ifndef GL_UNSIGNED_SHORT_4_4_4_4_REV
#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365
#endif
#ifndef GL_UNSIGNED_SHORT_1_5_5_5_REV
#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366
#endif
#ifndef GL_UNSIGNED_SHORT_4_4_4_4
#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
#endif

View file

@ -632,7 +632,11 @@ typedef struct
unsigned int minver; //lowest glsl version usable
unsigned int maxver; //highest glsl version usable
qboolean texture_non_power_of_two;
qboolean texfmt[PTI_MAX]; //which texture formats are supported (renderable not implied)
unsigned int texture_maxsize; //max size of a 2d texture
qboolean texture_non_power_of_two; //full support for npot
qboolean texture_non_power_of_two_pic; //npot only works with clamp-to-edge mipless images.
qboolean npot_rounddown; //memory limited systems can say that they want to use less ram.
qboolean tex_env_combine;
qboolean nv_tex_env_combine4;
qboolean env_add;

View file

@ -451,13 +451,13 @@ reeval:
if ((unsigned)OPA->edict >= (unsigned)sv_num_edicts)
{
pr_xstatement = st-pr_statements;
if (PR_RunWarning (&progfuncs->funcs, "OP_LOAD references invalid entity %i in %s", OPA->edict, PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)))
{
st--;
goto cont;
}
PR_RunError (&progfuncs->funcs, "OP_LOAD references invalid entity %i in %s", OPA->edict, PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name));
OPC->_int = 0;
break;
}
ed = PROG_TO_EDICT(progfuncs, OPA->edict);
#ifdef PARANOID
@ -471,7 +471,15 @@ reeval:
if ((unsigned)OPA->edict >= (unsigned)sv_num_edicts)
{
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "OP_LOAD_V references invalid entity %i in %s", OPA->edict, PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name));
if (PR_RunWarning (&progfuncs->funcs, "OP_LOAD_V references invalid entity %i in %s", OPA->edict, PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)))
{
st--;
goto cont;
}
OPC->_vector[0] = 0;
OPC->_vector[1] = 0;
OPC->_vector[2] = 0;
break;
}
ed = PROG_TO_EDICT(progfuncs, OPA->edict);
#ifdef PARANOID

View file

@ -342,7 +342,7 @@ void NPP_QWWriteString(int dest, char *data)
{
NPP_NQWriteString(dest, data);
}
void NPP_QWWriteEntity(int dest, short data)
void NPP_QWWriteEntity(int dest, int data)
{
NPP_NQWriteEntity(dest, data);
}
@ -1487,7 +1487,7 @@ void NPP_NQWriteString(int dest, const char *data) //replacement write func (nq
nullterms--;
NPP_NQCheckFlush();
}
void NPP_NQWriteEntity(int dest, short data) //replacement write func (nq to qw)
void NPP_NQWriteEntity(int dest, int data) //replacement write func (nq to qw)
{
NPP_NQCheckDest(dest);
if (!bufferlen)
@ -2150,7 +2150,7 @@ void NPP_QWWriteString(int dest, const char *data) //replacement write func (nq
NPP_QWCheckFlush();
#endif
}
void NPP_QWWriteEntity(int dest, short data) //replacement write func (nq to qw)
void NPP_QWWriteEntity(int dest, int data) //replacement write func (nq to qw)
{
if (data >= 0x8000)
{

View file

@ -4728,13 +4728,13 @@ void QCBUILTIN PF_WriteEntity (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
if (progstype != PROG_QW)
{
NPP_NQWriteEntity(dest, (short)G_EDICTNUM(prinst, OFS_PARM1));
NPP_NQWriteEntity(dest, G_EDICTNUM(prinst, OFS_PARM1));
return;
}
#ifdef NQPROT
else
{
NPP_QWWriteEntity(dest, (short)G_EDICTNUM(prinst, OFS_PARM1));
NPP_QWWriteEntity(dest, G_EDICTNUM(prinst, OFS_PARM1));
return;
}
#else

View file

@ -1270,7 +1270,7 @@ void NPP_NQWriteAngle(int dest, float data);
void NPP_NQWriteCoord(int dest, float data);
void NPP_NQWriteFloat(int dest, float data);
void NPP_NQWriteString(int dest, const char *data);
void NPP_NQWriteEntity(int dest, short data);
void NPP_NQWriteEntity(int dest, int data);
void NPP_QWWriteByte(int dest, qbyte data);
void NPP_QWWriteChar(int dest, char data);
@ -1280,7 +1280,7 @@ void NPP_QWWriteAngle(int dest, float data);
void NPP_QWWriteCoord(int dest, float data);
void NPP_QWWriteFloat(int dest, float data);
void NPP_QWWriteString(int dest, const char *data);
void NPP_QWWriteEntity(int dest, short data);
void NPP_QWWriteEntity(int dest, int data);

View file

@ -260,6 +260,12 @@ void SVNQ_CreateBaseline (void)
svent->baseline.modelindex = playermodel;
}
svent->baseline.modelindex&=255; //FIXME
if (!svent->baseline.modelindex)
{
memcpy(&svent->baseline, &nullentitystate, sizeof(entity_state_t));
svent->baseline.number = entnum;
}
}
}

View file

@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// sv_user.c -- server code for moving users
#include "quakedef.h"
#include "fs.h"
#ifndef CLIENTONLY
#include "pr_common.h"
@ -2813,7 +2814,7 @@ static int SV_LocateDownload(char *name, flocation_t *loc, char **replacementnam
if (found)
{
protectedpak = com_file_copyprotected;
protectedpak = loc->search && (loc->search->flags & SPF_COPYPROTECTED);
// special check for maps, if it came from a pak file, don't allow download
if (protectedpak)

View file

@ -29,6 +29,8 @@ void emscriptenfte_abortmainloop(const char *caller);
//avoid all of emscripten's sdl emulation.
//this resolves input etc issues.
unsigned long emscriptenfte_ticks_ms(void);
void emscriptenfte_polljoyevents(void);
void emscriptenfte_settitle(const char *text);
int emscriptenfte_setupcanvas(
int width,
int height,
@ -36,6 +38,8 @@ int emscriptenfte_setupcanvas(
void(*Mouse)(int devid,int abs,float x,float y,float z,float size),
void(*Button)(int devid, int down, int mbutton),
int(*Keyboard)(int devid, int down, int keycode, int unicode),
void(*LoadFile)(char *newhash, int filehandle)
void(*LoadFile)(char *newhash, int filehandle),
void(*buttonevent)(int joydev, int button, int ispressed),
void(*axisevent)(int joydev, int axis, float value)
);

View file

@ -199,24 +199,88 @@ mergeInto(LibraryManager.library,
reader.readAsArrayBuffer(file);
}
break;
case 'gamepadconnected':
var gp = e.gamepad;
if (FTEH.gamepads === undefined)
FTEH.gamepads = [];
FTEH.gamepads[gp.index] = gp;
console.log("Gamepad connected at index %d: %s. %d buttons, %d axes.", gp.index, gp.id, gp.buttons.length, gp.axes.length);
break;
case 'gamepaddisconnected':
var gp = e.gamepad;
delete FTEH.gamepads[gp.index];
if (FTEC.evcb.jaxis) //try and clear out the axis when released.
for (var j = 0; j < 6; j+=1)
Runtime.dynCall('viid', FTEC.evcb.jaxis, [gp.index, j, 0]);
if (FTEC.evcb.jbutton) //try and clear out the axis when released.
for (var j = 0; j < 32+4; j+=1)
Runtime.dynCall('viid', FTEC.evcb.jbutton, [gp.index, j, 0]);
console.log("Gamepad disconnected from index %d: %s", gp.index, gp.id);
break;
default:
console.log(event);
break;
}
}
},
emscriptenfte_setupcanvas__deps: ['$FTEC', '$Browser', 'emscriptenfte_buf_createfromarraybuf'],
emscriptenfte_setupcanvas : function(nw,nh,evresz,evm,evb,evk,evf)
emscriptenfte_polljoyevents : function(be,ae)
{
FTEC.evcb.resize = evresz;
FTEC.evcb.mouse = evm;
FTEC.evcb.button = evb;
FTEC.evcb.key = evk;
FTEC.evcb.loadfile = evf;
//with events, we can do unplug stuff properly.
//otherwise hot unplug might be buggy.
var gamepads;
if (FTEH.gamepads !== undefined)
gamepads = FTEH.gamepads;
else
gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads : []);
if (gamepads !== undefined)
for (var i = 0; i < gamepads.length; i+=1)
{
var gp = gamepads[i];
if (gp === undefined)
continue;
for (var j = 0; j < gp.buttons.length; j+=1)
{
var b = gp.buttons[j];
var p;
if (typeof(b) == "object")
{
p = b.pressed;
if (b.lastframe != p)
{ //cache it to avoid spam
b.lastframe = p;
Runtime.dynCall('viii', FTEC.evcb.jbutton, [gp.index, j, p]);
}
}
else
{//old chrome bug
p = b==1.0;
//warning: no cache. this is going to be spammy.
Runtime.dynCall('viii', FTEC.evcb.jbutton, [gp.index, j, p]);
}
}
for (var j = 0; j < gp.axes.length; j+=1)
Runtime.dynCall('viid', FTEC.evcb.jaxis, [gp.index, j, gp.axes[j]]);
}
},
emscriptenfte_setupcanvas__deps: ['$FTEC', '$Browser', 'emscriptenfte_buf_createfromarraybuf'],
emscriptenfte_setupcanvas : function(nw,nh,evresize,evmouse,evmbutton,evkey,evfile,evjbutton,evjaxis)
{
FTEC.evcb.resize = evresize;
FTEC.evcb.mouse = evmouse;
FTEC.evcb.button = evmbutton;
FTEC.evcb.key = evkey;
FTEC.evcb.loadfile = evfile;
FTEC.evcb.jbutton = evjbutton;
FTEC.evcb.jaxis = evjaxis;
if ('GamepadEvent' in window)
FTEH.gamepads = []; //don't bother ever trying to poll if we can use gamepad events. this will hopefully avoid weirdness.
if (!FTEC.donecb)
{
FTEC.donecb = 1;
var events = ['mousedown', 'mouseup', 'mousemove', 'wheel', 'mousewheel', 'mouseout', 'keypress', 'keydown', 'keyup', 'touchstart', 'touchend', 'touchcancel', 'touchleave', 'touchmove', 'dragenter', 'dragover', 'drop'];
var events = ['mousedown', 'mouseup', 'mousemove', 'wheel', 'mousewheel', 'mouseout', 'keypress', 'keydown', 'keyup', 'touchstart', 'touchend', 'touchcancel', 'touchleave', 'touchmove', 'dragenter', 'dragover', 'drop', 'gamepadconnected', 'gamepaddisconnected'];
events.forEach(function(event)
{
Module['canvas'].addEventListener(event, FTEC.handleevent, true);
@ -273,7 +337,10 @@ mergeInto(LibraryManager.library,
return 1;
},
emscriptenfte_settitle : function(txt)
{
document.title = Pointer_stringify(txt);
},
emscriptenfte_abortmainloop : function(msg)
{
msg = Pointer_stringify(msg);

View file

@ -18,6 +18,13 @@ static void *GLVID_getsdlglfunction(char *functionname)
return NULL;
}
static void IN_JoystickButtonEvent(int joydevid, int button, int ispressed)
{
if (button >= 32+4)
return;
IN_KeyEvent(joydevid, ispressed, K_JOY1+button, 0);
}
static void VID_Resized(int width, int height)
{
extern cvar_t vid_conautoscale, vid_conwidth;
@ -176,7 +183,9 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
IN_MouseMove,
DOM_ButtonEvent,
DOM_KeyEvent,
DOM_LoadFile
DOM_LoadFile,
IN_JoystickButtonEvent,
IN_JoystickAxisEvent
))
{
Con_Printf("Couldn't set up canvas\n");
@ -200,7 +209,7 @@ void GLVID_DeInit (void)
{
ActiveApp = false;
emscriptenfte_setupcanvas(-1, -1, NULL, NULL, NULL, NULL, NULL);
emscriptenfte_setupcanvas(-1, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
}
@ -240,12 +249,13 @@ qboolean GLVID_ApplyGammaRamps (unsigned short *ramps)
void GLVID_SetCaption(char *text)
{
// SDL_WM_SetCaption( text, NULL );
emscriptenfte_settitle(text);
}
void Sys_SendKeyEvents(void)
{
/*callbacks happen outside our code, we don't need to poll for events*/
/*most callbacks happen outside our code, we don't need to poll for events - except for joysticks*/
emscriptenfte_polljoyevents();
}
/*various stuff for joysticks, which we don't support in this port*/
void INS_Shutdown (void)