Q3TA: Added snd_ignorecueloops cvar to ignore auto-looping sounds.

Q3TA: Fixed script parsing, so the menus are not so broken.
Q3TA: added the UI_CIN_* and CG_CIN_* builtins for 2d cinematic playbacks.
Q3TA: backspace should work for gamecode text entry now.
Q3TA: map_restart now directly restarts without needing loading screens.
Fixed multiple envmap generation bugs.
Fixed envmaps getting flushed with r_keepimages 0.
Console image previews can now display cubemaps (although their orientation is probably a little off).
Made a 'remapshader' csqc builtin. Depending on the r_remapshader console command was stupid.
Fixed packet command to create a udp socket, if needed.
sv_public can now be set to a non-numeric name for custom names (instead of needing to poke sv_port too).
Support extended data on the end of miptex entries in bsps. Requires a qbsp (like vanilla) that doesn't rewrite the miptex entries.
Updated imgtool to generate/read our new extended miptex data.



git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5644 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2020-03-07 09:00:40 +00:00
parent 2b01dbea52
commit 062cdf6b21
53 changed files with 2231 additions and 972 deletions

View File

@ -383,6 +383,10 @@ qboolean CG_GetServerCommand(int cmdnum)
if (!strcmp(Cmd_Argv(0), "cs"))
CG_InsertIntoGameState(atoi(Cmd_Argv(1)), Cmd_Argv(2));
else if (!strcmp(Cmd_Argv(0), "map_restart"))
Con_ClearNotify();
else if (!strcmp(Cmd_Argv(0), "disconnect"))
Host_EndGame("Server disconnected - %s", (Cmd_Argc()>1)?Cmd_Argv(1):"No reason given");
return true;
}
@ -1232,6 +1236,17 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
UI_RegisterFont(VM_POINTER(arg[0]), VM_LONG(arg[1]), VM_POINTER(arg[2]));
break;
case CG_CIN_PLAYCINEMATIC:
return UI_Cin_Play(VM_POINTER(arg[0]), VM_LONG(arg[1]), VM_LONG(arg[2]), VM_LONG(arg[3]), VM_LONG(arg[4]), VM_LONG(arg[5]));
case CG_CIN_STOPCINEMATIC:
return UI_Cin_Stop(VM_LONG(arg[0]));
case CG_CIN_RUNCINEMATIC:
return UI_Cin_Run(VM_LONG(arg[0]));
case CG_CIN_DRAWCINEMATIC:
return UI_Cin_Draw(VM_LONG(arg[0]));
case CG_CIN_SETEXTENTS:
return UI_Cin_SetExtents(VM_LONG(arg[0]), VM_LONG(arg[1]), VM_LONG(arg[2]), VM_LONG(arg[3]), VM_LONG(arg[4]));
case CG_FTE_FINDPARTICLEEFFECT:
return pe->FindParticleType(VM_POINTER(arg[0]));
case CG_FTE_SPAWNPARTICLEEFFECT:

View File

@ -3867,7 +3867,10 @@ void CL_ReadPacket(void)
if (net_message.cursize < 6 && (cls.demoplayback != DPB_MVD && cls.demoplayback != DPB_EZTV)) //MVDs don't have the whole sequence header thing going on
{
char adr[MAX_ADR_SIZE];
Con_TPrintf ("%s: Runt packet\n", NET_AdrToString(adr, sizeof(adr), &net_from));
if (net_message.cursize == 1 && net_message.data[0] == A2A_ACK)
Con_TPrintf ("%s: Ack (Pong)\n", NET_AdrToString(adr, sizeof(adr), &net_from));
else
Con_TPrintf ("%s: Runt packet\n", NET_AdrToString(adr, sizeof(adr), &net_from));
return;
}
@ -3965,7 +3968,7 @@ void CL_ReadPackets (void)
NET_ReadPackets(cls.sockets);
#ifdef HAVE_DTLS
NET_DTLS_Timeouts(cls.sockets);
NET_DTLS_Timeouts(cls.sockets);
#endif
//

View File

@ -2850,7 +2850,7 @@ void SCR_ScreenShot_Cubemap_f(void)
qboolean horizontalflip;
} sides[] =
{
//standard cubemap
//standard cubemap (flipping is done on save)
{{0, 0, 90}, "_px", true},
{{0, 180, -90}, "_nx", true},
{{0, 90, 0}, "_py", true}, //upside down
@ -2899,7 +2899,7 @@ void SCR_ScreenShot_Cubemap_f(void)
{
qboolean fail = false;
mips.type = PTI_CUBE;
mips.encoding = 0;
mips.encoding = PTI_INVALID;
mips.extrafree = NULL;
mips.mipcount = 1;
@ -2909,13 +2909,14 @@ void SCR_ScreenShot_Cubemap_f(void)
VectorCopy(sides[i].angle, cl.playerview->simangles);
VectorCopy(cl.playerview->simangles, cl.playerview->viewangles);
facedata = SCR_ScreenShot_Capture(fbwidth, fbheight, &stride, &fmt, true, true);
//don't use hdr when saving dds files. it generally means dx10 dds files and most tools suck too much and then I get blamed for writing 'corrupt' dds files.
facedata = SCR_ScreenShot_Capture(fbwidth, fbheight, &stride, &fmt, true, !!strcmp(ext, ".dds"));
if (!facedata)
break;
if (!i)
if (!bb)
{
Image_BlockSizeForEncoding(fmt, &bb, &bw, &bh);
if (bw != 1 || bh != 1)
if (!bb || bw != 1 || bh != 1 || fbwidth != fbheight)
{ //erk, no block compression here...
BZ_Free(facedata);
break; //zomgwtfbbq
@ -2936,23 +2937,27 @@ void SCR_ScreenShot_Cubemap_f(void)
break; //zomgwtfbbq
}
Image_FlipImage(facedata, (qbyte*)mips.mip[0].data + i*mips.mip[0].datasize/6, &fbwidth, &fbheight, bb, sides[i].horizontalflip, sides[i].verticalflip, false);
Image_FlipImage(facedata, (qbyte*)mips.mip[0].data + i*(mips.mip[0].datasize/6), &fbwidth, &fbheight, bb, sides[i].horizontalflip, sides[i].verticalflip^(stride<0), false);
BZ_Free(facedata);
}
if (i == 6)
{
qboolean pixelformats[PTI_MAX] = {0};
pixelformats[PTI_E5BGR9] = true;
Image_ChangeFormat(&mips, pixelformats, mips.encoding, fname);
if (mips.encoding == PTI_RGB32F || mips.encoding == PTI_RGBA16F || mips.encoding == PTI_RGBA32F)
{ //convert to a more memory-efficient hdr format.
qboolean pixelformats[PTI_MAX] = {0};
pixelformats[PTI_E5BGR9] = true;
Image_ChangeFormat(&mips, pixelformats, mips.encoding, fname);
}
else if ((mips.encoding == PTI_RGBX8 || mips.encoding == PTI_BGRX8) && !strcmp(ext, ".dds"))
{ //gimp-dds plugin is buggy. convert to a less problematic format, so that I don't get invalid complaints.
qboolean pixelformats[PTI_MAX] = {0};
pixelformats[PTI_BGR8] = true;
Image_ChangeFormat(&mips, pixelformats, mips.encoding, fname);
}
Q_snprintfz(filename, sizeof(filename), "textures/%s", fname);
COM_DefaultExtension (filename, ext, sizeof(filename));
#ifdef IMAGEFMT_KTX
COM_DefaultExtension (filename, ".ktx", sizeof(filename));
#endif
#ifdef IMAGEFMT_DDS
COM_DefaultExtension (filename, ".dds", sizeof(filename));
#endif
ext = COM_GetFileExtension(filename, NULL);
if (fail)
Con_Printf("Unable to generate cubemap data\n");

View File

@ -181,29 +181,39 @@ int Script_Read(int handle, struct pc_token_s *token)
StripCSyntax(token->string);
token->intvalue = atoi(token->string);
token->floatvalue = atof(token->string);
if (token->floatvalue || *token->string == '0' || *token->string == '.')
if (token->string[0] == '0' && (token->string[1] == 'x'||token->string[1] == 'X'))
{
token->intvalue = strtoul(token->string, NULL, 16);
token->floatvalue = token->intvalue;
token->type = TT_NUMBER;
token->subtype = 0;
}
else if (com_tokentype == TTP_STRING)
{
token->type = TT_STRING;
token->subtype = strlen(token->string);
token->subtype = 0x100;//TT_HEX;
}
else
{
if (token->string[1] == '\0')
token->intvalue = atoi(token->string);
token->floatvalue = atof(token->string);
if (token->floatvalue || *token->string == '0' || *token->string == '.')
{
token->type = TT_PUNCTUATION;
token->subtype = token->string[0];
token->type = TT_NUMBER;
token->subtype = 0;
}
else if (com_tokentype == TTP_STRING)
{
token->type = TT_STRING;
token->subtype = strlen(token->string);
}
else
{
token->type = TT_NAME;
token->subtype = strlen(token->string);
if (token->string[1] == '\0')
{
token->type = TT_PUNCTUATION;
token->subtype = token->string[0];
}
else
{
token->type = TT_NAME;
token->subtype = strlen(token->string);
}
}
}
@ -303,10 +313,11 @@ struct
#define UITAGNUM 2452
extern model_t *mod_known;
#define VM_FROMMHANDLE(a) (a?mod_known+a-1:NULL)
extern int mod_numknown;
#define VM_FROMMHANDLE(a) (a>0&&a<=mod_numknown?mod_known+a-1:NULL)
#define VM_TOMHANDLE(a) (a?a-mod_known+1:0)
#define VM_FROMSHANDLE(a) (a?r_shaders[a-1]:NULL)
#define VM_FROMSHANDLE(a) (a>0&&a<=r_numshaders?r_shaders[a-1]:NULL)
#define VM_TOSHANDLE(a) (a?a->id+1:0)
@ -359,8 +370,8 @@ struct q3polyvert_s
#define Q3RF_NOSHADOW 64
#define Q3RF_LIGHTING_ORIGIN 128
#define MAX_VMQ3_CACHED_STRINGS 1024
char *stringcache[1024];
#define MAX_VMQ3_CACHED_STRINGS 2048
char *stringcache[MAX_VMQ3_CACHED_STRINGS];
void VMQ3_FlushStringHandles(void)
{
@ -675,6 +686,7 @@ void UI_RegisterFont(char *fontName, int pointSize, fontInfo_t *font)
int i;
char name[MAX_QPATH];
size_t sz;
shader_t *shader;
#define readInt() LittleLong(*in.i++)
#define readFloat() LittleFloat(*in.f++)
@ -701,17 +713,138 @@ void UI_RegisterFont(char *fontName, int pointSize, fontInfo_t *font)
in.c += 32;
}
font->glyphScale = readFloat();
memcpy(font->name, in.i, MAX_QPATH);
memcpy(font->name, in.i, sizeof(font->name));
// Com_Memcpy(font, faceData, sizeof(fontInfo_t));
Q_strncpyz(font->name, name, sizeof(font->name));
for (i = GLYPH_START; i < GLYPH_END; i++)
{
font->glyphs[i].glyph = VM_TOSHANDLE(R_RegisterPic(font->glyphs[i].shaderName, NULL));
shader = R_RegisterPic(font->glyphs[i].shaderName, NULL);
font->glyphs[i].glyph = VM_TOSHANDLE(shader);
}
}
}
static struct
{
int shaderhandle;
int x, y, w, h;
qboolean loop;
} uicinematics[16];
int UI_Cin_Play(const char *name, int x, int y, int w, int h, unsigned int flags)
{
int idx;
shader_t *mediashader;
cin_t *cin;
for (idx = 0; ; idx++)
{
if (idx == countof(uicinematics))
return -1; //out of handles
if (uicinematics[idx].shaderhandle)
continue; //slot in use
break; //this slot is usable
}
mediashader = R_RegisterCustom(name, SUF_NONE, Shader_DefaultCinematic, va("video/%s", name));
if (!mediashader)
return -1; //wtf?
cin = R_ShaderGetCinematic(mediashader);
if (cin)
Media_SetState(cin, CINSTATE_PLAY);
else
return -1; //FAIL!
uicinematics[idx].x = x;
uicinematics[idx].y = y;
uicinematics[idx].w = w;
uicinematics[idx].h = h;
uicinematics[idx].loop = !!(flags&1);
uicinematics[idx].shaderhandle = VM_TOSHANDLE(mediashader);
return idx;
}
int UI_Cin_Stop(int idx)
{
if (idx >= 0 && idx < countof(uicinematics))
{
shader_t *shader = VM_FROMSHANDLE(uicinematics[idx].shaderhandle);
R_UnloadShader(shader);
uicinematics[idx].shaderhandle = 0;
}
return 0;
}
int UI_Cin_Run(int idx)
{
enum {
FMV_IDLE,
FMV_PLAY, // play
FMV_EOF, // all other conditions, i.e. stop/EOF/abort
FMV_ID_BLT,
FMV_ID_IDLE,
FMV_LOOPED,
FMV_ID_WAIT
};
int ret = FMV_IDLE;
if (idx >= 0 && idx < countof(uicinematics))
{
shader_t *shader = VM_FROMSHANDLE(uicinematics[idx].shaderhandle);
cin_t *cin = R_ShaderGetCinematic(shader);
if (cin)
{
switch(Media_GetState(cin))
{
case CINSTATE_INVALID: ret = FMV_IDLE; break;
case CINSTATE_PLAY: ret = FMV_PLAY; break;
case CINSTATE_LOOP: ret = FMV_PLAY; break;
case CINSTATE_PAUSE: ret = FMV_PLAY; break;
case CINSTATE_ENDED:
Media_SetState(cin, CINSTATE_FLUSHED);
ret = FMV_EOF;
break;
case CINSTATE_FLUSHED:
//FIXME: roq decoder has no reset method!
Media_Send_Reset(cin);
ret = FMV_LOOPED;
break;
}
}
}
return ret;
}
int UI_Cin_Draw(int idx)
{
if (idx >= 0 && idx < countof(uicinematics))
{
shader_t *shader = VM_FROMSHANDLE(uicinematics[idx].shaderhandle);
float x = uicinematics[idx].x;
float y = uicinematics[idx].y;
float w = uicinematics[idx].w;
float h = uicinematics[idx].h;
//gah! q3 compat sucks!
x *= vid.pixelwidth/640.0;
w *= vid.pixelwidth/640.0;
y *= vid.pixelheight/480.0;
h *= vid.pixelheight/480.0;
R2D_Image(x, y, w, h, 0, 0, 1, 1, shader);
}
return 0;
}
int UI_Cin_SetExtents(int idx, int x, int y, int w, int h)
{
if (idx >= 0 && idx < countof(uicinematics))
{
uicinematics[idx].x = x;
uicinematics[idx].y = y;
uicinematics[idx].w = w;
uicinematics[idx].h = h;
}
return 0;
}
static cvar_t *Cvar_Q3FindVar (const char *var_name)
{
struct {
@ -760,10 +893,24 @@ static cvar_t *Cvar_Q3FindVar (const char *var_name)
return NULL;
}
static void UI_SimulateTextEntry(void *cb, char *utf8)
{
const char *line = utf8;
unsigned int unicode;
int err;
while(*line)
{
unicode = utf8_decode(&err, line, &line);
if (uivm)
VM_Call(uivm, UI_KEY_EVENT, unicode|1024, true);
}
}
#define VALIDATEPOINTER(o,l) if ((quintptr_t)o + l >= mask || VM_POINTER(o) < offset) Host_EndGame("Call to ui trap %i passes invalid pointer\n", (int)fn); //out of bounds.
static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, const qintptr_t *arg)
{
static int overstrikemode;
int ret=0;
char adrbuf[MAX_ADR_SIZE];
@ -779,6 +926,15 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
switch((uiImport_t)fn)
{
case UI_CVAR_CREATE:
case UI_CVAR_INFOSTRINGBUFFER:
case UI_R_ADDPOLYTOSCENE:
case UI_R_REMAP_SHADER:
case UI_UPDATESCREEN:
case UI_CM_LOADMODEL:
case UI_FS_SEEK:
Con_Printf("Q3UI: Not implemented system trap: %i\n", (int)fn);
break;
case UI_ERROR:
Con_Printf("%s", (char*)VM_POINTER(arg[0]));
break;
@ -810,7 +966,8 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
char *vval = VM_POINTER(arg[1]);
if (!strcmp(vname, "fs_game"))
{
Cbuf_AddText(va("gamedir %s\nui_restart\n", (char*)vval), RESTRICT_SERVER);
char quoted[256];
Cbuf_AddText(va("gamedir %s\nui_restart\n", COM_QuotedString(vval, quoted, sizeof(quoted), false)), RESTRICT_SERVER);
}
else
{
@ -972,7 +1129,10 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
if (!*(char*)VM_POINTER(arg[0]))
VM_LONG(ret) = 0;
else
VM_LONG(ret) = VM_TOSHANDLE(R_RegisterPic(VM_POINTER(arg[0]), NULL));
{
shader_t *shader = R_RegisterPic(VM_POINTER(arg[0]), NULL);
VM_LONG(ret) = VM_TOSHANDLE(shader);
}
break;
case UI_R_CLEARSCENE: //clear scene
@ -1023,8 +1183,31 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
S_LocalSound(VM_FROMSTRCACHE(arg[0])); //now we can fix up the sound name
break;
case UI_S_STARTBACKGROUNDTRACK:
Media_NamedTrack(VM_POINTER(arg[0]), VM_POINTER(arg[1]));
break;
case UI_S_STOPBACKGROUNDTRACK:
Media_NamedTrack(NULL, NULL);
break;
//q3 shares insert mode between its ui and console. whereas fte doesn't support it (FIXME: add to Key_EntryInsert).
case UI_KEY_SETOVERSTRIKEMODE:
overstrikemode = arg[0];
return 0;
case UI_KEY_GETOVERSTRIKEMODE:
return true;
return overstrikemode;
case UI_GETCLIPBOARDDATA:
if (VM_OOB(arg[0], VM_LONG(arg[1])))
break; //out of bounds.
//our clipboard doesn't allow us to simply query without blocking (would result in stalls on x11/wayland)
//so just return nothing - we can send the text as if it were regular text entry for a similar result.
Q_strncpyz(VM_POINTER(arg[0]), "", VM_LONG(arg[1]));
//but do we really want to let mods read the system clipboard? I suppose it SHOULD be okay if the UI was manually installed by the user.
//side note: q3's text entry logic is kinda flawed.
Sys_Clipboard_PasteText(CBT_CLIPBOARD, UI_SimulateTextEntry, NULL);
break;
case UI_KEY_KEYNUMTOSTRINGBUF:
if (VM_LONG(arg[0]) < 0 || VM_LONG(arg[0]) > 255 || (int)arg[1] + VM_LONG(arg[2]) >= mask || VM_POINTER(arg[1]) < offset || VM_LONG(arg[2]) < 1)
@ -1223,6 +1406,110 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
strcpy(buf, "");
}
break;
case UI_LAN_UPDATEVISIBLEPINGS:
return CL_QueryServers(); //return true while we're still going.
case UI_LAN_RESETPINGS:
return 0;
case UI_LAN_ADDSERVER:
return 0;
case UI_LAN_REMOVESERVER:
return 0;
case UI_LAN_SERVERSTATUS:
//*address, *status, statuslen
return 0;
case UI_LAN_COMPARESERVERS:
{
hostcachekey_t q3tofte[] = {SLKEY_NAME, SLKEY_MAP, SLKEY_NUMHUMANS, SLKEY_GAMEDIR, SLKEY_PING, 0};
qboolean keyisstring[] = {true, true, false, true, false, false};
//int source = VM_LONG(arg[0]);
int key = bound(0, VM_LONG(arg[1]), countof(q3tofte));
int sortdir = VM_LONG(arg[2]);
serverinfo_t *s1 = Master_InfoForNum(VM_LONG(arg[3]));
serverinfo_t *s2 = Master_InfoForNum(VM_LONG(arg[4]));
if (keyisstring[key])
ret = strcasecmp(Master_ReadKeyString(s2, q3tofte[key]), Master_ReadKeyString(s1, q3tofte[key]));
else
{
ret = Master_ReadKeyFloat(s2, q3tofte[key]) - Master_ReadKeyFloat(s1, q3tofte[key]);
if (ret < 0)
ret = -1;
else if (ret > 0)
ret = 1;
}
if (sortdir)
ret = -ret;
}
return ret;
case UI_LAN_GETSERVERCOUNT: //LAN Get server count
//int (int source)
Master_CheckPollSockets();
VM_LONG(ret) = Master_TotalCount();
break;
case UI_LAN_GETSERVERADDRESSSTRING: //LAN get server address
//void (int source, int svnum, char *buffer, int buflen)
if ((int)arg[2] + VM_LONG(arg[3]) >= mask || VM_POINTER(arg[2]) < offset)
break; //out of bounds.
{
char *buf = VM_POINTER(arg[2]);
char *adr;
serverinfo_t *info = Master_InfoForNum(VM_LONG(arg[1]));
if (info)
{
adr = Master_ServerToString(adrbuf, sizeof(adrbuf), info);
if (strlen(adr) < VM_LONG(arg[3]))
{
strcpy(buf, adr);
VM_LONG(ret) = true;
}
}
else
strcpy(buf, "");
}
break;
case UI_LAN_LOADCACHEDSERVERS:
break;
case UI_LAN_SAVECACHEDSERVERS:
break;
case UI_LAN_GETSERVERPING:
return 50;
case UI_LAN_GETSERVERINFO:
if (VM_OOB(arg[2], arg[3]) || !arg[3])
break; //out of bounds.
{
//int source = VM_LONG(arg[0]);
int servernum = VM_LONG(arg[1]);
char *out = VM_POINTER(arg[2]);
int maxsize = VM_LONG(arg[3]);
char adr[MAX_ADR_SIZE];
serverinfo_t *info = Master_InfoForNum(servernum);
*out = 0;
if (info)
{
Info_SetValueForStarKey(out, "hostname", info->name, maxsize);
Info_SetValueForStarKey(out, "mapname", info->map, maxsize);
Info_SetValueForStarKey(out, "clients", va("%i", info->players), maxsize);
Info_SetValueForStarKey(out, "sv_maxclients", va("%i", info->maxplayers), maxsize);
Info_SetValueForStarKey(out, "ping", va("%i", info->ping), maxsize);
// Info_SetValueForStarKey(out, "minping", info->map, maxsize);
// Info_SetValueForStarKey(out, "maxping", info->map, maxsize);
// Info_SetValueForStarKey(out, "game", info->map, maxsize);
// Info_SetValueForStarKey(out, "gametype", info->map, maxsize);
// Info_SetValueForStarKey(out, "nettype", info->map, maxsize);
Info_SetValueForStarKey(out, "addr", NET_AdrToString(adr, sizeof(adr), &info->adr), maxsize);
// Info_SetValueForStarKey(out, "punkbuster", info->map, maxsize);
// Info_SetValueForStarKey(out, "g_needpass", info->map, maxsize);
// Info_SetValueForStarKey(out, "g_humanplayers", info->map, maxsize);
}
}
break;
case UI_LAN_MARKSERVERVISIBLE:
/*not implemented*/
return 0;
case UI_LAN_SERVERISVISIBLE:
return 1;
#endif
case UI_CVAR_REGISTER:
@ -1262,45 +1549,6 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
VALIDATEPOINTER(arg[0], sizeof(q3time_t));
return Q3VM_GetRealtime(VM_POINTER(arg[0]));
#ifdef CL_MASTER
case UI_LAN_GETSERVERCOUNT: //LAN Get server count
//int (int source)
VM_LONG(ret) = Master_TotalCount();
break;
case UI_LAN_GETSERVERADDRESSSTRING: //LAN get server address
//void (int source, int svnum, char *buffer, int buflen)
if ((int)arg[2] + VM_LONG(arg[3]) >= mask || VM_POINTER(arg[2]) < offset)
break; //out of bounds.
{
char *buf = VM_POINTER(arg[2]);
char *adr;
serverinfo_t *info = Master_InfoForNum(VM_LONG(arg[1]));
if (info)
{
adr = Master_ServerToString(adrbuf, sizeof(adrbuf), info);
if (strlen(adr) < VM_LONG(arg[3]))
{
strcpy(buf, adr);
VM_LONG(ret) = true;
}
}
else
strcpy(buf, "");
}
break;
case UI_LAN_LOADCACHEDSERVERS:
break;
case UI_LAN_SAVECACHEDSERVERS:
break;
case UI_LAN_GETSERVERPING:
return 50;
case UI_LAN_GETSERVERINFO:
break;
case UI_LAN_SERVERISVISIBLE:
return 1;
break;
#endif
case UI_VERIFY_CDKEY:
VM_LONG(ret) = true;
break;
@ -1429,19 +1677,18 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
return Script_Read(arg[0], VM_POINTER(arg[1]));
case UI_CIN_PLAYCINEMATIC:
//handle(name, x, y, w, h, looping)
return UI_Cin_Play(VM_POINTER(arg[0]), VM_LONG(arg[1]), VM_LONG(arg[2]), VM_LONG(arg[3]), VM_LONG(arg[4]), VM_LONG(arg[5]));
case UI_CIN_STOPCINEMATIC:
//(handle)
return UI_Cin_Stop(VM_LONG(arg[0]));
case UI_CIN_RUNCINEMATIC:
//(handle)
return UI_Cin_Run(VM_LONG(arg[0]));
case UI_CIN_DRAWCINEMATIC:
//(handle)
return UI_Cin_Draw(VM_LONG(arg[0]));
case UI_CIN_SETEXTENTS:
//(handle, x, y, w, h)
break;
return UI_Cin_SetExtents(VM_LONG(arg[0]), VM_LONG(arg[1]), VM_LONG(arg[2]), VM_LONG(arg[3]), VM_LONG(arg[4]));
default:
Con_Printf("Q3UI: Not implemented system trap: %i\n", (int)fn);
Con_Printf("Q3UI: Unknown system trap: %i\n", (int)fn);
return 0;
}
@ -1513,8 +1760,6 @@ static void UI_DrawMenu(menu_t *m)
}
qboolean UI_KeyPress(struct menu_s *m, qboolean isdown, unsigned int devid, int key, int unicode)
{
extern qboolean keydown[K_MAX];
extern int keyshift[K_MAX]; // key to map to if shift held down in console
// qboolean result;
if (!uivm)
return false;
@ -1530,12 +1775,10 @@ qboolean UI_KeyPress(struct menu_s *m, qboolean isdown, unsigned int devid, int
return false;
}
if (keydown[K_SHIFT])
key = keyshift[key];
if (key < K_BACKSPACE && key >= ' ')
key |= 1024;
/*result = */VM_Call(uivm, UI_KEY_EVENT, key, isdown);
if (key && key < 1024)
/*result = */VM_Call(uivm, UI_KEY_EVENT, key, isdown);
if (unicode && unicode < 1024)
/*result = */VM_Call(uivm, UI_KEY_EVENT, unicode|1024, isdown);
return true;
}

View File

@ -717,6 +717,7 @@ void CLQ3_ParseServerMessage (void)
qboolean CLQ3_Netchan_Process(void)
{
#ifndef Q3_NOENCRYPT
int sequence;
int lastClientCommandNum;
qbyte bitmask;
@ -725,12 +726,14 @@ qboolean CLQ3_Netchan_Process(void)
char *string;
int bit;
int readcount;
#endif
if(!Netchan_ProcessQ3(&cls.netchan))
{
return false;
}
#ifndef Q3_NOENCRYPT
// archive buffer state
bit = net_message.currentbit;
readcount = msg_readcount;
@ -748,7 +751,6 @@ qboolean CLQ3_Netchan_Process(void)
bitmask = (sequence ^ cls.challenge) & 0xff;
string = ccs.clientCommands[lastClientCommandNum & Q3TEXTCMD_MASK];
#ifndef Q3_NOENCRYPT
// decrypt the packet
for(i=msg_readcount+4,j=0 ; i<net_message.cursize ; i++,j++)
{
@ -772,6 +774,7 @@ qboolean CLQ3_Netchan_Process(void)
void CL_Netchan_Transmit( int length, const qbyte *data )
{
#define msg net_message
#ifndef Q3_NOENCRYPT
int serverid;
int lastSequence;
int lastServerCommandNum;
@ -779,6 +782,7 @@ void CL_Netchan_Transmit( int length, const qbyte *data )
qbyte c;
int i, j;
char *string;
#endif
net_message.cursize = 0;
SZ_Write(&msg, data, length);
@ -787,6 +791,7 @@ void CL_Netchan_Transmit( int length, const qbyte *data )
Host_EndGame("Client message overflowed");
}
#ifndef Q3_NOENCRYPT
msg_readcount = 0;
msg.currentbit = 0;
msg.packing = SZ_HUFFMAN;
@ -799,7 +804,6 @@ void CL_Netchan_Transmit( int length, const qbyte *data )
bitmask = (lastSequence ^ serverid ^ cls.challenge) & 0xff;
string = ccs.serverCommands[lastServerCommandNum & Q3TEXTCMD_MASK];
#ifndef Q3_NOENCRYPT
// encrypt the packet
for( i=12,j=0 ; i<msg.cursize ; i++,j++ )
{

View File

@ -1,5 +1,9 @@
#ifndef _Q3DEFS_H_
#define _Q3DEFS_H_
//#define Q3_NOENCRYPT //a debugging property, makes it incompatible with q3
#define PROTOCOL_VERSION_Q3 68
void Q3_SetKeyCatcher(int newcatcher);
@ -18,8 +22,6 @@ typedef struct {
int entityNum; // entity the contacted surface is a part of
} q3trace_t;
//#define Q3_NOENCRYPT //a debugging property, makes it incompatible with q3
#define MAX_Q3_STATS 16
#define MAX_Q3_PERSISTANT 16
#define MAX_Q3_POWERUPS 16
@ -316,6 +318,11 @@ typedef struct {
} fontInfo_t;
void UI_RegisterFont(char *fontName, int pointSize, fontInfo_t *font);
int UI_Cin_Play(const char *name, int x, int y, int w, int h, unsigned int flags);
int UI_Cin_Stop(int idx);
int UI_Cin_Run(int idx);
int UI_Cin_Draw(int idx);
int UI_Cin_SetExtents(int idx, int x, int y, int w, int h);
void Netchan_TransmitNextFragment( netchan_t *chan );
void Netchan_TransmitQ3( netchan_t *chan, int length, const qbyte *data );

View File

@ -2246,20 +2246,29 @@ static int Con_DrawConsoleLines(console_t *con, conline_t *l, float displayscrol
imgname = Info_ValueForKey(linkinfo, "imgptr");
if (*imgname)
{
pic = R2D_SafeCachePic("tiprawimg");
pic->defaulttextures->base = Image_TextureIsValid(strtoull(imgname, NULL, 0));
if (pic && pic->defaulttextures->base)
image_t *img = Image_TextureIsValid(strtoull(imgname, NULL, 0));
if (img && (img->flags & IF_TEXTYPEMASK)==IF_TEXTYPE_CUBE)
{
if (!pic->defaulttextures->base->width || !pic->defaulttextures->base->height || !TEXLOADED(pic->defaulttextures->base))
pic = R_RegisterShader("tiprawimgcube", 0, "{\nprogram postproc_equirectangular\n{\nmap \"$cube:$reflectcube\"\n}\n}");
pic->defaulttextures->reflectcube = img;
}
else
{
pic = R2D_SafeCachePic("tiprawimg");
pic->defaulttextures->base = img;
}
if (img)
{
if (!img->width || !img->height || !TEXLOADED(img))
picw = pich = 64;
else if (pic->defaulttextures->base->width > pic->defaulttextures->base->height)
else if (img->width > img->height)
{
picw = 64;
pich = (64.0*pic->defaulttextures->base->height)/pic->defaulttextures->base->width;
pich = (64.0*img->height)/img->width;
}
else
{
picw = (64.0*pic->defaulttextures->base->width)/pic->defaulttextures->base->height;
picw = (64.0*img->width)/img->height;
pich = 64;
}
break;
@ -2936,41 +2945,53 @@ void Con_DrawConsole (int lines, qboolean noback)
}
else
{
image_t *img = NULL;
key = Info_ValueForKey(info, "tiprawimg");
if (*key)
{
shader = R2D_SafeCachePic("tiprawimg");
shader->defaulttextures->base = Image_FindTexture(key, NULL, IF_NOREPLACE|IF_PREMULTIPLYALPHA);
if (!shader->defaulttextures->base)
shader->defaulttextures->base = Image_FindTexture(key, NULL, IF_NOREPLACE);
if (!shader->defaulttextures->base)
img = Image_FindTexture(key, NULL, IF_NOREPLACE|IF_PREMULTIPLYALPHA|IF_TEXTYPE_ANY);
if (!img)
img = Image_FindTexture(key, NULL, IF_NOREPLACE|IF_TEXTYPE_ANY);
if (!img)
{
size_t fsize;
char *buf;
shader->defaulttextures->base = Image_CreateTexture(key, NULL, IF_NOREPLACE|IF_PREMULTIPLYALPHA);
img = Image_CreateTexture(key, NULL, IF_NOREPLACE|IF_PREMULTIPLYALPHA|IF_TEXTYPE_ANY);
if ((buf = FS_LoadMallocFile (key, &fsize)))
Image_LoadTextureFromMemory(shader->defaulttextures->base, shader->defaulttextures->base->flags|IF_NOWORKER, key, key, buf, fsize);
Image_LoadTextureFromMemory(img, img->flags|IF_NOWORKER, key, key, buf, fsize);
}
}
key = Info_ValueForKey(info, "tipimgptr");
if (*key)
img = Image_TextureIsValid(strtoull(key, NULL, 0));
if (img && img->status == TEX_LOADED)
{
shader = R2D_SafeCachePic("tiprawimg");
shader->defaulttextures->base = Image_TextureIsValid(strtoull(key, NULL, 0));
}
if (shader && shader->defaulttextures->base && shader->defaulttextures->base->status == TEX_LOADED && ((shader->defaulttextures->base->flags&IF_TEXTYPEMASK) == (PTI_2D<<IF_TEXTYPESHIFT)))
{
shader->width = shader->defaulttextures->base->width;
shader->height = shader->defaulttextures->base->height;
if (shader->width > 320)
if ((img->flags & IF_TEXTYPEMASK)==IF_TEXTYPE_CUBE)
{
shader->height *= 320.0/shader->width;
shader->width = 320;
shader = R_RegisterShader("tiprawimgcube", 0, "{\nprogram postproc_equirectangular\n{\nmap \"$cube:$reflectcube\"\n}\n}");
shader->defaulttextures->reflectcube = img;
}
if (shader->height > 240)
else if ((img->flags&IF_TEXTYPEMASK) == IF_TEXTYPE_2D)
{
shader->width *= 240.0/shader->height;
shader->height = 240;
shader = R2D_SafeCachePic("tiprawimg");
shader->defaulttextures->base = img;
}
if (shader)
{
shader->width = img->width;
shader->height = img->height;
if (shader->width > 320)
{
shader->height *= 320.0/shader->width;
shader->width = 320;
}
if (shader->height > 240)
{
shader->width *= 240.0/shader->height;
shader->height = 240;
}
}
}
else

View File

@ -31,7 +31,7 @@ static void QDECL R_Image_BuggyCvar (struct cvar_s *var, char *oldvalue)
{ //force these cvars to value 1 if they're empty.
//cvars using this should be changed to 0 by default, once our engine bugs are debugged/fixed.
if (!*var->string)
var->ival = true;
var->ival = var->value = true;
}
cvar_t r_keepimages = CVARCD("r_keepimages", "", R_Image_BuggyCvar, "Retain unused images in memory for slightly faster map loading. FIXME: a setting of 0 may be crashy! (empty is treated as 1 for now)");
cvar_t r_ignoremapprefixes = CVARCD("r_ignoremapprefixes", "", R_Image_BuggyCvar, "Ignores when textures were loaded from map-specific paths. FIXME: empty is currently interpretted as 1 because the alternative is too memory hungary with r_keepimages 1.");
@ -2552,18 +2552,19 @@ qboolean screenshotJPEG(char *filename, enum fs_relative fsroot, int compression
WritePCXfile
==============
*/
void WritePCXfile (const char *filename, enum fs_relative fsroot, qbyte *data, int width, int height,
qboolean WritePCXfile (const char *filename, enum fs_relative fsroot, qbyte *data, int width, int height,
int rowbytes, qbyte *palette, qboolean upload) //data is 8bit.
{
int i, j, length;
pcx_t *pcx;
qbyte *pack;
qboolean ret;
pcx = BZ_Malloc(width*height*2+1000);
if (pcx == NULL)
{
Con_Printf("WritePCXfile: not enough memory\n");
return;
return false;
}
pcx->manufacturer = 0x0a; // PCX id
@ -2610,11 +2611,16 @@ void WritePCXfile (const char *filename, enum fs_relative fsroot, qbyte *data, i
#ifdef HAVE_CLIENT
if (upload)
{
CL_StartUpload((void *)pcx, length);
ret = true;
}
else
#endif
COM_WriteFile (filename, fsroot, pcx, length);
ret = COM_WriteFile (filename, fsroot, pcx, length);
BZ_Free(pcx);
return ret;
}
/*
@ -4600,10 +4606,11 @@ static void Image_LoadTexture_Failed(void *ctx, void *data, size_t a, size_t b)
texid_t tex = ctx;
tex->status = TEX_FAILED;
}
static void Image_FixupImageSize(texid_t tex, unsigned int w, unsigned int h)
static void Image_FixupImageSize(texid_t tex, unsigned int w, unsigned int h, unsigned int d)
{
tex->width = w;
tex->height = h;
tex->depth = d;
//ezhud breaks without this. I assume other things will too. this is why you shouldn't depend upon querying an image's size.
if (!strncmp(tex->ident, "gfx/", 4))
@ -4698,6 +4705,9 @@ static void Image_LoadTextureMips(void *ctx, void *data, size_t a, size_t b)
break;
}
if ((tex->flags & IF_TEXTYPEMASK)==IF_TEXTYPE_ANY)
tex->flags = (tex->flags&~IF_TEXTYPEMASK)|(mips->type<<IF_TEXTYPESHIFT);
if (rf->IMG_LoadTextureMips(tex, mips))
{
tex->format = mips->encoding;
@ -4811,10 +4821,10 @@ qboolean Image_WriteKTXFile(const char *filename, enum fs_relative fsroot, struc
case PTI_BC2_RGBA_SRGB: header.glinternalformat = 0x8C4E/*GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT*/; break;
case PTI_BC3_RGBA: header.glinternalformat = 0x83F3/*GL_COMPRESSED_RGBA_S3TC_DXT5_EXT*/; break;
case PTI_BC3_RGBA_SRGB: header.glinternalformat = 0x8C4F/*GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT*/; break;
case PTI_BC4_R8_SNORM: header.glinternalformat = 0x8DBC/*GL_COMPRESSED_SIGNED_RED_RGTC1*/; break;
case PTI_BC4_R8: header.glinternalformat = 0x8DBB/*GL_COMPRESSED_RED_RGTC1*/; break;
case PTI_BC5_RG8_SNORM: header.glinternalformat = 0x8DBE/*GL_COMPRESSED_SIGNED_RG_RGTC2*/; break;
case PTI_BC5_RG8: header.glinternalformat = 0x8DBD/*GL_COMPRESSED_RG_RGTC2*/; break;
case PTI_BC4_R_SNORM: header.glinternalformat = 0x8DBC/*GL_COMPRESSED_SIGNED_RED_RGTC1*/; break;
case PTI_BC4_R: header.glinternalformat = 0x8DBB/*GL_COMPRESSED_RED_RGTC1*/; break;
case PTI_BC5_RG_SNORM: header.glinternalformat = 0x8DBE/*GL_COMPRESSED_SIGNED_RG_RGTC2*/; break;
case PTI_BC5_RG: header.glinternalformat = 0x8DBD/*GL_COMPRESSED_RG_RGTC2*/; break;
case PTI_BC6_RGB_UFLOAT: header.glinternalformat = 0x8E8F/*GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB*/; break;
case PTI_BC6_RGB_SFLOAT: header.glinternalformat = 0x8E8E/*GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB*/; break;
case PTI_BC7_RGBA: header.glinternalformat = 0x8E8C/*GL_COMPRESSED_RGBA_BPTC_UNORM_ARB*/; break;
@ -4937,6 +4947,9 @@ qboolean Image_WriteKTXFile(const char *filename, enum fs_relative fsroot, struc
}
switch(mips->type)
{
case PTI_ANY:
VFS_CLOSE(file);
return false;
case PTI_2D:
case PTI_2D_ARRAY:
case PTI_CUBE:
@ -4975,7 +4988,6 @@ static struct pendingtextureinfo *Image_ReadKTXFile(unsigned int flags, const ch
ktxheader_t header;
int nummips;
int mipnum;
int face;
int datasize;
unsigned int *swap, w, h, d, f, l, browbytes,padbytes,y,x,rows;
struct pendingtextureinfo *mips;
@ -5041,10 +5053,10 @@ static struct pendingtextureinfo *Image_ReadKTXFile(unsigned int flags, const ch
case 0x8C4E/*GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT*/: encoding = PTI_BC2_RGBA_SRGB; break;
case 0x83F3/*GL_COMPRESSED_RGBA_S3TC_DXT5_EXT*/: encoding = PTI_BC3_RGBA; break;
case 0x8C4F/*GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT*/: encoding = PTI_BC3_RGBA_SRGB; break;
case 0x8DBC/*GL_COMPRESSED_SIGNED_RED_RGTC1*/: encoding = PTI_BC4_R8_SNORM; break;
case 0x8DBB/*GL_COMPRESSED_RED_RGTC1*/: encoding = PTI_BC4_R8; break;
case 0x8DBE/*GL_COMPRESSED_SIGNED_RG_RGTC2*/: encoding = PTI_BC5_RG8_SNORM; break;
case 0x8DBD/*GL_COMPRESSED_RG_RGTC2*/: encoding = PTI_BC5_RG8; break;
case 0x8DBC/*GL_COMPRESSED_SIGNED_RED_RGTC1*/: encoding = PTI_BC4_R_SNORM; break;
case 0x8DBB/*GL_COMPRESSED_RED_RGTC1*/: encoding = PTI_BC4_R; break;
case 0x8DBE/*GL_COMPRESSED_SIGNED_RG_RGTC2*/: encoding = PTI_BC5_RG_SNORM; break;
case 0x8DBD/*GL_COMPRESSED_RG_RGTC2*/: encoding = PTI_BC5_RG; break;
case 0x8E8F/*GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB*/: encoding = PTI_BC6_RGB_UFLOAT; break;
case 0x8E8E/*GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB*/: encoding = PTI_BC6_RGB_SFLOAT; break;
case 0x8E8C/*GL_COMPRESSED_RGBA_BPTC_UNORM_ARB*/: encoding = PTI_BC7_RGBA; break;
@ -5266,7 +5278,8 @@ static struct pendingtextureinfo *Image_ReadKTXFile(unsigned int flags, const ch
w = max(1, w>>1);
h = max(1, h>>1);
d = max(1, d>>1);
if (mips->type == PTI_3D)
d = max(1, d>>1);
}
if (!mips->mipcount)
@ -5278,6 +5291,7 @@ static struct pendingtextureinfo *Image_ReadKTXFile(unsigned int flags, const ch
#ifdef ASTC_WITH_HDRTEST
if (encoding >= PTI_ASTC_4X4_LDR && encoding <= PTI_ASTC_12X12_LDR)
{
int face;
for (face = 0; face < header.numberoffaces; face++)
{
if (ASTC_BlocksAreHDR(mips->mip[face].data, mips->mip[face].datasize, blockwidth, blockheight, 1))
@ -5564,14 +5578,14 @@ static struct pendingtextureinfo *Image_ReadDDSFile(unsigned int flags, const ch
}
else if (*(int*)&fmtheader.ddpfPixelFormat.dwFourCC == (('A'<<0)|('T'<<8)|('I'<<16)|('1'<<24))
|| *(int*)&fmtheader.ddpfPixelFormat.dwFourCC == (('B'<<0)|('C'<<8)|('4'<<16)|('U'<<24)))
encoding = PTI_BC4_R8;
encoding = PTI_BC4_R;
else if (*(int*)&fmtheader.ddpfPixelFormat.dwFourCC == (('A'<<0)|('T'<<8)|('I'<<16)|('2'<<24))
|| *(int*)&fmtheader.ddpfPixelFormat.dwFourCC == (('B'<<0)|('C'<<8)|('5'<<16)|('U'<<24)))
encoding = PTI_BC5_RG8;
encoding = PTI_BC5_RG;
else if (*(int*)&fmtheader.ddpfPixelFormat.dwFourCC == (('B'<<0)|('C'<<8)|('4'<<16)|('S'<<24)))
encoding = PTI_BC4_R8_SNORM;
encoding = PTI_BC4_R_SNORM;
else if (*(int*)&fmtheader.ddpfPixelFormat.dwFourCC == (('B'<<0)|('C'<<8)|('5'<<16)|('S'<<24)))
encoding = PTI_BC5_RG8_SNORM;
encoding = PTI_BC5_RG_SNORM;
else if (*(int*)&fmtheader.ddpfPixelFormat.dwFourCC == (('E'<<0)|('T'<<8)|('C'<<16)|('2'<<24)))
encoding = PTI_ETC2_RGB8;
else if (*(int*)&fmtheader.ddpfPixelFormat.dwFourCC == (('D'<<0)|('X'<<8)|('1'<<16)|('0'<<24)))
@ -5661,11 +5675,11 @@ static struct pendingtextureinfo *Image_ReadDDSFile(unsigned int flags, const ch
case 0x4d/*DXGI_FORMAT_BC3_UNORM*/: encoding = PTI_BC3_RGBA; break;
case 0x4e/*DXGI_FORMAT_BC3_UNORM_SRGB*/: encoding = PTI_BC3_RGBA_SRGB; break;
// case 0x4f/*DXGI_FORMAT_BC4_TYPELESS*/: encoding = PTI_INVALID; break;
case 0x50/*DXGI_FORMAT_BC4_UNORM*/: encoding = PTI_BC4_R8; break;
case 0x51/*DXGI_FORMAT_BC4_SNORM*/: encoding = PTI_BC4_R8_SNORM; break;
case 0x50/*DXGI_FORMAT_BC4_UNORM*/: encoding = PTI_BC4_R; break;
case 0x51/*DXGI_FORMAT_BC4_SNORM*/: encoding = PTI_BC4_R_SNORM; break;
// case 0x52/*DXGI_FORMAT_BC5_TYPELESS*/: encoding = PTI_INVALID; break;
case 0x53/*DXGI_FORMAT_BC5_UNORM*/: encoding = PTI_BC5_RG8; break;
case 0x54/*DXGI_FORMAT_BC5_SNORM*/: encoding = PTI_BC5_RG8_SNORM; break;
case 0x53/*DXGI_FORMAT_BC5_UNORM*/: encoding = PTI_BC5_RG; break;
case 0x54/*DXGI_FORMAT_BC5_SNORM*/: encoding = PTI_BC5_RG_SNORM; break;
case 0x55/*DXGI_FORMAT_B5G6R5_UNORM*/: encoding = PTI_RGB565; break;
case 0x56/*DXGI_FORMAT_B5G5R5A1_UNORM*/: encoding = PTI_ARGB1555; break;
case 0x57/*DXGI_FORMAT_B8G8R8A8_UNORM*/: encoding = PTI_BGRA8; break;
@ -5759,12 +5773,12 @@ static struct pendingtextureinfo *Image_ReadDDSFile(unsigned int flags, const ch
if (fmt10header.arraysize == 6)
{
ttype = PTI_CUBE;
fmtheader.dwDepth = 6;
layers = 6;
}
else
{
ttype = PTI_CUBE_ARRAY;
fmtheader.dwDepth = fmt10header.arraysize;
layers = fmt10header.arraysize;
}
}
else if (fmtheader.ddsCaps[1] & 0x200000)
@ -5779,7 +5793,7 @@ static struct pendingtextureinfo *Image_ReadDDSFile(unsigned int flags, const ch
ttype = PTI_2D;
else
ttype = PTI_2D_ARRAY;
fmtheader.dwDepth = fmt10header.arraysize;
layers = fmt10header.arraysize;
}
mips = Z_Malloc(sizeof(*mips));
@ -5794,27 +5808,55 @@ static struct pendingtextureinfo *Image_ReadDDSFile(unsigned int flags, const ch
h = fmtheader.dwHeight;
d = fmtheader.dwDepth;
for (mipnum = 0; mipnum < nummips; mipnum++)
{
if (mips->mipcount >= countof(mips->mip))
break;
// if (datasize < 8)
// datasize = pad;
datasize = ((w+blockwidth-1)/blockwidth) * ((h+blockheight-1)/blockheight) * (d) * blockbytes;
for (layer = 0; layer < layers; layer++)
if (layers == 1)
{ //can just use the data without copying.
for (mipnum = 0; mipnum < nummips; mipnum++)
{
mips->mip[mips->mipcount].data = filedata;
mips->mip[mips->mipcount].datasize = datasize;
mips->mip[mips->mipcount].width = w;
mips->mip[mips->mipcount].height = h;
mips->mip[mips->mipcount].depth = d;
datasize = ((w+blockwidth-1)/blockwidth) * ((h+blockheight-1)/blockheight) * (d) * blockbytes;
mips->mip[mipnum].data = filedata;
mips->mip[mipnum].datasize = datasize;
mips->mip[mipnum].width = w;
mips->mip[mipnum].height = h;
mips->mip[mipnum].depth = d;
mips->mipcount++;
filedata += datasize;
w = max(1, w>>1);
h = max(1, h>>1);
d = max(1, d>>1);
}
w = (w+1)>>1;
h = (h+1)>>1;
}
else
{ //we need to copy stuff in order to pack it properly. :(
//allocate space and calc mip sizes
for (mipnum = 0; mipnum < nummips; mipnum++)
{
datasize = ((w+blockwidth-1)/blockwidth) * ((h+blockheight-1)/blockheight) * (layers*d) * blockbytes;
mips->mip[mipnum].data = BZ_Malloc(datasize);
mips->mip[mipnum].datasize = datasize;
mips->mip[mipnum].width = w;
mips->mip[mipnum].height = h;
mips->mip[mipnum].depth = layers*d;
w = max(1, w>>1);
h = max(1, h>>1);
d = max(1, d>>1);
}
mips->mipcount = mipnum;
//and now copy over the data
for (layer = 0; layer < layers; layer++)
{
for (mipnum = 0; mipnum < nummips; mipnum++)
{
datasize = mips->mip[mipnum].datasize/layers;
memcpy((qbyte*)mips->mip[mipnum].data+datasize*layer, filedata, datasize);
filedata += datasize;
}
}
//and now we're done with the source file. we might as well free it early.
BZ_Free(mips->extrafree);
mips->extrafree = NULL;
}
return mips;
@ -5869,6 +5911,8 @@ qboolean Image_WriteDDSFile(const char *filename, enum fs_relative fsroot, struc
arraysize = mips->mip[0].depth;
switch(mips->type)
{
case PTI_ANY:
return false;
case PTI_3D:
arraysize = 1;
h9.ddsCaps[1] |= 0x200000; //VOLUME
@ -6007,11 +6051,11 @@ qboolean Image_WriteDDSFile(const char *filename, enum fs_relative fsroot, struc
case PTI_BC3_RGBA: h10.dxgiformat = 0x4d/*DXGI_FORMAT_BC3_UNORM*/; DX9FOURCC('D','X','T','5'); break;
case PTI_BC3_RGBA_SRGB: h10.dxgiformat = 0x4e/*DXGI_FORMAT_BC3_UNORM_SRGB*/; break;
// case PTI_INVALID: h10.dxgiformat = 0x4f/*DXGI_FORMAT_BC4_TYPELESS*/; break;
case PTI_BC4_R8: h10.dxgiformat = 0x50/*DXGI_FORMAT_BC4_UNORM*/; /*DX9FOURCC('B','C','4','U');*/ DX9FOURCC('A','T','I','1'); break;
case PTI_BC4_R8_SNORM: h10.dxgiformat = 0x51/*DXGI_FORMAT_BC4_SNORM*/; DX9FOURCC('B','C','4','S'); break;
case PTI_BC4_R: h10.dxgiformat = 0x50/*DXGI_FORMAT_BC4_UNORM*/; /*DX9FOURCC('B','C','4','U');*/ DX9FOURCC('A','T','I','1'); break;
case PTI_BC4_R_SNORM: h10.dxgiformat = 0x51/*DXGI_FORMAT_BC4_SNORM*/; DX9FOURCC('B','C','4','S'); break;
// case PTI_INVALID: h10.dxgiformat = 0x52/*DXGI_FORMAT_BC5_TYPELESS*/; break;
case PTI_BC5_RG8: h10.dxgiformat = 0x53/*DXGI_FORMAT_BC5_UNORM*/; /*DX9FOURCC('B','C','5','U');*/ DX9FOURCC('A','T','I','2'); break;
case PTI_BC5_RG8_SNORM: h10.dxgiformat = 0x54/*DXGI_FORMAT_BC5_SNORM*/; DX9FOURCC('B','C','5','S'); break;
case PTI_BC5_RG: h10.dxgiformat = 0x53/*DXGI_FORMAT_BC5_UNORM*/; /*DX9FOURCC('B','C','5','U');*/ DX9FOURCC('A','T','I','2'); break;
case PTI_BC5_RG_SNORM: h10.dxgiformat = 0x54/*DXGI_FORMAT_BC5_SNORM*/; DX9FOURCC('B','C','5','S'); break;
case PTI_RGB565: h10.dxgiformat = 0x55/*DXGI_FORMAT_B5G6R5_UNORM*/; DX9FMT(16, 0xf800, 0x07e0, 0x001f, 0x0000,DX9RGB); break;
case PTI_ARGB1555: h10.dxgiformat = 0x56/*DXGI_FORMAT_B5G5R5A1_UNORM*/; DX9FMT(16, 0x7c00, 0x03e0, 0x001f, 0x8000,DX9RGBA); break;
case PTI_BGRA8: h10.dxgiformat = 0x57/*DXGI_FORMAT_B8G8R8A8_UNORM*/; DX9FMT(32,0x00ff0000,0x0000ff00,0x000000ff,0xff000000,DX9RGBA); break;
@ -7126,8 +7170,11 @@ static float HalfToFloat(unsigned short val)
float f;
unsigned int u;
} u;
u.u = (((val&0x7c00)>>10)-15+127)<<23; //read exponent, rebias it, and reshift.
u.u |= ((val & 0x3ff)<<13) | ((val & 0x3ff)<<3) | ((val & 0x3ff)>>7); //shift up the mantissa, and fold a little
if (val&0x7c00)
u.u = (((val&0x7c00)>>10)-15+127)<<23; //read exponent, rebias it, and reshift.
else
u.u = 0; //denormal (or 0).
u.u |= ((val & 0x3ff)<<13);//shift up the mantissa, but don't fold
u.u |= (val&0x8000)<<16; //retain the sign bit.
return u.f;
}
@ -8448,8 +8495,8 @@ static void Image_Tr_FloatToE5BGR9(struct pendingtextureinfo *mips, int dummy)
float *dofree = mips->mip[mip].needfree?in:NULL;
unsigned int p = mips->mip[mip].width*mips->mip[mip].height*mips->mip[mip].depth;
mips->mip[mip].needfree = true;
mips->mip[mip].data = out = BZ_Malloc(sizeof(*out)*p);
mips->mip[mip].datasize = p*sizeof(*out);
mips->mip[mip].data = out = BZ_Malloc(mips->mip[mip].datasize);
for (; p-->0; out++, in+=4)
{
int e = 0;
@ -8594,13 +8641,13 @@ static void Image_Tr_HalfToFloat(struct pendingtextureinfo *mips, int channels)
unsigned int mip;
for (mip = 0; mip < mips->mipcount; mip++)
{
float *in = mips->mip[mip].data;
unsigned short *in = mips->mip[mip].data;
float *out = mips->mip[mip].data;
float *dofree = mips->mip[mip].needfree?in:NULL;
unsigned int p = mips->mip[mip].width*mips->mip[mip].height*mips->mip[mip].depth;
unsigned short *dofree = mips->mip[mip].needfree?in:NULL;
unsigned int p = mips->mip[mip].width*mips->mip[mip].height*mips->mip[mip].depth*channels;
mips->mip[mip].needfree = true;
mips->mip[mip].data = out = BZ_Malloc(sizeof(*out)*p*4);
mips->mip[mip].datasize = p*sizeof(*out)*4;
mips->mip[mip].datasize = p*sizeof(*out);
mips->mip[mip].data = out = BZ_Malloc(mips->mip[mip].datasize);
while(p-->0)
*out++ = HalfToFloat(*in++);
BZ_Free(dofree);
@ -9251,7 +9298,7 @@ static void Image_Decode_BC4_Block(qbyte *fte_restrict in, pixel32_t *fte_restri
Vector4Set(r.v, 0, 0, 0, 0xff);
for (i = 0; i < 4; i++)
out[w*0+i] = out[w*1+i] = out[w*2+i] = out[w*3+i] = r;
Image_Decode_RGTC_Block_Internal(in, out->v+0, w*4, fmt==PTI_BC4_R8_SNORM);
Image_Decode_RGTC_Block_Internal(in, out->v+0, w*4, fmt==PTI_BC4_R_SNORM);
}
static void Image_Decode_BC5_Block(qbyte *fte_restrict in, pixel32_t *fte_restrict out, int w, uploadfmt_t fmt)
{ //BC5: two of BC3's alpha channels but used as red+green only.
@ -9260,8 +9307,8 @@ static void Image_Decode_BC5_Block(qbyte *fte_restrict in, pixel32_t *fte_restri
Vector4Set(r.v, 0, 0, 0, 0xff);
for (i = 0; i < 4; i++)
out[w*0+i] = out[w*1+i] = out[w*2+i] = out[w*3+i] = r;
Image_Decode_RGTC_Block_Internal(in+0, out->v+0, w*4, fmt==PTI_BC5_RG8_SNORM);
Image_Decode_RGTC_Block_Internal(in+8, out->v+1, w*4, fmt==PTI_BC5_RG8_SNORM);
Image_Decode_RGTC_Block_Internal(in+0, out->v+0, w*4, fmt==PTI_BC5_RG_SNORM);
Image_Decode_RGTC_Block_Internal(in+8, out->v+1, w*4, fmt==PTI_BC5_RG_SNORM);
}
#endif
@ -10389,8 +10436,8 @@ void Image_BlockSizeForEncoding(uploadfmt_t encoding, unsigned int *blockbytes,
case PTI_BC1_RGB_SRGB:
case PTI_BC1_RGBA:
case PTI_BC1_RGBA_SRGB:
case PTI_BC4_R8:
case PTI_BC4_R8_SNORM:
case PTI_BC4_R:
case PTI_BC4_R_SNORM:
case PTI_ETC1_RGB8:
case PTI_ETC2_RGB8:
case PTI_ETC2_RGB8_SRGB:
@ -10405,8 +10452,8 @@ void Image_BlockSizeForEncoding(uploadfmt_t encoding, unsigned int *blockbytes,
case PTI_BC2_RGBA_SRGB:
case PTI_BC3_RGBA:
case PTI_BC3_RGBA_SRGB:
case PTI_BC5_RG8:
case PTI_BC5_RG8_SNORM:
case PTI_BC5_RG:
case PTI_BC5_RG_SNORM:
case PTI_BC6_RGB_UFLOAT:
case PTI_BC6_RGB_SFLOAT:
case PTI_BC7_RGBA:
@ -10508,10 +10555,10 @@ qboolean Image_FormatHasAlpha(uploadfmt_t encoding)
case PTI_L8_SRGB:
case PTI_BC1_RGB:
case PTI_BC1_RGB_SRGB:
case PTI_BC4_R8:
case PTI_BC4_R8_SNORM:
case PTI_BC5_RG8:
case PTI_BC5_RG8_SNORM:
case PTI_BC4_R:
case PTI_BC4_R_SNORM:
case PTI_BC5_RG:
case PTI_BC5_RG_SNORM:
case PTI_BC6_RGB_UFLOAT:
case PTI_BC6_RGB_SFLOAT:
case PTI_ETC1_RGB8:
@ -10621,13 +10668,13 @@ const char *Image_FormatName(uploadfmt_t fmt)
case PTI_BGRA8_SRGB: return "BGRA8_SRGB";
case PTI_BGRX8_SRGB: return "BGRX8_SRGB";
case PTI_A2BGR10: return "A2BGR10";
case PTI_E5BGR9: return "E5BGR9";
case PTI_B10G11R11F: return "B10G11R11F";
case PTI_R16F: return "R16F";
case PTI_R32F: return "R32F";
case PTI_RGBA16F: return "RGBA16F";
case PTI_RGBA32F: return "RGBA32F";
case PTI_RGB32F: return "RGB32F";
case PTI_E5BGR9: return "E5BGR9_UF";
case PTI_B10G11R11F: return "B10G11R11_UF";
case PTI_R16F: return "R16_SF";
case PTI_R32F: return "R32_SF";
case PTI_RGBA16F: return "RGBA16_SF";
case PTI_RGBA32F: return "RGBA32_SF";
case PTI_RGB32F: return "RGB32_SF";
case PTI_R16: return "R16";
case PTI_RGBA16: return "RGBA16";
case PTI_P8: return "P8";
@ -10655,12 +10702,12 @@ const char *Image_FormatName(uploadfmt_t fmt)
case PTI_BC2_RGBA_SRGB: return "BC2_RGBA_SRGB";
case PTI_BC3_RGBA: return "BC3_RGBA";
case PTI_BC3_RGBA_SRGB: return "BC3_RGBA_SRGB";
case PTI_BC4_R8: return "BC4_R8";
case PTI_BC4_R8_SNORM: return "BC4_R8_SNORM";
case PTI_BC5_RG8: return "BC5_RG8";
case PTI_BC5_RG8_SNORM: return "BC5_RG8_SNORM";
case PTI_BC6_RGB_UFLOAT: return "BC6_RGBF";
case PTI_BC6_RGB_SFLOAT: return "BC6_RGBF_SNORM";
case PTI_BC4_R: return "BC4_R";
case PTI_BC4_R_SNORM: return "BC4_R_SNORM";
case PTI_BC5_RG: return "BC5_RG";
case PTI_BC5_RG_SNORM: return "BC5_RG_SNORM";
case PTI_BC6_RGB_UFLOAT: return "BC6_RGB_UF";
case PTI_BC6_RGB_SFLOAT: return "BC6_RGB_SF";
case PTI_BC7_RGBA: return "BC7_RGBA";
case PTI_BC7_RGBA_SRGB: return "BC7_RGBA_SRGB";
case PTI_ETC1_RGB8: return "ETC1_RGB8";
@ -10999,13 +11046,13 @@ static qboolean Image_DecompressFormat(struct pendingtextureinfo *mips, const ch
#endif
break;
#ifdef DECOMPRESS_RGTC
case PTI_BC4_R8_SNORM:
case PTI_BC4_R8:
case PTI_BC4_R_SNORM:
case PTI_BC4_R:
decodefunc = Image_Decode_BC4_Block;
rcoding = PTI_RGBX8;
break;
case PTI_BC5_RG8_SNORM:
case PTI_BC5_RG8:
case PTI_BC5_RG_SNORM:
case PTI_BC5_RG:
decodefunc = Image_Decode_BC5_Block;
rcoding = PTI_RGBX8;
break;
@ -11459,6 +11506,39 @@ static qboolean Image_GenMip0(struct pendingtextureinfo *mips, unsigned int flag
switch(fmt)
{
default:
if (fmt&PTI_FULLMIPCHAIN)
{
fmt = fmt&~PTI_FULLMIPCHAIN;
Image_RoundDimensions(&mips->mip[0].width, &mips->mip[0].height, flags);
if (mips->mip[0].width == imgwidth && mips->mip[0].height == imgheight) //make sure its okay
{
size_t sz = 0;
Image_BlockSizeForEncoding(fmt, &bb, &bw, &bh);
for (i = 0; i < countof(mips->mip) && (imgwidth || imgheight); i++, imgwidth>>=1, imgheight>>=1)
{
mips->mip[i].width = max(1,imgwidth);
mips->mip[i].height = max(1,imgheight);
mips->mip[i].depth = 1;
mips->mip[i].datasize = bb * ((mips->mip[i].width+bw-1)/bw) * ((mips->mip[i].height+bh-1)/bh);
mips->mip[i].needfree = false;
sz += mips->mip[i].datasize;
}
mips->mipcount = i;
mips->encoding = fmt;
if (!freedata)
{
rgbadata = BZ_Malloc(sz);
memcpy(rgbadata, rawdata, sz);
}
mips->extrafree = rawdata = rgbadata;
for (i = 0; i < mips->mipcount; i++)
{
mips->mip[i].data = rawdata;
rawdata = (qbyte*)rawdata+mips->mip[i].datasize;
}
return true;
}
}
mips->encoding = fmt;
break;
@ -11985,10 +12065,10 @@ static qboolean Image_GenMip0(struct pendingtextureinfo *mips, unsigned int flag
case PTI_BGRX8_SRGB:
case PTI_BC1_RGB:
case PTI_BC1_RGB_SRGB:
case PTI_BC4_R8:
case PTI_BC4_R8_SNORM:
case PTI_BC5_RG8:
case PTI_BC5_RG8_SNORM:
case PTI_BC4_R:
case PTI_BC4_R_SNORM:
case PTI_BC5_RG:
case PTI_BC5_RG_SNORM:
case PTI_BC6_RGB_UFLOAT:
case PTI_BC6_RGB_SFLOAT:
case PTI_ETC1_RGB8:
@ -12498,7 +12578,7 @@ void *Image_FlipImage(const void *inbuffer, void *outbuffer, int *inoutwidth, in
{
inb = inr; //reset the input after each row, so we have truely independant row+column strides
inr += rowstride;
for (x = 0; x < inheight; x++)
for (x = 0; x < inwidth; x++)
{
for (b = 0; b < pixelbytes; b++)
*outb++ = inb[b];
@ -12545,12 +12625,12 @@ static struct pendingtextureinfo *Image_LoadCubemapTextureData(const char *nicen
} cmscheme[][6] =
{
{
{"rt", true, false, true},
{"lf", false, true, true},
{"ft", true, true, false},
{"bk", false, false, false},
{"up", true, false, true},
{"dn", true, false, true}
{"rt", false, false, true},
{"lf", true, true, true},
{"bk", false, true, false},
{"ft", true, false, false},
{"up", false, false, true},
{"dn", false, false, true}
},
{
@ -12614,8 +12694,8 @@ static struct pendingtextureinfo *Image_LoadCubemapTextureData(const char *nicen
extern cvar_t vid_hardwaregamma;
int bb,bw,bh;
Image_BlockSizeForEncoding(format, &bb, &bw, &bh);
if (needsflipping && (bb!=4 || bw!=1 || bh!=1))
;
if (needsflipping && (bw!=1 || bh!=1))
/*can't do it*/;
else if (width == height && (!mips || width == mips->mip[0].width)) //cubemaps must be square and all the same size (npot is fine though)
{ //(skies have a fallback for invalid sizes, but it'll run a bit slower)
@ -12624,13 +12704,13 @@ static struct pendingtextureinfo *Image_LoadCubemapTextureData(const char *nicen
mips = Z_Malloc(sizeof(*mips));
mips->type = PTI_CUBE;
mips->mipcount = 1;
mips->encoding = PTI_RGBA8;
mips->encoding = format;
mips->extrafree = NULL;
mips->mip[0].datasize = width*height*4*6;
mips->mip[0].datasize = width*height*bb*6;
mips->mip[0].data = BZ_Malloc(mips->mip[0].datasize);
mips->mip[0].width = width;
mips->mip[0].height = height;
mips->mip[0].depth = 6;;
mips->mip[0].depth = 6;
mips->mip[0].needfree = true;
}
@ -12691,10 +12771,11 @@ static qboolean Image_LoadRawTexture(texid_t tex, unsigned int flags, void *rawd
COM_AddWork(WG_MAIN, Image_LoadTexture_Failed, tex, NULL, 0, 0);
return false;
}
fmt &= ~PTI_FULLMIPCHAIN;
Image_GenerateMips(mips, flags);
Image_ChangeFormatFlags(mips, flags, fmt, tex->ident);
Image_FixupImageSize(tex, imgwidth, imgheight);
Image_FixupImageSize(tex, imgwidth, imgheight, mips->mip[0].depth);
if (flags & IF_NOWORKER)
Image_LoadTextureMips(tex, mips, 0, 0);
else
@ -12712,7 +12793,7 @@ qboolean Image_LoadTextureFromMemory(texid_t tex, int flags, const char *iname,
BZ_Free(tex->fallbackdata);
tex->fallbackdata = NULL;
Image_FixupImageSize(tex, mips->mip[0].width, mips->mip[0].height);
Image_FixupImageSize(tex, mips->mip[0].width, mips->mip[0].height, mips->mip[0].depth);
if ((flags & IF_NOWORKER) || Sys_IsMainThread())
Image_LoadTextureMips(tex, mips, 0, 0);
else
@ -13065,7 +13146,7 @@ static void Image_LoadHiResTextureWorker(void *ctx, void *data, size_t a, size_t
if (mips)
{
Image_FixupImageSize(tex, mips->mip[0].width, mips->mip[0].height);
Image_FixupImageSize(tex, mips->mip[0].width, mips->mip[0].height, mips->mip[0].depth);
if (tex->flags & IF_NOWORKER)
Image_LoadTextureMips(tex, mips, 0, 0);
else
@ -13358,7 +13439,14 @@ image_t *QDECL Image_GetTexture(const char *identifier, const char *subpath, uns
(fallbackwidth>>3)*(fallbackheight>>3);
break;
default:
Sys_Error("Image_GetTexture: bad format");
{
unsigned int bb, bw, bh;
unsigned int lev;
Image_BlockSizeForEncoding(fallbackfmt&~PTI_FULLMIPCHAIN, &bb, &bw, &bh);
for (b=0, lev = 0; fallbackwidth>>lev||fallbackheight>>lev; lev++)
b += bb * (max(1,fallbackwidth>>lev)+bw-1)/bw * (max(1,fallbackheight>>lev)+bh-1)/bh;
}
break;
}
tex->fallbackdata = BZ_Malloc(b + pb);
memcpy(tex->fallbackdata, fallbackdata, b);
@ -13601,11 +13689,11 @@ void Image_List_f(void)
failed++;
continue;
}
if (((tex->flags&IF_TEXTYPEMASK)>>IF_TEXTYPESHIFT) == PTI_2D)
if (((tex->flags&IF_TEXTYPEMASK)>>IF_TEXTYPESHIFT) == PTI_2D || ((tex->flags&IF_TEXTYPEMASK)>>IF_TEXTYPESHIFT) == PTI_CUBE)
Con_Printf("^[\\imgptr\\%#"PRIxSIZE"^]", (size_t)tex);
if (tex->subpath)
Con_Printf("^h(%s)^h", tex->subpath);
Con_DLPrintf(1, " %x", tex->flags);
// Con_DLPrintf(1, " %x", tex->flags);
if (Image_LocateHighResTexture(tex, &loc, fname, sizeof(fname), &loadflags))
{
@ -13614,7 +13702,7 @@ void Image_List_f(void)
while((bullshit=strchr(defuck, '\\')))
*bullshit = '/';
if (((tex->flags&IF_TEXTYPEMASK)>>IF_TEXTYPESHIFT) == PTI_2D || tex->format == PTI_P8)
if (((tex->flags&IF_TEXTYPEMASK)>>IF_TEXTYPESHIFT) == PTI_2D||((tex->flags&IF_TEXTYPEMASK)>>IF_TEXTYPESHIFT) == PTI_CUBE || tex->format == PTI_P8)
Con_Printf("^[%s\\tip\\%s/%s\\tipimgptr\\%#"PRIxSIZE"^]: ", tex->ident, defuck, fname, (size_t)tex);
else
Con_Printf("^[%s\\tip\\%s/%s^]: ", tex->ident, defuck, fname);
@ -13635,15 +13723,25 @@ void Image_List_f(void)
if (tex->status == TEX_LOADED)
{
char *type;
unsigned int blockbytes, blockwidth, blockheight;
Image_BlockSizeForEncoding(tex->format, &blockbytes, &blockwidth, &blockheight);
imgmem = blockbytes * (tex->width+blockwidth-1)/blockwidth * (tex->height+blockheight-1)/blockheight;
imgmem = blockbytes * (tex->width+blockwidth-1)/blockwidth * (tex->height+blockheight-1)/blockheight * tex->depth;
switch((tex->flags & IF_TEXTYPEMASK)>>IF_TEXTYPESHIFT)
{
case PTI_2D: type = ""; break;
case PTI_3D: type = "3D "; break;
case PTI_CUBE: type = "Cube "; break;
case PTI_2D_ARRAY: type = "Array "; break;
case PTI_CUBE_ARRAY:type = "CubeArray "; break;
default: type = "UNKNOWN "; break;
}
if (!(tex->flags & IF_NOMIPMAP))
imgmem += imgmem/3; //mips take about a third extra mem.
if (tex->depth != 1)
Con_Printf("^2loaded (%i*%i*%i ^4%s^2, %3fKB->%3fKB)\n", tex->width, tex->height, tex->depth, Image_FormatName(tex->format), loc.len/(1024.0), imgmem/(1024.0));
Con_Printf("^2loaded (%s%i*%i*%i ^4%s^2, %3fKB->%3fKB)\n", type, tex->width, tex->height, tex->depth, Image_FormatName(tex->format), loc.len/(1024.0), imgmem/(1024.0));
else
Con_Printf("^2loaded (%i*%i ^4%s^2, %3fKB->%3fKB)\n", tex->width, tex->height, Image_FormatName(tex->format), loc.len/(1024.0), imgmem/(1024.0));
Con_Printf("^2loaded (%s%i*%i ^4%s^2, %3fKB->%3fKB)\n", type, tex->width, tex->height, Image_FormatName(tex->format), loc.len/(1024.0), imgmem/(1024.0));
if (tex->aliasof)
{
aliasedmem += imgmem;

View File

@ -360,6 +360,13 @@ qboolean Media_NamedTrack(const char *track, const char *looptrack)
int ie, ip;
char *trackend;
if (!track && !looptrack)
{
*media_playtrack = *media_loopingtrack = 0;
Media_Changed(MEDIA_GAMEMUSIC);
return true;
}
if (!track || !*track) //ignore calls if the primary track is invalid. whatever is already playing will continue to play.
return false;
if (!looptrack || !*looptrack) //null or empty looptrack loops using the primary track, for compat with q3.

View File

@ -298,6 +298,8 @@ struct pendingtextureinfo
PTI_CUBE, //w*h*6 - depth MUST be 6 (faces must be tightly packed)
PTI_2D_ARRAY, //w*h*layers - depth is =layers
PTI_CUBE_ARRAY, //w*h*(layers*6) - depth is =(layers*6).
PTI_ANY //says we don't care.
} type;
uploadfmt_t encoding; //PTI_* formats

View File

@ -103,7 +103,7 @@ typedef struct {
} net_masterlist_t;
static net_masterlist_t net_masterlist[] = {
#if 0 //for debugging
{MP_DPMASTER, CVARFC("net_masterextra1", "localhost:27950", CVAR_NOSAVE, Net_Masterlist_Callback)}, //admin: Eukara
{MP_DPMASTER, CVARFC("net_masterextra1", "localhost:27950", CVAR_NOSAVE, Net_Masterlist_Callback)}, //admin: the reader...
#else
#ifndef QUAKETC
@ -119,7 +119,7 @@ static net_masterlist_t net_masterlist[] = {
#endif
//dpmaster is the generic non-quake-specific master protocol that we use for custom stand-alone mods.
{MP_DPMASTER, CVARAFC("net_master1", "localhost", "sv_master1", 0, Net_Masterlist_Callback)},
{MP_DPMASTER, CVARAFC("net_master1", "", "sv_master1", 0, Net_Masterlist_Callback)},
{MP_DPMASTER, CVARAFC("net_master2", "", "sv_master2", 0, Net_Masterlist_Callback)},
{MP_DPMASTER, CVARAFC("net_master3", "", "sv_master3", 0, Net_Masterlist_Callback)},
{MP_DPMASTER, CVARAFC("net_master4", "", "sv_master4", 0, Net_Masterlist_Callback)},
@ -145,11 +145,11 @@ static net_masterlist_t net_masterlist[] = {
#ifdef HAVE_PACKET
#ifndef QUAKETC
//engine-specified/maintained master lists (so users can be lazy and update the engine without having to rewrite all their configs).
{MP_QUAKEWORLD, CVARFC("net_qwmasterextra1", "qwmaster.ocrana.de:27000", CVAR_NOSAVE, Net_Masterlist_Callback), "Ocrana(2nd)"}, //german. admin unknown
{MP_QUAKEWORLD, CVARFC("net_qwmasterextra2", ""/*"masterserver.exhale.de:27000" seems dead*/, CVAR_NOSAVE, Net_Masterlist_Callback)}, //german. admin unknown
{MP_QUAKEWORLD, CVARFC("net_qwmasterextra1", ""/*"qwmaster.ocrana.de:27000" not responding*/, CVAR_NOSAVE, Net_Masterlist_Callback), "Ocrana(2nd)"}, //german. admin unknown
{MP_QUAKEWORLD, CVARFC("net_qwmasterextra2", ""/*"masterserver.exhale.de:27000" dns dead*/, CVAR_NOSAVE, Net_Masterlist_Callback)}, //german. admin unknown
// {MP_QUAKEWORLD, CVARFC("net_qwmasterextra3", "asgaard.morphos-team.net:27000", CVAR_NOSAVE, Net_Masterlist_Callback), "Germany, admin: bigfoot"},
{MP_QUAKEWORLD, CVARFC("net_qwmasterextra4", "master.quakeservers.net:27000", CVAR_NOSAVE, Net_Masterlist_Callback), "Germany, admin: raz0?"},
// {MP_QUAKEWORLD, CVARFC("net_qwmasterextra5", "qwmaster.fodquake.net:27000", CVAR_NOSAVE, Net_Masterlist_Callback), "admin: bigfoot"},
{MP_QUAKEWORLD, CVARFC("net_qwmasterextra5", "qwmaster.fodquake.net:27000", CVAR_NOSAVE, Net_Masterlist_Callback), "admin: bigfoot"},
// {MP_QUAKEWORLD, CVARFC("net_qwmasterextraHistoric", "satan.idsoftware.com:27000", CVAR_NOSAVE, Net_Masterlist_Callback), "Official id Master"},
// {MP_QUAKEWORLD, CVARFC("net_qwmasterextraHistoric", "satan.idsoftware.com:27002", CVAR_NOSAVE, Net_Masterlist_Callback), "Official id Master For CTF Servers"},
// {MP_QUAKEWORLD, CVARFC("net_qwmasterextraHistoric", "satan.idsoftware.com:27003", CVAR_NOSAVE, Net_Masterlist_Callback), "Official id Master For TeamFortress Servers"},
@ -167,7 +167,7 @@ static net_masterlist_t net_masterlist[] = {
// {MP_QUAKEWORLD, CVARFC("net_qwmasterextraHistoric", "master.teamdamage.com:27000", CVAR_NOSAVE, Net_Masterlist_Callback), "master.teamdamage.com"},
//Total conversions will need to define their own in defaults.cfg or whatever.
{MP_DPMASTER, CVARFC("net_masterextra1", "master.frag-net.com:27950 198.58.111.37:27950", CVAR_NOSAVE, Net_Masterlist_Callback)}, //admin: Eukara
{MP_DPMASTER, CVARFC("net_masterextra1", "master.frag-net.com:27950 198.58.111.37:27950", CVAR_NOSAVE, Net_Masterlist_Callback)}, //admin: Eukara
// {MP_DPMASTER, CVARFC("net_masterextra1", ""/*"ghdigital.com:27950 207.55.114.154:27950"*/, CVAR_NOSAVE, Net_Masterlist_Callback)}, //(was 69.59.212.88) admin: LordHavoc
{MP_DPMASTER, CVARFC("net_masterextra2", "dpmaster.deathmask.net:27950 107.161.23.68:27950 [2604:180::4ac:98c1]:27950", CVAR_NOSAVE, Net_Masterlist_Callback)}, //admin: Willis
{MP_DPMASTER, CVARFC("net_masterextra3", "dpmaster.tchr.no:27950 92.62.40.73:27950", CVAR_NOSAVE, Net_Masterlist_Callback)}, //admin: tChr
@ -197,7 +197,6 @@ static net_masterlist_t net_masterlist[] = {
{MP_QUAKE3, CVARFC("net_q3masterextra3", "master.ioquake3.org:27950", CVAR_NOSAVE, Net_Masterlist_Callback), "DE: ioquake3"},
{MP_QUAKE3, CVARFC("net_q3masterextra4", "master.huxxer.de:27950", CVAR_NOSAVE, Net_Masterlist_Callback), "DE: BMA Team"},
{MP_QUAKE3, CVARFC("net_q3masterextra5", "master.maverickservers.com:27950", CVAR_NOSAVE, Net_Masterlist_Callback), "US: Maverickservers.com"},
{MP_QUAKE3, CVARFC("net_q3masterextra6", "dpmaster.deathmask.net:27950", CVAR_NOSAVE, Net_Masterlist_Callback), "US: DeathMask.net"},
{MP_QUAKE3, CVARFC("net_q3masterextra8", "master3.idsoftware.com:27950", CVAR_NOSAVE, Net_Masterlist_Callback), "US: id Software Quake III Master"},
#endif
#endif

View File

@ -917,6 +917,15 @@ void QCBUILTIN PF_shaderforname (pubprogfuncs_t *prinst, struct globalvars_s *pr
G_FLOAT(OFS_RETURN) = 0;
}
void QCBUILTIN PF_remapshader (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
const char *shadername = PR_GetStringOfs(prinst, OFS_PARM0);
const char *replacement = PR_GetStringOfs(prinst, OFS_PARM1);
float timeoffset = G_FLOAT(OFS_PARM2);
R_RemapShader(shadername, replacement, timeoffset);
}
void QCBUILTIN PF_cl_GetBindMap (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int bm[2];

View File

@ -6548,6 +6548,7 @@ static struct {
{"rotatevectorsbyvectors", PF_rotatevectorsbymatrix, 236}, // #236
{"skinforname", PF_skinforname, 237}, // #237
{"shaderforname", PF_shaderforname, 238}, // #238
{"remapshader", PF_remapshader, 0},
{"te_bloodqw", PF_cl_te_bloodqw, 239}, // #239 void te_bloodqw(vector org[, float count]) (FTE_TE_STANDARDEFFECTBUILTINS)
{"checkpvs", PF_checkpvs, 240},

View File

@ -4127,7 +4127,7 @@ Groups surfaces into their respective batches (based on the lightmap number).
*/
void Surf_BuildLightmaps (void)
{
int i;
unsigned int i, j;
model_t *m;
extern model_t *mod_known;
@ -4170,6 +4170,10 @@ void Surf_BuildLightmaps (void)
if (m->loadstate != MLS_LOADED)
continue;
Surf_BuildModelLightmaps(m);
for (j = 0; j < m->numenvmaps; j++)
if (m->envmaps[j].image)
m->envmaps[j].image->regsequence = r_regsequence;
}
BE_UploadAllLightmaps();
}

View File

@ -337,7 +337,7 @@ void R_LightArraysByte_BGR(const entity_t *entity, vecV_t *coords, byte_vec4_t *
void R_LightArrays(const entity_t *entity, vecV_t *coords, avec4_t *colours, int vertcount, vec3_t *normals, float scale, qboolean colormod);
qboolean R_DrawSkyChain (struct batch_s *batch); /*called from the backend, and calls back into it*/
void R_InitSky (shader_t *shader, const char *skyname, qbyte *src, unsigned int width, unsigned int height); /*generate q1 sky texnums*/
void R_InitSky (shader_t *shader, const char *skyname, uploadfmt_t fmt, qbyte *src, unsigned int width, unsigned int height); /*generate q1 sky texnums*/
void R_Clutter_Emit(struct batch_s **batches);
void R_Clutter_Purge(void);
@ -429,6 +429,7 @@ enum imageflags
#define IF_TEXTYPE_CUBE (PTI_CUBE<<IF_TEXTYPESHIFT)
#define IF_TEXTYPE_2D_ARRAY (PTI_2D_ARRAY<<IF_TEXTYPESHIFT)
#define IF_TEXTYPE_CUBE_ARRAY (PTI_CUBE_ARRAY<<IF_TEXTYPESHIFT)
#define IF_TEXTYPE_ANY (PTI_ANY<<IF_TEXTYPESHIFT)
IF_MIPCAP = 1<<13, //allow the use of d_mipcap
IF_PREMULTIPLYALPHA = 1<<14, //rgb *= alpha
@ -603,7 +604,7 @@ struct texture_s *R_TextureAnimation_Q2 (struct texture_s *base); //mostly depre
void RQ_Init(void);
void RQ_Shutdown(void);
void WritePCXfile (const char *filename, enum fs_relative fsroot, qbyte *data, int width, int height, int rowbytes, qbyte *palette, qboolean upload); //data is 8bit.
qboolean WritePCXfile (const char *filename, enum fs_relative fsroot, qbyte *data, int width, int height, int rowbytes, qbyte *palette, qboolean upload); //data is 8bit.
qbyte *ReadPCXFile(qbyte *buf, int length, int *width, int *height);
void *ReadTargaFile(qbyte *buf, int length, int *width, int *height, uploadfmt_t *format, qboolean greyonly, uploadfmt_t forceformat);
qbyte *ReadPNGFile(const char *fname, qbyte *buf, int length, int *width, int *height, uploadfmt_t *format);

View File

@ -50,6 +50,7 @@ void QDECL SCR_Fov_Callback (struct cvar_s *var, char *oldvalue);
void QDECL Image_TextureMode_Callback (struct cvar_s *var, char *oldvalue);
void QDECL R_SkyBox_Changed (struct cvar_s *var, char *oldvalue)
{
R_SetSky(var->string);
// Shader_NeedReload(false);
}
void R_ForceSky_f(void)
@ -211,7 +212,7 @@ cvar_t r_menutint = CVARF ("r_menutint", "0.68 0.4 0.13",
CVAR_RENDERERCALLBACK);
cvar_t r_netgraph = CVARD ("r_netgraph", "0", "Displays a graph of packet latency. A value of 2 will give additional info about what sort of data is being received from the server.");
extern cvar_t r_lerpmuzzlehack;
extern cvar_t mod_h2holey_bugged;
extern cvar_t mod_h2holey_bugged, mod_halftexel;
cvar_t r_nolerp = CVARF ("r_nolerp", "0", CVAR_ARCHIVE);
cvar_t r_noframegrouplerp = CVARF ("r_noframegrouplerp", "0", CVAR_ARCHIVE);
cvar_t r_nolightdir = CVARF ("r_nolightdir", "0", CVAR_ARCHIVE);
@ -561,6 +562,7 @@ void GLRenderer_Init(void)
#endif
#ifdef MD1MODELS
Cvar_Register (&mod_h2holey_bugged, GLRENDEREROPTIONS);
Cvar_Register (&mod_halftexel, GLRENDEREROPTIONS);
#endif
Cvar_Register (&r_lerpmuzzlehack, GLRENDEREROPTIONS);
Cvar_Register (&r_noframegrouplerp, GLRENDEREROPTIONS);
@ -642,7 +644,9 @@ void R_InitTextures (void)
// create a simple checkerboard texture for the default
r_notexture_mip = (texture_t*)r_notexture_mip_mem;
r_notexture_mip->width = r_notexture_mip->height = 16;
r_notexture_mip->vwidth = r_notexture_mip->vheight = 16;
r_notexture_mip->srcwidth = r_notexture_mip->srcheight = 16;
r_notexture_mip->srcfmt = TF_SOLID8;
for (m=0 ; m<1 ; m++)
{
@ -777,17 +781,6 @@ void Renderer_Init(void)
Cmd_AddCommand("r_remapshader", Shader_RemapShader_f);
Cmd_AddCommand("r_showshader", Shader_ShowShader_f);
#if defined(D3DQUAKE)
GLD3DRenderer_Init();
#endif
#if defined(GLQUAKE)
GLRenderer_Init();
#endif
#if defined(GLQUAKE) || defined(VKQUAKE)
R_BloomRegister();
#endif
#ifdef SWQUAKE
{
extern cvar_t sw_interlace;
@ -869,6 +862,8 @@ void Renderer_Init(void)
Cvar_Register(&r_keepimages, GRAPHICALNICETIES);
Cvar_Register(&r_ignoremapprefixes, GRAPHICALNICETIES);
Cvar_ForceCallback(&r_keepimages);
Cvar_ForceCallback(&r_ignoremapprefixes);
#ifdef IMAGEFMT_TGA
Cvar_Register(&r_dodgytgafiles, "Hacky bug workarounds");
#endif
@ -1067,6 +1062,18 @@ void Renderer_Init(void)
Cmd_AddCommand ("listskyboxes", R_ListSkyBoxes_f);
Cmd_AddCommand ("listconfigs", R_ListConfigs_f);
#if defined(D3DQUAKE)
GLD3DRenderer_Init();
#endif
#if defined(GLQUAKE)
GLRenderer_Init();
#endif
#if defined(GLQUAKE) || defined(VKQUAKE)
R_BloomRegister();
#endif
P_InitParticleSystem();
R_InitTextures();
}
@ -3198,7 +3205,7 @@ void R_InitParticleTexture (void)
}
}
TEXASSIGN(particletexture, R_LoadTexture32("dotparticle", 8, 8, data, IF_NOMIPMAP|IF_NOPICMIP|IF_CLAMP));
TEXASSIGN(particletexture, R_LoadTexture32("dotparticle", 8, 8, data, IF_NOMIPMAP|IF_NOPICMIP|IF_CLAMP|IF_NOPURGE));
//
@ -3222,7 +3229,7 @@ void R_InitParticleTexture (void)
data[y*32+x][3] = 255;
}
}
particlecqtexture = Image_GetTexture("classicparticle", "particles", IF_NOMIPMAP|IF_NOPICMIP|IF_CLAMP, data, NULL, 32, 32, TF_RGBA32);
particlecqtexture = Image_GetTexture("classicparticle", "particles", IF_NOMIPMAP|IF_NOPICMIP|IF_CLAMP|IF_NOPURGE, data, NULL, 32, 32, TF_RGBA32);
//draw a square in the top left. still a triangle.
for (x=0 ; x<16 ; x++)
@ -3232,7 +3239,7 @@ void R_InitParticleTexture (void)
data[y*32+x][3] = 255;
}
}
Image_GetTexture("classicparticle_square", "particles", IF_NOMIPMAP|IF_NOPICMIP|IF_CLAMP, data, NULL, 32, 32, TF_RGBA32);
Image_GetTexture("classicparticle_square", "particles", IF_NOMIPMAP|IF_NOPICMIP|IF_CLAMP|IF_NOPURGE, data, NULL, 32, 32, TF_RGBA32);
for (x=0 ; x<16 ; x++)
@ -3245,7 +3252,7 @@ void R_InitParticleTexture (void)
data[y*16+x][3] = exptexture[x][y]*255/9.0;
}
}
explosiontexture = Image_GetTexture("fte_fuzzyparticle", "particles", IF_NOMIPMAP|IF_NOPICMIP, data, NULL, 16, 16, TF_RGBA32);
explosiontexture = Image_GetTexture("fte_fuzzyparticle", "particles", IF_NOMIPMAP|IF_NOPICMIP|IF_NOPURGE, data, NULL, 16, 16, TF_RGBA32);
for (x=0 ; x<16 ; x++)
{
@ -3257,7 +3264,7 @@ void R_InitParticleTexture (void)
data[y*16+x][3] = exptexture[x][y]*255/9.0;
}
}
Image_GetTexture("fte_bloodparticle", "particles", IF_NOMIPMAP|IF_NOPICMIP, data, NULL, 16, 16, TF_RGBA32);
Image_GetTexture("fte_bloodparticle", "particles", IF_NOMIPMAP|IF_NOPICMIP|IF_NOPURGE, data, NULL, 16, 16, TF_RGBA32);
for (x=0 ; x<16 ; x++)
{
@ -3269,7 +3276,7 @@ void R_InitParticleTexture (void)
data[y*16+x][3] = 255;
}
}
Image_GetTexture("fte_blooddecal", "particles", IF_NOMIPMAP|IF_NOPICMIP, data, NULL, 16, 16, TF_RGBA32);
Image_GetTexture("fte_blooddecal", "particles", IF_NOMIPMAP|IF_NOPICMIP|IF_NOPURGE, data, NULL, 16, 16, TF_RGBA32);
memset(data, 255, sizeof(data));
for (y = 0;y < PARTICLETEXTURESIZE;y++)
@ -3283,7 +3290,7 @@ void R_InitParticleTexture (void)
data[y*PARTICLETEXTURESIZE+x][3] = (qbyte) d;
}
}
balltexture = R_LoadTexture32("balltexture", PARTICLETEXTURESIZE, PARTICLETEXTURESIZE, data, IF_NOMIPMAP|IF_NOPICMIP);
balltexture = R_LoadTexture32("balltexture", PARTICLETEXTURESIZE, PARTICLETEXTURESIZE, data, IF_NOMIPMAP|IF_NOPICMIP|IF_NOPURGE);
memset(data, 255, sizeof(data));
for (y = 0;y < PARTICLETEXTURESIZE;y++)
@ -3296,7 +3303,7 @@ void R_InitParticleTexture (void)
data[y*PARTICLETEXTURESIZE+x][3] = (qbyte) d;
}
}
beamtexture = R_LoadTexture32("beamparticle", PARTICLETEXTURESIZE, PARTICLETEXTURESIZE, data, IF_NOMIPMAP|IF_NOPICMIP);
beamtexture = R_LoadTexture32("beamparticle", PARTICLETEXTURESIZE, PARTICLETEXTURESIZE, data, IF_NOMIPMAP|IF_NOPICMIP|IF_NOPURGE);
for (y = 0;y < PARTICLETEXTURESIZE;y++)
{
@ -3314,6 +3321,6 @@ void R_InitParticleTexture (void)
data[y*PARTICLETEXTURESIZE+x][3] = (qbyte) d/2;
}
}
ptritexture = R_LoadTexture32("ptritexture", PARTICLETEXTURESIZE, PARTICLETEXTURESIZE, data, IF_NOMIPMAP|IF_NOPICMIP);
ptritexture = R_LoadTexture32("ptritexture", PARTICLETEXTURESIZE, PARTICLETEXTURESIZE, data, IF_NOMIPMAP|IF_NOPICMIP|IF_NOPURGE);
}

View File

@ -309,7 +309,7 @@ int i;
if((fp = FS_OpenVFS(fname, "rb", FS_GAME)) == NULL)
{
if((fp = FS_OpenVFS(va("video/%s.roq", fname), "rb", FS_GAME)) == NULL) //for q3 compat
if((fp = FS_OpenVFS(va("video/%s", fname), "rb", FS_GAME)) == NULL) //for q3 compat
return NULL;
}

View File

@ -139,10 +139,10 @@ typedef enum uploadfmt
PTI_BC2_RGBA_SRGB, /*8bpp*/
PTI_BC3_RGBA, /*8bpp*/ //maybe add a bc3 normalmapswizzle type for d3d9?
PTI_BC3_RGBA_SRGB, /*8bpp*/
PTI_BC4_R8, /*4bpp*/ //greyscale, kinda
PTI_BC4_R8_SNORM, /*4bpp*/
PTI_BC5_RG8, /*8bpp*/ //useful for normalmaps
PTI_BC5_RG8_SNORM, /*8bpp*/ //useful for normalmaps
PTI_BC4_R, /*4bpp*/ //greyscale, kinda
PTI_BC4_R_SNORM, /*4bpp*/
PTI_BC5_RG, /*8bpp*/ //useful for normalmaps
PTI_BC5_RG_SNORM, /*8bpp*/ //useful for normalmaps
PTI_BC6_RGB_UFLOAT, /*8bpp*/ //unsigned (half) floats!
PTI_BC6_RGB_SFLOAT, /*8bpp*/ //signed (half) floats!
PTI_BC7_RGBA, /*8bpp*/ //multimode compression, using as many bits as bc2/bc3
@ -251,6 +251,7 @@ typedef enum uploadfmt
//these are emulated formats. this 'case' value allows drivers to easily ignore them
#define PTI_EMULATED TF_INVALID:case TF_BGR24_FLIP:case TF_MIP4_P8:case TF_MIP4_SOLID8:case TF_MIP4_8PAL24:case TF_MIP4_8PAL24_T255:case TF_SOLID8:case TF_TRANS8:case TF_TRANS8_FULLBRIGHT:case TF_HEIGHT8:case TF_HEIGHT8PAL:case TF_H2_T7G1:case TF_H2_TRANS8_0:case TF_H2_T4A4:case TF_8PAL24:case TF_8PAL32:case PTI_LLLX8:case PTI_LLLA8
} uploadfmt_t;
#define PTI_FULLMIPCHAIN 0x80000000 //valid for Image_GetTexture (and thus GenMip0) to signify that there's a full round-down mipchain there, not a single one (or 4)
qboolean SCR_ScreenShot (char *filename, enum fs_relative fsroot, void **buffer, int numbuffers, qintptr_t bytestride, int width, int height, enum uploadfmt fmt, qboolean writemeta);

View File

@ -133,6 +133,7 @@ cvar_t snd_doppler_max = CVARAFD( "s_doppler_max", "2",
cvar_t snd_playbackrate = CVARFD( "snd_playbackrate", "1", CVAR_CHEAT, "Debugging cvar that changes the playback rate of all new sounds.");
cvar_t snd_ignoregamespeed = CVARFD( "snd_ignoregamespeed", "0", 0, "When set, allows sounds to desynchronise with game time or demo speeds.");
cvar_t snd_ignorecueloops = CVARD( "snd_ignorecueloops", "0", "Ignores cue commands in wav files, for q3 compat.");
cvar_t snd_linearresample = CVARAF( "s_linearresample", "1",
"snd_linearresample", 0);
cvar_t snd_linearresample_stream = CVARAF( "s_linearresample_stream", "0",
@ -2321,6 +2322,7 @@ void S_Init (void)
Cvar_Register(&snd_device, "Sound controls");
Cvar_Register(&snd_device_opts, "Sound controls");
Cvar_Register(&snd_ignorecueloops, "Sound controls");
Cvar_Register(&snd_linearresample, "Sound controls");
Cvar_Register(&snd_linearresample_stream, "Sound controls");

View File

@ -1109,6 +1109,7 @@ GetWavinfo
*/
static wavinfo_t GetWavinfo (char *name, qbyte *wav, int wavlength)
{
extern cvar_t snd_ignorecueloops;
wavinfo_t info;
int i;
int samples;
@ -1156,7 +1157,7 @@ static wavinfo_t GetWavinfo (char *name, qbyte *wav, int wavlength)
// get cue chunk
chunklen = FindChunk(&ctx, "cue ");
if (chunklen >= 36-8)
if (chunklen >= 36-8 && !snd_ignorecueloops.ival)
{
ctx.data_p += 32;
info.loopstart = GetLittleLong(&ctx);

View File

@ -1913,7 +1913,8 @@ qboolean Cmd_AddCommandAD (const char *cmd_name, xcommand_t function, xcommandar
cmd_function_t *cmd;
// fail if the command is a variable name
if (Cvar_VariableString(cmd_name)[0])
cvar_t *var = Cvar_FindVar (cmd_name);
if (var && function)
{
Con_Printf ("Cmd_AddCommand: %s already defined as a var\n", cmd_name);
return false;

View File

@ -22,6 +22,7 @@ extern cvar_t r_noframegrouplerp;
cvar_t r_lerpmuzzlehack = CVARF ("r_lerpmuzzlehack", "1", CVAR_ARCHIVE);
#ifdef MD1MODELS
cvar_t mod_h2holey_bugged = CVARD ("mod_h2holey_bugged", "0", "Hexen2's holey-model flag uses index 0 as transparent (and additionally 255 in gl, due to a bug). GLQuake engines tend to have bugs that use ONLY index 255, resulting in a significant compatibility issue that can be resolved only with this shitty cvar hack.");
cvar_t mod_halftexel = CVARD ("mod_halftexel", "1", "Offset texture coords by a half-texel, for compatibility with glquake and the majority of engine forks.");
#endif
static void QDECL r_meshpitch_callback(cvar_t *var, char *oldvalue)
{
@ -3059,7 +3060,6 @@ static int Mod_CountSkinFiles(model_t *mod)
void Mod_LoadAliasShaders(model_t *mod)
{
qbyte *mipdata[4];
galiasinfo_t *ai = mod->meshinfo;
galiasskin_t *s;
skinframe_t *f;
@ -3198,11 +3198,7 @@ void Mod_LoadAliasShaders(model_t *mod)
loadflags |= SHADER_HASFULLBRIGHT;
if (r_loadbumpmapping)
loadflags |= SHADER_HASNORMALMAP;
mipdata[0] = f->texels;
mipdata[1] = NULL;
mipdata[2] = NULL;
mipdata[3] = NULL;
R_BuildLegacyTexnums(f->shader, basename, alttexpath, loadflags, imageflags, skintranstype, s->skinwidth, s->skinheight, mipdata, host_basepal);
R_BuildLegacyTexnums(f->shader, basename, alttexpath, loadflags, imageflags, skintranstype, s->skinwidth, s->skinheight, f->texels, host_basepal);
}
else
R_BuildDefaultTexnums(&f->texnums, f->shader, 0);
@ -3812,6 +3808,7 @@ static qboolean QDECL Mod_LoadQ1Model (model_t *mod, void *buffer, size_t fsize)
#ifndef SERVERONLY
vec2_t *st_array;
int j;
float halftexel = mod_halftexel.ival?0.5:0;
#endif
int version;
int i, onseams;
@ -3993,13 +3990,13 @@ static qboolean QDECL Mod_LoadQ1Model (model_t *mod, void *buffer, size_t fsize)
{
if (stremap[k] > pq1inmodel->num_st)
{ /*onseam verts? shrink the index, and add half a texture width to the s coord*/
st_array[k][0] = 0.5+(LittleLong(pinstverts[stremap[k]-pq1inmodel->num_st].s)+0.5)/(float)pq1inmodel->skinwidth;
st_array[k][1] = (LittleLong(pinstverts[stremap[k]-pq1inmodel->num_st].t)+0.5)/(float)pq1inmodel->skinheight;
st_array[k][0] = 0.5+(LittleLong(pinstverts[stremap[k]-pq1inmodel->num_st].s)+halftexel)/(float)pq1inmodel->skinwidth;
st_array[k][1] = (LittleLong(pinstverts[stremap[k]-pq1inmodel->num_st].t)+halftexel)/(float)pq1inmodel->skinheight;
}
else
{
st_array[k][0] = (LittleLong(pinstverts[stremap[k]].s)+0.5)/(float)pq1inmodel->skinwidth;
st_array[k][1] = (LittleLong(pinstverts[stremap[k]].t)+0.5)/(float)pq1inmodel->skinheight;
st_array[k][0] = (LittleLong(pinstverts[stremap[k]].s)+halftexel)/(float)pq1inmodel->skinwidth;
st_array[k][1] = (LittleLong(pinstverts[stremap[k]].t)+halftexel)/(float)pq1inmodel->skinheight;
}
}
#endif
@ -4038,8 +4035,8 @@ static qboolean QDECL Mod_LoadQ1Model (model_t *mod, void *buffer, size_t fsize)
galias->ofs_st_array = st_array;
for (j=pq1inmodel->numverts,i = 0; i < pq1inmodel->numverts; i++)
{
st_array[i][0] = (LittleLong(pinstverts[i].s)+0.5)/(float)pq1inmodel->skinwidth;
st_array[i][1] = (LittleLong(pinstverts[i].t)+0.5)/(float)pq1inmodel->skinheight;
st_array[i][0] = (LittleLong(pinstverts[i].s)+halftexel)/(float)pq1inmodel->skinwidth;
st_array[i][1] = (LittleLong(pinstverts[i].t)+halftexel)/(float)pq1inmodel->skinheight;
if (pinstverts[i].onseam)
{

View File

@ -3377,7 +3377,7 @@ void COM_Gamedir (const char *dir, const struct gamepacks *packagespaths)
/*yay q2!*/
#define Q2CFG "set v_gammainverted 1\nset com_parseutf8 0\ncom_nogamedirnativecode 0\nset sv_bigcoords 0\nsv_port "STRINGIFY(PORT_Q2SERVER)"\n"
/*Q3's ui doesn't like empty model/headmodel/handicap cvars, even if the gamecode copes*/
#define Q3CFG "set v_gammainverted 0\nset com_parseutf8 0\ngl_overbright 2\nseta model sarge\nseta headmodel sarge\nseta handicap 100\ncom_nogamedirnativecode 0\nsv_port "STRINGIFY(PORT_Q3SERVER)"\n"
#define Q3CFG "set v_gammainverted 0\nset snd_ignorecueloops 1\nsetfl g_gametype 0 s\nset gl_clear 8\nset com_parseutf8 0\ngl_overbright 2\nseta model sarge\nseta headmodel sarge\nseta handicap 100\ncom_nogamedirnativecode 0\nsv_port "STRINGIFY(PORT_Q3SERVER)"\n"
//#define RMQCFG "sv_bigcoords 1\n"
#ifdef HAVE_SSL

View File

@ -1338,10 +1338,10 @@ static texture_t *Mod_LoadWall(model_t *loadmodel, char *mapname, char *texname,
tex = ZG_Malloc(&loadmodel->memgroup, sizeof(texture_t));
tex->width = wal->width;
tex->height = wal->height;
tex->vwidth = wal->width;
tex->vheight = wal->height;
if (!tex->width || !tex->height || wal == &replacementwal)
if (!tex->vwidth || !tex->vheight || wal == &replacementwal)
{
imageflags |= IF_LOADNOW; //make sure the size is known BEFORE it returns.
if (wal->offsets[0])
@ -1358,8 +1358,8 @@ static texture_t *Mod_LoadWall(model_t *loadmodel, char *mapname, char *texname,
{
if (base->status == TEX_LOADED||base->status==TEX_LOADING)
{
tex->width = base->width;
tex->height = base->height;
tex->vwidth = base->width;
tex->vheight = base->height;
}
else
Con_Printf("Unable to load textures/%s.wal\n", wal->name);
@ -1368,21 +1368,23 @@ static texture_t *Mod_LoadWall(model_t *loadmodel, char *mapname, char *texname,
}
else
{
qbyte *out;
unsigned int size =
(wal->width>>0)*(wal->height>>0) +
(wal->width>>1)*(wal->height>>1) +
(wal->width>>2)*(wal->height>>2) +
(wal->width>>3)*(wal->height>>3);
tex->mips[0] = BZ_Malloc(size);
tex->srcdata = out = BZ_Malloc(size);
tex->palette = host_basepal;
tex->mips[1] = tex->mips[0] + (wal->width>>0)*(wal->height>>0);
tex->mips[2] = tex->mips[1] + (wal->width>>1)*(wal->height>>1);
tex->mips[3] = tex->mips[2] + (wal->width>>2)*(wal->height>>2);
memcpy(tex->mips[0], (qbyte *)wal + wal->offsets[0], (wal->width>>0)*(wal->height>>0));
memcpy(tex->mips[1], (qbyte *)wal + wal->offsets[1], (wal->width>>1)*(wal->height>>1));
memcpy(tex->mips[2], (qbyte *)wal + wal->offsets[2], (wal->width>>2)*(wal->height>>2));
memcpy(tex->mips[3], (qbyte *)wal + wal->offsets[3], (wal->width>>3)*(wal->height>>3));
memcpy(out, (qbyte *)wal + wal->offsets[0], (wal->width>>0)*(wal->height>>0));
out += (wal->width>>0)*(wal->height>>0);
memcpy(out, (qbyte *)wal + wal->offsets[1], (wal->width>>1)*(wal->height>>1));
out += (wal->width>>1)*(wal->height>>1);
memcpy(out, (qbyte *)wal + wal->offsets[2], (wal->width>>2)*(wal->height>>2));
out += (wal->width>>2)*(wal->height>>2);
memcpy(out, (qbyte *)wal + wal->offsets[3], (wal->width>>3)*(wal->height>>3));
out += (wal->width>>3)*(wal->height>>3);
BZ_Free(wal);
}
@ -1476,7 +1478,7 @@ static qboolean CModQ2_LoadTexInfo (model_t *mod, qbyte *mod_base, lump_t *l, ch
*lwr = *lwr - 'A' + 'a';
}
out->texture = Mod_LoadWall (mod, mapname, in->texture, sname, (out->flags&TEX_SPECIAL)?0:IF_NOALPHA);
if (!out->texture || !out->texture->width || !out->texture->height)
if (!out->texture || !out->texture->srcwidth || !out->texture->srcheight)
{
out->texture = ZG_Malloc(&mod->memgroup, sizeof(texture_t) + 16*16+8*8+4*4+2*2);

View File

@ -7006,8 +7006,9 @@ int FTENET_WebRTC_GetAddresses(struct ftenet_generic_connection_s *con, unsigned
return 0;
}
static ftenet_generic_connection_t *FTENET_WebSocket_EstablishConnection(qboolean isserver, const char *address, netadr_t adr)
static ftenet_generic_connection_t *FTENET_WebSocket_EstablishConnection(ftenet_connections_t *col, const char *address, netadr_t adr)
{
qboolean isserver = col->islisten;
ftenet_websocket_connection_t *newcon;
int brokersocket = INVALID_SOCKET;
@ -7311,8 +7312,9 @@ static neterr_t FTENET_NaClWebSocket_SendPacket(ftenet_generic_connection_t *gco
}
/*nacl websockets implementation...*/
static ftenet_generic_connection_t *FTENET_WebSocket_EstablishConnection(qboolean isserver, const char *address, netadr_t adr)
static ftenet_generic_connection_t *FTENET_WebSocket_EstablishConnection(ftenet_connections_t *col, const char *address, netadr_t adr)
{
qboolean isserver = col->islisten;
ftenet_websocket_connection_t *newcon;
PP_Resource newsocket;
@ -7594,6 +7596,9 @@ qboolean NET_EnsureRoute(ftenet_connections_t *collection, char *routename, char
case NP_DGRAM:
if (NET_SendPacketCol(collection, 0, NULL, adr) != NETERR_NOROUTE)
return true;
if (!FTENET_AddToCollection(collection, routename, "0", adr->type, adr->prot))
return false;
break;
case NP_WS:
case NP_WSS:
case NP_TLS:

View File

@ -146,8 +146,11 @@
//requires linux 2.6.27 up (and equivelent libc)
//note that BSD does tend to support the api, but emulated.
//this works around the select FD limit, and supposedly has better performance.
#define HAVE_EPOLL
#include <sys/epoll.h>
#ifdef EPOLL_CLOEXEC
#define HAVE_EPOLL
//#else too old, probably android...
#endif
#endif
#if defined(__MORPHOS__) && !defined(ixemul)

View File

@ -479,6 +479,7 @@ typedef enum{
SLIST_SORTDESCENDING
} hostcacheglobal_t;
void QCBUILTIN PF_shaderforname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_remapshader (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_cl_sprint (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_cl_bprint (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);

View File

@ -280,6 +280,8 @@ static int QDECL VMEnumMods(const char *match, qofs_t size, time_t modtime, void
}
memcpy(((vmsearch_t *)args)->buffer, match, newlen);
if (newlen > 1 && match[newlen-2] == '/')
((vmsearch_t *)args)->buffer[--newlen-1] = 0;
((vmsearch_t *)args)->buffer+=newlen;
((vmsearch_t *)args)->bufferleft-=newlen;
@ -325,7 +327,7 @@ int VM_GetFileList(const char *path, const char *ext, char *output, int buffersi
#include "clq3defs.h" //okay, urr, this is bad for dedicated servers. urhum. Maybe they're not looking? It's only typedefs and one extern.
#define MAX_VMQ3_CVARS 256 //can be blindly increased
#define MAX_VMQ3_CVARS 512 //can be blindly increased
cvar_t *q3cvlist[MAX_VMQ3_CVARS];
int VMQ3_Cvar_Register(q3vmcvar_t *v, char *name, char *defval, int flags)
{

View File

@ -186,16 +186,16 @@ qboolean D3D11_LoadTextureMips(image_t *tex, const struct pendingtextureinfo *mi
case PTI_BC3_RGBA_SRGB:
tdesc.Format = DXGI_FORMAT_BC3_UNORM_SRGB;
break;
case PTI_BC4_R8:
case PTI_BC4_R:
tdesc.Format = DXGI_FORMAT_BC4_UNORM;
break;
case PTI_BC4_R8_SNORM:
case PTI_BC4_R_SNORM:
tdesc.Format = DXGI_FORMAT_BC4_SNORM;
break;
case PTI_BC5_RG8:
case PTI_BC5_RG:
tdesc.Format = DXGI_FORMAT_BC5_UNORM;
break;
case PTI_BC5_RG8_SNORM:
case PTI_BC5_RG_SNORM:
tdesc.Format = DXGI_FORMAT_BC5_SNORM;
break;
case PTI_BC6_RGB_UFLOAT:

View File

@ -925,13 +925,13 @@ static qboolean initD3D11Device(HWND hWnd, rendererstate_t *info, PFN_D3D11_CREA
if (SUCCEEDED(ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC3_UNORM_SRGB, &support)))
sh_config.texfmt[PTI_BC3_RGBA_SRGB] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
if (SUCCEEDED(ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC4_UNORM, &support)))
sh_config.texfmt[PTI_BC4_R8] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
sh_config.texfmt[PTI_BC4_R] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
if (SUCCEEDED(ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC4_SNORM, &support)))
sh_config.texfmt[PTI_BC4_R8_SNORM] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
sh_config.texfmt[PTI_BC4_R_SNORM] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
if (SUCCEEDED(ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC5_UNORM, &support)))
sh_config.texfmt[PTI_BC5_RG8] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
sh_config.texfmt[PTI_BC5_RG] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
if (SUCCEEDED(ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC5_SNORM, &support)))
sh_config.texfmt[PTI_BC5_RG8_SNORM] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
sh_config.texfmt[PTI_BC5_RG_SNORM] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
if (SUCCEEDED(ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC6H_UF16, &support)))
sh_config.texfmt[PTI_BC6_RGB_UFLOAT] = !!(support & D3D11_FORMAT_SUPPORT_TEXTURE2D);
if (SUCCEEDED(ID3D11Device_CheckFormatSupport(pD3DDev11, DXGI_FORMAT_BC6H_SF16, &support)))

View File

@ -1626,7 +1626,11 @@ void GLBE_Init(void)
shaderstate.identitylighting = 1;
shaderstate.identitylightmap = 1;
for (i = 0; i < MAXRLIGHTMAPS; i++)
{
shaderstate.dummybatch.lightmap[i] = -1;
shaderstate.dummybatch.lmlightstyle[i] = INVALID_LIGHTSTYLE;
shaderstate.dummybatch.vtlightstyle[i] = ~0;
}
#ifdef RTLIGHTS
Sh_CheckSettings();
@ -1826,7 +1830,7 @@ static float *tcgen3(const shaderpass_t *pass, int cnt, float *dst, const mesh_t
for (i = 0; i < cnt; i++, dst += 3)
{
dst[0] = src[i][0] - r_refdef.vieworg[0];
dst[1] = r_refdef.vieworg[1] - src[i][1];
dst[1] = src[i][1] - r_refdef.vieworg[1];
dst[2] = src[i][2] - r_refdef.vieworg[2];
}
return dst-cnt*3;

View File

@ -347,10 +347,10 @@ void GL_SetupFormats(void)
}
if (bc45)
{
glfmtb(PTI_BC4_R8, GL_COMPRESSED_RED_RGTC1);
glfmtb(PTI_BC4_R8_SNORM, GL_COMPRESSED_SIGNED_RED_RGTC1);
glfmtb(PTI_BC5_RG8, GL_COMPRESSED_RG_RGTC2);
glfmtb(PTI_BC5_RG8_SNORM, GL_COMPRESSED_SIGNED_RG_RGTC2);
glfmtb(PTI_BC4_R, GL_COMPRESSED_RED_RGTC1);
glfmtb(PTI_BC4_R_SNORM, GL_COMPRESSED_SIGNED_RED_RGTC1);
glfmtb(PTI_BC5_RG, GL_COMPRESSED_RG_RGTC2);
glfmtb(PTI_BC5_RG_SNORM, GL_COMPRESSED_SIGNED_RG_RGTC2);
}
if (bc67)
{
@ -830,7 +830,7 @@ qboolean GL_LoadTextureMips(texid_t tex, const struct pendingtextureinfo *mips)
{
if (mips->mip[i].width != max(1,(mips->mip[i-1].width>>1)) ||
mips->mip[i].height != max(1,(mips->mip[i-1].height>>1)))
{ //okay, this mip looks like it was sized wrongly. this can easily happen with npot dds files made for direct3d.
{ //okay, this mip looks like it was sized wrongly. I've seen this happen with some dds files.
nummips = i;
break;
}
@ -1053,10 +1053,10 @@ qboolean GL_LoadTextureMips(texid_t tex, const struct pendingtextureinfo *mips)
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: out.encoding = PTI_BC1_RGBA_SRGB; break;
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: out.encoding = PTI_BC2_RGBA_SRGB; break;
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: out.encoding = PTI_BC3_RGBA_SRGB; break;
case GL_COMPRESSED_RED_RGTC1: out.encoding = PTI_BC4_R8; break;
case GL_COMPRESSED_SIGNED_RED_RGTC1: out.encoding = PTI_BC4_R8_SNORM; break;
case GL_COMPRESSED_RG_RGTC2: out.encoding = PTI_BC5_RG8; break;
case GL_COMPRESSED_SIGNED_RG_RGTC2: out.encoding = PTI_BC5_RG8_SNORM; break;
case GL_COMPRESSED_RED_RGTC1: out.encoding = PTI_BC4_R; break;
case GL_COMPRESSED_SIGNED_RED_RGTC1: out.encoding = PTI_BC4_R_SNORM; break;
case GL_COMPRESSED_RG_RGTC2: out.encoding = PTI_BC5_RG; break;
case GL_COMPRESSED_SIGNED_RG_RGTC2: out.encoding = PTI_BC5_RG_SNORM; break;
case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB: out.encoding = PTI_BC6_RGB_UFLOAT; break;
case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB: out.encoding = PTI_BC6_RGB_SFLOAT; break;
case GL_COMPRESSED_RGBA_BPTC_UNORM_ARB: out.encoding = PTI_BC7_RGBA; break;

View File

@ -5849,12 +5849,11 @@ void Terr_Brush_Draw(heightmap_t *hm, batch_t **batches, entity_t *e)
}
if (!Q_strncasecmp(bt->shadername, "sky", 3) && tx)
R_InitSky (bt->shader, bt->shadername, (qbyte*)tx + tx->offsets[0], tx->width, tx->height);
R_InitSky (bt->shader, bt->shadername, TF_SOLID8, (qbyte*)tx + tx->offsets[0], tx->width, tx->height);
else if (tx)
{
qbyte *mips[4] = {(qbyte*)tx + tx->offsets[0], (qbyte*)tx + tx->offsets[1], (qbyte*)tx + tx->offsets[2], (qbyte*)tx + tx->offsets[3]};
unsigned int mapflags = SHADER_HASPALETTED | SHADER_HASDIFFUSE | SHADER_HASFULLBRIGHT | SHADER_HASNORMALMAP | SHADER_HASGLOSS;
R_BuildLegacyTexnums(bt->shader, tx->name, NULL, mapflags, 0, TF_MIP4_SOLID8, tx->width, tx->height, mips, NULL);
R_BuildLegacyTexnums(bt->shader, tx->name, NULL, mapflags, 0, TF_SOLID8, tx->width, tx->height, (qbyte*)tx + tx->offsets[0], NULL);
}
else
R_BuildDefaultTexnums(NULL, bt->shader, IF_WORLDTEX);

View File

@ -1428,7 +1428,7 @@ static void Mod_FinishTexture(texture_t *tx, const char *loadname, qboolean safe
if (!safetoloadfromwads)
{
//remap to avoid bugging out on textures with the same name and different images (vanilla content sucks)
shadername = Mod_RemapBuggyTexture(shadername, tx->mips[0], tx->width*tx->height);
shadername = Mod_RemapBuggyTexture(shadername, tx->srcdata, tx->srcwidth*tx->srcheight);
if (shadername)
origname = tx->name;
else
@ -1450,20 +1450,19 @@ static void Mod_FinishTexture(texture_t *tx, const char *loadname, qboolean safe
tx->shader = R_RegisterCustom (shadername, SUF_LIGHTMAP, Shader_DefaultBSPQ1, NULL);
if (!tx->mips[0] && !safetoloadfromwads)
if (!tx->srcdata && !safetoloadfromwads)
return;
}
else
{ //already loaded. don't waste time / crash (this will be a dead pointer).
if (tx->mips[0])
if (tx->srcdata)
return;
}
if (!strncmp(tx->name, "sky", 3))
R_InitSky (tx->shader, shadername, tx->mips[0], tx->width, tx->height);
R_InitSky (tx->shader, shadername, tx->srcfmt, tx->srcdata, tx->srcwidth, tx->srcheight);
else
{
uploadfmt_t fmt;
unsigned int maps = 0;
maps |= SHADER_HASPALETTED;
maps |= SHADER_HASDIFFUSE;
@ -1474,24 +1473,10 @@ static void Mod_FinishTexture(texture_t *tx, const char *loadname, qboolean safe
if (gl_specular.ival)
maps |= SHADER_HASGLOSS;
if (tx->palette)
{ //halflife, probably...
if (*tx->name == '{')
fmt = TF_MIP4_8PAL24_T255;
else
fmt = TF_MIP4_8PAL24;
}
else
{
if (*tx->name == '{')
fmt = TF_TRANS8;
else
fmt = TF_MIP4_SOLID8;
}
R_BuildLegacyTexnums(tx->shader, origname, loadname, maps, 0, fmt, tx->width, tx->height, tx->mips, tx->palette);
R_BuildLegacyTexnums(tx->shader, origname, loadname, maps, 0, tx->srcfmt, tx->srcwidth, tx->srcheight, tx->srcdata, tx->palette);
}
BZ_Free(tx->mips[0]);
BZ_Free(tx->srcdata);
tx->srcdata = NULL;
}
#endif
@ -1513,7 +1498,7 @@ void Mod_NowLoadExternal(model_t *loadmodel)
if (!tx) //e1m2, this happens
continue;
if (tx->mips[0])
if (tx->srcdata)
continue;
Mod_FinishTexture(tx, loadname, true);
@ -2421,10 +2406,10 @@ void ModQ1_Batches_BuildQ1Q2Poly(model_t *mod, msurface_t *surf, builddata_t *co
{
mesh->st_array[i][0] = s;
mesh->st_array[i][1] = t;
if (surf->texinfo->texture->width)
mesh->st_array[i][0] /= surf->texinfo->texture->width;
if (surf->texinfo->texture->height)
mesh->st_array[i][1] /= surf->texinfo->texture->height;
if (surf->texinfo->texture->vwidth)
mesh->st_array[i][0] /= surf->texinfo->texture->vwidth;
if (surf->texinfo->texture->vheight)
mesh->st_array[i][1] /= surf->texinfo->texture->vheight;
}
#ifndef SERVERONLY
@ -3359,34 +3344,196 @@ static void Mod_LoadVisibility (model_t *loadmodel, qbyte *mod_base, lump_t *l,
}
#ifndef SERVERONLY
static void Mod_LoadMiptex(model_t *loadmodel, texture_t *tx, miptex_t *mt)
static void Mod_LoadMiptex(model_t *loadmodel, texture_t *tx, miptex_t *mt, size_t miptexsize)
{
unsigned int size =
unsigned int legacysize =
(mt->width>>0)*(mt->height>>0) +
(mt->width>>1)*(mt->height>>1) +
(mt->width>>2)*(mt->height>>2) +
(mt->width>>3)*(mt->height>>3);
if (loadmodel->fromgame == fg_halflife && *(short*)((qbyte *)mt + mt->offsets[3] + (mt->width>>3)*(mt->height>>3)) == 256)
uploadfmt_t newfmt = PTI_INVALID;
size_t neww=0, newh=0;
qbyte *newdata=NULL;
qbyte *pal = NULL;
//bug: vanilla quake ignored offsets and just made assumptions.
//this means we can't just play with offsets to hide stuff, we have to postfix it (which requires guessing lump sizes)
//issue: halflife textures have (leshort)256,(byte)pal[256*3] stuck on the end
//we signal the presence of our extended data using 0x00,0xfb,0x2b,0xaf (this should be uncommon as the next mip's name shouldn't normally be empty, nor a weird char (which should hopefully also not come from random stack junk in the wad tool)
//each extended block of data then has a size value, followed by a block name.
//compressed formats then contain a width+height value, and then a FULL (round-down) mip chain.
//if the gpu doesn't support npot, or its too big, or can't use the pixelformat then the engine will simply have to fall back on the paletted data. lets hope it was present.
size_t extofs;
if (!mt->offsets[0])
extofs = sizeof(miptex_t);
else if (mt->offsets[0] == sizeof(miptex_t) &&
mt->offsets[1] == mt->offsets[0]+(mt->width>>0)*(mt->height>>0) &&
mt->offsets[2] == mt->offsets[1]+(mt->width>>1)*(mt->height>>1) &&
mt->offsets[3] == mt->offsets[2]+(mt->width>>2)*(mt->height>>2))
{
extofs = mt->offsets[3]+(mt->width>>3)*(mt->height>>3);
if (loadmodel->fromgame == fg_halflife && *(short*)((qbyte *)mt + mt->offsets[3] + (mt->width>>3)*(mt->height>>3)) == 256)
{
pal = (qbyte*)mt + extofs+2;
extofs += 2+256*3;
}
}
else
extofs = miptexsize; //the numbers don't match what we expect... something weird is going on here... don't misinterpret it.
if (extofs+4 <= miptexsize && ((qbyte*)mt)[extofs+0] == 0 && ((qbyte*)mt)[extofs+1]==0xfb && ((qbyte*)mt)[extofs+2]==0x2b && ((qbyte*)mt)[extofs+3]==0xaf)
{
unsigned int extsize;
extofs += 4;
for (; extofs < miptexsize; extofs += extsize)
{
size_t sz, w, h;
unsigned int bb,bw,bh;
int mip;
qbyte *extdata = (void*)((qbyte*)mt+extofs);
char *extfmt = (char*)(extdata+4);
extsize = (extdata[0]<<0)|(extdata[1]<<8)|(extdata[2]<<16)|(extdata[3]<<24);
if (extsize<8 || extofs+extsize>miptexsize) break; //not a valid entry... something weird is happening here
else if (!strncmp(extfmt, "NAME", 4))
{ //replacement name, for longer shader/external names
size_t sz = extsize-8;
if (sz >= sizeof(tx->name))
continue;
memcpy(tx->name, (qbyte*)extdata+8, sz);
tx->name[sz] = 0;
}
else if (!strncmp(extfmt, "LPAL", 4) && extsize == 8+256*3)
{ //replacement palette for the 8bit data, for feature parity with halflife, but with extra markup so we know its actually meant to be a replacement palette.
pal = extdata+8;
continue;
}
else if (extsize <= 16) continue; //too small for an altformat lump
else if (newdata != PTI_INVALID) continue; //only accept the first accepted format (allowing for eg astc+bc1 fallbacks)
else if (!strncmp(extfmt, "RGBA", 4)) newfmt = PTI_RGBA8; //32bpp, we don't normally need this alpha precision (padding can be handy though, for the lazy).
else if (!strncmp(extfmt, "RGB", 4)) newfmt = PTI_RGB8; //24bpp
else if (!strncmp(extfmt, "565", 4)) newfmt = PTI_RGB565; //16bpp
else if (!strncmp(extfmt, "5551", 4)) newfmt = PTI_RGBA5551; //16bpp
else if (!strncmp(extfmt, "EXP5", 4)) newfmt = PTI_E5BGR9; //32bpp, we don't normally need this alpha precision...
else if (!strncmp(extfmt, "BC1", 4)) newfmt = PTI_BC1_RGBA; //4bpp
else if (!strncmp(extfmt, "BC2", 4)) newfmt = PTI_BC2_RGBA; //8bpp, we don't normally need this alpha precision...
else if (!strncmp(extfmt, "BC3", 4)) newfmt = PTI_BC3_RGBA; //8bpp, we don't normally need this alpha precision...
else if (!strncmp(extfmt, "BC4", 4)) newfmt = PTI_BC4_R; //4bpp, wtf
else if (!strncmp(extfmt, "BC5", 4)) newfmt = PTI_BC5_RG; //8bpp, wtf
else if (!strncmp(extfmt, "BC6", 4)) newfmt = PTI_BC6_RGB_UFLOAT; //8bpp, weird
else if (!strncmp(extfmt, "BC7", 4)) newfmt = PTI_BC7_RGBA; //8bpp
else if (!strncmp(extfmt, "AST4", 4)) newfmt = PTI_ASTC_4X4_LDR; //8 bpp
else if (!strncmp(extfmt, "AS54", 4)) newfmt = PTI_ASTC_5X4_LDR; //6.40bpp
else if (!strncmp(extfmt, "AST5", 4)) newfmt = PTI_ASTC_5X5_LDR; //5.12bpp
else if (!strncmp(extfmt, "AS65", 4)) newfmt = PTI_ASTC_6X5_LDR; //4.17bpp
else if (!strncmp(extfmt, "AST6", 4)) newfmt = PTI_ASTC_6X6_LDR; //3.56bpp
else if (!strncmp(extfmt, "AS85", 4)) newfmt = PTI_ASTC_8X5_LDR; //3.20bpp
else if (!strncmp(extfmt, "AS86", 4)) newfmt = PTI_ASTC_8X6_LDR; //2.67bpp
else if (!strncmp(extfmt, "AS05", 4)) newfmt = PTI_ASTC_10X5_LDR; //2.56bpp
else if (!strncmp(extfmt, "AS06", 4)) newfmt = PTI_ASTC_10X6_LDR; //2.13bpp
else if (!strncmp(extfmt, "AST8", 4)) newfmt = PTI_ASTC_8X8_LDR; //2 bpp
else if (!strncmp(extfmt, "AS08", 4)) newfmt = PTI_ASTC_10X8_LDR; //1.60bpp
else if (!strncmp(extfmt, "AS00", 4)) newfmt = PTI_ASTC_10X10_LDR; //1.28bpp
else if (!strncmp(extfmt, "AS20", 4)) newfmt = PTI_ASTC_12X10_LDR; //1.07bpp
else if (!strncmp(extfmt, "AST2", 4)) newfmt = PTI_ASTC_12X12_LDR; //0.89bpp
else if (!strncmp(extfmt, "ETC1", 4)) newfmt = PTI_ETC1_RGB8; //4bpp
else if (!strncmp(extfmt, "ETC2", 4)) newfmt = PTI_ETC2_RGB8; //4bpp
else if (!strncmp(extfmt, "ETCP", 4)) newfmt = PTI_ETC2_RGB8A1; //4bpp
else if (!strncmp(extfmt, "ETCA", 4)) newfmt = PTI_ETC2_RGB8A8; //8bpp, we don't normally need this alpha precision...
else continue; //dunno what that is, ignore it
//alternative textures are usually compressed
//this means we insist on a FULL mip chain
//npot mips are explicitly round-down (but don't drop to 0 with non-square).
Image_BlockSizeForEncoding(newfmt, &bb, &bw, &bh);
neww = (extdata[8]<<0)|(extdata[9]<<8)|(extdata[10]<<16)|(extdata[11]<<24);
newh = (extdata[12]<<0)|(extdata[13]<<8)|(extdata[14]<<16)|(extdata[15]<<24);
for (mip = 0, w=neww, h=newh, sz=0; w || h; mip++, w>>=1,h>>=1)
{
w = max(1, w);
h = max(1, h);
sz += bb *
((w+bw-1)/bw) *
((h+bh-1)/bh);
//Support truncation to top-mip only? tempting...
}
if (extsize != 16+sz)
{
Con_Printf("miptex %s has incomplete mipchain\n", Image_FormatName(newfmt));
continue;
}
//make sure we're not going to need to rescale compressed formats.
//gles<3 or gl<2 requires npot inputs for this to work. I guess that means dx9.3+ gpus, so all astc+bc7 but not necessarily all bc1+etc2. oh well.
if (!sh_config.texture_non_power_of_two)
{
if (neww & (neww - 1))
continue;
if (newh & (newh - 1))
continue;
}
//make sure its within our limits
if (!neww || !newh || neww > sh_config.texture2d_maxsize || newh > sh_config.texture2d_maxsize)
continue;
//that our hardware supports it... (Note: FTE can soft-decompress all of the above so this doesn't make too much sense if there's only one)
//if (!sh_config.texfmt[newfmt])
// continue;
//that we can actually use non-paletted data...
if (r_softwarebanding && mt->offsets[0])
continue;
newdata = BZ_Malloc(sz);
memcpy(newdata, extdata+16, sz);
}
}
if (newdata)
{
tx->srcfmt = newfmt|PTI_FULLMIPCHAIN;
tx->srcwidth = neww;
tx->srcheight = newh;
tx->srcdata = newdata;
tx->palette = NULL;
return;
}
if (pal)
{ //mostly identical, just a specific palette hidden at the end. handle fences elsewhere.
tx->mips[0] = BZ_Malloc(size + 768);
tx->palette = tx->mips[0] + size;
memcpy(tx->palette, (qbyte *)mt + mt->offsets[3] + (mt->width>>3)*(mt->height>>3) + 2, 768);
tx->srcdata = BZ_Malloc(legacysize + 768);
tx->palette = tx->srcdata + legacysize;
memcpy(tx->palette, pal, 768);
}
else
{
tx->mips[0] = BZ_Malloc(size);
tx->srcdata = BZ_Malloc(legacysize);
tx->palette = NULL;
}
tx->mips[1] = tx->mips[0] + (mt->width>>0)*(mt->height>>0);
tx->mips[2] = tx->mips[1] + (mt->width>>1)*(mt->height>>1);
tx->mips[3] = tx->mips[2] + (mt->width>>2)*(mt->height>>2);
memcpy(tx->mips[0], (qbyte *)mt + mt->offsets[0], (mt->width>>0)*(mt->height>>0));
memcpy(tx->mips[1], (qbyte *)mt + mt->offsets[1], (mt->width>>1)*(mt->height>>1));
memcpy(tx->mips[2], (qbyte *)mt + mt->offsets[2], (mt->width>>2)*(mt->height>>2));
memcpy(tx->mips[3], (qbyte *)mt + mt->offsets[3], (mt->width>>3)*(mt->height>>3));
if (tx->palette)
{ //halflife, probably...
if (*tx->name == '{')
tx->srcfmt = TF_MIP4_8PAL24_T255;
else
tx->srcfmt = TF_MIP4_8PAL24;
}
else
{
if (*tx->name == '{')
tx->srcfmt = TF_TRANS8;
else
tx->srcfmt = TF_MIP4_SOLID8;
}
tx->srcwidth = mt->width;
tx->srcheight = mt->height;
legacysize = 0;
memcpy(tx->srcdata+legacysize, (qbyte *)mt + mt->offsets[0], (mt->width>>0)*(mt->height>>0));
legacysize += (mt->width>>0)*(mt->height>>0);
memcpy(tx->srcdata+legacysize, (qbyte *)mt + mt->offsets[1], (mt->width>>1)*(mt->height>>1));
legacysize += (mt->width>>1)*(mt->height>>1);
memcpy(tx->srcdata+legacysize, (qbyte *)mt + mt->offsets[2], (mt->width>>2)*(mt->height>>2));
legacysize += (mt->width>>2)*(mt->height>>2);
memcpy(tx->srcdata+legacysize, (qbyte *)mt + mt->offsets[3], (mt->width>>3)*(mt->height>>3));
// legacysize += (mt->width>>3)*(mt->height>>3);
}
#endif
@ -3403,6 +3550,8 @@ static qboolean Mod_LoadTextures (model_t *loadmodel, qbyte *mod_base, lump_t *l
texture_t *anims[10];
texture_t *altanims[10];
dmiptexlump_t *m;
unsigned int *sizes;
unsigned int e, o;
TRACE(("dbg: Mod_LoadTextures: inittexturedescs\n"));
@ -3429,11 +3578,12 @@ TRACE(("dbg: Mod_LoadTextures: inittexturedescs\n"));
loadmodel->numtextures = m->nummiptex;
loadmodel->textures = ZG_Malloc(&loadmodel->memgroup, m->nummiptex * sizeof(*loadmodel->textures));
sizes = alloca(sizeof(*sizes)*m->nummiptex);
for (i=0 ; i<m->nummiptex ; i++)
for (i=m->nummiptex, e = l->filelen; i-->0; )
{
m->dataofs[i] = LittleLong(m->dataofs[i]);
if (m->dataofs[i] == -1) //e1m2, this happens
o = LittleLong(m->dataofs[i]);
if (o >= l->filelen) //e1m2, this happens
{
tx = ZG_Malloc(&loadmodel->memgroup, sizeof(texture_t));
memcpy(tx, r_notexture_mip, sizeof(texture_t));
@ -3441,7 +3591,9 @@ TRACE(("dbg: Mod_LoadTextures: inittexturedescs\n"));
loadmodel->textures[i] = tx;
continue;
}
mt = (miptex_t *)((qbyte *)m + m->dataofs[i]);
if (o >= e)
e = l->filelen; //something doesn't make sense. try to avoid making too many assumptions.
mt = (miptex_t *)((qbyte *)m + o);
TRACE(("dbg: Mod_LoadTextures: texture %s\n", mt->name));
@ -3464,17 +3616,16 @@ TRACE(("dbg: Mod_LoadTextures: inittexturedescs\n"));
loadmodel->textures[i] = tx;
Q_strncpyz(tx->name, mt->name, min(sizeof(mt->name)+1, sizeof(tx->name)));
tx->width = mt->width;
tx->height = mt->height;
if (!mt->offsets[0]) //this is a hl external style texture, load it a little later (from a wad)
{
continue;
}
tx->vwidth = mt->width;
tx->vheight = mt->height;
#ifndef SERVERONLY
Mod_LoadMiptex(loadmodel, tx, mt);
Mod_LoadMiptex(loadmodel, tx, mt, e-o);
#else
(void)e;
#endif
e = o;
}
//
// sequence the animations
@ -4989,8 +5140,9 @@ void ModBrush_LoadGLStuff(void *ctx, void *data, size_t a, size_t b)
// maps |= SHADER_HASNORMALMAP;
if (gl_specular.ival)
maps |= SHADER_HASGLOSS;
R_BuildLegacyTexnums(mod->textures[a]->shader, mod->textures[a]->name, loadname, maps, IF_WORLDTEX, TF_MIP4_8PAL24_T255, mod->textures[a]->width, mod->textures[a]->height, mod->textures[a]->mips, mod->textures[a]->palette);
BZ_Free(mod->textures[a]->mips[0]);
R_BuildLegacyTexnums(mod->textures[a]->shader, mod->textures[a]->name, loadname, maps, IF_WORLDTEX, TF_MIP4_8PAL24_T255, mod->textures[a]->srcwidth, mod->textures[a]->srcheight, mod->textures[a]->srcdata, mod->textures[a]->palette);
BZ_Free(mod->textures[a]->srcdata);
mod->textures[a]->srcdata = NULL;
}
}
else

View File

@ -325,7 +325,7 @@ void GL_DeselectVAO(void);
typedef struct texture_s
{
char name[64];
unsigned width, height;
unsigned vwidth, vheight; //used for lightmap coord generation
struct shader_s *shader;
char *partname; //parsed from the worldspawn entity
@ -335,8 +335,10 @@ typedef struct texture_s
struct texture_s *anim_next; // in the animation sequence
struct texture_s *alternate_anims; // bmodels in frmae 1 use these
qbyte *mips[4]; //the different mipmap levels.
qbyte *palette; //host_basepal or halflife per-texture palette
uploadfmt_t srcfmt;
unsigned int srcwidth, srcheight; //actual size (updated miptex format)
qbyte *srcdata; //the different mipmap levels.
qbyte *palette; //host_basepal or halflife per-texture palette (or null)
} texture_t;
/*
typedef struct

View File

@ -1776,6 +1776,7 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
if (strncmp("DELUX", script, end - script))
if (strncmp("OFFSETMAPPING", script, end - script))
if (strncmp("RELIEFMAPPING", script, end - script))
if (strncmp("FAKESHADOWS", script, end - script))
Con_DPrintf("Unknown pemutation in glsl program %s\n", name);
}
script = end;
@ -5923,7 +5924,7 @@ static qbyte *ReadRGBA8ImageFile(const char *fname, const char *subpath, int *wi
#endif
//call this with some fallback textures to directly load some textures
void QDECL R_BuildLegacyTexnums(shader_t *shader, const char *fallbackname, const char *subpath, unsigned int loadflags, unsigned int imageflags, uploadfmt_t basefmt, size_t width, size_t height, qbyte *mipdata[4], qbyte *palette)
void QDECL R_BuildLegacyTexnums(shader_t *shader, const char *fallbackname, const char *subpath, unsigned int loadflags, unsigned int imageflags, uploadfmt_t basefmt, size_t width, size_t height, qbyte *srcdata, qbyte *palette)
{
char *h;
char imagename[MAX_QPATH];
@ -5931,9 +5932,6 @@ void QDECL R_BuildLegacyTexnums(shader_t *shader, const char *fallbackname, cons
//extern cvar_t gl_miptexLevel;
texnums_t *tex = shader->defaulttextures;
int a, aframes;
qbyte *dontcrashme[4] = {NULL};
if (!mipdata)
mipdata = dontcrashme;
/*else if (gl_miptexLevel.ival)
{
unsigned int miplevel = 0, i;
@ -5985,7 +5983,7 @@ void QDECL R_BuildLegacyTexnums(shader_t *shader, const char *fallbackname, cons
imageflags |= IF_NOALPHA;
//fallthrough
case TF_MIP4_8PAL24_T255:
if (!mipdata || !mipdata[0] || !mipdata[1] || !mipdata[2] || !mipdata[3])
if (!srcdata)
basefmt = TF_SOLID8;
break;
default:
@ -6097,10 +6095,10 @@ void QDECL R_BuildLegacyTexnums(shader_t *shader, const char *fallbackname, cons
}
}
if (!TEXLOADED(tex->base))
tex->base = Image_GetTexture(imagename, subpath, imageflags, mipdata[0], palette, width, height, basefmt);
tex->base = Image_GetTexture(imagename, subpath, imageflags, srcdata, palette, width, height, basefmt);
}
else if (!TEXVALID(tex->base))
tex->base = Image_GetTexture(imagename, subpath, imageflags, mipdata[0], palette, width, height, basefmt);
tex->base = Image_GetTexture(imagename, subpath, imageflags, srcdata, palette, width, height, basefmt);
}
if (loadflags & SHADER_HASPALETTED)
@ -6108,7 +6106,7 @@ void QDECL R_BuildLegacyTexnums(shader_t *shader, const char *fallbackname, cons
if (!TEXVALID(tex->paletted) && *mapname)
tex->paletted = R_LoadHiResTexture(va("%s_pal", mapname), NULL, imageflags|IF_NEAREST);
if (!TEXVALID(tex->paletted))
tex->paletted = Image_GetTexture(va("%s_pal", imagename), subpath, imageflags|IF_NEAREST|IF_NOSRGB, mipdata[0], palette, width, height, (basefmt==TF_MIP4_SOLID8)?TF_MIP4_P8:PTI_P8);
tex->paletted = Image_GetTexture(va("%s_pal", imagename), subpath, imageflags|IF_NEAREST|IF_NOSRGB, srcdata, palette, width, height, (basefmt==TF_MIP4_SOLID8)?TF_MIP4_P8:PTI_P8);
}
imageflags |= IF_LOWPRIORITY;
@ -6122,7 +6120,14 @@ void QDECL R_BuildLegacyTexnums(shader_t *shader, const char *fallbackname, cons
if (!TEXVALID(tex->bump) && *mapname)
tex->bump = R_LoadHiResTexture(va("%s_norm", mapname), NULL, imageflags|IF_TRYBUMP|IF_NOSRGB);
if (!TEXVALID(tex->bump) && (r_shadow_bumpscale_basetexture.ival||*imagename=='#'||gl_load24bit.ival))
tex->bump = Image_GetTexture(va("%s_norm", imagename), subpath, imageflags|IF_TRYBUMP|IF_NOSRGB|(*imagename=='#'?IF_LINEAR:0), (r_shadow_bumpscale_basetexture.ival||*imagename=='#')?mipdata[0]:NULL, palette, width, height, TF_HEIGHT8PAL);
{
qbyte *fallbackheight;
if ((r_shadow_bumpscale_basetexture.ival||*imagename=='#') && !(basefmt&PTI_FULLMIPCHAIN))
fallbackheight = srcdata; //generate normalmap from assumed heights.
else
fallbackheight = NULL; //disabled
tex->bump = Image_GetTexture(va("%s_norm", imagename), subpath, imageflags|IF_TRYBUMP|IF_NOSRGB|(*imagename=='#'?IF_LINEAR:0), fallbackheight, palette, width, height, TF_HEIGHT8PAL);
}
}
if (loadflags & SHADER_HASTOPBOTTOM)
@ -6163,13 +6168,13 @@ void QDECL R_BuildLegacyTexnums(shader_t *shader, const char *fallbackname, cons
if (!TEXVALID(tex->fullbright))
{
int s=-1;
if (mipdata[0] && (!palette || palette == host_basepal))
if (srcdata && !(basefmt&PTI_FULLMIPCHAIN) && (!palette || palette == host_basepal))
for(s = width*height-1; s>=0; s--)
{
if (mipdata[0][s] >= 256-vid.fullbright)
if (srcdata[s] >= 256-vid.fullbright)
break;
}
tex->fullbright = Image_GetTexture(va("%s_luma:%s_glow", imagename,imagename), subpath, imageflags, (s>=0)?mipdata[0]:NULL, palette, width, height, TF_TRANS8_FULLBRIGHT);
tex->fullbright = Image_GetTexture(va("%s_luma:%s_glow", imagename,imagename), subpath, imageflags, (s>=0)?srcdata:NULL, palette, width, height, TF_TRANS8_FULLBRIGHT);
}
}
}
@ -7796,10 +7801,11 @@ void Shader_ShowShader_f(void)
o = R_LoadShader(sourcename, SUF_2D, NULL, NULL);
if (o)
{
char *body = Shader_GetShaderBody(o, NULL, 0);
char fname[256];
char *body = Shader_GetShaderBody(o, fname, sizeof(fname));
if (body)
{
Con_Printf("%s\n{%s\n", o->name, body);
Con_Printf("^h(%s)^h\n%s\n{%s\n", fname, o->name, body);
Z_Free(body);
}
else
@ -8014,19 +8020,21 @@ void R_RemapShader(const char *sourcename, const char *destname, float timeoffse
shader_t *o;
shader_t *n;
int i;
size_t l;
char cleansrcname[MAX_QPATH];
Q_strncpyz(cleansrcname, sourcename, sizeof(cleansrcname));
COM_CleanUpPath(cleansrcname);
l = strlen(cleansrcname);
for (i = 0; i < r_numshaders; i++)
{
o = r_shaders[i];
if (o && o->uses)
{
if (!strcmp(o->name, cleansrcname))
if (!strncmp(o->name, cleansrcname, l) && (!o->name[l] || o->name[l]=='#'))
{
n = R_LoadShader (destname, o->usageflags, NULL, NULL);
n = R_LoadShader (va("%s%s", destname, o->name+l), o->usageflags, NULL, NULL);
if (!n)
{ //if it isn't actually available on disk then don't care about usageflags, just find ANY that's already loaded.
// check the hash first

View File

@ -77,7 +77,9 @@ void R_SetSky(const char *sky)
texnums_t tex;
memset(&tex, 0, sizeof(tex));
tex.reflectcube = R_LoadHiResTexture(sky, "env:gfx/env", IF_LOADNOW|IF_TEXTYPE_CUBE|IF_CLAMP);
if (tex.reflectcube->width)
if (tex.reflectcube && tex.reflectcube->status == TEX_LOADING)
COM_WorkerPartialSync(tex.reflectcube, &tex.reflectcube->status, TEX_LOADING);
if (tex.reflectcube->width && TEXLOADED(tex.reflectcube))
{
/* FIXME: Q2/HL require the skybox to not draw over geometry, shouldn't we force it? --eukara */
if (cls.allow_skyboxes) {
@ -1011,7 +1013,7 @@ A sky image is 256*128 and comprises two logical textures.
the left is the transparent/blended part. the right is the opaque/background part.
==============
*/
void R_InitSky (shader_t *shader, const char *skyname, qbyte *src, unsigned int width, unsigned int height)
void R_InitSky (shader_t *shader, const char *skyname, uploadfmt_t fmt, qbyte *src, unsigned int width, unsigned int height)
{
int i, j, p;
unsigned *temp;
@ -1083,53 +1085,88 @@ void R_InitSky (shader_t *shader, const char *skyname, qbyte *src, unsigned int
}
}
temp = BZ_Malloc(width*height*sizeof(*temp));
if (fmt & PTI_FULLMIPCHAIN)
{ //input is expected to make sense...
qbyte *front, *back;
unsigned int bb, bw, bh;
unsigned int w, h, y;
fmt = fmt&~PTI_FULLMIPCHAIN;
Image_BlockSizeForEncoding(fmt, &bb, &bw, &bh);
// make an average value for the back to avoid
// a fringe on the top level
w = (width+bw-1)/bw;
h = (height+bh-1)/bh;
r = g = b = 0;
for (i=0 ; i<height ; i++)
for (j=0 ; j<width ; j++)
back = BZ_Malloc(bb*w*2*h);
front = back + bb*w*h;
for (y = 0; y < h; y++)
{
p = src[i*stride + j + width];
rgba = &d_8to24rgbtable[p];
temp[(i*width) + j] = *rgba;
r += ((qbyte *)rgba)[0];
g += ((qbyte *)rgba)[1];
b += ((qbyte *)rgba)[2];
memcpy(back + bb*y*w, src + bb*(y*w*2+w), w*bb);
memcpy(front + bb*y*w, src + bb*(y*w*2), w*bb);
}
if (!shader->defaulttextures->base)
{
Q_snprintfz(name, sizeof(name), "%s_solid", skyname);
Q_strlwr(name);
shader->defaulttextures->base = R_LoadReplacementTexture(name, NULL, IF_NOALPHA, temp, width, height, TF_RGBX32);
if (!shader->defaulttextures->base)
{
Q_snprintfz(name, sizeof(name), "%s_solid", skyname);
Q_strlwr(name);
shader->defaulttextures->base = R_LoadReplacementTexture(name, NULL, IF_NOALPHA, back, width, height, fmt);
}
if (!shader->defaulttextures->fullbright)
{ //FIXME: support _trans
Q_snprintfz(name, sizeof(name), "%s_alpha:%s_trans", skyname, skyname);
Q_strlwr(name);
shader->defaulttextures->fullbright = R_LoadReplacementTexture(name, NULL, 0, front, width, height, fmt);
}
BZ_Free(back);
}
if (!shader->defaulttextures->fullbright)
else
{
//fixme: use premultiplied alpha here.
((qbyte *)&transpix)[0] = r/(width*height);
((qbyte *)&transpix)[1] = g/(width*height);
((qbyte *)&transpix)[2] = b/(width*height);
((qbyte *)&transpix)[3] = 0;
alphamask = LittleLong(0x7fffffff);
temp = BZ_Malloc(width*height*sizeof(*temp));
// make an average value for the back to avoid
// a fringe on the top level
r = g = b = 0;
for (i=0 ; i<height ; i++)
for (j=0 ; j<width ; j++)
{
p = src[i*stride + j];
if (p == 0)
temp[(i*width) + j] = transpix;
else
temp[(i*width) + j] = d_8to24rgbtable[p] & alphamask;
p = src[i*stride + j + width];
rgba = &d_8to24rgbtable[p];
temp[(i*width) + j] = *rgba;
r += ((qbyte *)rgba)[0];
g += ((qbyte *)rgba)[1];
b += ((qbyte *)rgba)[2];
}
//FIXME: support _trans
Q_snprintfz(name, sizeof(name), "%s_alpha:%s_trans", skyname, skyname);
Q_strlwr(name);
shader->defaulttextures->fullbright = R_LoadReplacementTexture(name, NULL, 0, temp, width, height, TF_RGBA32);
if (!shader->defaulttextures->base)
{
Q_snprintfz(name, sizeof(name), "%s_solid", skyname);
Q_strlwr(name);
shader->defaulttextures->base = R_LoadReplacementTexture(name, NULL, IF_NOALPHA, temp, width, height, TF_RGBX32);
}
if (!shader->defaulttextures->fullbright)
{
//fixme: use premultiplied alpha here.
((qbyte *)&transpix)[0] = r/(width*height);
((qbyte *)&transpix)[1] = g/(width*height);
((qbyte *)&transpix)[2] = b/(width*height);
((qbyte *)&transpix)[3] = 0;
alphamask = LittleLong(0x7fffffff);
for (i=0 ; i<height ; i++)
for (j=0 ; j<width ; j++)
{
p = src[i*stride + j];
if (p == 0)
temp[(i*width) + j] = transpix;
else
temp[(i*width) + j] = d_8to24rgbtable[p] & alphamask;
}
//FIXME: support _trans
Q_snprintfz(name, sizeof(name), "%s_alpha:%s_trans", skyname, skyname);
Q_strlwr(name);
shader->defaulttextures->fullbright = R_LoadReplacementTexture(name, NULL, 0, temp, width, height, TF_RGBA32);
}
BZ_Free(temp);
}
BZ_Free(temp);
}
#endif

View File

@ -4632,7 +4632,6 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"void main ()\n"
"{\n"
"pos = v_position.xyz - e_eyepos;\n"
"pos.y = -pos.y;\n"
"if (r_glsl_skybox_orientation.xyz != vec3(0.0))\n"
"pos = pos*rotateAroundAxis(r_glsl_skybox_orientation);\n"
@ -4652,11 +4651,11 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
#ifdef VKQUAKE
{QR_VULKAN, -1, "defaultskybox",
"\xFF\x53\x50\x56\x01\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x2C\x00\x00\x00\x13\x00\x00\x00\x40\x00\x00\x00"
"\xB8\x0F\x00\x00\xF8\x0F\x00\x00\x70\x11\x00\x00\x01\x00\x62\x31\x72\x5F\x66\x6F\x67\x5F\x65\x78\x70\x32\x00\x00\x00\x00\x00\x00"
"\x03\x02\x23\x07\x00\x00\x01\x00\x07\x00\x08\x00\x58\x00\x00\x00\x00\x00\x00\x00\x11\x00\x02\x00\x01\x00\x00\x00\x0B\x00\x06\x00"
"\x54\x0F\x00\x00\x94\x0F\x00\x00\x70\x11\x00\x00\x01\x00\x62\x31\x72\x5F\x66\x6F\x67\x5F\x65\x78\x70\x32\x00\x00\x00\x00\x00\x00"
"\x03\x02\x23\x07\x00\x00\x01\x00\x07\x00\x08\x00\x53\x00\x00\x00\x00\x00\x00\x00\x11\x00\x02\x00\x01\x00\x00\x00\x0B\x00\x06\x00"
"\x01\x00\x00\x00\x47\x4C\x53\x4C\x2E\x73\x74\x64\x2E\x34\x35\x30\x00\x00\x00\x00\x0E\x00\x03\x00\x00\x00\x00\x00\x01\x00\x00\x00"
"\x0F\x00\x0E\x00\x00\x00\x00\x00\x04\x00\x00\x00\x6D\x61\x69\x6E\x00\x00\x00\x00\x1C\x00\x00\x00\x39\x00\x00\x00\x47\x00\x00\x00"
"\x51\x00\x00\x00\x53\x00\x00\x00\x54\x00\x00\x00\x55\x00\x00\x00\x56\x00\x00\x00\x57\x00\x00\x00\x03\x00\x03\x00\x02\x00\x00\x00"
"\x0F\x00\x0E\x00\x00\x00\x00\x00\x04\x00\x00\x00\x6D\x61\x69\x6E\x00\x00\x00\x00\x1C\x00\x00\x00\x39\x00\x00\x00\x42\x00\x00\x00"
"\x4C\x00\x00\x00\x4E\x00\x00\x00\x4F\x00\x00\x00\x50\x00\x00\x00\x51\x00\x00\x00\x52\x00\x00\x00\x03\x00\x03\x00\x02\x00\x00\x00"
"\xC2\x01\x00\x00\x05\x00\x04\x00\x04\x00\x00\x00\x6D\x61\x69\x6E\x00\x00\x00\x00\x05\x00\x06\x00\x09\x00\x00\x00\x66\x74\x65\x74"
"\x72\x61\x6E\x73\x66\x6F\x72\x6D\x28\x00\x00\x00\x05\x00\x04\x00\x0C\x00\x00\x00\x70\x72\x6F\x6A\x00\x00\x00\x00\x05\x00\x05\x00"
"\x13\x00\x00\x00\x65\x6E\x74\x69\x74\x79\x62\x6C\x6F\x63\x6B\x00\x06\x00\x07\x00\x13\x00\x00\x00\x00\x00\x00\x00\x6D\x5F\x6D\x6F"
@ -4678,22 +4677,22 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"\x00\x00\x00\x00\x06\x00\x07\x00\x13\x00\x00\x00\x15\x00\x00\x00\x77\x5F\x66\x6F\x67\x64\x65\x70\x74\x68\x62\x69\x61\x73\x00\x00"
"\x06\x00\x05\x00\x13\x00\x00\x00\x16\x00\x00\x00\x65\x70\x61\x64\x37\x00\x00\x00\x05\x00\x03\x00\x15\x00\x00\x00\x00\x00\x00\x00"
"\x05\x00\x05\x00\x1C\x00\x00\x00\x76\x5F\x70\x6F\x73\x69\x74\x69\x6F\x6E\x00\x00\x05\x00\x03\x00\x39\x00\x00\x00\x70\x6F\x73\x00"
"\x05\x00\x06\x00\x45\x00\x00\x00\x67\x6C\x5F\x50\x65\x72\x56\x65\x72\x74\x65\x78\x00\x00\x00\x00\x06\x00\x06\x00\x45\x00\x00\x00"
"\x00\x00\x00\x00\x67\x6C\x5F\x50\x6F\x73\x69\x74\x69\x6F\x6E\x00\x05\x00\x03\x00\x47\x00\x00\x00\x00\x00\x00\x00\x05\x00\x07\x00"
"\x4B\x00\x00\x00\x5F\x63\x76\x61\x72\x5F\x72\x5F\x66\x6F\x67\x5F\x65\x78\x70\x32\x00\x00\x00\x00\x05\x00\x04\x00\x4C\x00\x00\x00"
"\x5F\x46\x4F\x47\x00\x00\x00\x00\x05\x00\x05\x00\x4D\x00\x00\x00\x6C\x69\x67\x68\x74\x62\x6C\x6F\x63\x6B\x00\x00\x06\x00\x07\x00"
"\x4D\x00\x00\x00\x00\x00\x00\x00\x6C\x5F\x63\x75\x62\x65\x6D\x61\x74\x72\x69\x78\x00\x00\x00\x00\x06\x00\x07\x00\x4D\x00\x00\x00"
"\x01\x00\x00\x00\x6C\x5F\x6C\x69\x67\x68\x74\x70\x6F\x73\x69\x74\x69\x6F\x6E\x00\x06\x00\x05\x00\x4D\x00\x00\x00\x02\x00\x00\x00"
"\x6C\x70\x61\x64\x31\x00\x00\x00\x06\x00\x07\x00\x4D\x00\x00\x00\x03\x00\x00\x00\x6C\x5F\x6C\x69\x67\x68\x74\x63\x6F\x6C\x6F\x75"
"\x72\x00\x00\x00\x06\x00\x05\x00\x4D\x00\x00\x00\x04\x00\x00\x00\x6C\x70\x61\x64\x32\x00\x00\x00\x06\x00\x08\x00\x4D\x00\x00\x00"
"\x05\x00\x00\x00\x6C\x5F\x6C\x69\x67\x68\x74\x63\x6F\x6C\x6F\x75\x72\x73\x63\x61\x6C\x65\x00\x00\x06\x00\x07\x00\x4D\x00\x00\x00"
"\x06\x00\x00\x00\x6C\x5F\x6C\x69\x67\x68\x74\x72\x61\x64\x69\x75\x73\x00\x00\x00\x06\x00\x07\x00\x4D\x00\x00\x00\x07\x00\x00\x00"
"\x6C\x5F\x73\x68\x61\x64\x6F\x77\x6D\x61\x70\x70\x72\x6F\x6A\x00\x06\x00\x08\x00\x4D\x00\x00\x00\x08\x00\x00\x00\x6C\x5F\x73\x68"
"\x61\x64\x6F\x77\x6D\x61\x70\x73\x63\x61\x6C\x65\x00\x00\x00\x00\x06\x00\x05\x00\x4D\x00\x00\x00\x09\x00\x00\x00\x6C\x70\x61\x64"
"\x33\x00\x00\x00\x05\x00\x03\x00\x4F\x00\x00\x00\x00\x00\x00\x00\x05\x00\x05\x00\x51\x00\x00\x00\x76\x5F\x74\x65\x78\x63\x6F\x6F"
"\x72\x64\x00\x00\x05\x00\x05\x00\x53\x00\x00\x00\x76\x5F\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x00\x05\x00\x05\x00\x54\x00\x00\x00"
"\x76\x5F\x6C\x6D\x63\x6F\x6F\x72\x64\x00\x00\x00\x05\x00\x05\x00\x55\x00\x00\x00\x76\x5F\x6E\x6F\x72\x6D\x61\x6C\x00\x00\x00\x00"
"\x05\x00\x05\x00\x56\x00\x00\x00\x76\x5F\x73\x76\x65\x63\x74\x6F\x72\x00\x00\x00\x05\x00\x05\x00\x57\x00\x00\x00\x76\x5F\x74\x76"
"\x05\x00\x06\x00\x40\x00\x00\x00\x67\x6C\x5F\x50\x65\x72\x56\x65\x72\x74\x65\x78\x00\x00\x00\x00\x06\x00\x06\x00\x40\x00\x00\x00"
"\x00\x00\x00\x00\x67\x6C\x5F\x50\x6F\x73\x69\x74\x69\x6F\x6E\x00\x05\x00\x03\x00\x42\x00\x00\x00\x00\x00\x00\x00\x05\x00\x07\x00"
"\x46\x00\x00\x00\x5F\x63\x76\x61\x72\x5F\x72\x5F\x66\x6F\x67\x5F\x65\x78\x70\x32\x00\x00\x00\x00\x05\x00\x04\x00\x47\x00\x00\x00"
"\x5F\x46\x4F\x47\x00\x00\x00\x00\x05\x00\x05\x00\x48\x00\x00\x00\x6C\x69\x67\x68\x74\x62\x6C\x6F\x63\x6B\x00\x00\x06\x00\x07\x00"
"\x48\x00\x00\x00\x00\x00\x00\x00\x6C\x5F\x63\x75\x62\x65\x6D\x61\x74\x72\x69\x78\x00\x00\x00\x00\x06\x00\x07\x00\x48\x00\x00\x00"
"\x01\x00\x00\x00\x6C\x5F\x6C\x69\x67\x68\x74\x70\x6F\x73\x69\x74\x69\x6F\x6E\x00\x06\x00\x05\x00\x48\x00\x00\x00\x02\x00\x00\x00"
"\x6C\x70\x61\x64\x31\x00\x00\x00\x06\x00\x07\x00\x48\x00\x00\x00\x03\x00\x00\x00\x6C\x5F\x6C\x69\x67\x68\x74\x63\x6F\x6C\x6F\x75"
"\x72\x00\x00\x00\x06\x00\x05\x00\x48\x00\x00\x00\x04\x00\x00\x00\x6C\x70\x61\x64\x32\x00\x00\x00\x06\x00\x08\x00\x48\x00\x00\x00"
"\x05\x00\x00\x00\x6C\x5F\x6C\x69\x67\x68\x74\x63\x6F\x6C\x6F\x75\x72\x73\x63\x61\x6C\x65\x00\x00\x06\x00\x07\x00\x48\x00\x00\x00"
"\x06\x00\x00\x00\x6C\x5F\x6C\x69\x67\x68\x74\x72\x61\x64\x69\x75\x73\x00\x00\x00\x06\x00\x07\x00\x48\x00\x00\x00\x07\x00\x00\x00"
"\x6C\x5F\x73\x68\x61\x64\x6F\x77\x6D\x61\x70\x70\x72\x6F\x6A\x00\x06\x00\x08\x00\x48\x00\x00\x00\x08\x00\x00\x00\x6C\x5F\x73\x68"
"\x61\x64\x6F\x77\x6D\x61\x70\x73\x63\x61\x6C\x65\x00\x00\x00\x00\x06\x00\x05\x00\x48\x00\x00\x00\x09\x00\x00\x00\x6C\x70\x61\x64"
"\x33\x00\x00\x00\x05\x00\x03\x00\x4A\x00\x00\x00\x00\x00\x00\x00\x05\x00\x05\x00\x4C\x00\x00\x00\x76\x5F\x74\x65\x78\x63\x6F\x6F"
"\x72\x64\x00\x00\x05\x00\x05\x00\x4E\x00\x00\x00\x76\x5F\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x00\x05\x00\x05\x00\x4F\x00\x00\x00"
"\x76\x5F\x6C\x6D\x63\x6F\x6F\x72\x64\x00\x00\x00\x05\x00\x05\x00\x50\x00\x00\x00\x76\x5F\x6E\x6F\x72\x6D\x61\x6C\x00\x00\x00\x00"
"\x05\x00\x05\x00\x51\x00\x00\x00\x76\x5F\x73\x76\x65\x63\x74\x6F\x72\x00\x00\x00\x05\x00\x05\x00\x52\x00\x00\x00\x76\x5F\x74\x76"
"\x65\x63\x74\x6F\x72\x00\x00\x00\x47\x00\x04\x00\x11\x00\x00\x00\x06\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00\x13\x00\x00\x00"
"\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x13\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00"
"\x13\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00\x13\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00"
@ -4715,20 +4714,20 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"\x13\x00\x00\x00\x16\x00\x00\x00\x23\x00\x00\x00\x98\x01\x00\x00\x47\x00\x03\x00\x13\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00"
"\x15\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x15\x00\x00\x00\x21\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00"
"\x1C\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x39\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00"
"\x45\x00\x00\x00\x00\x00\x00\x00\x0B\x00\x00\x00\x00\x00\x00\x00\x47\x00\x03\x00\x45\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00"
"\x4B\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x47\x00\x04\x00\x4C\x00\x00\x00\x01\x00\x00\x00\x15\x00\x00\x00\x48\x00\x04\x00"
"\x4D\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x4D\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00"
"\x48\x00\x05\x00\x4D\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x05\x00\x4D\x00\x00\x00\x01\x00\x00\x00"
"\x23\x00\x00\x00\x40\x00\x00\x00\x48\x00\x05\x00\x4D\x00\x00\x00\x02\x00\x00\x00\x23\x00\x00\x00\x4C\x00\x00\x00\x48\x00\x05\x00"
"\x4D\x00\x00\x00\x03\x00\x00\x00\x23\x00\x00\x00\x50\x00\x00\x00\x48\x00\x05\x00\x4D\x00\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00"
"\x5C\x00\x00\x00\x48\x00\x05\x00\x4D\x00\x00\x00\x05\x00\x00\x00\x23\x00\x00\x00\x60\x00\x00\x00\x48\x00\x05\x00\x4D\x00\x00\x00"
"\x06\x00\x00\x00\x23\x00\x00\x00\x6C\x00\x00\x00\x48\x00\x05\x00\x4D\x00\x00\x00\x07\x00\x00\x00\x23\x00\x00\x00\x70\x00\x00\x00"
"\x48\x00\x05\x00\x4D\x00\x00\x00\x08\x00\x00\x00\x23\x00\x00\x00\x80\x00\x00\x00\x48\x00\x05\x00\x4D\x00\x00\x00\x09\x00\x00\x00"
"\x23\x00\x00\x00\x88\x00\x00\x00\x47\x00\x03\x00\x4D\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x4F\x00\x00\x00\x22\x00\x00\x00"
"\x00\x00\x00\x00\x47\x00\x04\x00\x4F\x00\x00\x00\x21\x00\x00\x00\x01\x00\x00\x00\x47\x00\x04\x00\x51\x00\x00\x00\x1E\x00\x00\x00"
"\x01\x00\x00\x00\x47\x00\x04\x00\x53\x00\x00\x00\x1E\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x54\x00\x00\x00\x1E\x00\x00\x00"
"\x03\x00\x00\x00\x47\x00\x04\x00\x55\x00\x00\x00\x1E\x00\x00\x00\x04\x00\x00\x00\x47\x00\x04\x00\x56\x00\x00\x00\x1E\x00\x00\x00"
"\x05\x00\x00\x00\x47\x00\x04\x00\x57\x00\x00\x00\x1E\x00\x00\x00\x06\x00\x00\x00\x13\x00\x02\x00\x02\x00\x00\x00\x21\x00\x03\x00"
"\x40\x00\x00\x00\x00\x00\x00\x00\x0B\x00\x00\x00\x00\x00\x00\x00\x47\x00\x03\x00\x40\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00"
"\x46\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x47\x00\x04\x00\x47\x00\x00\x00\x01\x00\x00\x00\x15\x00\x00\x00\x48\x00\x04\x00"
"\x48\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x48\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00"
"\x48\x00\x05\x00\x48\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x05\x00\x48\x00\x00\x00\x01\x00\x00\x00"
"\x23\x00\x00\x00\x40\x00\x00\x00\x48\x00\x05\x00\x48\x00\x00\x00\x02\x00\x00\x00\x23\x00\x00\x00\x4C\x00\x00\x00\x48\x00\x05\x00"
"\x48\x00\x00\x00\x03\x00\x00\x00\x23\x00\x00\x00\x50\x00\x00\x00\x48\x00\x05\x00\x48\x00\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00"
"\x5C\x00\x00\x00\x48\x00\x05\x00\x48\x00\x00\x00\x05\x00\x00\x00\x23\x00\x00\x00\x60\x00\x00\x00\x48\x00\x05\x00\x48\x00\x00\x00"
"\x06\x00\x00\x00\x23\x00\x00\x00\x6C\x00\x00\x00\x48\x00\x05\x00\x48\x00\x00\x00\x07\x00\x00\x00\x23\x00\x00\x00\x70\x00\x00\x00"
"\x48\x00\x05\x00\x48\x00\x00\x00\x08\x00\x00\x00\x23\x00\x00\x00\x80\x00\x00\x00\x48\x00\x05\x00\x48\x00\x00\x00\x09\x00\x00\x00"
"\x23\x00\x00\x00\x88\x00\x00\x00\x47\x00\x03\x00\x48\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x4A\x00\x00\x00\x22\x00\x00\x00"
"\x00\x00\x00\x00\x47\x00\x04\x00\x4A\x00\x00\x00\x21\x00\x00\x00\x01\x00\x00\x00\x47\x00\x04\x00\x4C\x00\x00\x00\x1E\x00\x00\x00"
"\x01\x00\x00\x00\x47\x00\x04\x00\x4E\x00\x00\x00\x1E\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x4F\x00\x00\x00\x1E\x00\x00\x00"
"\x03\x00\x00\x00\x47\x00\x04\x00\x50\x00\x00\x00\x1E\x00\x00\x00\x04\x00\x00\x00\x47\x00\x04\x00\x51\x00\x00\x00\x1E\x00\x00\x00"
"\x05\x00\x00\x00\x47\x00\x04\x00\x52\x00\x00\x00\x1E\x00\x00\x00\x06\x00\x00\x00\x13\x00\x02\x00\x02\x00\x00\x00\x21\x00\x03\x00"
"\x03\x00\x00\x00\x02\x00\x00\x00\x16\x00\x03\x00\x06\x00\x00\x00\x20\x00\x00\x00\x17\x00\x04\x00\x07\x00\x00\x00\x06\x00\x00\x00"
"\x04\x00\x00\x00\x21\x00\x03\x00\x08\x00\x00\x00\x07\x00\x00\x00\x20\x00\x04\x00\x0B\x00\x00\x00\x07\x00\x00\x00\x07\x00\x00\x00"
"\x18\x00\x04\x00\x0D\x00\x00\x00\x07\x00\x00\x00\x04\x00\x00\x00\x17\x00\x04\x00\x0E\x00\x00\x00\x06\x00\x00\x00\x03\x00\x00\x00"
@ -4746,179 +4745,176 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"\x02\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00\x2E\x00\x00\x00\x03\x00\x00\x00\x2B\x00\x04\x00\x06\x00\x00\x00\x32\x00\x00\x00"
"\x00\x00\x00\x40\x20\x00\x04\x00\x38\x00\x00\x00\x03\x00\x00\x00\x0E\x00\x00\x00\x3B\x00\x04\x00\x38\x00\x00\x00\x39\x00\x00\x00"
"\x03\x00\x00\x00\x2B\x00\x04\x00\x16\x00\x00\x00\x3B\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00\x3C\x00\x00\x00\x02\x00\x00\x00"
"\x0E\x00\x00\x00\x20\x00\x04\x00\x40\x00\x00\x00\x03\x00\x00\x00\x06\x00\x00\x00\x1E\x00\x03\x00\x45\x00\x00\x00\x07\x00\x00\x00"
"\x20\x00\x04\x00\x46\x00\x00\x00\x03\x00\x00\x00\x45\x00\x00\x00\x3B\x00\x04\x00\x46\x00\x00\x00\x47\x00\x00\x00\x03\x00\x00\x00"
"\x20\x00\x04\x00\x49\x00\x00\x00\x03\x00\x00\x00\x07\x00\x00\x00\x32\x00\x04\x00\x16\x00\x00\x00\x4B\x00\x00\x00\x00\x01\x00\x00"
"\x32\x00\x04\x00\x16\x00\x00\x00\x4C\x00\x00\x00\x15\x00\x00\x00\x1E\x00\x0C\x00\x4D\x00\x00\x00\x0D\x00\x00\x00\x0E\x00\x00\x00"
"\x06\x00\x00\x00\x0E\x00\x00\x00\x06\x00\x00\x00\x0E\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x12\x00\x00\x00\x12\x00\x00\x00"
"\x20\x00\x04\x00\x4E\x00\x00\x00\x02\x00\x00\x00\x4D\x00\x00\x00\x3B\x00\x04\x00\x4E\x00\x00\x00\x4F\x00\x00\x00\x02\x00\x00\x00"
"\x20\x00\x04\x00\x50\x00\x00\x00\x01\x00\x00\x00\x12\x00\x00\x00\x3B\x00\x04\x00\x50\x00\x00\x00\x51\x00\x00\x00\x01\x00\x00\x00"
"\x20\x00\x04\x00\x52\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00\x52\x00\x00\x00\x53\x00\x00\x00\x01\x00\x00\x00"
"\x3B\x00\x04\x00\x50\x00\x00\x00\x54\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x55\x00\x00\x00\x01\x00\x00\x00"
"\x3B\x00\x04\x00\x1B\x00\x00\x00\x56\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x57\x00\x00\x00\x01\x00\x00\x00"
"\x36\x00\x05\x00\x02\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\xF8\x00\x02\x00\x05\x00\x00\x00\x3D\x00\x04\x00"
"\x0E\x00\x00\x00\x3A\x00\x00\x00\x1C\x00\x00\x00\x41\x00\x05\x00\x3C\x00\x00\x00\x3D\x00\x00\x00\x15\x00\x00\x00\x3B\x00\x00\x00"
"\x3D\x00\x04\x00\x0E\x00\x00\x00\x3E\x00\x00\x00\x3D\x00\x00\x00\x83\x00\x05\x00\x0E\x00\x00\x00\x3F\x00\x00\x00\x3A\x00\x00\x00"
"\x3E\x00\x00\x00\x3E\x00\x03\x00\x39\x00\x00\x00\x3F\x00\x00\x00\x41\x00\x05\x00\x40\x00\x00\x00\x41\x00\x00\x00\x39\x00\x00\x00"
"\x25\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x42\x00\x00\x00\x41\x00\x00\x00\x7F\x00\x04\x00\x06\x00\x00\x00\x43\x00\x00\x00"
"\x42\x00\x00\x00\x41\x00\x05\x00\x40\x00\x00\x00\x44\x00\x00\x00\x39\x00\x00\x00\x25\x00\x00\x00\x3E\x00\x03\x00\x44\x00\x00\x00"
"\x43\x00\x00\x00\x39\x00\x04\x00\x07\x00\x00\x00\x48\x00\x00\x00\x09\x00\x00\x00\x41\x00\x05\x00\x49\x00\x00\x00\x4A\x00\x00\x00"
"\x47\x00\x00\x00\x17\x00\x00\x00\x3E\x00\x03\x00\x4A\x00\x00\x00\x48\x00\x00\x00\xFD\x00\x01\x00\x38\x00\x01\x00\x36\x00\x05\x00"
"\x07\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\xF8\x00\x02\x00\x0A\x00\x00\x00\x3B\x00\x04\x00\x0B\x00\x00\x00"
"\x0C\x00\x00\x00\x07\x00\x00\x00\x41\x00\x05\x00\x18\x00\x00\x00\x19\x00\x00\x00\x15\x00\x00\x00\x17\x00\x00\x00\x3D\x00\x04\x00"
"\x0D\x00\x00\x00\x1A\x00\x00\x00\x19\x00\x00\x00\x3D\x00\x04\x00\x0E\x00\x00\x00\x1D\x00\x00\x00\x1C\x00\x00\x00\x51\x00\x05\x00"
"\x06\x00\x00\x00\x1F\x00\x00\x00\x1D\x00\x00\x00\x00\x00\x00\x00\x51\x00\x05\x00\x06\x00\x00\x00\x20\x00\x00\x00\x1D\x00\x00\x00"
"\x01\x00\x00\x00\x51\x00\x05\x00\x06\x00\x00\x00\x21\x00\x00\x00\x1D\x00\x00\x00\x02\x00\x00\x00\x50\x00\x07\x00\x07\x00\x00\x00"
"\x22\x00\x00\x00\x1F\x00\x00\x00\x20\x00\x00\x00\x21\x00\x00\x00\x1E\x00\x00\x00\x91\x00\x05\x00\x07\x00\x00\x00\x23\x00\x00\x00"
"\x1A\x00\x00\x00\x22\x00\x00\x00\x3E\x00\x03\x00\x0C\x00\x00\x00\x23\x00\x00\x00\x41\x00\x05\x00\x26\x00\x00\x00\x27\x00\x00\x00"
"\x0C\x00\x00\x00\x25\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x28\x00\x00\x00\x27\x00\x00\x00\x85\x00\x05\x00\x06\x00\x00\x00"
"\x29\x00\x00\x00\x28\x00\x00\x00\x24\x00\x00\x00\x41\x00\x05\x00\x26\x00\x00\x00\x2A\x00\x00\x00\x0C\x00\x00\x00\x25\x00\x00\x00"
"\x3E\x00\x03\x00\x2A\x00\x00\x00\x29\x00\x00\x00\x41\x00\x05\x00\x26\x00\x00\x00\x2C\x00\x00\x00\x0C\x00\x00\x00\x2B\x00\x00\x00"
"\x3D\x00\x04\x00\x06\x00\x00\x00\x2D\x00\x00\x00\x2C\x00\x00\x00\x41\x00\x05\x00\x26\x00\x00\x00\x2F\x00\x00\x00\x0C\x00\x00\x00"
"\x2E\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x30\x00\x00\x00\x2F\x00\x00\x00\x81\x00\x05\x00\x06\x00\x00\x00\x31\x00\x00\x00"
"\x2D\x00\x00\x00\x30\x00\x00\x00\x88\x00\x05\x00\x06\x00\x00\x00\x33\x00\x00\x00\x31\x00\x00\x00\x32\x00\x00\x00\x41\x00\x05\x00"
"\x26\x00\x00\x00\x34\x00\x00\x00\x0C\x00\x00\x00\x2B\x00\x00\x00\x3E\x00\x03\x00\x34\x00\x00\x00\x33\x00\x00\x00\x3D\x00\x04\x00"
"\x07\x00\x00\x00\x35\x00\x00\x00\x0C\x00\x00\x00\xFE\x00\x02\x00\x35\x00\x00\x00\x38\x00\x01\x00\x03\x02\x23\x07\x00\x00\x01\x00"
"\x07\x00\x08\x00\x72\x00\x00\x00\x00\x00\x00\x00\x11\x00\x02\x00\x01\x00\x00\x00\x0B\x00\x06\x00\x01\x00\x00\x00\x47\x4C\x53\x4C"
"\x2E\x73\x74\x64\x2E\x34\x35\x30\x00\x00\x00\x00\x0E\x00\x03\x00\x00\x00\x00\x00\x01\x00\x00\x00\x0F\x00\x08\x00\x04\x00\x00\x00"
"\x04\x00\x00\x00\x6D\x61\x69\x6E\x00\x00\x00\x00\x27\x00\x00\x00\x62\x00\x00\x00\x66\x00\x00\x00\x10\x00\x03\x00\x04\x00\x00\x00"
"\x07\x00\x00\x00\x03\x00\x03\x00\x02\x00\x00\x00\xC2\x01\x00\x00\x05\x00\x04\x00\x04\x00\x00\x00\x6D\x61\x69\x6E\x00\x00\x00\x00"
"\x05\x00\x05\x00\x0B\x00\x00\x00\x66\x6F\x67\x33\x28\x76\x66\x33\x3B\x00\x00\x00\x05\x00\x06\x00\x0A\x00\x00\x00\x72\x65\x67\x75"
"\x6C\x61\x72\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x04\x00\x0E\x00\x00\x00\x5F\x46\x4F\x47\x00\x00\x00\x00\x05\x00\x03\x00"
"\x18\x00\x00\x00\x7A\x00\x00\x00\x05\x00\x05\x00\x1F\x00\x00\x00\x65\x6E\x74\x69\x74\x79\x62\x6C\x6F\x63\x6B\x00\x06\x00\x07\x00"
"\x1F\x00\x00\x00\x00\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x76\x69\x65\x77\x70\x72\x6F\x6A\x00\x06\x00\x05\x00\x1F\x00\x00\x00"
"\x01\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x00\x06\x00\x06\x00\x1F\x00\x00\x00\x02\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x69"
"\x6E\x76\x00\x00\x06\x00\x06\x00\x1F\x00\x00\x00\x03\x00\x00\x00\x65\x5F\x65\x79\x65\x70\x6F\x73\x00\x00\x00\x00\x06\x00\x05\x00"
"\x1F\x00\x00\x00\x04\x00\x00\x00\x65\x5F\x74\x69\x6D\x65\x00\x00\x06\x00\x07\x00\x1F\x00\x00\x00\x05\x00\x00\x00\x65\x5F\x6C\x69"
"\x67\x68\x74\x5F\x61\x6D\x62\x69\x65\x6E\x74\x00\x06\x00\x05\x00\x1F\x00\x00\x00\x06\x00\x00\x00\x65\x70\x61\x64\x31\x00\x00\x00"
"\x06\x00\x06\x00\x1F\x00\x00\x00\x07\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x64\x69\x72\x00\x06\x00\x05\x00\x1F\x00\x00\x00"
"\x08\x00\x00\x00\x65\x70\x61\x64\x32\x00\x00\x00\x06\x00\x06\x00\x1F\x00\x00\x00\x09\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F"
"\x6D\x75\x6C\x00\x06\x00\x05\x00\x1F\x00\x00\x00\x0A\x00\x00\x00\x65\x70\x61\x64\x33\x00\x00\x00\x06\x00\x06\x00\x1F\x00\x00\x00"
"\x0B\x00\x00\x00\x65\x5F\x6C\x6D\x73\x63\x61\x6C\x65\x73\x00\x00\x06\x00\x07\x00\x1F\x00\x00\x00\x0C\x00\x00\x00\x65\x5F\x75\x70"
"\x70\x65\x72\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x06\x00\x05\x00\x1F\x00\x00\x00\x0D\x00\x00\x00\x65\x70\x61\x64\x34\x00\x00\x00"
"\x06\x00\x07\x00\x1F\x00\x00\x00\x0E\x00\x00\x00\x65\x5F\x6C\x6F\x77\x65\x72\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x06\x00\x05\x00"
"\x1F\x00\x00\x00\x0F\x00\x00\x00\x65\x70\x61\x64\x35\x00\x00\x00\x06\x00\x06\x00\x1F\x00\x00\x00\x10\x00\x00\x00\x65\x5F\x67\x6C"
"\x6F\x77\x6D\x6F\x64\x00\x00\x00\x06\x00\x05\x00\x1F\x00\x00\x00\x11\x00\x00\x00\x65\x70\x61\x64\x36\x00\x00\x00\x06\x00\x07\x00"
"\x1F\x00\x00\x00\x12\x00\x00\x00\x65\x5F\x63\x6F\x6C\x6F\x75\x72\x69\x64\x65\x6E\x74\x00\x00\x00\x06\x00\x07\x00\x1F\x00\x00\x00"
"\x13\x00\x00\x00\x77\x5F\x66\x6F\x67\x63\x6F\x6C\x6F\x75\x72\x73\x00\x00\x00\x00\x06\x00\x07\x00\x1F\x00\x00\x00\x14\x00\x00\x00"
"\x77\x5F\x66\x6F\x67\x64\x65\x6E\x73\x69\x74\x79\x00\x00\x00\x00\x06\x00\x07\x00\x1F\x00\x00\x00\x15\x00\x00\x00\x77\x5F\x66\x6F"
"\x67\x64\x65\x70\x74\x68\x62\x69\x61\x73\x00\x00\x06\x00\x05\x00\x1F\x00\x00\x00\x16\x00\x00\x00\x65\x70\x61\x64\x37\x00\x00\x00"
"\x05\x00\x03\x00\x21\x00\x00\x00\x00\x00\x00\x00\x05\x00\x06\x00\x27\x00\x00\x00\x67\x6C\x5F\x46\x72\x61\x67\x43\x6F\x6F\x72\x64"
"\x00\x00\x00\x00\x05\x00\x07\x00\x38\x00\x00\x00\x5F\x63\x76\x61\x72\x5F\x72\x5F\x66\x6F\x67\x5F\x65\x78\x70\x32\x00\x00\x00\x00"
"\x05\x00\x03\x00\x3F\x00\x00\x00\x66\x61\x63\x00\x05\x00\x04\x00\x5B\x00\x00\x00\x73\x6B\x79\x62\x6F\x78\x00\x00\x05\x00\x06\x00"
"\x5F\x00\x00\x00\x73\x5F\x72\x65\x66\x6C\x65\x63\x74\x63\x75\x62\x65\x00\x00\x00\x05\x00\x03\x00\x62\x00\x00\x00\x70\x6F\x73\x00"
"\x05\x00\x05\x00\x66\x00\x00\x00\x6F\x75\x74\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x04\x00\x67\x00\x00\x00\x70\x61\x72\x61"
"\x6D\x00\x00\x00\x05\x00\x05\x00\x6F\x00\x00\x00\x6C\x69\x67\x68\x74\x62\x6C\x6F\x63\x6B\x00\x00\x06\x00\x07\x00\x6F\x00\x00\x00"
"\x00\x00\x00\x00\x6C\x5F\x63\x75\x62\x65\x6D\x61\x74\x72\x69\x78\x00\x00\x00\x00\x06\x00\x07\x00\x6F\x00\x00\x00\x01\x00\x00\x00"
"\x6C\x5F\x6C\x69\x67\x68\x74\x70\x6F\x73\x69\x74\x69\x6F\x6E\x00\x06\x00\x05\x00\x6F\x00\x00\x00\x02\x00\x00\x00\x6C\x70\x61\x64"
"\x31\x00\x00\x00\x06\x00\x07\x00\x6F\x00\x00\x00\x03\x00\x00\x00\x6C\x5F\x6C\x69\x67\x68\x74\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00"
"\x06\x00\x05\x00\x6F\x00\x00\x00\x04\x00\x00\x00\x6C\x70\x61\x64\x32\x00\x00\x00\x06\x00\x08\x00\x6F\x00\x00\x00\x05\x00\x00\x00"
"\x6C\x5F\x6C\x69\x67\x68\x74\x63\x6F\x6C\x6F\x75\x72\x73\x63\x61\x6C\x65\x00\x00\x06\x00\x07\x00\x6F\x00\x00\x00\x06\x00\x00\x00"
"\x6C\x5F\x6C\x69\x67\x68\x74\x72\x61\x64\x69\x75\x73\x00\x00\x00\x06\x00\x07\x00\x6F\x00\x00\x00\x07\x00\x00\x00\x6C\x5F\x73\x68"
"\x61\x64\x6F\x77\x6D\x61\x70\x70\x72\x6F\x6A\x00\x06\x00\x08\x00\x6F\x00\x00\x00\x08\x00\x00\x00\x6C\x5F\x73\x68\x61\x64\x6F\x77"
"\x6D\x61\x70\x73\x63\x61\x6C\x65\x00\x00\x00\x00\x06\x00\x05\x00\x6F\x00\x00\x00\x09\x00\x00\x00\x6C\x70\x61\x64\x33\x00\x00\x00"
"\x05\x00\x03\x00\x71\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x0E\x00\x00\x00\x01\x00\x00\x00\x15\x00\x00\x00\x47\x00\x04\x00"
"\x1D\x00\x00\x00\x06\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00\x1F\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00"
"\x1F\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00"
"\x10\x00\x00\x00\x48\x00\x04\x00\x1F\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x01\x00\x00\x00"
"\x23\x00\x00\x00\x40\x00\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00"
"\x1F\x00\x00\x00\x02\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x02\x00\x00\x00\x23\x00\x00\x00\x80\x00\x00\x00"
"\x48\x00\x05\x00\x1F\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x03\x00\x00\x00"
"\x23\x00\x00\x00\xC0\x00\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00\xCC\x00\x00\x00\x48\x00\x05\x00"
"\x1F\x00\x00\x00\x05\x00\x00\x00\x23\x00\x00\x00\xD0\x00\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x06\x00\x00\x00\x23\x00\x00\x00"
"\xDC\x00\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x07\x00\x00\x00\x23\x00\x00\x00\xE0\x00\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00"
"\x08\x00\x00\x00\x23\x00\x00\x00\xEC\x00\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x09\x00\x00\x00\x23\x00\x00\x00\xF0\x00\x00\x00"
"\x48\x00\x05\x00\x1F\x00\x00\x00\x0A\x00\x00\x00\x23\x00\x00\x00\xFC\x00\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x0B\x00\x00\x00"
"\x23\x00\x00\x00\x00\x01\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x0C\x00\x00\x00\x23\x00\x00\x00\x40\x01\x00\x00\x48\x00\x05\x00"
"\x1F\x00\x00\x00\x0D\x00\x00\x00\x23\x00\x00\x00\x4C\x01\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x0E\x00\x00\x00\x23\x00\x00\x00"
"\x50\x01\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x0F\x00\x00\x00\x23\x00\x00\x00\x5C\x01\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00"
"\x10\x00\x00\x00\x23\x00\x00\x00\x60\x01\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x11\x00\x00\x00\x23\x00\x00\x00\x6C\x01\x00\x00"
"\x48\x00\x05\x00\x1F\x00\x00\x00\x12\x00\x00\x00\x23\x00\x00\x00\x70\x01\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x13\x00\x00\x00"
"\x23\x00\x00\x00\x80\x01\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x14\x00\x00\x00\x23\x00\x00\x00\x90\x01\x00\x00\x48\x00\x05\x00"
"\x1F\x00\x00\x00\x15\x00\x00\x00\x23\x00\x00\x00\x94\x01\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x16\x00\x00\x00\x23\x00\x00\x00"
"\x98\x01\x00\x00\x47\x00\x03\x00\x1F\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x21\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00"
"\x47\x00\x04\x00\x21\x00\x00\x00\x21\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x27\x00\x00\x00\x0B\x00\x00\x00\x0F\x00\x00\x00"
"\x47\x00\x04\x00\x38\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x47\x00\x04\x00\x5F\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00"
"\x47\x00\x04\x00\x5F\x00\x00\x00\x21\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x62\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00"
"\x47\x00\x04\x00\x66\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x48\x00\x04\x00\x6F\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00"
"\x48\x00\x05\x00\x6F\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00\x6F\x00\x00\x00\x00\x00\x00\x00"
"\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x05\x00\x6F\x00\x00\x00\x01\x00\x00\x00\x23\x00\x00\x00\x40\x00\x00\x00\x48\x00\x05\x00"
"\x6F\x00\x00\x00\x02\x00\x00\x00\x23\x00\x00\x00\x4C\x00\x00\x00\x48\x00\x05\x00\x6F\x00\x00\x00\x03\x00\x00\x00\x23\x00\x00\x00"
"\x50\x00\x00\x00\x48\x00\x05\x00\x6F\x00\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00\x5C\x00\x00\x00\x48\x00\x05\x00\x6F\x00\x00\x00"
"\x05\x00\x00\x00\x23\x00\x00\x00\x60\x00\x00\x00\x48\x00\x05\x00\x6F\x00\x00\x00\x06\x00\x00\x00\x23\x00\x00\x00\x6C\x00\x00\x00"
"\x48\x00\x05\x00\x6F\x00\x00\x00\x07\x00\x00\x00\x23\x00\x00\x00\x70\x00\x00\x00\x48\x00\x05\x00\x6F\x00\x00\x00\x08\x00\x00\x00"
"\x23\x00\x00\x00\x80\x00\x00\x00\x48\x00\x05\x00\x6F\x00\x00\x00\x09\x00\x00\x00\x23\x00\x00\x00\x88\x00\x00\x00\x47\x00\x03\x00"
"\x6F\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x71\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x71\x00\x00\x00"
"\x21\x00\x00\x00\x01\x00\x00\x00\x13\x00\x02\x00\x02\x00\x00\x00\x21\x00\x03\x00\x03\x00\x00\x00\x02\x00\x00\x00\x16\x00\x03\x00"
"\x06\x00\x00\x00\x20\x00\x00\x00\x17\x00\x04\x00\x07\x00\x00\x00\x06\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00\x08\x00\x00\x00"
"\x07\x00\x00\x00\x07\x00\x00\x00\x21\x00\x04\x00\x09\x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00\x15\x00\x04\x00\x0D\x00\x00\x00"
"\x20\x00\x00\x00\x01\x00\x00\x00\x32\x00\x04\x00\x0D\x00\x00\x00\x0E\x00\x00\x00\x15\x00\x00\x00\x2B\x00\x04\x00\x0D\x00\x00\x00"
"\x0F\x00\x00\x00\x00\x00\x00\x00\x14\x00\x02\x00\x10\x00\x00\x00\x34\x00\x06\x00\x10\x00\x00\x00\x11\x00\x00\x00\xAB\x00\x00\x00"
"\x0E\x00\x00\x00\x0F\x00\x00\x00\x34\x00\x05\x00\x10\x00\x00\x00\x12\x00\x00\x00\xA8\x00\x00\x00\x11\x00\x00\x00\x20\x00\x04\x00"
"\x17\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x17\x00\x04\x00\x19\x00\x00\x00\x06\x00\x00\x00\x04\x00\x00\x00\x18\x00\x04\x00"
"\x1A\x00\x00\x00\x19\x00\x00\x00\x04\x00\x00\x00\x15\x00\x04\x00\x1B\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x2B\x00\x04\x00"
"\x1B\x00\x00\x00\x1C\x00\x00\x00\x04\x00\x00\x00\x1C\x00\x04\x00\x1D\x00\x00\x00\x19\x00\x00\x00\x1C\x00\x00\x00\x17\x00\x04\x00"
"\x1E\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x1E\x00\x19\x00\x1F\x00\x00\x00\x1A\x00\x00\x00\x1A\x00\x00\x00\x1A\x00\x00\x00"
"\x07\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00"
"\x1D\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x19\x00\x00\x00"
"\x19\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x1E\x00\x00\x00\x20\x00\x04\x00\x20\x00\x00\x00\x02\x00\x00\x00\x1F\x00\x00\x00"
"\x3B\x00\x04\x00\x20\x00\x00\x00\x21\x00\x00\x00\x02\x00\x00\x00\x2B\x00\x04\x00\x0D\x00\x00\x00\x22\x00\x00\x00\x14\x00\x00\x00"
"\x20\x00\x04\x00\x23\x00\x00\x00\x02\x00\x00\x00\x06\x00\x00\x00\x20\x00\x04\x00\x26\x00\x00\x00\x01\x00\x00\x00\x19\x00\x00\x00"
"\x3B\x00\x04\x00\x26\x00\x00\x00\x27\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00\x1B\x00\x00\x00\x28\x00\x00\x00\x02\x00\x00\x00"
"\x20\x00\x04\x00\x29\x00\x00\x00\x01\x00\x00\x00\x06\x00\x00\x00\x2B\x00\x04\x00\x1B\x00\x00\x00\x2D\x00\x00\x00\x03\x00\x00\x00"
"\x2B\x00\x04\x00\x06\x00\x00\x00\x31\x00\x00\x00\x00\x00\x00\x00\x2B\x00\x04\x00\x0D\x00\x00\x00\x33\x00\x00\x00\x15\x00\x00\x00"
"\x32\x00\x04\x00\x0D\x00\x00\x00\x38\x00\x00\x00\x00\x01\x00\x00\x34\x00\x06\x00\x10\x00\x00\x00\x39\x00\x00\x00\xAB\x00\x00\x00"
"\x38\x00\x00\x00\x0F\x00\x00\x00\x2B\x00\x04\x00\x06\x00\x00\x00\x41\x00\x00\x00\x3B\xAA\xB8\x3F\x2B\x00\x04\x00\x06\x00\x00\x00"
"\x45\x00\x00\x00\x00\x00\x80\x3F\x2B\x00\x04\x00\x0D\x00\x00\x00\x46\x00\x00\x00\x13\x00\x00\x00\x20\x00\x04\x00\x50\x00\x00\x00"
"\x02\x00\x00\x00\x19\x00\x00\x00\x20\x00\x04\x00\x5A\x00\x00\x00\x07\x00\x00\x00\x19\x00\x00\x00\x19\x00\x09\x00\x5C\x00\x00\x00"
"\x06\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x1B\x00\x03\x00"
"\x5D\x00\x00\x00\x5C\x00\x00\x00\x20\x00\x04\x00\x5E\x00\x00\x00\x00\x00\x00\x00\x5D\x00\x00\x00\x3B\x00\x04\x00\x5E\x00\x00\x00"
"\x5F\x00\x00\x00\x00\x00\x00\x00\x20\x00\x04\x00\x61\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00\x61\x00\x00\x00"
"\x62\x00\x00\x00\x01\x00\x00\x00\x20\x00\x04\x00\x65\x00\x00\x00\x03\x00\x00\x00\x19\x00\x00\x00\x3B\x00\x04\x00\x65\x00\x00\x00"
"\x66\x00\x00\x00\x03\x00\x00\x00\x1E\x00\x0C\x00\x6F\x00\x00\x00\x1A\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00"
"\x06\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x19\x00\x00\x00\x1E\x00\x00\x00\x1E\x00\x00\x00\x20\x00\x04\x00\x70\x00\x00\x00"
"\x02\x00\x00\x00\x6F\x00\x00\x00\x3B\x00\x04\x00\x70\x00\x00\x00\x71\x00\x00\x00\x02\x00\x00\x00\x36\x00\x05\x00\x02\x00\x00\x00"
"\x04\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\xF8\x00\x02\x00\x05\x00\x00\x00\x3B\x00\x04\x00\x5A\x00\x00\x00\x5B\x00\x00\x00"
"\x07\x00\x00\x00\x3B\x00\x04\x00\x08\x00\x00\x00\x67\x00\x00\x00\x07\x00\x00\x00\x3D\x00\x04\x00\x5D\x00\x00\x00\x60\x00\x00\x00"
"\x5F\x00\x00\x00\x3D\x00\x04\x00\x07\x00\x00\x00\x63\x00\x00\x00\x62\x00\x00\x00\x57\x00\x05\x00\x19\x00\x00\x00\x64\x00\x00\x00"
"\x60\x00\x00\x00\x63\x00\x00\x00\x3E\x00\x03\x00\x5B\x00\x00\x00\x64\x00\x00\x00\x3D\x00\x04\x00\x19\x00\x00\x00\x68\x00\x00\x00"
"\x5B\x00\x00\x00\x4F\x00\x08\x00\x07\x00\x00\x00\x69\x00\x00\x00\x68\x00\x00\x00\x68\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00"
"\x02\x00\x00\x00\x3E\x00\x03\x00\x67\x00\x00\x00\x69\x00\x00\x00\x39\x00\x05\x00\x07\x00\x00\x00\x6A\x00\x00\x00\x0B\x00\x00\x00"
"\x67\x00\x00\x00\x51\x00\x05\x00\x06\x00\x00\x00\x6B\x00\x00\x00\x6A\x00\x00\x00\x00\x00\x00\x00\x51\x00\x05\x00\x06\x00\x00\x00"
"\x6C\x00\x00\x00\x6A\x00\x00\x00\x01\x00\x00\x00\x51\x00\x05\x00\x06\x00\x00\x00\x6D\x00\x00\x00\x6A\x00\x00\x00\x02\x00\x00\x00"
"\x50\x00\x07\x00\x19\x00\x00\x00\x6E\x00\x00\x00\x6B\x00\x00\x00\x6C\x00\x00\x00\x6D\x00\x00\x00\x45\x00\x00\x00\x3E\x00\x03\x00"
"\x66\x00\x00\x00\x6E\x00\x00\x00\xFD\x00\x01\x00\x38\x00\x01\x00\x36\x00\x05\x00\x07\x00\x00\x00\x0B\x00\x00\x00\x00\x00\x00\x00"
"\x09\x00\x00\x00\x37\x00\x03\x00\x08\x00\x00\x00\x0A\x00\x00\x00\xF8\x00\x02\x00\x0C\x00\x00\x00\x3B\x00\x04\x00\x17\x00\x00\x00"
"\x18\x00\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00\x17\x00\x00\x00\x3F\x00\x00\x00\x07\x00\x00\x00\xF7\x00\x03\x00\x14\x00\x00\x00"
"\x00\x00\x00\x00\xFA\x00\x04\x00\x12\x00\x00\x00\x13\x00\x00\x00\x14\x00\x00\x00\xF8\x00\x02\x00\x13\x00\x00\x00\x3D\x00\x04\x00"
"\x07\x00\x00\x00\x15\x00\x00\x00\x0A\x00\x00\x00\xFE\x00\x02\x00\x15\x00\x00\x00\xF8\x00\x02\x00\x14\x00\x00\x00\x41\x00\x05\x00"
"\x23\x00\x00\x00\x24\x00\x00\x00\x21\x00\x00\x00\x22\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x25\x00\x00\x00\x24\x00\x00\x00"
"\x41\x00\x05\x00\x29\x00\x00\x00\x2A\x00\x00\x00\x27\x00\x00\x00\x28\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x2B\x00\x00\x00"
"\x2A\x00\x00\x00\x85\x00\x05\x00\x06\x00\x00\x00\x2C\x00\x00\x00\x25\x00\x00\x00\x2B\x00\x00\x00\x41\x00\x05\x00\x29\x00\x00\x00"
"\x2E\x00\x00\x00\x27\x00\x00\x00\x2D\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x2F\x00\x00\x00\x2E\x00\x00\x00\x88\x00\x05\x00"
"\x06\x00\x00\x00\x30\x00\x00\x00\x2C\x00\x00\x00\x2F\x00\x00\x00\x3E\x00\x03\x00\x18\x00\x00\x00\x30\x00\x00\x00\x3D\x00\x04\x00"
"\x06\x00\x00\x00\x32\x00\x00\x00\x18\x00\x00\x00\x41\x00\x05\x00\x23\x00\x00\x00\x34\x00\x00\x00\x21\x00\x00\x00\x33\x00\x00\x00"
"\x3D\x00\x04\x00\x06\x00\x00\x00\x35\x00\x00\x00\x34\x00\x00\x00\x83\x00\x05\x00\x06\x00\x00\x00\x36\x00\x00\x00\x32\x00\x00\x00"
"\x35\x00\x00\x00\x0C\x00\x07\x00\x06\x00\x00\x00\x37\x00\x00\x00\x01\x00\x00\x00\x28\x00\x00\x00\x31\x00\x00\x00\x36\x00\x00\x00"
"\x3E\x00\x03\x00\x18\x00\x00\x00\x37\x00\x00\x00\xF7\x00\x03\x00\x3B\x00\x00\x00\x00\x00\x00\x00\xFA\x00\x04\x00\x39\x00\x00\x00"
"\x3A\x00\x00\x00\x3B\x00\x00\x00\xF8\x00\x02\x00\x3A\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x3C\x00\x00\x00\x18\x00\x00\x00"
"\x3D\x00\x04\x00\x06\x00\x00\x00\x3D\x00\x00\x00\x18\x00\x00\x00\x85\x00\x05\x00\x06\x00\x00\x00\x3E\x00\x00\x00\x3D\x00\x00\x00"
"\x3C\x00\x00\x00\x3E\x00\x03\x00\x18\x00\x00\x00\x3E\x00\x00\x00\xF9\x00\x02\x00\x3B\x00\x00\x00\xF8\x00\x02\x00\x3B\x00\x00\x00"
"\x3D\x00\x04\x00\x06\x00\x00\x00\x40\x00\x00\x00\x18\x00\x00\x00\x85\x00\x05\x00\x06\x00\x00\x00\x42\x00\x00\x00\x40\x00\x00\x00"
"\x41\x00\x00\x00\x7F\x00\x04\x00\x06\x00\x00\x00\x43\x00\x00\x00\x42\x00\x00\x00\x0C\x00\x06\x00\x06\x00\x00\x00\x44\x00\x00\x00"
"\x01\x00\x00\x00\x1D\x00\x00\x00\x43\x00\x00\x00\x3E\x00\x03\x00\x3F\x00\x00\x00\x44\x00\x00\x00\x41\x00\x06\x00\x23\x00\x00\x00"
"\x47\x00\x00\x00\x21\x00\x00\x00\x46\x00\x00\x00\x2D\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x48\x00\x00\x00\x47\x00\x00\x00"
"\x83\x00\x05\x00\x06\x00\x00\x00\x49\x00\x00\x00\x45\x00\x00\x00\x48\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x4A\x00\x00\x00"
"\x3F\x00\x00\x00\x0C\x00\x08\x00\x06\x00\x00\x00\x4B\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x00\x00\x4A\x00\x00\x00\x31\x00\x00\x00"
"\x45\x00\x00\x00\x41\x00\x06\x00\x23\x00\x00\x00\x4C\x00\x00\x00\x21\x00\x00\x00\x46\x00\x00\x00\x2D\x00\x00\x00\x3D\x00\x04\x00"
"\x06\x00\x00\x00\x4D\x00\x00\x00\x4C\x00\x00\x00\x85\x00\x05\x00\x06\x00\x00\x00\x4E\x00\x00\x00\x4B\x00\x00\x00\x4D\x00\x00\x00"
"\x81\x00\x05\x00\x06\x00\x00\x00\x4F\x00\x00\x00\x49\x00\x00\x00\x4E\x00\x00\x00\x3E\x00\x03\x00\x3F\x00\x00\x00\x4F\x00\x00\x00"
"\x41\x00\x05\x00\x50\x00\x00\x00\x51\x00\x00\x00\x21\x00\x00\x00\x46\x00\x00\x00\x3D\x00\x04\x00\x19\x00\x00\x00\x52\x00\x00\x00"
"\x51\x00\x00\x00\x4F\x00\x08\x00\x07\x00\x00\x00\x53\x00\x00\x00\x52\x00\x00\x00\x52\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00"
"\x02\x00\x00\x00\x3D\x00\x04\x00\x07\x00\x00\x00\x54\x00\x00\x00\x0A\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x55\x00\x00\x00"
"\x3F\x00\x00\x00\x50\x00\x06\x00\x07\x00\x00\x00\x56\x00\x00\x00\x55\x00\x00\x00\x55\x00\x00\x00\x55\x00\x00\x00\x0C\x00\x08\x00"
"\x07\x00\x00\x00\x57\x00\x00\x00\x01\x00\x00\x00\x2E\x00\x00\x00\x53\x00\x00\x00\x54\x00\x00\x00\x56\x00\x00\x00\xFE\x00\x02\x00"
"\x57\x00\x00\x00\x38\x00\x01\x00"},
"\x0E\x00\x00\x00\x1E\x00\x03\x00\x40\x00\x00\x00\x07\x00\x00\x00\x20\x00\x04\x00\x41\x00\x00\x00\x03\x00\x00\x00\x40\x00\x00\x00"
"\x3B\x00\x04\x00\x41\x00\x00\x00\x42\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00\x44\x00\x00\x00\x03\x00\x00\x00\x07\x00\x00\x00"
"\x32\x00\x04\x00\x16\x00\x00\x00\x46\x00\x00\x00\x00\x01\x00\x00\x32\x00\x04\x00\x16\x00\x00\x00\x47\x00\x00\x00\x15\x00\x00\x00"
"\x1E\x00\x0C\x00\x48\x00\x00\x00\x0D\x00\x00\x00\x0E\x00\x00\x00\x06\x00\x00\x00\x0E\x00\x00\x00\x06\x00\x00\x00\x0E\x00\x00\x00"
"\x06\x00\x00\x00\x07\x00\x00\x00\x12\x00\x00\x00\x12\x00\x00\x00\x20\x00\x04\x00\x49\x00\x00\x00\x02\x00\x00\x00\x48\x00\x00\x00"
"\x3B\x00\x04\x00\x49\x00\x00\x00\x4A\x00\x00\x00\x02\x00\x00\x00\x20\x00\x04\x00\x4B\x00\x00\x00\x01\x00\x00\x00\x12\x00\x00\x00"
"\x3B\x00\x04\x00\x4B\x00\x00\x00\x4C\x00\x00\x00\x01\x00\x00\x00\x20\x00\x04\x00\x4D\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00"
"\x3B\x00\x04\x00\x4D\x00\x00\x00\x4E\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x4B\x00\x00\x00\x4F\x00\x00\x00\x01\x00\x00\x00"
"\x3B\x00\x04\x00\x1B\x00\x00\x00\x50\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x51\x00\x00\x00\x01\x00\x00\x00"
"\x3B\x00\x04\x00\x1B\x00\x00\x00\x52\x00\x00\x00\x01\x00\x00\x00\x36\x00\x05\x00\x02\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00"
"\x03\x00\x00\x00\xF8\x00\x02\x00\x05\x00\x00\x00\x3D\x00\x04\x00\x0E\x00\x00\x00\x3A\x00\x00\x00\x1C\x00\x00\x00\x41\x00\x05\x00"
"\x3C\x00\x00\x00\x3D\x00\x00\x00\x15\x00\x00\x00\x3B\x00\x00\x00\x3D\x00\x04\x00\x0E\x00\x00\x00\x3E\x00\x00\x00\x3D\x00\x00\x00"
"\x83\x00\x05\x00\x0E\x00\x00\x00\x3F\x00\x00\x00\x3A\x00\x00\x00\x3E\x00\x00\x00\x3E\x00\x03\x00\x39\x00\x00\x00\x3F\x00\x00\x00"
"\x39\x00\x04\x00\x07\x00\x00\x00\x43\x00\x00\x00\x09\x00\x00\x00\x41\x00\x05\x00\x44\x00\x00\x00\x45\x00\x00\x00\x42\x00\x00\x00"
"\x17\x00\x00\x00\x3E\x00\x03\x00\x45\x00\x00\x00\x43\x00\x00\x00\xFD\x00\x01\x00\x38\x00\x01\x00\x36\x00\x05\x00\x07\x00\x00\x00"
"\x09\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\xF8\x00\x02\x00\x0A\x00\x00\x00\x3B\x00\x04\x00\x0B\x00\x00\x00\x0C\x00\x00\x00"
"\x07\x00\x00\x00\x41\x00\x05\x00\x18\x00\x00\x00\x19\x00\x00\x00\x15\x00\x00\x00\x17\x00\x00\x00\x3D\x00\x04\x00\x0D\x00\x00\x00"
"\x1A\x00\x00\x00\x19\x00\x00\x00\x3D\x00\x04\x00\x0E\x00\x00\x00\x1D\x00\x00\x00\x1C\x00\x00\x00\x51\x00\x05\x00\x06\x00\x00\x00"
"\x1F\x00\x00\x00\x1D\x00\x00\x00\x00\x00\x00\x00\x51\x00\x05\x00\x06\x00\x00\x00\x20\x00\x00\x00\x1D\x00\x00\x00\x01\x00\x00\x00"
"\x51\x00\x05\x00\x06\x00\x00\x00\x21\x00\x00\x00\x1D\x00\x00\x00\x02\x00\x00\x00\x50\x00\x07\x00\x07\x00\x00\x00\x22\x00\x00\x00"
"\x1F\x00\x00\x00\x20\x00\x00\x00\x21\x00\x00\x00\x1E\x00\x00\x00\x91\x00\x05\x00\x07\x00\x00\x00\x23\x00\x00\x00\x1A\x00\x00\x00"
"\x22\x00\x00\x00\x3E\x00\x03\x00\x0C\x00\x00\x00\x23\x00\x00\x00\x41\x00\x05\x00\x26\x00\x00\x00\x27\x00\x00\x00\x0C\x00\x00\x00"
"\x25\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x28\x00\x00\x00\x27\x00\x00\x00\x85\x00\x05\x00\x06\x00\x00\x00\x29\x00\x00\x00"
"\x28\x00\x00\x00\x24\x00\x00\x00\x41\x00\x05\x00\x26\x00\x00\x00\x2A\x00\x00\x00\x0C\x00\x00\x00\x25\x00\x00\x00\x3E\x00\x03\x00"
"\x2A\x00\x00\x00\x29\x00\x00\x00\x41\x00\x05\x00\x26\x00\x00\x00\x2C\x00\x00\x00\x0C\x00\x00\x00\x2B\x00\x00\x00\x3D\x00\x04\x00"
"\x06\x00\x00\x00\x2D\x00\x00\x00\x2C\x00\x00\x00\x41\x00\x05\x00\x26\x00\x00\x00\x2F\x00\x00\x00\x0C\x00\x00\x00\x2E\x00\x00\x00"
"\x3D\x00\x04\x00\x06\x00\x00\x00\x30\x00\x00\x00\x2F\x00\x00\x00\x81\x00\x05\x00\x06\x00\x00\x00\x31\x00\x00\x00\x2D\x00\x00\x00"
"\x30\x00\x00\x00\x88\x00\x05\x00\x06\x00\x00\x00\x33\x00\x00\x00\x31\x00\x00\x00\x32\x00\x00\x00\x41\x00\x05\x00\x26\x00\x00\x00"
"\x34\x00\x00\x00\x0C\x00\x00\x00\x2B\x00\x00\x00\x3E\x00\x03\x00\x34\x00\x00\x00\x33\x00\x00\x00\x3D\x00\x04\x00\x07\x00\x00\x00"
"\x35\x00\x00\x00\x0C\x00\x00\x00\xFE\x00\x02\x00\x35\x00\x00\x00\x38\x00\x01\x00\x03\x02\x23\x07\x00\x00\x01\x00\x07\x00\x08\x00"
"\x72\x00\x00\x00\x00\x00\x00\x00\x11\x00\x02\x00\x01\x00\x00\x00\x0B\x00\x06\x00\x01\x00\x00\x00\x47\x4C\x53\x4C\x2E\x73\x74\x64"
"\x2E\x34\x35\x30\x00\x00\x00\x00\x0E\x00\x03\x00\x00\x00\x00\x00\x01\x00\x00\x00\x0F\x00\x08\x00\x04\x00\x00\x00\x04\x00\x00\x00"
"\x6D\x61\x69\x6E\x00\x00\x00\x00\x27\x00\x00\x00\x62\x00\x00\x00\x66\x00\x00\x00\x10\x00\x03\x00\x04\x00\x00\x00\x07\x00\x00\x00"
"\x03\x00\x03\x00\x02\x00\x00\x00\xC2\x01\x00\x00\x05\x00\x04\x00\x04\x00\x00\x00\x6D\x61\x69\x6E\x00\x00\x00\x00\x05\x00\x05\x00"
"\x0B\x00\x00\x00\x66\x6F\x67\x33\x28\x76\x66\x33\x3B\x00\x00\x00\x05\x00\x06\x00\x0A\x00\x00\x00\x72\x65\x67\x75\x6C\x61\x72\x63"
"\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x04\x00\x0E\x00\x00\x00\x5F\x46\x4F\x47\x00\x00\x00\x00\x05\x00\x03\x00\x18\x00\x00\x00"
"\x7A\x00\x00\x00\x05\x00\x05\x00\x1F\x00\x00\x00\x65\x6E\x74\x69\x74\x79\x62\x6C\x6F\x63\x6B\x00\x06\x00\x07\x00\x1F\x00\x00\x00"
"\x00\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x76\x69\x65\x77\x70\x72\x6F\x6A\x00\x06\x00\x05\x00\x1F\x00\x00\x00\x01\x00\x00\x00"
"\x6D\x5F\x6D\x6F\x64\x65\x6C\x00\x06\x00\x06\x00\x1F\x00\x00\x00\x02\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x69\x6E\x76\x00\x00"
"\x06\x00\x06\x00\x1F\x00\x00\x00\x03\x00\x00\x00\x65\x5F\x65\x79\x65\x70\x6F\x73\x00\x00\x00\x00\x06\x00\x05\x00\x1F\x00\x00\x00"
"\x04\x00\x00\x00\x65\x5F\x74\x69\x6D\x65\x00\x00\x06\x00\x07\x00\x1F\x00\x00\x00\x05\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F"
"\x61\x6D\x62\x69\x65\x6E\x74\x00\x06\x00\x05\x00\x1F\x00\x00\x00\x06\x00\x00\x00\x65\x70\x61\x64\x31\x00\x00\x00\x06\x00\x06\x00"
"\x1F\x00\x00\x00\x07\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x64\x69\x72\x00\x06\x00\x05\x00\x1F\x00\x00\x00\x08\x00\x00\x00"
"\x65\x70\x61\x64\x32\x00\x00\x00\x06\x00\x06\x00\x1F\x00\x00\x00\x09\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x6D\x75\x6C\x00"
"\x06\x00\x05\x00\x1F\x00\x00\x00\x0A\x00\x00\x00\x65\x70\x61\x64\x33\x00\x00\x00\x06\x00\x06\x00\x1F\x00\x00\x00\x0B\x00\x00\x00"
"\x65\x5F\x6C\x6D\x73\x63\x61\x6C\x65\x73\x00\x00\x06\x00\x07\x00\x1F\x00\x00\x00\x0C\x00\x00\x00\x65\x5F\x75\x70\x70\x65\x72\x63"
"\x6F\x6C\x6F\x75\x72\x00\x00\x00\x06\x00\x05\x00\x1F\x00\x00\x00\x0D\x00\x00\x00\x65\x70\x61\x64\x34\x00\x00\x00\x06\x00\x07\x00"
"\x1F\x00\x00\x00\x0E\x00\x00\x00\x65\x5F\x6C\x6F\x77\x65\x72\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x06\x00\x05\x00\x1F\x00\x00\x00"
"\x0F\x00\x00\x00\x65\x70\x61\x64\x35\x00\x00\x00\x06\x00\x06\x00\x1F\x00\x00\x00\x10\x00\x00\x00\x65\x5F\x67\x6C\x6F\x77\x6D\x6F"
"\x64\x00\x00\x00\x06\x00\x05\x00\x1F\x00\x00\x00\x11\x00\x00\x00\x65\x70\x61\x64\x36\x00\x00\x00\x06\x00\x07\x00\x1F\x00\x00\x00"
"\x12\x00\x00\x00\x65\x5F\x63\x6F\x6C\x6F\x75\x72\x69\x64\x65\x6E\x74\x00\x00\x00\x06\x00\x07\x00\x1F\x00\x00\x00\x13\x00\x00\x00"
"\x77\x5F\x66\x6F\x67\x63\x6F\x6C\x6F\x75\x72\x73\x00\x00\x00\x00\x06\x00\x07\x00\x1F\x00\x00\x00\x14\x00\x00\x00\x77\x5F\x66\x6F"
"\x67\x64\x65\x6E\x73\x69\x74\x79\x00\x00\x00\x00\x06\x00\x07\x00\x1F\x00\x00\x00\x15\x00\x00\x00\x77\x5F\x66\x6F\x67\x64\x65\x70"
"\x74\x68\x62\x69\x61\x73\x00\x00\x06\x00\x05\x00\x1F\x00\x00\x00\x16\x00\x00\x00\x65\x70\x61\x64\x37\x00\x00\x00\x05\x00\x03\x00"
"\x21\x00\x00\x00\x00\x00\x00\x00\x05\x00\x06\x00\x27\x00\x00\x00\x67\x6C\x5F\x46\x72\x61\x67\x43\x6F\x6F\x72\x64\x00\x00\x00\x00"
"\x05\x00\x07\x00\x38\x00\x00\x00\x5F\x63\x76\x61\x72\x5F\x72\x5F\x66\x6F\x67\x5F\x65\x78\x70\x32\x00\x00\x00\x00\x05\x00\x03\x00"
"\x3F\x00\x00\x00\x66\x61\x63\x00\x05\x00\x04\x00\x5B\x00\x00\x00\x73\x6B\x79\x62\x6F\x78\x00\x00\x05\x00\x06\x00\x5F\x00\x00\x00"
"\x73\x5F\x72\x65\x66\x6C\x65\x63\x74\x63\x75\x62\x65\x00\x00\x00\x05\x00\x03\x00\x62\x00\x00\x00\x70\x6F\x73\x00\x05\x00\x05\x00"
"\x66\x00\x00\x00\x6F\x75\x74\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x04\x00\x67\x00\x00\x00\x70\x61\x72\x61\x6D\x00\x00\x00"
"\x05\x00\x05\x00\x6F\x00\x00\x00\x6C\x69\x67\x68\x74\x62\x6C\x6F\x63\x6B\x00\x00\x06\x00\x07\x00\x6F\x00\x00\x00\x00\x00\x00\x00"
"\x6C\x5F\x63\x75\x62\x65\x6D\x61\x74\x72\x69\x78\x00\x00\x00\x00\x06\x00\x07\x00\x6F\x00\x00\x00\x01\x00\x00\x00\x6C\x5F\x6C\x69"
"\x67\x68\x74\x70\x6F\x73\x69\x74\x69\x6F\x6E\x00\x06\x00\x05\x00\x6F\x00\x00\x00\x02\x00\x00\x00\x6C\x70\x61\x64\x31\x00\x00\x00"
"\x06\x00\x07\x00\x6F\x00\x00\x00\x03\x00\x00\x00\x6C\x5F\x6C\x69\x67\x68\x74\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x06\x00\x05\x00"
"\x6F\x00\x00\x00\x04\x00\x00\x00\x6C\x70\x61\x64\x32\x00\x00\x00\x06\x00\x08\x00\x6F\x00\x00\x00\x05\x00\x00\x00\x6C\x5F\x6C\x69"
"\x67\x68\x74\x63\x6F\x6C\x6F\x75\x72\x73\x63\x61\x6C\x65\x00\x00\x06\x00\x07\x00\x6F\x00\x00\x00\x06\x00\x00\x00\x6C\x5F\x6C\x69"
"\x67\x68\x74\x72\x61\x64\x69\x75\x73\x00\x00\x00\x06\x00\x07\x00\x6F\x00\x00\x00\x07\x00\x00\x00\x6C\x5F\x73\x68\x61\x64\x6F\x77"
"\x6D\x61\x70\x70\x72\x6F\x6A\x00\x06\x00\x08\x00\x6F\x00\x00\x00\x08\x00\x00\x00\x6C\x5F\x73\x68\x61\x64\x6F\x77\x6D\x61\x70\x73"
"\x63\x61\x6C\x65\x00\x00\x00\x00\x06\x00\x05\x00\x6F\x00\x00\x00\x09\x00\x00\x00\x6C\x70\x61\x64\x33\x00\x00\x00\x05\x00\x03\x00"
"\x71\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x0E\x00\x00\x00\x01\x00\x00\x00\x15\x00\x00\x00\x47\x00\x04\x00\x1D\x00\x00\x00"
"\x06\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00\x1F\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00"
"\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00"
"\x48\x00\x04\x00\x1F\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x01\x00\x00\x00\x23\x00\x00\x00"
"\x40\x00\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00\x1F\x00\x00\x00"
"\x02\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x02\x00\x00\x00\x23\x00\x00\x00\x80\x00\x00\x00\x48\x00\x05\x00"
"\x1F\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x03\x00\x00\x00\x23\x00\x00\x00"
"\xC0\x00\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00\xCC\x00\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00"
"\x05\x00\x00\x00\x23\x00\x00\x00\xD0\x00\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x06\x00\x00\x00\x23\x00\x00\x00\xDC\x00\x00\x00"
"\x48\x00\x05\x00\x1F\x00\x00\x00\x07\x00\x00\x00\x23\x00\x00\x00\xE0\x00\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x08\x00\x00\x00"
"\x23\x00\x00\x00\xEC\x00\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x09\x00\x00\x00\x23\x00\x00\x00\xF0\x00\x00\x00\x48\x00\x05\x00"
"\x1F\x00\x00\x00\x0A\x00\x00\x00\x23\x00\x00\x00\xFC\x00\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x0B\x00\x00\x00\x23\x00\x00\x00"
"\x00\x01\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x0C\x00\x00\x00\x23\x00\x00\x00\x40\x01\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00"
"\x0D\x00\x00\x00\x23\x00\x00\x00\x4C\x01\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x0E\x00\x00\x00\x23\x00\x00\x00\x50\x01\x00\x00"
"\x48\x00\x05\x00\x1F\x00\x00\x00\x0F\x00\x00\x00\x23\x00\x00\x00\x5C\x01\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x10\x00\x00\x00"
"\x23\x00\x00\x00\x60\x01\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x11\x00\x00\x00\x23\x00\x00\x00\x6C\x01\x00\x00\x48\x00\x05\x00"
"\x1F\x00\x00\x00\x12\x00\x00\x00\x23\x00\x00\x00\x70\x01\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x13\x00\x00\x00\x23\x00\x00\x00"
"\x80\x01\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x14\x00\x00\x00\x23\x00\x00\x00\x90\x01\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00"
"\x15\x00\x00\x00\x23\x00\x00\x00\x94\x01\x00\x00\x48\x00\x05\x00\x1F\x00\x00\x00\x16\x00\x00\x00\x23\x00\x00\x00\x98\x01\x00\x00"
"\x47\x00\x03\x00\x1F\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x21\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00"
"\x21\x00\x00\x00\x21\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x27\x00\x00\x00\x0B\x00\x00\x00\x0F\x00\x00\x00\x47\x00\x04\x00"
"\x38\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x47\x00\x04\x00\x5F\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00"
"\x5F\x00\x00\x00\x21\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x62\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00"
"\x66\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x48\x00\x04\x00\x6F\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00"
"\x6F\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00\x6F\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00"
"\x10\x00\x00\x00\x48\x00\x05\x00\x6F\x00\x00\x00\x01\x00\x00\x00\x23\x00\x00\x00\x40\x00\x00\x00\x48\x00\x05\x00\x6F\x00\x00\x00"
"\x02\x00\x00\x00\x23\x00\x00\x00\x4C\x00\x00\x00\x48\x00\x05\x00\x6F\x00\x00\x00\x03\x00\x00\x00\x23\x00\x00\x00\x50\x00\x00\x00"
"\x48\x00\x05\x00\x6F\x00\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00\x5C\x00\x00\x00\x48\x00\x05\x00\x6F\x00\x00\x00\x05\x00\x00\x00"
"\x23\x00\x00\x00\x60\x00\x00\x00\x48\x00\x05\x00\x6F\x00\x00\x00\x06\x00\x00\x00\x23\x00\x00\x00\x6C\x00\x00\x00\x48\x00\x05\x00"
"\x6F\x00\x00\x00\x07\x00\x00\x00\x23\x00\x00\x00\x70\x00\x00\x00\x48\x00\x05\x00\x6F\x00\x00\x00\x08\x00\x00\x00\x23\x00\x00\x00"
"\x80\x00\x00\x00\x48\x00\x05\x00\x6F\x00\x00\x00\x09\x00\x00\x00\x23\x00\x00\x00\x88\x00\x00\x00\x47\x00\x03\x00\x6F\x00\x00\x00"
"\x02\x00\x00\x00\x47\x00\x04\x00\x71\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x71\x00\x00\x00\x21\x00\x00\x00"
"\x01\x00\x00\x00\x13\x00\x02\x00\x02\x00\x00\x00\x21\x00\x03\x00\x03\x00\x00\x00\x02\x00\x00\x00\x16\x00\x03\x00\x06\x00\x00\x00"
"\x20\x00\x00\x00\x17\x00\x04\x00\x07\x00\x00\x00\x06\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00\x08\x00\x00\x00\x07\x00\x00\x00"
"\x07\x00\x00\x00\x21\x00\x04\x00\x09\x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00\x15\x00\x04\x00\x0D\x00\x00\x00\x20\x00\x00\x00"
"\x01\x00\x00\x00\x32\x00\x04\x00\x0D\x00\x00\x00\x0E\x00\x00\x00\x15\x00\x00\x00\x2B\x00\x04\x00\x0D\x00\x00\x00\x0F\x00\x00\x00"
"\x00\x00\x00\x00\x14\x00\x02\x00\x10\x00\x00\x00\x34\x00\x06\x00\x10\x00\x00\x00\x11\x00\x00\x00\xAB\x00\x00\x00\x0E\x00\x00\x00"
"\x0F\x00\x00\x00\x34\x00\x05\x00\x10\x00\x00\x00\x12\x00\x00\x00\xA8\x00\x00\x00\x11\x00\x00\x00\x20\x00\x04\x00\x17\x00\x00\x00"
"\x07\x00\x00\x00\x06\x00\x00\x00\x17\x00\x04\x00\x19\x00\x00\x00\x06\x00\x00\x00\x04\x00\x00\x00\x18\x00\x04\x00\x1A\x00\x00\x00"
"\x19\x00\x00\x00\x04\x00\x00\x00\x15\x00\x04\x00\x1B\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x2B\x00\x04\x00\x1B\x00\x00\x00"
"\x1C\x00\x00\x00\x04\x00\x00\x00\x1C\x00\x04\x00\x1D\x00\x00\x00\x19\x00\x00\x00\x1C\x00\x00\x00\x17\x00\x04\x00\x1E\x00\x00\x00"
"\x06\x00\x00\x00\x02\x00\x00\x00\x1E\x00\x19\x00\x1F\x00\x00\x00\x1A\x00\x00\x00\x1A\x00\x00\x00\x1A\x00\x00\x00\x07\x00\x00\x00"
"\x06\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x1D\x00\x00\x00"
"\x07\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x19\x00\x00\x00\x19\x00\x00\x00"
"\x06\x00\x00\x00\x06\x00\x00\x00\x1E\x00\x00\x00\x20\x00\x04\x00\x20\x00\x00\x00\x02\x00\x00\x00\x1F\x00\x00\x00\x3B\x00\x04\x00"
"\x20\x00\x00\x00\x21\x00\x00\x00\x02\x00\x00\x00\x2B\x00\x04\x00\x0D\x00\x00\x00\x22\x00\x00\x00\x14\x00\x00\x00\x20\x00\x04\x00"
"\x23\x00\x00\x00\x02\x00\x00\x00\x06\x00\x00\x00\x20\x00\x04\x00\x26\x00\x00\x00\x01\x00\x00\x00\x19\x00\x00\x00\x3B\x00\x04\x00"
"\x26\x00\x00\x00\x27\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00\x1B\x00\x00\x00\x28\x00\x00\x00\x02\x00\x00\x00\x20\x00\x04\x00"
"\x29\x00\x00\x00\x01\x00\x00\x00\x06\x00\x00\x00\x2B\x00\x04\x00\x1B\x00\x00\x00\x2D\x00\x00\x00\x03\x00\x00\x00\x2B\x00\x04\x00"
"\x06\x00\x00\x00\x31\x00\x00\x00\x00\x00\x00\x00\x2B\x00\x04\x00\x0D\x00\x00\x00\x33\x00\x00\x00\x15\x00\x00\x00\x32\x00\x04\x00"
"\x0D\x00\x00\x00\x38\x00\x00\x00\x00\x01\x00\x00\x34\x00\x06\x00\x10\x00\x00\x00\x39\x00\x00\x00\xAB\x00\x00\x00\x38\x00\x00\x00"
"\x0F\x00\x00\x00\x2B\x00\x04\x00\x06\x00\x00\x00\x41\x00\x00\x00\x3B\xAA\xB8\x3F\x2B\x00\x04\x00\x06\x00\x00\x00\x45\x00\x00\x00"
"\x00\x00\x80\x3F\x2B\x00\x04\x00\x0D\x00\x00\x00\x46\x00\x00\x00\x13\x00\x00\x00\x20\x00\x04\x00\x50\x00\x00\x00\x02\x00\x00\x00"
"\x19\x00\x00\x00\x20\x00\x04\x00\x5A\x00\x00\x00\x07\x00\x00\x00\x19\x00\x00\x00\x19\x00\x09\x00\x5C\x00\x00\x00\x06\x00\x00\x00"
"\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x1B\x00\x03\x00\x5D\x00\x00\x00"
"\x5C\x00\x00\x00\x20\x00\x04\x00\x5E\x00\x00\x00\x00\x00\x00\x00\x5D\x00\x00\x00\x3B\x00\x04\x00\x5E\x00\x00\x00\x5F\x00\x00\x00"
"\x00\x00\x00\x00\x20\x00\x04\x00\x61\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00\x61\x00\x00\x00\x62\x00\x00\x00"
"\x01\x00\x00\x00\x20\x00\x04\x00\x65\x00\x00\x00\x03\x00\x00\x00\x19\x00\x00\x00\x3B\x00\x04\x00\x65\x00\x00\x00\x66\x00\x00\x00"
"\x03\x00\x00\x00\x1E\x00\x0C\x00\x6F\x00\x00\x00\x1A\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00"
"\x07\x00\x00\x00\x06\x00\x00\x00\x19\x00\x00\x00\x1E\x00\x00\x00\x1E\x00\x00\x00\x20\x00\x04\x00\x70\x00\x00\x00\x02\x00\x00\x00"
"\x6F\x00\x00\x00\x3B\x00\x04\x00\x70\x00\x00\x00\x71\x00\x00\x00\x02\x00\x00\x00\x36\x00\x05\x00\x02\x00\x00\x00\x04\x00\x00\x00"
"\x00\x00\x00\x00\x03\x00\x00\x00\xF8\x00\x02\x00\x05\x00\x00\x00\x3B\x00\x04\x00\x5A\x00\x00\x00\x5B\x00\x00\x00\x07\x00\x00\x00"
"\x3B\x00\x04\x00\x08\x00\x00\x00\x67\x00\x00\x00\x07\x00\x00\x00\x3D\x00\x04\x00\x5D\x00\x00\x00\x60\x00\x00\x00\x5F\x00\x00\x00"
"\x3D\x00\x04\x00\x07\x00\x00\x00\x63\x00\x00\x00\x62\x00\x00\x00\x57\x00\x05\x00\x19\x00\x00\x00\x64\x00\x00\x00\x60\x00\x00\x00"
"\x63\x00\x00\x00\x3E\x00\x03\x00\x5B\x00\x00\x00\x64\x00\x00\x00\x3D\x00\x04\x00\x19\x00\x00\x00\x68\x00\x00\x00\x5B\x00\x00\x00"
"\x4F\x00\x08\x00\x07\x00\x00\x00\x69\x00\x00\x00\x68\x00\x00\x00\x68\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00"
"\x3E\x00\x03\x00\x67\x00\x00\x00\x69\x00\x00\x00\x39\x00\x05\x00\x07\x00\x00\x00\x6A\x00\x00\x00\x0B\x00\x00\x00\x67\x00\x00\x00"
"\x51\x00\x05\x00\x06\x00\x00\x00\x6B\x00\x00\x00\x6A\x00\x00\x00\x00\x00\x00\x00\x51\x00\x05\x00\x06\x00\x00\x00\x6C\x00\x00\x00"
"\x6A\x00\x00\x00\x01\x00\x00\x00\x51\x00\x05\x00\x06\x00\x00\x00\x6D\x00\x00\x00\x6A\x00\x00\x00\x02\x00\x00\x00\x50\x00\x07\x00"
"\x19\x00\x00\x00\x6E\x00\x00\x00\x6B\x00\x00\x00\x6C\x00\x00\x00\x6D\x00\x00\x00\x45\x00\x00\x00\x3E\x00\x03\x00\x66\x00\x00\x00"
"\x6E\x00\x00\x00\xFD\x00\x01\x00\x38\x00\x01\x00\x36\x00\x05\x00\x07\x00\x00\x00\x0B\x00\x00\x00\x00\x00\x00\x00\x09\x00\x00\x00"
"\x37\x00\x03\x00\x08\x00\x00\x00\x0A\x00\x00\x00\xF8\x00\x02\x00\x0C\x00\x00\x00\x3B\x00\x04\x00\x17\x00\x00\x00\x18\x00\x00\x00"
"\x07\x00\x00\x00\x3B\x00\x04\x00\x17\x00\x00\x00\x3F\x00\x00\x00\x07\x00\x00\x00\xF7\x00\x03\x00\x14\x00\x00\x00\x00\x00\x00\x00"
"\xFA\x00\x04\x00\x12\x00\x00\x00\x13\x00\x00\x00\x14\x00\x00\x00\xF8\x00\x02\x00\x13\x00\x00\x00\x3D\x00\x04\x00\x07\x00\x00\x00"
"\x15\x00\x00\x00\x0A\x00\x00\x00\xFE\x00\x02\x00\x15\x00\x00\x00\xF8\x00\x02\x00\x14\x00\x00\x00\x41\x00\x05\x00\x23\x00\x00\x00"
"\x24\x00\x00\x00\x21\x00\x00\x00\x22\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x25\x00\x00\x00\x24\x00\x00\x00\x41\x00\x05\x00"
"\x29\x00\x00\x00\x2A\x00\x00\x00\x27\x00\x00\x00\x28\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x2B\x00\x00\x00\x2A\x00\x00\x00"
"\x85\x00\x05\x00\x06\x00\x00\x00\x2C\x00\x00\x00\x25\x00\x00\x00\x2B\x00\x00\x00\x41\x00\x05\x00\x29\x00\x00\x00\x2E\x00\x00\x00"
"\x27\x00\x00\x00\x2D\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x2F\x00\x00\x00\x2E\x00\x00\x00\x88\x00\x05\x00\x06\x00\x00\x00"
"\x30\x00\x00\x00\x2C\x00\x00\x00\x2F\x00\x00\x00\x3E\x00\x03\x00\x18\x00\x00\x00\x30\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00"
"\x32\x00\x00\x00\x18\x00\x00\x00\x41\x00\x05\x00\x23\x00\x00\x00\x34\x00\x00\x00\x21\x00\x00\x00\x33\x00\x00\x00\x3D\x00\x04\x00"
"\x06\x00\x00\x00\x35\x00\x00\x00\x34\x00\x00\x00\x83\x00\x05\x00\x06\x00\x00\x00\x36\x00\x00\x00\x32\x00\x00\x00\x35\x00\x00\x00"
"\x0C\x00\x07\x00\x06\x00\x00\x00\x37\x00\x00\x00\x01\x00\x00\x00\x28\x00\x00\x00\x31\x00\x00\x00\x36\x00\x00\x00\x3E\x00\x03\x00"
"\x18\x00\x00\x00\x37\x00\x00\x00\xF7\x00\x03\x00\x3B\x00\x00\x00\x00\x00\x00\x00\xFA\x00\x04\x00\x39\x00\x00\x00\x3A\x00\x00\x00"
"\x3B\x00\x00\x00\xF8\x00\x02\x00\x3A\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x3C\x00\x00\x00\x18\x00\x00\x00\x3D\x00\x04\x00"
"\x06\x00\x00\x00\x3D\x00\x00\x00\x18\x00\x00\x00\x85\x00\x05\x00\x06\x00\x00\x00\x3E\x00\x00\x00\x3D\x00\x00\x00\x3C\x00\x00\x00"
"\x3E\x00\x03\x00\x18\x00\x00\x00\x3E\x00\x00\x00\xF9\x00\x02\x00\x3B\x00\x00\x00\xF8\x00\x02\x00\x3B\x00\x00\x00\x3D\x00\x04\x00"
"\x06\x00\x00\x00\x40\x00\x00\x00\x18\x00\x00\x00\x85\x00\x05\x00\x06\x00\x00\x00\x42\x00\x00\x00\x40\x00\x00\x00\x41\x00\x00\x00"
"\x7F\x00\x04\x00\x06\x00\x00\x00\x43\x00\x00\x00\x42\x00\x00\x00\x0C\x00\x06\x00\x06\x00\x00\x00\x44\x00\x00\x00\x01\x00\x00\x00"
"\x1D\x00\x00\x00\x43\x00\x00\x00\x3E\x00\x03\x00\x3F\x00\x00\x00\x44\x00\x00\x00\x41\x00\x06\x00\x23\x00\x00\x00\x47\x00\x00\x00"
"\x21\x00\x00\x00\x46\x00\x00\x00\x2D\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x48\x00\x00\x00\x47\x00\x00\x00\x83\x00\x05\x00"
"\x06\x00\x00\x00\x49\x00\x00\x00\x45\x00\x00\x00\x48\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x4A\x00\x00\x00\x3F\x00\x00\x00"
"\x0C\x00\x08\x00\x06\x00\x00\x00\x4B\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x00\x00\x4A\x00\x00\x00\x31\x00\x00\x00\x45\x00\x00\x00"
"\x41\x00\x06\x00\x23\x00\x00\x00\x4C\x00\x00\x00\x21\x00\x00\x00\x46\x00\x00\x00\x2D\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00"
"\x4D\x00\x00\x00\x4C\x00\x00\x00\x85\x00\x05\x00\x06\x00\x00\x00\x4E\x00\x00\x00\x4B\x00\x00\x00\x4D\x00\x00\x00\x81\x00\x05\x00"
"\x06\x00\x00\x00\x4F\x00\x00\x00\x49\x00\x00\x00\x4E\x00\x00\x00\x3E\x00\x03\x00\x3F\x00\x00\x00\x4F\x00\x00\x00\x41\x00\x05\x00"
"\x50\x00\x00\x00\x51\x00\x00\x00\x21\x00\x00\x00\x46\x00\x00\x00\x3D\x00\x04\x00\x19\x00\x00\x00\x52\x00\x00\x00\x51\x00\x00\x00"
"\x4F\x00\x08\x00\x07\x00\x00\x00\x53\x00\x00\x00\x52\x00\x00\x00\x52\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00"
"\x3D\x00\x04\x00\x07\x00\x00\x00\x54\x00\x00\x00\x0A\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x55\x00\x00\x00\x3F\x00\x00\x00"
"\x50\x00\x06\x00\x07\x00\x00\x00\x56\x00\x00\x00\x55\x00\x00\x00\x55\x00\x00\x00\x55\x00\x00\x00\x0C\x00\x08\x00\x07\x00\x00\x00"
"\x57\x00\x00\x00\x01\x00\x00\x00\x2E\x00\x00\x00\x53\x00\x00\x00\x54\x00\x00\x00\x56\x00\x00\x00\xFE\x00\x02\x00\x57\x00\x00\x00"
"\x38\x00\x01\x00"},
#endif
#ifdef D3D9QUAKE
{QR_DIRECT3D9, 9, "defaultskybox",
@ -4953,7 +4949,6 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"float4 main (v2f inp) : COLOR0\n"
"{\n"
"float3 tc = inp.texc - e_eyepos.xyz;\n"
"tc.y = -tc.y;\n"
"return texCUBE(s_reflectcube, tc);\n"
"}\n"
"#endif\n"
@ -4984,7 +4979,6 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"v2f outp;\n"
"outp.pos = mul(m_model, inp.pos);\n"
"outp.texc= outp.pos.xyz - v_eyepos;\n"
"outp.texc.y = -outp.texc.y;\n"
"outp.pos = mul(m_view, outp.pos);\n"
"outp.pos = mul(m_projection, outp.pos);\n"
"return outp;\n"
@ -5642,7 +5636,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"!!samps =SPECULAR specular\n"
"!!samps lightmap\n"
"!!samps =LIGHTSTYLED lightmap1 lightmap2 lightmap3\n"
"!!samps =DELUXE deluxmap\n"
"!!samps =DELUXE deluxemap\n"
"!!samps =LIGHTSTYLED =DELUXE deluxemap1 deluxemap2 deluxemap3\n"
"!!samps =FAKESHADOWS shadowmap\n"

View File

@ -719,7 +719,7 @@ shader_t *QDECL R_RegisterSkin (const char *shadername, const char *modname);
shader_t *R_RegisterCustom (const char *name, unsigned int usageflags, shader_gen_t *defaultgen, const void *args);
//once loaded, most shaders should have one of the following two calls used upon it
void QDECL R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader, unsigned int imageflags);
void QDECL R_BuildLegacyTexnums(shader_t *shader, const char *fallbackname, const char *subpath, unsigned int loadflags, unsigned int imageflags, uploadfmt_t basefmt, size_t width, size_t height, qbyte *mipdata[4], qbyte *palette);
void QDECL R_BuildLegacyTexnums(shader_t *shader, const char *fallbackname, const char *subpath, unsigned int loadflags, unsigned int imageflags, uploadfmt_t basefmt, size_t width, size_t height, qbyte *mipdata, qbyte *palette);
void R_RemapShader(const char *sourcename, const char *destname, float timeoffset);
cin_t *R_ShaderGetCinematic(shader_t *s);

View File

@ -10624,7 +10624,7 @@ static BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"changelevel", PF_changelevel, 70, 70, 70, 0, D("void(string mapname, optional string newmapstartspot)", "Attempts to change the map to the named map. If 'newmapstartspot' is specified, the state of the current map will be preserved, and the argument will be passed to the next map in the 'startspot' global, and the next map will be loaded from archived state if it was previously visited. If not specified, all archived map states will be purged.")}, //70
{"cvar_set", PF_cvar_set, 72, 72, 72, 0, D("void(string cvarname, string valuetoset)", "Instantly sets a cvar to the given string value.")}, //72
{"cvar_set", PF_cvar_set, 72, 72, 72, 0, D("void(string cvarname, string valuetoset)", "Instantly sets a cvar to the given string value. Warning: the resulting string includes apostrophies surrounding the result. You may wish to use sprintf instead.")}, //72
{"centerprint", PF_centerprint, 73, 73, 73, 0, "void(entity ent, string text, optional string text2, optional string text3, optional string text4, optional string text5, optional string text6, optional string text7)"}, //73
{"ambientsound", PF_ambientsound, 74, 74, 74, 0, "void (vector pos, string samp, float vol, float atten)"}, //74
@ -10866,12 +10866,13 @@ static BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"rotatevectorsbyvectors",PF_rotatevectorsbymatrix,0,0, 0, 236, "void(vector fwd, vector right, vector up)"}, // #236
{"skinforname", PF_skinforname, 0, 0, 0, 237, "float(float mdlindex, string skinname)"}, // #237
{"shaderforname", PF_Fixme, 0, 0, 0, 238, D("float(string shadername, optional string defaultshader, ...)", "Caches the named shader and returns a handle to it.\nIf the shader could not be loaded from disk (missing file or ruleset_allow_shaders 0), it will be created from the 'defaultshader' string if specified, or a 'skin shader' default will be used.\ndefaultshader if not empty should include the outer {} that you would ordinarily find in a shader.")},
{"remapshader", PF_Fixme, 0, 0, 0, 0, D("void(string shadername, string replacement, float timeoffset)", "All surfaces drawn with the specified shader will instead be drawn using the specified replacement shader. Shaders can be remapped to something else later by using the same source shadername. This is mostly useful for worldmodel surfaces (eg showing which team is currently winning). Entities should generally use setcustomskin or forceshader instead. Remaps will be forgotten on vid_reload, but can be reapplied via CSQC_RendererRestarted.")},
{"te_bloodqw", PF_te_bloodqw, 0, 0, 0, 239, "void(vector org, optional float count)"},
{"te_muzzleflash", PF_te_muzzleflash, 0, 0, 0, 0, "void(entity ent)"},
{"checkpvs", PF_checkpvs, 0, 0, 0, 240, "float(vector viewpos, entity entity)"},
{"matchclientname", PF_matchclient, 0, 0, 0, 241, "entity(string match, optional float matchnum)"},
{"sendpacket", PF_SendPacket, 0, 0, 0, 242, D("void(string destaddress, string content)", "Sends a UDP packet to the specified destination. Note that the payload will be prefixed with four 255 bytes as a sort of security feature.")},// (FTE_QC_SENDPACKET)
{"sendpacket", PF_SendPacket, 0, 0, 0, 242, D("float(string destaddress, string content)", "Sends a UDP packet to the specified destination. Note that the payload will be prefixed with four 255 bytes as a sort of security feature.")},// (FTE_QC_SENDPACKET)
// {"bulleten", PF_bulleten, 0, 0, 0, 243}, (removed builtin)
@ -12349,7 +12350,7 @@ void PR_DumpPlatform_f(void)
{"CONTENTBIT_BODY", "const int", QW|NQ|CS, NULL, 0,STRINGIFY(FTECONTENTS_BODY)"i"},
{"CONTENTBIT_CORPSE", "const int", QW|NQ|CS, NULL, 0,STRINGIFY(FTECONTENTS_CORPSE)"i"},
{"CONTENTBIT_Q2LADDER", "const int", QW|NQ|CS, D("Content bit specific to q2bsp"), 0,STRINGIFY(Q2CONTENTS_LADDER)"i"},
{"CONTENTBIT_SKY", "const int", QW|NQ|CS, NULL, 0,STRINGIFY(FTECONTENTS_SKY)"i"},
{"CONTENTBIT_SKY", "const int", QW|NQ|CS, D("Content bit somewhat specific to q1bsp (aliases to NODROP in q3bsp), but you should probably check surfaceflags&SURF_SKY as well for q2+q3bsp too."), 0,STRINGIFY(FTECONTENTS_SKY)"i"},
{"CONTENTBITS_POINTSOLID", "const int", QW|NQ|CS, D("Bits that traceline would normally consider solid"), 0,"CONTENTBIT_SOLID|"STRINGIFY(Q2CONTENTS_WINDOW)"i|CONTENTBIT_BODY"},
{"CONTENTBITS_BOXSOLID", "const int", QW|NQ|CS, D("Bits that tracebox would normally consider solid"), 0,"CONTENTBIT_SOLID|"STRINGIFY(Q2CONTENTS_WINDOW)"i|CONTENTBIT_BODY|CONTENTBIT_PLAYERCLIP"},
{"CONTENTBITS_FLUID", "const int", QW|NQ|CS, NULL, 0,"CONTENTBIT_WATER|CONTENTBIT_SLIME|CONTENTBIT_LAVA|CONTENTBIT_SKY"},

View File

@ -113,13 +113,15 @@ typedef struct
qboolean csqcdebug;
unsigned int csqcchecksum;
qboolean mapchangelocked;
qboolean restarting;
#ifdef SAVEDGAMES
char loadgame_on_restart[MAX_QPATH]; //saved game to load on map_restart
double autosave_time;
#endif
double time;
double starttime;
double time; //current map time
double restartedtime; //sv.time from last map restart
double starttime; //system time we changed map.
int framenum;
int logindatabase;
@ -1283,8 +1285,10 @@ void SVQ2_BuildBaselines(void);
//q3 stuff
#ifdef Q3SERVER
void SVQ3_ShutdownGame(void);
qboolean SVQ3_InitGame(void);
void SVQ3_ShutdownGame(qboolean restarting);
qboolean SVQ3_InitGame(qboolean restarting);
void SVQ3_ServerinfoChanged(const char *key);
qboolean SVQ3_RestartGamecode(void);
qboolean SVQ3_ConsoleCommand(void);
qboolean SVQ3_HandleClient(void);
void SVQ3_DirectConnect(void);

View File

@ -556,6 +556,13 @@ void SV_Map_f (void)
if (!Q_strcasecmp(Cmd_Argv(0), "map_restart"))
{
const char *arg = Cmd_Argv(1);
#ifdef Q3SERVER
if (sv.state==ss_active && svs.gametype==GT_QUAKE3)
if (SVQ3_RestartGamecode())
return;
#endif
#ifdef SAVEDGAMES
if (!strcmp(arg, "restore")) //hexen2 reload-saved-game
;
@ -800,6 +807,8 @@ void SV_Map_f (void)
{
cvar_t *gametype;
Cvar_ApplyLatches(CVAR_LATCH);
gametype = Cvar_Get("mapname", "", CVAR_LATCH|CVAR_SERVERINFO, "Q3 compatability");
gametype->flags |= CVAR_SERVERINFO;
Cvar_ForceSet(gametype, level);

View File

@ -625,7 +625,7 @@ void SV_UnspawnServer (void) //terminate the running server.
}
PR_Deinit();
#ifdef Q3SERVER
SVQ3_ShutdownGame();
SVQ3_ShutdownGame(false);
#endif
#ifdef Q2SERVER
SVQ2_ShutdownGameProgs();
@ -921,7 +921,7 @@ void SV_SpawnServer (const char *server, const char *startspot, qboolean noents,
#ifdef Q3SERVER
if (svs.gametype == GT_QUAKE3)
SVQ3_ShutdownGame(); //botlib kinda mandates this. :(
SVQ3_ShutdownGame(false); //botlib kinda mandates this. :(
#endif
Mod_ClearAll ();
@ -981,7 +981,7 @@ void SV_SpawnServer (const char *server, const char *startspot, qboolean noents,
CL_CheckServerInfo();
#endif
sv.restarting = false;
sv.state = ss_loading;
#if defined(Q2BSPS)
if (usecinematic)
@ -1132,7 +1132,7 @@ MSV_OpenUserDatabase();
else
#endif
#ifdef Q3SERVER
if (SVQ3_InitGame())
if (SVQ3_InitGame(false))
newgametype = GT_QUAKE3;
else
#endif
@ -1167,7 +1167,7 @@ MSV_OpenUserDatabase();
#endif
#ifdef Q3SERVER
if (newgametype != GT_QUAKE3)
SVQ3_ShutdownGame();
SVQ3_ShutdownGame(false);
#endif
#ifdef Q2SERVER
if (newgametype != GT_QUAKE2) //we don't want the q2 stuff anymore.
@ -1380,7 +1380,7 @@ MSV_OpenUserDatabase();
#endif
#ifdef Q3SERVER
case GT_QUAKE3:
SV_UpdateMaxPlayers(32);
SV_UpdateMaxPlayers(max(8,maxclients.ival));
break;
#endif
#ifdef HLSERVER

View File

@ -111,7 +111,15 @@ extern cvar_t sv_allow_splitscreen;
#ifdef SUPPORT_ICE
static void QDECL SV_Public_Callback(struct cvar_s *var, char *oldvalue)
{
if (var->ival == 2)
char name[64], *e;
COM_ParseOut(var->string, name, sizeof(name));
strtol(name, &e, 0);
if (*name&&e==name) //failed to read any number out of it.
{
FTENET_AddToCollection(svs.sockets, var->name, va("/%s", name), NA_INVALID, NP_RTC_TLS);
var->value = var->ival = 2; //so other stuff sees us as holepunched.
}
else if (var->ival == 2)
FTENET_AddToCollection(svs.sockets, var->name, "/", NA_INVALID, NP_RTC_TLS);
else
FTENET_AddToCollection(svs.sockets, var->name, "", NA_INVALID, NP_INVALID);
@ -5281,6 +5289,11 @@ float SV_Frame (void)
static void SV_InfoChanged(void *context, const char *key)
{
size_t i;
#ifdef Q3SERVER
SVQ3_ServerinfoChanged(key);
#endif
if (context != &svs.info && *key == '_')
return; //these keys are considered private to originating client/server, and are not broadcast to anyone else

View File

@ -1941,6 +1941,18 @@ void SVQW_Spawn_f (void)
// when that is completed, a begin command will be issued
ClientReliableWrite_Begin (host_client, svc_stufftext, 8);
ClientReliableWrite_String (host_client, "skins\n" );
if (sv.allocated_client_slots > 1)
{ //okay, so nq player physics don't suppot prediction.
//if we use qw physics in nq mods then we risk breaking things.
//the only progs many players will have is the vanilla nq one.
//so prediction is broken on most people's quicky servers.
//which really sucks.
//so let multiplayer people know what's going on so that they don't think its an actual bug, and can harass the admin to get it fixed in mods that allow for it.
if (!strcmp(sv_nqplayerphysics.string, "auto") || !strcmp(sv_nqplayerphysics.string, ""))
if (sv_nqplayerphysics.ival)
SV_PrintToClient(host_client, PRINT_HIGH, CON_WARNING"Movement prediction is disabled in favour of non-quakeworld mod compatibilty\n");
}
}
/*

View File

@ -61,6 +61,7 @@ static vm_t *q3gamevm;
#define MAX_CONFIGSTRINGS 1024
static char *svq3_configstrings[MAX_CONFIGSTRINGS];
static qboolean q3_serverinfo_dirty;
static q3sharedEntity_t *q3_entarray;
static int numq3entities;
static int sizeofq3gentity;
@ -799,14 +800,21 @@ void SVQ3_SendConfigString(client_t *dest, int num, char *string)
void SVQ3_SetConfigString(int num, char *string)
{
int len;
if (num < 0 || num >= MAX_Q3_CONFIGSTRINGS)
return; //no exploits please
if (!string)
string = "";
if (!strcmp(svq3_configstrings[num]?svq3_configstrings[num]:"", string))
return;
len = strlen(string);
if (svq3_configstrings[num])
Z_Free(svq3_configstrings[num]);
svq3_configstrings[num] = Z_Malloc(len+1);
strcpy(svq3_configstrings[num], string);
if (sv.state == ss_loading && !sv.restarting)
return; //don't spam these, the svcq3_gamestate will have a copy anyway and the gamecode can get confused.
SVQ3_SendConfigString(NULL, num, string);
}
@ -1676,33 +1684,37 @@ static qintptr_t EXPORT_FN Q3G_SystemCallsNative(qintptr_t arg, ...)
return Q3G_SystemCalls(NULL, ~(quintptr_t)0, arg, args);
}
void SVQ3_ShutdownGame(void)
void SVQ3_ShutdownGame(qboolean restarting)
{
int i;
if (!q3gamevm)
return;
if (!restarting)
{
#ifdef USEBOTLIB
if (botlib)
{ //it crashes otherwise, probably due to our huck clearage
botlib->BotLibShutdown();
Z_FreeTags(Z_TAG_BOTLIB);
}
if (botlib)
{ //it crashes otherwise, probably due to our huck clearage
botlib->BotLibShutdown();
Z_FreeTags(Z_TAG_BOTLIB);
}
#endif
for (i = 0; i < MAX_CONFIGSTRINGS; i++)
{
if (svq3_configstrings[i])
for (i = 0; i < MAX_CONFIGSTRINGS; i++)
{
Z_Free(svq3_configstrings[i]);
svq3_configstrings[i] = NULL;
if (svq3_configstrings[i])
{
Z_Free(svq3_configstrings[i]);
svq3_configstrings[i] = NULL;
}
}
Z_Free(q3_sentities);
q3_sentities = NULL;
BZ_Free(q3_snapshot_entities);
q3_snapshot_entities = NULL;
}
Z_Free(q3_sentities);
q3_sentities = NULL;
BZ_Free(q3_snapshot_entities);
q3_snapshot_entities = NULL;
VM_Destroy(q3gamevm);
q3gamevm = NULL;
@ -1926,12 +1938,27 @@ static void SV_InitBotLib(void)
#endif
}
qboolean SVQ3_InitGame(void)
void SVQ3_ServerinfoChanged(const char *key)
{ //roll up multiple updates into a single splurge. SVQ3_UpdateServerinfo will be called after the next frame.
q3_serverinfo_dirty = true;
}
static void SVQ3_UpdateServerinfo(void)
{
char buffer[8192];
/*update serverinfo - qw serverinfo settings are not normally visible in the q3 serverinfo, so strip them from the configstring*/
static const char *ignores[] = {"maxclients", "map", "sv_maxclients", "*z_ext", "*bspversion", "*gamedir", NULL};
extern cvar_t maxclients;
InfoBuf_ToString(&svs.info, buffer, sizeof(buffer), NULL, ignores, NULL, NULL, NULL);
//add in maxclients.. the q3 version
Q_strncatz(buffer, va("\\sv_maxclients\\%s", maxclients.string), sizeof(buffer));
SVQ3_SetConfigString(0, buffer);
q3_serverinfo_dirty = false;
}
qboolean SVQ3_InitGame(qboolean restart)
{
int i;
char buffer[8192];
char *str;
char sysinfo[8192];
if (sv.world.worldmodel->type == mod_heightmap)
{
@ -1946,7 +1973,7 @@ qboolean SVQ3_InitGame(void)
return false;
SVQ3_ShutdownGame();
SVQ3_ShutdownGame(restart);
q3gamevm = VM_Create("qagame", com_nogamedirnativecode.ival?NULL:Q3G_SystemCallsNative, "vm/qagame", Q3G_SystemCallsVM);
@ -1965,68 +1992,67 @@ qboolean SVQ3_InitGame(void)
q3_sentities = Z_Malloc(sizeof(q3serverEntity_t)*MAX_GENTITIES);
{ /*qw serverinfo settings are not normally visible in the q3 serverinfo, so strip them from the configstring*/
static const char *ignores[] = {"maxclients", "map", "sv_maxclients", "*z_ext", "*bspversion", "*gamedir", NULL};
extern cvar_t maxclients;
InfoBuf_ToString(&svs.info, buffer, sizeof(buffer), NULL, ignores, NULL, NULL, NULL);
//add in maxclients.. the q3 version
Q_strncatz(buffer, va("\\sv_maxclients\\%s", maxclients.string), sizeof(buffer));
}
SVQ3_SetConfigString(0, buffer);
Cvar_Set(Cvar_Get("sv_running", "0", 0, "Q3 compatability"), "1");
sysinfo[0] = '\0';
Info_SetValueForKey(sysinfo, "sv_serverid", va("%i", svs.spawncount), MAX_SERVERINFO_STRING);
if (!restart)
{
char buffer[8192];
char sysinfo[8192];
/*update the system info*/
sysinfo[0] = '\0';
Info_SetValueForKey(sysinfo, "sv_serverid", va("%i", svs.spawncount), MAX_SERVERINFO_STRING);
str = FS_GetPackHashes(buffer, sizeof(buffer), false);
Info_SetValueForKey(sysinfo, "sv_paks", str, MAX_SERVERINFO_STRING);
str = FS_GetPackNames(buffer, sizeof(buffer), false, false);
Info_SetValueForKey(sysinfo, "sv_pakNames", str, MAX_SERVERINFO_STRING);
str = FS_GetPackHashes(buffer, sizeof(buffer), true);
Info_SetValueForKey(sysinfo, "sv_referencedPaks", str, MAX_SERVERINFO_STRING);
str = FS_GetPackNames(buffer, sizeof(buffer), true, false);
Info_SetValueForKey(sysinfo, "sv_referencedPakNames", str, MAX_SERVERINFO_STRING);
Info_SetValueForKey(sysinfo, "sv_pure", sv_pure.string, MAX_SERVERINFO_STRING);
SVQ3_SetConfigString(1, sysinfo);
Info_SetValueForKey(sysinfo, "sv_paks", FS_GetPackHashes(buffer, sizeof(buffer), false ), MAX_SERVERINFO_STRING);
Info_SetValueForKey(sysinfo, "sv_pakNames", FS_GetPackNames (buffer, sizeof(buffer), false, false), MAX_SERVERINFO_STRING);
Info_SetValueForKey(sysinfo, "sv_referencedPaks", FS_GetPackHashes(buffer, sizeof(buffer), true ), MAX_SERVERINFO_STRING);
Info_SetValueForKey(sysinfo, "sv_referencedPakNames", FS_GetPackNames (buffer, sizeof(buffer), true, false ), MAX_SERVERINFO_STRING);
Info_SetValueForKey(sysinfo, "sv_pure", sv_pure.string, MAX_SERVERINFO_STRING);
SVQ3_SetConfigString(1, sysinfo);
q3_serverinfo_dirty = true;
}
mapentspointer = Mod_GetEntitiesString(sv.world.worldmodel);
VM_Call(q3gamevm, GAME_INIT, 0, (int)rand(), false);
VM_Call(q3gamevm, GAME_INIT, (intptr_t)(sv.time*1000), (int)rand(), restart);
CM_InitBoxHull();
SVQ3_CreateBaseline();
if (!restart)
{
SVQ3_CreateBaseline();
q3_num_snapshot_entities = 32 * Q3UPDATE_BACKUP * 32;
if (q3_snapshot_entities)
BZ_Free(q3_snapshot_entities);
q3_next_snapshot_entities = 0;
q3_snapshot_entities = BZ_Malloc(sizeof( q3entityState_t ) * q3_num_snapshot_entities);
q3_num_snapshot_entities = 32 * Q3UPDATE_BACKUP * 32;
if (q3_snapshot_entities)
BZ_Free(q3_snapshot_entities);
q3_next_snapshot_entities = 0;
q3_snapshot_entities = Z_Malloc(sizeof( q3entityState_t ) * q3_num_snapshot_entities);
}
// run a few frames to allow everything to settle
// run a few frames to allow everything to settle
for (i = 0; i < 3; i++)
{
SVQ3_RunFrame();
sv.time += 0.1;
}
#ifdef HAVE_CLIENT
//there's a whole load of ugly debug crap there. make sure it stays hidden.
Con_ClearNotify();
#endif
return true;
}
void SVQ3_RunFrame(void)
{
VM_Call(q3gamevm, GAME_RUN_FRAME, (int)(sv.time*1000));
#ifdef USEBOTLIB
if (botlib)
VM_Call(q3gamevm, BOTAI_START_FRAME, (int)(sv.time*1000));
#endif
VM_Call(q3gamevm, GAME_RUN_FRAME, (int)(sv.time*1000));
if (q3_serverinfo_dirty)
SVQ3_UpdateServerinfo();
}
void SVQ3_ClientCommand(client_t *cl)
@ -2038,6 +2064,7 @@ void SVQ3_ClientBegin(client_t *cl)
{
VM_Call(q3gamevm, GAME_CLIENT_BEGIN, (int)(cl-svs.clients));
sv.spawned_client_slots++;
cl->spawned = true;
}
void SVQ3_ClientThink(client_t *cl)
@ -2464,7 +2491,7 @@ void SVQ3_BuildClientSnapshot( client_t *client )
{
q3_num_snapshot_entities = 32 * Q3UPDATE_BACKUP * 32;
q3_next_snapshot_entities = 0;
q3_snapshot_entities = BZ_Malloc(sizeof( q3entityState_t ) * q3_num_snapshot_entities);
q3_snapshot_entities = Z_Malloc(sizeof( q3entityState_t ) * q3_num_snapshot_entities);
}
clientNum = client - svs.clients;
@ -2484,7 +2511,7 @@ void SVQ3_BuildClientSnapshot( client_t *client )
// this is the frame we are creating
snap = &client->frameunion.q3frames[client->netchan.outgoing_sequence & Q3UPDATE_MASK];
snap->serverTime = sv.time*1000;//svs.levelTime; // save it for ping calc later
snap->serverTime = sv.restartedtime*1000 + sv.time*1000;//svs.levelTime; // save it for ping calc later
snap->flags = 0;
if( client->state < cs_spawned )
@ -2818,8 +2845,8 @@ void SVQ3_SendGameState(client_t *client)
// write baselines
for( i=0; i<MAX_GENTITIES; i++ )
{
if (!q3_baselines[i].number)
continue;
if (!q3_baselines[i].number)
continue;
MSG_WriteBits(&msg, svcq3_baseline, 8);
MSGQ3_WriteDeltaEntity( &msg, NULL, &q3_baselines[i], true );
@ -2932,6 +2959,7 @@ client_t *SVQ3_FindExistingPlayerByIP(netadr_t *na, int qport)
qboolean Netchan_ProcessQ3 (netchan_t *chan);
static qboolean SVQ3_Netchan_Process(client_t *client)
{
#ifndef Q3_NOENCRYPT
int serverid;
int lastSequence;
int lastServerCommandNum;
@ -2941,12 +2969,14 @@ static qboolean SVQ3_Netchan_Process(client_t *client)
char *string;
int bit;
int readcount;
#endif
if (!Netchan_ProcessQ3(&client->netchan))
{
return false;
}
#ifndef Q3_NOENCRYPT
// archive buffer state
bit = net_message.currentbit;
readcount = msg_readcount;
@ -2965,7 +2995,6 @@ static qboolean SVQ3_Netchan_Process(client_t *client)
bitmask = (serverid ^ lastSequence ^ client->challenge) & 0xff;
string = client->server_commands[lastServerCommandNum & Q3TEXTCMD_MASK];
#ifndef Q3_NOENCRYPT
// decrypt the packet
for(i=msg_readcount+12,j=0; i<net_message.cursize; i++,j++)
{
@ -2989,16 +3018,17 @@ static qboolean SVQ3_Netchan_Process(client_t *client)
void SVQ3_Netchan_Transmit(client_t *client, int length, qbyte *data)
{
qbyte buffer[MAX_OVERALLMSGLEN];
int i;
#ifndef Q3_NOENCRYPT
qbyte bitmask;
qbyte c;
int i, j;
int j;
char *string;
// calculate bitmask
bitmask = (client->netchan.outgoing_sequence ^ client->challenge) & 0xff;
string = client->last_client_command;
#ifndef Q3_NOENCRYPT
//first four bytes are not encrypted.
for(i=0; i<4 ; i++)
buffer[i] = data[i];
@ -3145,7 +3175,7 @@ void SVQ3_UpdateUserinfo_f(client_t *cl)
InfoBuf_FromString(&cl->userinfo, Cmd_Argv(1), false);
SV_ExtractFromUserinfo (cl, true);
if (svs.gametype == GT_QUAKE3)
if (svs.gametype == GT_QUAKE3 && cl->spawned)
VM_Call(q3gamevm, GAME_CLIENT_USERINFO_CHANGED, (int)(cl-svs.clients));
}
@ -3385,6 +3415,69 @@ qboolean SVQ3_HandleClient(void)
SVQ3_ParseClientMessage(&svs.clients[i]);
return true;
}
//Q3 gamecode does map_restart weirdly.
//it simply reloads the gamecode without changing any maps/models/sounds
//this won't work for q1/q2, but q3 expects it.
//note that time continues from its prior value without any kind of reset.
qboolean SVQ3_RestartGamecode(void)
{
int i;
extern cvar_t maxclients;
int newmaxclients = max(8,maxclients.ival);
if (sv.allocated_client_slots != newmaxclients)
return false; //can't do it if maxclients needs to change.
Cvar_ApplyLatches(CVAR_LATCH);
//reload the gamecode
sv.state = ss_loading;
sv.restarting = true;
if (!SVQ3_InitGame(true))
return false;
// svs.spawncount++; //so new snapshots get sent
sv.restartedtime = 0;
//and then reconnect the players as appropriate
// SVQ3_NewMapConnects();
for (i = 0; i < sv.allocated_client_slots; i++)
{
if (svs.clients[i].state < cs_connected)
continue;
if (VM_Call(q3gamevm, GAME_CLIENT_CONNECT, i, false, svs.clients[i].protocol == SCP_BAD))
{
SV_DropClient(&svs.clients[i]);
continue;
}
if (svs.clients[i].spawned)
{
sv.spawned_client_slots--;
SVQ3_ClientBegin(&svs.clients[i]);
}
}
sv.starttime = Sys_DoubleTime() - sv.time;
#ifdef SAVEDGAMES
sv.autosave_time = sv.time + sv_autosave.value*60;
#endif
//basically done
sv.state = ss_active;
sv.restarting = false;
//and an extra physics frame for luck
sv.time+=0.1;
sv.world.physicstime=sv.time;
SVQ3_RunFrame();
SVQ3_SendServerCommand(NULL, "map_restart");
return true; //yup, we did it.
}
void SVQ3_NewMapConnects(void)
{
int i;
@ -3467,10 +3560,13 @@ void SVQ3_DirectConnect(void) //Actually connect the client, use up a slot, and
else
{
InfoBuf_FromString(&cl->userinfo, userinfo, false);
reason = NET_AdrToString(adr, sizeof(adr), &net_from);
if (net_from.type == NA_LOOPBACK)
reason = "localhost"; //Q3 uses this specific string for listen servers.
else
reason = NET_AdrToString(adr, sizeof(adr), &net_from);
InfoBuf_SetKey(&cl->userinfo, "ip", reason); //q3 gamecode needs to know the client's ip (server's perception of the client, NOT QW client's perception of the server/proxy)
ret = VM_Call(q3gamevm, GAME_CLIENT_CONNECT, (int)(cl-svs.clients), false, false);
ret = VM_Call(q3gamevm, GAME_CLIENT_CONNECT, (int)(cl-svs.clients), true, false);
if (!ret)
reason = NULL;
else

View File

@ -24,7 +24,6 @@ mat3 rotateAroundAxis(vec4 axis) //xyz axis, with angle in w
void main ()
{
pos = v_position.xyz - e_eyepos;
pos.y = -pos.y;
if (r_glsl_skybox_orientation.xyz != vec3(0.0))
pos = pos*rotateAroundAxis(r_glsl_skybox_orientation);

View File

@ -20,7 +20,7 @@
!!samps =SPECULAR specular
!!samps lightmap
!!samps =LIGHTSTYLED lightmap1 lightmap2 lightmap3
!!samps =DELUXE deluxmap
!!samps =DELUXE deluxemap
!!samps =LIGHTSTYLED =DELUXE deluxemap1 deluxemap2 deluxemap3
!!samps =FAKESHADOWS shadowmap

View File

@ -21,7 +21,6 @@ struct v2f
v2f outp;
outp.pos = mul(m_model, inp.pos);
outp.texc= outp.pos.xyz - v_eyepos;
outp.texc.y = -outp.texc.y;
outp.pos = mul(m_view, outp.pos);
outp.pos = mul(m_projection, outp.pos);
return outp;

View File

@ -29,7 +29,6 @@
float4 main (v2f inp) : COLOR0
{
float3 tc = inp.texc - e_eyepos.xyz;
tc.y = -tc.y;
return texCUBE(s_reflectcube, tc);
}
#endif

View File

@ -11,7 +11,6 @@ layout(location=0) varying vec3 pos;
void main ()
{
pos = v_position.xyz - e_eyepos;
pos.y = -pos.y;
gl_Position = ftetransform();
}
#endif

View File

@ -1381,10 +1381,10 @@ vk_image_t VK_CreateTexture2DArray(uint32_t width, uint32_t height, uint32_t lay
case PTI_BC2_RGBA_SRGB: format = VK_FORMAT_BC2_SRGB_BLOCK; break;
case PTI_BC3_RGBA: format = VK_FORMAT_BC3_UNORM_BLOCK; break;
case PTI_BC3_RGBA_SRGB: format = VK_FORMAT_BC3_SRGB_BLOCK; break;
case PTI_BC4_R8: format = VK_FORMAT_BC4_UNORM_BLOCK; break;
case PTI_BC4_R8_SNORM: format = VK_FORMAT_BC4_SNORM_BLOCK; break;
case PTI_BC5_RG8: format = VK_FORMAT_BC5_UNORM_BLOCK; break;
case PTI_BC5_RG8_SNORM: format = VK_FORMAT_BC5_SNORM_BLOCK; break;
case PTI_BC4_R: format = VK_FORMAT_BC4_UNORM_BLOCK; break;
case PTI_BC4_R_SNORM: format = VK_FORMAT_BC4_SNORM_BLOCK; break;
case PTI_BC5_RG: format = VK_FORMAT_BC5_UNORM_BLOCK; break;
case PTI_BC5_RG_SNORM: format = VK_FORMAT_BC5_SNORM_BLOCK; break;
case PTI_BC6_RGB_UFLOAT: format = VK_FORMAT_BC6H_UFLOAT_BLOCK; break;
case PTI_BC6_RGB_SFLOAT: format = VK_FORMAT_BC6H_SFLOAT_BLOCK; break;
case PTI_BC7_RGBA: format = VK_FORMAT_BC7_UNORM_BLOCK; break;
@ -1828,7 +1828,7 @@ qboolean VK_LoadTextureMips (texid_t tex, const struct pendingtextureinfo *mips)
{
if (mips->mip[i].width != max(1,(mips->mip[i-1].width>>1)) ||
mips->mip[i].height != max(1,(mips->mip[i-1].height>>1)))
{ //okay, this mip looks like it was sized wrongly. this can easily happen with dds files.
{ //okay, this mip looks like it was sized wrongly.
mipcount = i;
break;
}
@ -4147,10 +4147,10 @@ void VK_CheckTextureFormats(void)
{PTI_BC1_RGBA_SRGB, VK_FORMAT_BC1_RGBA_SRGB_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_BC2_RGBA_SRGB, VK_FORMAT_BC2_SRGB_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_BC3_RGBA_SRGB, VK_FORMAT_BC3_SRGB_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_BC4_R8, VK_FORMAT_BC4_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_BC4_R8_SNORM, VK_FORMAT_BC4_SNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_BC5_RG8, VK_FORMAT_BC5_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_BC5_RG8_SNORM, VK_FORMAT_BC5_SNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_BC4_R, VK_FORMAT_BC4_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_BC4_R_SNORM, VK_FORMAT_BC4_SNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_BC5_RG, VK_FORMAT_BC5_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_BC5_RG_SNORM, VK_FORMAT_BC5_SNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_BC6_RGB_UFLOAT, VK_FORMAT_BC6H_UFLOAT_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_BC6_RGB_SFLOAT, VK_FORMAT_BC6H_SFLOAT_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_BC7_RGBA, VK_FORMAT_BC7_UNORM_BLOCK, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
@ -4231,7 +4231,7 @@ void VK_CheckTextureFormats(void)
sh_config.texfmt[texfmt[i].pti] = true;
}
if (sh_config.texfmt[PTI_BC1_RGBA] && sh_config.texfmt[PTI_BC2_RGBA] && sh_config.texfmt[PTI_BC3_RGBA] && sh_config.texfmt[PTI_BC5_RG8] && sh_config.texfmt[PTI_BC7_RGBA])
if (sh_config.texfmt[PTI_BC1_RGBA] && sh_config.texfmt[PTI_BC2_RGBA] && sh_config.texfmt[PTI_BC3_RGBA] && sh_config.texfmt[PTI_BC5_RG] && sh_config.texfmt[PTI_BC7_RGBA])
sh_config.hw_bc = 3;
if (sh_config.texfmt[PTI_ETC2_RGB8] && sh_config.texfmt[PTI_ETC2_RGB8A1] && sh_config.texfmt[PTI_ETC2_RGB8A8] && sh_config.texfmt[PTI_EAC_RG11])
sh_config.hw_etc = 2;

945
imgtool.c

File diff suppressed because it is too large Load Diff