mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-25 13:21:36 +00:00
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:
parent
71f4fe99e0
commit
97579ebfbb
52 changed files with 1185 additions and 372 deletions
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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*/
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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).
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue