diff --git a/engine/Makefile b/engine/Makefile index 262c25f20..98da5e65d 100644 --- a/engine/Makefile +++ b/engine/Makefile @@ -100,6 +100,9 @@ ifneq (,$(findstring -Os,$(FTE_CONFIG_EXTRA))) CPUOPTIMIZATIONS+=-Os BRANDFLAGS:=$(filter-out -O%,$(BRANDFLAGS)) endif +ifneq (,$(findstring DLINK_INTERNAL_BULLET,$(FTE_CONFIG_EXTRA))) + INTERNAL_BULLET=1 #bullet plugin will be built into the exe itself +endif ifeq ($(BITS),64) CC:=$(CC) -m64 @@ -845,6 +848,9 @@ ifeq (1,$(USE_FREETYPE)) LIBFREETYPE_STATIC=-DFREETYPE_STATIC LIBFREETYPE_LDFLAGS=-lfreetype endif +ifeq (1,$(strip $(INTERNAL_BULLET))) + COMMON_OBJS+=com_phys_bullet.o +endif COMMONLIBFLAGS= CLIENTLIBFLAGS=$(COMMONLIBFLAGS) $(LIBOPUS_STATIC) $(LIBSPEEX_STATIC) $(OGGVORBISFILE_STATIC) $(LIBFREETYPE_STATIC) @@ -2171,3 +2177,4 @@ install: sv-rel gl-rel mingl-rel qcc-rel $(INSTALL_PROGRAM) $(RELEASE_DIR)/$(EXE_NAME)-mingl $(DESTDIR)$(bindir)/$(EXE_NAME)-mingl $(INSTALL_PROGRAM) $(RELEASE_DIR)/$(EXE_NAME)-sv $(DESTDIR)$(bindir)/$(EXE_NAME)-sv $(INSTALL_PROGRAM) $(RELEASE_DIR)/fteqcc $(DESTDIR)$(bindir)/fteqcc + diff --git a/engine/client/api_menu.h b/engine/client/api_menu.h index a26b07333..a193c38f1 100644 --- a/engine/client/api_menu.h +++ b/engine/client/api_menu.h @@ -111,7 +111,7 @@ typedef struct { const char *engine_version; int (*checkextension) (const char *ext); - void (*error) (const char *err); + void (QDECL *error) (const char *err, ...); void (*printf) (const char *text, ...); void (*dprintf) (const char *text, ...); void (*localcmd) (const char *cmd); @@ -129,7 +129,7 @@ typedef struct { void (*localsound) (const char *sample, int channel, float volume); // file input / search crap - struct vfsfile_s *(*fopen) (const char *filename, char *modestring, enum fs_relative fsroot); //modestring should be one of rb,r+b,wb,w+b,ab,wbp. Mostly use a root of FS_GAMEONLY for writes, otherwise FS_GAME for reads. + struct vfsfile_s *(*fopen) (const char *filename, const char *modestring, enum fs_relative fsroot); //modestring should be one of rb,r+b,wb,w+b,ab,wbp. Mostly use a root of FS_GAMEONLY for writes, otherwise FS_GAME for reads. void (*fclose) (struct vfsfile_s *fhandle); char *(*fgets) (struct vfsfile_s *fhandle, char *out, size_t outsize); //returns output buffer, or NULL void (*fprintf) (struct vfsfile_s *fhandle, const char *s, ...); @@ -142,14 +142,14 @@ typedef struct { qboolean (*drawgetimagesize)(struct shader_s *pic, int *x, int *y); void (*drawquad) (const vec2_t position[4], const vec2_t texcoords[4], struct shader_s *pic, const vec4_t rgba, unsigned int be_flags); - float (*drawstring) (vec2_t position, const char *text, struct font_s *font, float height, const vec4_t rgba, unsigned int be_flags); + float (*drawstring) (const vec2_t position, const char *text, struct font_s *font, float height, const vec4_t rgba, unsigned int be_flags); float (*stringwidth) (const char *text, struct font_s *font, float height); struct font_s *(*loadfont) (const char *facename, float intendedheight); //with ttf fonts, you'll probably want one for each size. void (*destroyfont) (struct font_s *font); // 3D scene stuff struct model_s *(*cachemodel)(const char *name); - void (*getmodelsize) (struct model_s *model, vec3_t out_mins, vec3_t out_maxs); + qboolean (*getmodelsize) (struct model_s *model, vec3_t out_mins, vec3_t out_maxs); void (*renderscene) (menuscene_t *scene); // Menu specific stuff diff --git a/engine/client/cl_cg.c b/engine/client/cl_cg.c index 2ed90e8f4..45e462213 100644 --- a/engine/client/cl_cg.c +++ b/engine/client/cl_cg.c @@ -956,7 +956,7 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con int inwater = VM_LONG(arg[3]); cl.playerview[0].audio.defaulted = false; - cl.playerview[0].audio.entnum = VM_LONG(arg[0]); + cl.playerview[0].audio.entnum = VM_LONG(arg[0])+1; VectorCopy(org, cl.playerview[0].audio.origin); VectorCopy(axis[0], cl.playerview[0].audio.forward); VectorCopy(axis[1], cl.playerview[0].audio.right); diff --git a/engine/client/cl_demo.c b/engine/client/cl_demo.c index 6b5d09c51..d3711928d 100644 --- a/engine/client/cl_demo.c +++ b/engine/client/cl_demo.c @@ -1187,10 +1187,12 @@ void CL_RecordMap_f (void) #endif //qw-specific serverdata -static void CLQW_RecordServerData(sizebuf_t *buf) +static void CLQW_RecordServerData(sizebuf_t *buf, int *seq) { extern char gamedirfile[]; unsigned int i; + infosync_t sync; + char serverinfostring[1024]; // send the serverdata MSG_WriteByte (buf, svc_serverdata); @@ -1246,31 +1248,79 @@ static void CLQW_RecordServerData(sizebuf_t *buf) MSG_WriteFloat(buf, movevars.entgravity); // send server info string + memset(&sync, 0, sizeof(sync)); + InfoBuf_ToString(&cl.serverinfo, serverinfostring, sizeof(serverinfostring), NULL, NULL, NULL, &sync, NULL); MSG_WriteByte (buf, svc_stufftext); - MSG_WriteString (buf, va("fullserverinfo \"%s\"\n", cl.serverinfo) ); + MSG_WriteString (buf, va("fullserverinfo \"%s\"\n", serverinfostring)); + while(sync.numkeys) + { + char *keyname = sync.keys[0].name; + char enckey[2048], encdata[2048]; + if (InfoBuf_EncodeString(keyname,strlen(keyname), enckey, sizeof(enckey))) + { + size_t k; + if (InfoBuf_FindKey(&cl.serverinfo, keyname, &k)) + { + size_t offset, chunk; + qboolean final; + for (offset = 0 ; offset < cl.serverinfo.keys[k].size; offset += chunk) + { + chunk = cl.serverinfo.keys[k].size - offset; + if (chunk > 1024) + chunk = 1024; + + if (!InfoBuf_EncodeString(cl.serverinfo.keys[k].value, chunk, encdata, sizeof(encdata))) + break; //shouldn't happen. + + if (buf->cursize > 512) + CL_WriteRecordDemoMessage (buf, (*seq)++); + + final = (offset+chunk == cl.serverinfo.keys[k].size) && !cl.serverinfo.keys[k].partial; + if (!offset && final) + { //vanilla compat. we must just have a lot of data. + MSG_WriteByte(buf, svc_serverinfo); + MSG_WriteString(buf, enckey); + MSG_WriteString(buf, encdata); + } + else + { //awkward stuff. + MSG_WriteByte(buf, svc_setinfo); + MSG_WriteByte(buf, 255); //special meaning to say that this is a partial update + MSG_WriteByte(buf, 255); //the serverinfo + MSG_WriteLong(buf, (final?0x80000000:0)|offset); + MSG_WriteString(buf, enckey); + MSG_WriteString(buf, encdata); + } + offset += chunk; + } + } + } + InfoSync_Remove(&sync, 0); + } + InfoSync_Clear(&sync); } #ifdef NQPROT -void CLNQ_WriteServerData(sizebuf_t *buf) +void CLNQ_WriteServerData(sizebuf_t *buf) //for demo recording { unsigned int protmain; unsigned int protfl = 0; unsigned int i; const char *val; - val = Info_ValueForKey(cl.serverinfo, "*csprogs"); + val = InfoBuf_ValueForKey(&cl.serverinfo, "*csprogs"); if (*val) { MSG_WriteByte(buf, svc_stufftext); MSG_WriteString(buf, va("csqc_progcrc \"%s\"\n", val)); } - val = Info_ValueForKey(cl.serverinfo, "*csprogssize"); + val = InfoBuf_ValueForKey(&cl.serverinfo, "*csprogssize"); if (*val) { MSG_WriteByte(buf, svc_stufftext); MSG_WriteString(buf, va("csqc_progsize \"%s\"\n", val)); } - val = Info_ValueForKey(cl.serverinfo, "*csprogsname"); + val = InfoBuf_ValueForKey(&cl.serverinfo, "*csprogsname"); if (*val) { MSG_WriteByte(buf, svc_stufftext); @@ -1724,7 +1774,7 @@ void CL_Record_f (void) cls.demorecording = DPB_QUAKEWORLD; - CLQW_RecordServerData(&buf); + CLQW_RecordServerData(&buf, &seq); // send music Media_WriteCurrentTrack(&buf); @@ -1881,19 +1931,21 @@ void CL_Record_f (void) MSG_WriteByte (&buf, player->pl); } - if (*player->userinfo) + if (player->userinfo.numkeys) { MSG_WriteByte (&buf, svc_updateentertime); MSG_WriteByte (&buf, i); MSG_WriteFloat (&buf, realtime - player->realentertime); //seconds since } - if (*player->userinfo) + if (player->userinfo.numkeys) { + char info[MAX_LOCALINFO_STRING]; + InfoBuf_ToString(&player->userinfo, info, sizeof(info), basicuserinfos, NULL, NULL, NULL, NULL); MSG_WriteByte (&buf, svc_updateuserinfo); MSG_WriteByte (&buf, i); MSG_WriteLong (&buf, player->userid); - MSG_WriteString (&buf, player->userinfo); + MSG_WriteString (&buf, info); } if (buf.cursize > buf.maxsize/2) @@ -2954,7 +3006,11 @@ void CL_QTVPlay_f (void) { Q_snprintfz(msg+msglen, sizeof(msg)-msglen, "QTV_EZQUAKE_EXT: 3\n" - "USERINFO: %s\n", cls.userinfo[0]); + "USERINFO: "); + msglen += strlen(msg+msglen); + InfoBuf_ToString(&cls.userinfo[0], msg+msglen, sizeof(msg)-msglen-1, basicuserinfos, NULL, NULL, NULL, NULL); + msglen += strlen(msg+msglen); + Q_strncatz(msg+msglen, "\n", sizeof(msg)-msglen); msglen += strlen(msg+msglen); } diff --git a/engine/client/cl_input.c b/engine/client/cl_input.c index 12f7a6670..9a3df2f1d 100644 --- a/engine/client/cl_input.c +++ b/engine/client/cl_input.c @@ -1416,23 +1416,23 @@ void CL_UpdateSeats(void) { char *ver; char buffer[2048]; - char newinfo[2048]; - Q_strncpyz(newinfo, cls.userinfo[cl.splitclients], sizeof(newinfo)); + char infostr[2048]; + infobuf_t *info = &cls.userinfo[cl.splitclients]; //some userinfos should always have a value - if (!*Info_ValueForKey(newinfo, "name")) //$name-2 - Info_SetValueForKey(newinfo, "name", va("%s-%i\n", Info_ValueForKey(cls.userinfo[0], "name"), cl.splitclients+1), sizeof(newinfo)); + if (!*InfoBuf_ValueForKey(info, "name")) //$name-2 + InfoBuf_SetKey(info, "name", va("%s-%i\n", InfoBuf_ValueForKey(&cls.userinfo[0], "name"), cl.splitclients+1)); if (cls.protocol != CP_QUAKE2) { - if (!*Info_ValueForKey(newinfo, "team")) //put players on the same team by default. this avoids team damage in coop, and if you're playing on the same computer then you probably want to be on the same team anyway. - Info_SetValueForKey(newinfo, "team", Info_ValueForKey(cls.userinfo[0], "team"), sizeof(newinfo)); - if (!*Info_ValueForKey(newinfo, "bottomcolor")) //bottom colour implies team in nq - Info_SetValueForKey(newinfo, "bottomcolor", Info_ValueForKey(cls.userinfo[0], "bottomcolor"), sizeof(newinfo)); - if (!*Info_ValueForKey(newinfo, "topcolor")) //should probably pick a random top colour or something - Info_SetValueForKey(newinfo, "topcolor", Info_ValueForKey(cls.userinfo[0], "topcolor"), sizeof(newinfo)); + if (!*InfoBuf_ValueForKey(info, "team")) //put players on the same team by default. this avoids team damage in coop, and if you're playing on the same computer then you probably want to be on the same team anyway. + InfoBuf_SetKey(info, "team", InfoBuf_ValueForKey(&cls.userinfo[0], "team")); + if (!*InfoBuf_ValueForKey(info, "bottomcolor")) //bottom colour implies team in nq + InfoBuf_SetKey(info, "bottomcolor", InfoBuf_ValueForKey(&cls.userinfo[0], "bottomcolor")); + if (!*InfoBuf_ValueForKey(info, "topcolor")) //should probably pick a random top colour or something + InfoBuf_SetKey(info, "topcolor", InfoBuf_ValueForKey(&cls.userinfo[0], "topcolor")); } - if (!*Info_ValueForKey(newinfo, "skin")) //give players the same skin by default, because we can. q2 cares for teams. qw might as well (its not like anyone actually uses them thanks to enemy-skin forcing). - Info_SetValueForKey(newinfo, "skin", Info_ValueForKey(cls.userinfo[0], "skin"), sizeof(newinfo)); + if (!*InfoBuf_ValueForKey(info, "skin")) //give players the same skin by default, because we can. q2 cares for teams. qw might as well (its not like anyone actually uses them thanks to enemy-skin forcing). + InfoBuf_SetKey(info, "skin", InfoBuf_ValueForKey(&cls.userinfo[0], "skin")); #ifdef SVNREVISION if (strcmp(STRINGIFY(SVNREVISION), "-")) @@ -1440,11 +1440,12 @@ void CL_UpdateSeats(void) else #endif ver = va("%s v%i.%02i", DISTRIBUTION, FTE_VER_MAJOR, FTE_VER_MINOR); - Info_SetValueForStarKey(newinfo, "*ver", ver, sizeof(newinfo)); + InfoBuf_SetStarKey(info, "*ver", ver); + InfoBuf_ToString(info, infostr, sizeof(infostr), NULL, NULL, NULL, &cls.userinfosync, info); - CL_SendClientCommand(true, "addseat %i %s", cl.splitclients, COM_QuotedString(newinfo, buffer, sizeof(buffer), false)); + CL_SendClientCommand(true, "addseat %i %s", cl.splitclients, COM_QuotedString(infostr, buffer, sizeof(buffer), false)); } - else if (cl.splitclients > targ) + else if (cl.splitclients > targ && targ >= 1) CL_SendClientCommand(true, "addseat %i", targ); } } @@ -1510,13 +1511,6 @@ qboolean CLQ2_SendCmd (sizebuf_t *buf) if (cmd->msec > 100) cmd->msec = 100; - if (cls.resendinfo) - { - MSG_WriteByte (&cls.netchan.message, clcq2_userinfo); - MSG_WriteString (&cls.netchan.message, cls.userinfo[seat]); - cls.resendinfo = false; - } - MSG_WriteByte (buf, clcq2_move); if (seat) @@ -1703,6 +1697,96 @@ qboolean CLQW_SendCmd (sizebuf_t *buf, qboolean actuallysend) return dontdrop; } +static void CL_SendUserinfoUpdate(void) +{ + const char *key = cls.userinfosync.keys[0].name; + infobuf_t *info = cls.userinfosync.keys[0].context; + size_t bloboffset = cls.userinfosync.keys[0].syncpos; + unsigned int seat = info - cls.userinfo; + size_t blobsize; + const char *blobdata = InfoBuf_BlobForKey(info, key, &blobsize); + size_t sendsize = blobsize - bloboffset; + + const char *s; + qboolean final = true; + char enckey[2048]; + char encval[2048]; + //handle splitscreen + char pl[64]; + + if (seat) + Q_snprintfz(pl, sizeof(pl), "%i ", seat); + else + *pl = 0; + +#ifdef Q3CLIENT + if (cls.protocol == CP_QUAKE3) + { //q3 sends it all in one go + char userinfo[2048]; + InfoBuf_ToString(info, userinfo, sizeof(userinfo), NULL, NULL, NULL, NULL, NULL); + CLQ3_SendClientCommand("userinfo \"%s\"", userinfo); + InfoSync_Strip(&cls.userinfosync, info); //can't track this stuff. all or nothing. + return; + } +#endif +#ifdef Q2CLIENT + if (cls.protocol == CP_QUAKE2 && !cls.fteprotocolextensions) + { + char userinfo[2048]; + InfoSync_Strip(&cls.userinfosync, info); //can't track this stuff. all or nothing. + InfoBuf_ToString(info, userinfo, sizeof(userinfo), NULL, NULL, NULL, NULL, NULL); + + MSG_WriteByte (&cls.netchan.message, clcq2_userinfo); + SZ_Write(&cls.netchan.message, pl, strlen(pl)); + MSG_WriteString (&cls.netchan.message, userinfo); + return; + } +#endif + + if (seat < max(1,cl.splitclients)) + { + if (sendsize > 1023) + { + final = false; + sendsize = 1023; //should be a multiple of 3 + } + + if (!InfoBuf_EncodeString(key, strlen(key), enckey, sizeof(enckey)) || + !InfoBuf_EncodeString(blobdata+bloboffset, sendsize, encval, sizeof(encval))) + { //some buffer wasn't big enough... shouldn't happen. + InfoSync_Remove(&cls.userinfosync, 0); + return; + } + + if (final && !bloboffset && *encval != '\xff' && *encval != '\xff') + { //vanilla-compatible info. + s = va("%ssetinfo \"%s\" \"%s\"", pl, enckey, encval); + } + else if (cls.fteprotocolextensions2 & PEXT2_INFOBLOBS) + { //only flood servers that actually support it. + if (final) + s = va("%ssetinfo \"%s\" \"%s\" %u", pl, enckey, encval, bloboffset); + else + s = va("%ssetinfo \"%s\" \"%s\" %u+", pl, enckey, encval, bloboffset); + } + else + { //server doesn't support it, just ignore the key + InfoSync_Remove(&cls.userinfosync, 0); + return; + } + if (cls.protocol == CP_QUAKE2) + MSG_WriteByte (&cls.netchan.message, clcq2_stringcmd); + else + MSG_WriteByte (&cls.netchan.message, clc_stringcmd); + MSG_WriteString (&cls.netchan.message, s); + } + + if (bloboffset+sendsize == blobsize) + InfoSync_Remove(&cls.userinfosync, 0); + else + cls.userinfosync.keys[0].syncpos += sendsize; +} + void CL_SendCmd (double frametime, qboolean mainloop) { sizebuf_t buf; @@ -2001,6 +2085,10 @@ void CL_SendCmd (double frametime, qboolean mainloop) Z_Free(clientcmdlist); clientcmdlist = next; } + + //only start spamming userinfo blobs once we receive the initial serverinfo. + while (cls.userinfosync.numkeys && cls.netchan.message.cursize < 512 && (cl.haveserverinfo || cls.protocol == CP_QUAKE2 || cls.protocol == CP_QUAKE3)) + CL_SendUserinfoUpdate(); } // if we're not doing clc_moves and etc, don't continue unless we wrote something previous diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index da91643a9..e47dbf644 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -432,8 +432,6 @@ void CL_ConnectToDarkPlaces(char *challenge, netadr_t *adr) cls.fteprotocolextensions2 = 0; cls.ezprotocolextensions1 = 0; - cls.resendinfo = false; - connectinfo.time = realtime; // for retransmit requests Q_snprintfz(data, sizeof(data), "%c%c%c%cconnect\\protocol\\darkplaces 3\\protocols\\DP7 DP6 DP5 RMQ FITZ NEHAHRABJP2 NEHAHRABJP NEHAHRABJP3 QUAKE\\challenge\\%s\\name\\%s", 255, 255, 255, 255, challenge, name.string); @@ -619,8 +617,6 @@ void CL_SendConnectPacket (netadr_t *to, int mtu, t2 = Sys_DoubleTime (); - cls.resendinfo = false; - connectinfo.time = realtime+t2-t1; // for retransmit requests //fixme: we shouldn't cycle these so much @@ -652,7 +648,10 @@ void CL_SendConnectPacket (netadr_t *to, int mtu, *a = '@'; } //the info itself - Q_strncatz(data, cls.userinfo[0], sizeof(data)); + { + static const char *prioritykeys[] = {"name", "password", "spectator", "lang", "rate", "team", "topcolor", "bottomcolor", "skin", "_", "*", NULL}; + InfoBuf_ToString(&cls.userinfo[0], data+strlen(data), sizeof(data)-strlen(data), prioritykeys, NULL, NULL, &cls.userinfosync, &cls.userinfo[0]); + } if (connectinfo.protocol == CP_QUAKEWORLD) //zquake extension info. Q_strncatz(data, va("\\*z_ext\\%i", SUPPORTED_Z_EXTENSIONS), sizeof(data)); @@ -1633,6 +1632,8 @@ void CL_ClearState (void) Z_Free(cl.windowtitle); + InfoBuf_Clear(&cl.serverinfo, true); + // wipe the entire cl structure memset (&cl, 0, sizeof(cl)); @@ -1647,7 +1648,7 @@ void CL_ClearState (void) cl.allocated_client_slots = sv.allocated_client_slots; #endif - SZ_Clear (&cls.netchan.message); +// SZ_Clear (&cls.netchan.message); r_worldentity.model = NULL; @@ -1666,7 +1667,7 @@ void CL_ClearState (void) cl.playerview[i].maxspeed = 320; cl.playerview[i].entgravity = 1; - cl.playerview[i].chatstate = atoi(Info_ValueForKey(cls.userinfo[i], "chat")); + cl.playerview[i].chatstate = atoi(InfoBuf_ValueForKey(&cls.userinfo[i], "chat")); } #ifdef QUAKESTATS for (i = 0; i < MAX_CLIENTS; i++) //in case some server doesn't support it @@ -1889,7 +1890,7 @@ void CL_User_f (void) if (!cl.players[i].userinfovalid) Con_Printf("name: %s\ncolour %i %i\nping: %i\n", cl.players[i].name, cl.players[i].rbottomcolor, cl.players[i].rtopcolor, cl.players[i].ping); else - Info_Print (cl.players[i].userinfo, ""); + InfoBuf_Print (&cl.players[i].userinfo, ""); found = true; } } @@ -1953,8 +1954,8 @@ void CL_Color_f (void) if (Cmd_Argc() == 1) { - char *t = Info_ValueForKey (cls.userinfo[pnum], "topcolor"); - char *b = Info_ValueForKey (cls.userinfo[pnum], "bottomcolor"); + char *t = InfoBuf_ValueForKey(&cls.userinfo[pnum], "topcolor"); + char *b = InfoBuf_ValueForKey(&cls.userinfo[pnum], "bottomcolor"); if (!*t) t = "0"; if (!*b) @@ -1973,10 +1974,10 @@ void CL_Color_f (void) t = Cmd_Argv(1); b = (Cmd_Argc()==2)?t:Cmd_Argv(2); if (!strcmp(t, "-1")) - t = Info_ValueForKey (cls.userinfo[pnum], "topcolor"); + t = InfoBuf_ValueForKey(&cls.userinfo[pnum], "topcolor"); top = CL_ParseColour(t); if (!strcmp(b, "-1")) - b = Info_ValueForKey (cls.userinfo[pnum], "bottomcolor"); + b = InfoBuf_ValueForKey(&cls.userinfo[pnum], "bottomcolor"); bottom = CL_ParseColour(b); Q_snprintfz (num, sizeof(num), (top&0xff000000)?"0x%06x":"%i", top & 0xffffff); @@ -2049,7 +2050,7 @@ void CL_PakDownloads(int mode) void CL_CheckServerPacks(void) { static int oldpure; - int pure = atof(Info_ValueForKey(cl.serverinfo, "sv_pure")); + int pure = atof(InfoBuf_ValueForKey(&cl.serverinfo, "sv_pure")); if (pure < cl_pure.ival) pure = cl_pure.ival; pure = bound(0, pure, 2); @@ -2094,8 +2095,8 @@ void CL_CheckServerInfo(void) spectating = false; oldteamplay = cl.teamplay; - cl.teamplay = atoi(Info_ValueForKey(cl.serverinfo, "teamplay")); - cls.deathmatch = cl.deathmatch = atoi(Info_ValueForKey(cl.serverinfo, "deathmatch")); + cl.teamplay = atoi(InfoBuf_ValueForKey(&cl.serverinfo, "teamplay")); + cls.deathmatch = cl.deathmatch = atoi(InfoBuf_ValueForKey(&cl.serverinfo, "deathmatch")); cls.allow_cheats = false; cls.allow_semicheats=true; @@ -2106,16 +2107,16 @@ void CL_CheckServerInfo(void) // cls.allow_overbrightlight; - cls.allow_csqc = atoi(Info_ValueForKey(cl.serverinfo, "anycsqc")) || *Info_ValueForKey(cl.serverinfo, "*csprogs"); - cl.csqcdebug = atoi(Info_ValueForKey(cl.serverinfo, "*csqcdebug")); + cls.allow_csqc = atoi(InfoBuf_ValueForKey(&cl.serverinfo, "anycsqc")) || *InfoBuf_ValueForKey(&cl.serverinfo, "*csprogs"); + cl.csqcdebug = atoi(InfoBuf_ValueForKey(&cl.serverinfo, "*csqcdebug")); - if (spectating || cls.demoplayback || atoi(Info_ValueForKey(cl.serverinfo, "watervis"))) + if (spectating || cls.demoplayback || atoi(InfoBuf_ValueForKey(&cl.serverinfo, "watervis"))) cls.allow_watervis=true; - if (spectating || cls.demoplayback || atoi(Info_ValueForKey(cl.serverinfo, "allow_skybox")) || atoi(Info_ValueForKey(cl.serverinfo, "allow_skyboxes"))) + if (spectating || cls.demoplayback || atoi(InfoBuf_ValueForKey(&cl.serverinfo, "allow_skybox")) || atoi(InfoBuf_ValueForKey(&cl.serverinfo, "allow_skyboxes"))) cls.allow_skyboxes=true; //mostly obsolete. - s = Info_ValueForKey(cl.serverinfo, "fbskins"); + s = InfoBuf_ValueForKey(&cl.serverinfo, "fbskins"); if (*s) cls.allow_fbskins = atof(s); else if (cl.teamfortress) @@ -2123,7 +2124,7 @@ void CL_CheckServerInfo(void) else cls.allow_fbskins = 1; - s = Info_ValueForKey(cl.serverinfo, "*cheats"); + s = InfoBuf_ValueForKey(&cl.serverinfo, "*cheats"); if (spectating || cls.demoplayback || !stricmp(s, "on")) cls.allow_cheats = true; @@ -2134,14 +2135,14 @@ void CL_CheckServerInfo(void) cls.allow_cheats = true; #endif - s = Info_ValueForKey(cl.serverinfo, "strict"); + s = InfoBuf_ValueForKey(&cl.serverinfo, "strict"); if ((!spectating && !cls.demoplayback && *s && strcmp(s, "0")) || !ruleset_allow_semicheats.ival) { cls.allow_semicheats = false; cls.allow_cheats = false; } - cls.z_ext = atoi(Info_ValueForKey(cl.serverinfo, "*z_ext")); + cls.z_ext = atoi(InfoBuf_ValueForKey(&cl.serverinfo, "*z_ext")); #ifdef NQPROT if (cls.protocol == CP_NETQUAKE && CPNQ_IS_DP) @@ -2151,22 +2152,22 @@ void CL_CheckServerInfo(void) else #endif { - cls.maxfps = atof(Info_ValueForKey(cl.serverinfo, "maxfps")); + cls.maxfps = atof(InfoBuf_ValueForKey(&cl.serverinfo, "maxfps")); if (cls.maxfps < 20) cls.maxfps = 72; // movement vars for prediction - cl.bunnyspeedcap = Q_atof(Info_ValueForKey(cl.serverinfo, "pm_bunnyspeedcap")); - movevars.slidefix = (Q_atof(Info_ValueForKey(cl.serverinfo, "pm_slidefix")) != 0); - movevars.airstep = (Q_atof(Info_ValueForKey(cl.serverinfo, "pm_airstep")) != 0); - movevars.stepdown = (Q_atof(Info_ValueForKey(cl.serverinfo, "pm_stepdown")) != 0); - movevars.walljump = (Q_atof(Info_ValueForKey(cl.serverinfo, "pm_walljump"))); - movevars.ktjump = Q_atof(Info_ValueForKey(cl.serverinfo, "pm_ktjump")); - s = Info_ValueForKey(cl.serverinfo, "pm_stepheight"); + cl.bunnyspeedcap = Q_atof(InfoBuf_ValueForKey(&cl.serverinfo, "pm_bunnyspeedcap")); + movevars.slidefix = (Q_atof(InfoBuf_ValueForKey(&cl.serverinfo, "pm_slidefix")) != 0); + movevars.airstep = (Q_atof(InfoBuf_ValueForKey(&cl.serverinfo, "pm_airstep")) != 0); + movevars.stepdown = (Q_atof(InfoBuf_ValueForKey(&cl.serverinfo, "pm_stepdown")) != 0); + movevars.walljump = (Q_atof(InfoBuf_ValueForKey(&cl.serverinfo, "pm_walljump"))); + movevars.ktjump = Q_atof(InfoBuf_ValueForKey(&cl.serverinfo, "pm_ktjump")); + s = InfoBuf_ValueForKey(&cl.serverinfo, "pm_stepheight"); movevars.stepheight = *s?Q_atof(s):PM_DEFAULTSTEPHEIGHT; - s = Info_ValueForKey(cl.serverinfo, "pm_watersinkspeed"); + s = InfoBuf_ValueForKey(&cl.serverinfo, "pm_watersinkspeed"); movevars.watersinkspeed = *s?Q_atof(s):60; - s = Info_ValueForKey(cl.serverinfo, "pm_flyfriction"); + s = InfoBuf_ValueForKey(&cl.serverinfo, "pm_flyfriction"); movevars.flyfriction = *s?Q_atof(s):4; } movevars.coordsize = cls.netchan.netprim.coordsize; @@ -2174,9 +2175,9 @@ void CL_CheckServerInfo(void) // Initialize cl.maxpitch & cl.minpitch if (cls.protocol == CP_QUAKEWORLD || cls.protocol == CP_NETQUAKE) { - s = Info_ValueForKey (cl.serverinfo, "maxpitch"); + s = InfoBuf_ValueForKey(&cl.serverinfo, "maxpitch"); cl.maxpitch = *s ? Q_atof(s) : ((cl_fullpitch_nq.ival && !cl.haveserverinfo)?90.0f:80.0f); - s = Info_ValueForKey (cl.serverinfo, "minpitch"); + s = InfoBuf_ValueForKey(&cl.serverinfo, "minpitch"); cl.minpitch = *s ? Q_atof(s) : ((cl_fullpitch_nq.ival && !cl.haveserverinfo)?-90.0f:-70.0f); if (cls.protocol == CP_NETQUAKE) @@ -2195,9 +2196,9 @@ void CL_CheckServerInfo(void) cl.maxpitch = bound(-89.9, cl.maxpitch, 89.9); cl.minpitch = bound(-89.9, cl.minpitch, 89.9); - cl.hexen2pickups = atoi(Info_ValueForKey(cl.serverinfo, "sv_pupglow")); + cl.hexen2pickups = atoi(InfoBuf_ValueForKey(&cl.serverinfo, "sv_pupglow")); - allowed = atoi(Info_ValueForKey(cl.serverinfo, "allow")); + allowed = atoi(InfoBuf_ValueForKey(&cl.serverinfo, "allow")); if (allowed & 1) cls.allow_watervis = true; // if (allowed & 2) @@ -2224,14 +2225,14 @@ void CL_CheckServerInfo(void) if (spectating || cls.demoplayback) cl.fpd = 0; else - cl.fpd = atoi(Info_ValueForKey(cl.serverinfo, "fpd")); + cl.fpd = atoi(InfoBuf_ValueForKey(&cl.serverinfo, "fpd")); - cl.gamespeed = atof(Info_ValueForKey(cl.serverinfo, "*gamespeed"))/100.f; + cl.gamespeed = atof(InfoBuf_ValueForKey(&cl.serverinfo, "*gamespeed"))/100.f; if (cl.gamespeed < 0.1) cl.gamespeed = 1; #ifdef QUAKESTATS - s = Info_ValueForKey(cl.serverinfo, "status"); + s = InfoBuf_ValueForKey(&cl.serverinfo, "status"); oldstate = cl.matchstate; if (!stricmp(s, "standby")) cl.matchstate = MATCH_STANDBY; @@ -2253,7 +2254,7 @@ void CL_CheckServerInfo(void) { //always update it. this is to try to cope with overtime. oldstate = cl.matchstate = MATCH_INPROGRESS; - cl.matchgametimestart = cl.gametime + time - 60*atof(Info_ValueForKey(cl.serverinfo, "timelimit")); + cl.matchgametimestart = cl.gametime + time - 60*atof(InfoBuf_ValueForKey(&cl.serverinfo, "timelimit")); } else { @@ -2335,11 +2336,11 @@ void CL_FullInfo_f (void) if (!stricmp(key, pmodel_name) || !stricmp(key, emodel_name)) continue; - Info_SetValueForKey (cls.userinfo[pnum], key, value, sizeof(cls.userinfo[pnum])); + InfoBuf_SetKey (&cls.userinfo[pnum], key, value); } } -void CL_SetInfo (int pnum, char *key, char *value) +void CL_SetInfoBlob (int pnum, const char *key, const char *value, size_t valuesize) { cvar_t *var; if (!pnum) @@ -2352,25 +2353,11 @@ void CL_SetInfo (int pnum, char *key, char *value) } } - Info_SetValueForStarKey (cls.userinfo[pnum], key, value, sizeof(cls.userinfo[pnum])); - if (cls.state >= ca_connected && !cls.demoplayback) - { - if (pnum >= cl.splitclients) - return; - -#ifdef Q2CLIENT - if ((cls.protocol == CP_QUAKE2 || cls.protocol == CP_QUAKE3) && !cls.fteprotocolextensions) - cls.resendinfo = true; - else -#endif - if (cls.protocol != CP_NETQUAKE || (cls.fteprotocolextensions & PEXT_BIGUSERINFOS)) - { - if (pnum) - CL_SendClientCommand(true, "%i setinfo %s \"%s\"", pnum+1, key, value); - else - CL_SendClientCommand(true, "setinfo %s \"%s\"", key, value); - } - } + InfoBuf_SetStarBlobKey(&cls.userinfo[pnum], key, value, valuesize); +} +void CL_SetInfo (int pnum, const char *key, const char *value) +{ + CL_SetInfoBlob(pnum, key, value, strlen(value)); } /* ================== @@ -2385,7 +2372,8 @@ void CL_SetInfo_f (void) int pnum = CL_TargettedSplit(true); if (Cmd_Argc() == 1) { - Info_Print (cls.userinfo[pnum], ""); + InfoBuf_Print (&cls.userinfo[pnum], ""); + Con_Printf("[%u]", (unsigned int)cls.userinfo[pnum].totalsize); return; } if (Cmd_Argc() != 3) @@ -2402,18 +2390,18 @@ void CL_SetInfo_f (void) if (!strcmp(Cmd_Argv(1), "*")) if (!strcmp(Cmd_Argv(2), "")) { //clear it out - char *k; + const char *k; for(i=0;;) { - k = Info_KeyForNumber(cls.userinfo[pnum], i); - if (!*k) + k = InfoBuf_KeyForNumber(&cls.userinfo[pnum], i); + if (!k) break; //no more. else if (*k == '*') i++; //can't remove * keys - else if ((var = Cvar_FindVar(k)) && var->flags&CVAR_USERINFO) + else if ((var = Cvar_FindVar(k)) && (var->flags&CVAR_USERINFO)) i++; //this one is a cvar. else - Info_RemoveKey(cls.userinfo[pnum], k); //we can remove this one though, so yay. + InfoBuf_RemoveKey(&cls.userinfo[pnum], k); //we can remove this one though, so yay. } return; @@ -2422,10 +2410,49 @@ void CL_SetInfo_f (void) return; } - CL_SetInfo(pnum, Cmd_Argv(1), Cmd_Argv(2)); } +#ifdef _DEBUG +void CL_SetInfoBlob_f (void) +{ + qofs_t fsize; + void *data; + int pnum = CL_TargettedSplit(true); + if (Cmd_Argc() == 1) + { + InfoBuf_Print (&cls.userinfo[pnum], ""); + return; + } + if (Cmd_Argc() != 3) + { + Con_TPrintf ("usage: setinfo [ ]\n"); + return; + } + + //user isn't allowed to set pmodel, emodel, *foo as these could break stuff. + if (!stricmp(Cmd_Argv(1), pmodel_name) || !strcmp(Cmd_Argv(1), emodel_name)) + return; + if (Cmd_Argv(1)[0] == '*') + { + Con_Printf ("Can't set * keys\n"); + return; + } + + data = FS_MallocFile(Cmd_Argv(2), FS_GAME, &fsize); + if (!data) + { + Con_Printf ("Unable to read %s\n", Cmd_Argv(2)); + return; + } + if (fsize > 64*1024*1024) + Con_Printf ("File is over 64mb\n"); + else + CL_SetInfoBlob(pnum, Cmd_Argv(1), data, fsize); + FS_FreeFile(data); +} +#endif + void CL_SaveInfo(vfsfile_t *f) { int i; @@ -2435,12 +2462,12 @@ void CL_SaveInfo(vfsfile_t *f) if (i) { VFS_WRITE(f, va("p%i setinfo * \"\"\n", i+1), 16); - Info_WriteToFile(f, cls.userinfo[i], va("p%i setinfo", i+1), 0); + InfoBuf_WriteToFile(f, &cls.userinfo[i], va("p%i setinfo", i+1), 0); } else { VFS_WRITE(f, "setinfo * \"\"\n", 13); - Info_WriteToFile(f, cls.userinfo[i], "setinfo", CVAR_USERINFO); + InfoBuf_WriteToFile(f, &cls.userinfo[i], "setinfo", CVAR_USERINFO); } } } @@ -3921,10 +3948,8 @@ void CL_ServerInfo_f(void) { if (!sv.state && cls.state && Cmd_Argc() < 2) { - if (cls.demoplayback || cls.protocol != CP_QUAKEWORLD) - { - Info_Print (cl.serverinfo, ""); - } + if (cl.haveserverinfo) + InfoBuf_Print (&cl.serverinfo, ""); else Cmd_ForwardToServer (); } @@ -4117,6 +4142,12 @@ void CL_Demo_SetSpeed_f(void) Con_Printf("demo playback speed %g%%\n", cl_demospeed.value * 100); } +static void CL_UserinfoChanged(void *ctx, const char *keyname) +{ + InfoSync_Add(&cls.userinfosync, ctx, keyname); +} + + void CL_Skygroup_f(void); /* ================= @@ -4133,6 +4164,7 @@ void CL_Init (void) extern cvar_t noskins; #endif char *ver; + size_t seat; cls.state = ca_disconnected; @@ -4143,7 +4175,12 @@ void CL_Init (void) #endif ver = va("%s v%i.%02i", DISTRIBUTION, FTE_VER_MAJOR, FTE_VER_MINOR); - Info_SetValueForStarKey (cls.userinfo[0], "*ver", ver, sizeof(cls.userinfo[0])); + for (seat = 0; seat < MAX_SPLITS; seat++) + { + cls.userinfo[seat].ChangeCTX = &cls.userinfo[seat]; + cls.userinfo[seat].ChangeCB = CL_UserinfoChanged; + InfoBuf_SetStarKey (&cls.userinfo[seat], "*ver", ver); + } InitValidation(); @@ -4412,6 +4449,9 @@ void CL_Init (void) Cmd_AddCommand ("user", CL_User_f); Cmd_AddCommand ("users", CL_Users_f); +#ifdef _DEBUG + Cmd_AddCommand ("setinfoblob", CL_SetInfoBlob_f); +#endif Cmd_AddCommand ("setinfo", CL_SetInfo_f); Cmd_AddCommand ("fullinfo", CL_FullInfo_f); @@ -5756,7 +5796,7 @@ void CL_ReadCDKey(void) { //q3 cdkey //you don't need one, just use a server without sv_strictauth set to 0. char *buffer; - buffer = COM_LoadTempFile("q3key", NULL); + buffer = COM_LoadTempFile("q3key", FSLF_IGNOREPURE, NULL); if (buffer) //a cdkey is meant to be 16 chars { char *chr; @@ -6221,6 +6261,7 @@ to run quit through here before the final handoff to the sys code. */ void Host_Shutdown(void) { + size_t i; if (!host_initialized) return; host_initialized = false; @@ -6290,6 +6331,10 @@ void Host_Shutdown(void) Plug_Shutdown(true); #endif + for (i = 0; i < MAX_SPLITS; i++) + InfoBuf_Clear(&cls.userinfo[i], true); + InfoSync_Clear(&cls.userinfosync); + Con_Shutdown(); COM_BiDi_Shutdown(); Memory_DeInit(); diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 34424cbdc..f1f429fb3 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -1235,10 +1235,10 @@ static int CL_LoadModels(int stage, qboolean dontactuallyload) qboolean anycsqc; char *endptr; unsigned int chksum; - anycsqc = atoi(Info_ValueForKey(cl.serverinfo, "anycsqc")); + anycsqc = atoi(InfoBuf_ValueForKey(&cl.serverinfo, "anycsqc")); if (cls.demoplayback) anycsqc = true; - s = Info_ValueForKey(cl.serverinfo, "*csprogs"); + s = InfoBuf_ValueForKey(&cl.serverinfo, "*csprogs"); chksum = strtoul(s, &endptr, 0); if (*endptr) { @@ -1515,7 +1515,7 @@ static void Sound_CheckDownloads (void) // if (cls.fteprotocolextensions & PEXT_CSQC) { char *s; - s = Info_ValueForKey(cl.serverinfo, "*csprogs"); + s = InfoBuf_ValueForKey(&cl.serverinfo, "*csprogs"); if (*s) //only allow csqc if the server says so, and the 'checksum' matches. { extern cvar_t cl_download_csprogs, cl_nocsqc; @@ -1640,6 +1640,8 @@ void CL_RequestNextDownload (void) current_loading_size = cl.contentstage; if (stage < 0) return; + //if (cls.userinfosync.numkeys) + // return; //don't prespawn until we've actually sent all our initial userinfo. if (requiredownloads.ival && COM_HasWork()) { SCR_SetLoadingFile("loading content"); @@ -2457,7 +2459,7 @@ void DL_Abort(qdownload_t *dl, enum qdlabort aborttype) case DL_DARKPLACES: case DL_QWCHUNKS: { - char *serverversion = Info_ValueForKey(cl.serverinfo, "*version"); + char *serverversion = InfoBuf_ValueForKey(&cl.serverinfo, "*version"); if (strncmp(serverversion , "MVDSV ", 6)) //don't tell mvdsv to stop, because it has retarded annoying clientprints that are spammy as fuck, and we don't want that. CL_SendClientCommand(true, "stopdownload"); } @@ -3116,7 +3118,7 @@ static void CLQW_ParseServerData (void) COM_FlushTempoaryPacks(); COM_Gamedir(str, NULL); #ifndef CLIENTONLY - Info_SetValueForStarKey (svs.info, "*gamedir", str, MAX_SERVERINFO_STRING); + InfoBuf_SetStarKey (&svs.info, "*gamedir", str); #endif } @@ -3676,7 +3678,7 @@ static void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caut COM_FlushTempoaryPacks(); COM_Gamedir(str, NULL); #ifndef CLIENTONLY - Info_SetValueForStarKey (svs.info, "*gamedir", str, MAX_SERVERINFO_STRING); + InfoBuf_SetStarKey (&svs.info, "*gamedir", str); #endif } } @@ -3752,29 +3754,29 @@ static void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caut //fill in the csqc stuff if (!cl_dp_csqc_progscrc) { - Info_RemoveKey(cl.serverinfo, "*csprogs"); - Info_RemoveKey(cl.serverinfo, "*csprogssize"); - Info_RemoveKey(cl.serverinfo, "*csprogsname"); + InfoBuf_RemoveKey(&cl.serverinfo, "*csprogs"); + InfoBuf_RemoveKey(&cl.serverinfo, "*csprogssize"); + InfoBuf_RemoveKey(&cl.serverinfo, "*csprogsname"); } else { - Info_SetValueForStarKey(cl.serverinfo, "*csprogs", va("%i", cl_dp_csqc_progscrc), sizeof(cl.serverinfo)); - Info_SetValueForStarKey(cl.serverinfo, "*csprogssize", va("%i", cl_dp_csqc_progssize), sizeof(cl.serverinfo)); - Info_SetValueForStarKey(cl.serverinfo, "*csprogsname", va("%s", cl_dp_csqc_progsname), sizeof(cl.serverinfo)); + InfoBuf_SetStarKey(&cl.serverinfo, "*csprogs", va("%i", cl_dp_csqc_progscrc)); + InfoBuf_SetStarKey(&cl.serverinfo, "*csprogssize", va("%i", cl_dp_csqc_progssize)); + InfoBuf_SetStarKey(&cl.serverinfo, "*csprogsname", va("%s", cl_dp_csqc_progsname)); } //update gamemode if (gametype != GAME_COOP) - Info_SetValueForStarKey(cl.serverinfo, "deathmatch", "1", sizeof(cl.serverinfo)); + InfoBuf_SetKey(&cl.serverinfo, "deathmatch", "1"); else - Info_SetValueForStarKey(cl.serverinfo, "deathmatch", "0", sizeof(cl.serverinfo)); - Info_SetValueForStarKey(cl.serverinfo, "teamplay", "0", sizeof(cl.serverinfo)); + InfoBuf_SetKey(&cl.serverinfo, "deathmatch", "0"); + InfoBuf_SetKey(&cl.serverinfo, "teamplay", "0"); //allow some things by default that quakeworld bans by default - Info_SetValueForStarKey(cl.serverinfo, "watervis", "1", sizeof(cl.serverinfo)); + InfoBuf_SetKey(&cl.serverinfo, "watervis", "1"); //prohibit some things that QW/FTE has enabled by default, which would be frowned upon in NQ - Info_SetValueForStarKey(cl.serverinfo, "fbskins", "0", sizeof(cl.serverinfo)); + InfoBuf_SetKey(&cl.serverinfo, "fbskins", "0"); //pretend it came from the server, and update cheat/permissions/etc CL_CheckServerInfo(); @@ -3822,7 +3824,7 @@ Con_DPrintf ("CL_SignonReply: %i\n", cls.signon); CL_SendClientCommand(true, "name \"%s\"\n", name.string); CL_SendClientCommand(true, "color %i %i\n", topcolor.ival, bottomcolor.ival); if (cl.haveserverinfo) - Info_Enumerate(cls.userinfo[0], NULL, CLNQ_SendInitialUserInfo); + InfoBuf_Enumerate(&cls.userinfo[0], NULL, CLNQ_SendInitialUserInfo); else if (CPNQ_IS_DP) { //dp needs a couple of extras to work properly in certain cases. don't send them on other servers because that generally results in error messages. CL_SendClientCommand(true, "rate %s", rate.string); @@ -4168,7 +4170,7 @@ static void CLQ2_ParseClientinfo(int i, char *s) player = &cl.players[i]; - *player->userinfo = '\0'; + InfoBuf_Clear(&player->userinfo, true); cl.players[i].userinfovalid = true; model = strchr(s, '\\'); @@ -4192,12 +4194,12 @@ static void CLQ2_ParseClientinfo(int i, char *s) } else skin = ""; - Info_SetValueForKey(player->userinfo, "model", model, MAX_INFO_STRING); - Info_SetValueForKey(player->userinfo, "skin", skin, MAX_INFO_STRING); + InfoBuf_SetValueForKey(&player->userinfo, "model", model); + InfoBuf_SetValueForKey(&player->userinfo, "skin", skin); #else - Info_SetValueForKey(player->userinfo, "skin", model, sizeof(player->userinfo)); + InfoBuf_SetValueForKey(&player->userinfo, "skin", model); #endif - Info_SetValueForKey(player->userinfo, "name", name, sizeof(player->userinfo)); + InfoBuf_SetValueForKey(&player->userinfo, "name", name); cl.players[i].userid = i; cl.players[i].rbottomcolor = 1; @@ -4288,6 +4290,8 @@ static void CLQ2_ParseConfigString (void) { Media_NamedTrack (s, NULL); } + else if (i == Q2CS_AIRACCEL) + Q_strncpyz(cl.q2airaccel, s, sizeof(cl.q2airaccel)); else if (i >= Q2CS_MODELS && i < Q2CS_MODELS+Q2MAX_MODELS) { if (*s == '/') @@ -4756,7 +4760,7 @@ static void CLQ2_ParseStartSoundPacket(void) { //a 'sexed' sound if (ent > 0 && ent <= MAX_CLIENTS) { - char *model = Info_ValueForKey(cl.players[ent-1].userinfo, "skin"); + char *model = InfoBuf_ValueForKey(&cl.players[ent-1].userinfo, "skin"); char *skin; skin = strchr(model, '/'); if (skin) @@ -4975,7 +4979,7 @@ void CL_NewTranslation (int slot) player->ttopcolor = TOP_DEFAULT; player->tbottomcolor = BOTTOM_DEFAULT; - mod = Info_ValueForKey(player->userinfo, "skin"); + mod = InfoBuf_ValueForKey(&player->userinfo, "skin"); skin = strchr(mod, '/'); if (skin) *skin++ = 0; @@ -5077,22 +5081,22 @@ static void CL_ProcessUserInfo (int slot, player_info_t *player) int i; char *col; int ospec = player->spectator; - Q_strncpyz (player->name, Info_ValueForKey (player->userinfo, "name"), sizeof(player->name)); - Q_strncpyz (player->team, Info_ValueForKey (player->userinfo, "team"), sizeof(player->team)); + Q_strncpyz (player->name, InfoBuf_ValueForKey (&player->userinfo, "name"), sizeof(player->name)); + Q_strncpyz (player->team, InfoBuf_ValueForKey (&player->userinfo, "team"), sizeof(player->team)); - col = Info_ValueForKey (player->userinfo, "topcolor"); + col = InfoBuf_ValueForKey (&player->userinfo, "topcolor"); if (!strncmp(col, "0x", 2)) player->rtopcolor = 0xff000000|strtoul(col+2, NULL, 16); else player->rtopcolor = atoi(col); - col = Info_ValueForKey (player->userinfo, "bottomcolor"); + col = InfoBuf_ValueForKey (&player->userinfo, "bottomcolor"); if (!strncmp(col, "0x", 2)) player->rbottomcolor = 0xff000000|strtoul(col+2, NULL, 16); else player->rbottomcolor = atoi(col); - i = atoi(Info_ValueForKey (player->userinfo, "*spectator")); + i = atoi(InfoBuf_ValueForKey (&player->userinfo, "*spectator")); if (i == 2) player->spectator = 2; else if (i) @@ -5108,7 +5112,7 @@ static void CL_ProcessUserInfo (int slot, player_info_t *player) #ifdef HEXEN2 /*if we're running hexen2, they have to be some class...*/ - player->h2playerclass = atoi(Info_ValueForKey (player->userinfo, "cl_playerclass")); + player->h2playerclass = atoi(InfoBuf_ValueForKey (&player->userinfo, "cl_playerclass")); if (player->h2playerclass > 5) player->h2playerclass = 5; if (player->h2playerclass < 1) @@ -5168,7 +5172,7 @@ static void CL_UpdateUserinfo (void) player = &cl.players[slot]; player->userid = MSG_ReadLong (); - Q_strncpyz (player->userinfo, MSG_ReadString(), sizeof(player->userinfo)); + InfoBuf_FromString(&player->userinfo, MSG_ReadString(), false); player->userinfovalid = true; CL_ProcessUserInfo (slot, player); @@ -5178,7 +5182,7 @@ static void CL_UpdateUserinfo (void) if (slot == cl.playerview[0].playernum && player->name[0]) { char *qz; - qz = Info_ValueForKey(player->userinfo, "Qizmo"); + qz = InfoBuf_ValueForKey(&player->userinfo, "Qizmo"); if (*qz) TP_ExecTrigger("f_qizmoconnect", false); } @@ -5193,27 +5197,55 @@ static void CL_ParseSetInfo (void) { int slot; player_info_t *player; - char key[MAX_QWMSGLEN]; - char value[MAX_QWMSGLEN]; + char *temp; + char *key; + char *val; + unsigned int offset; + qboolean final; + size_t keysize; + size_t valsize; slot = MSG_ReadByte (); - Q_strncpyz (key, MSG_ReadString(), sizeof(key)); - Q_strncpyz (value, MSG_ReadString(), sizeof(value)); + if (slot == 255) + { + slot = MSG_ReadByte(); + offset = MSG_ReadLong(); + final = !!(offset & 0x80000000); + offset &= ~0x80000000; + } + else + { + final = true; + offset = 0; + } - if (slot >= MAX_CLIENTS) - Con_Printf("INVALID SETINFO %i: %s=%s\n", slot, key, value); + temp = MSG_ReadString(); + key = InfoBuf_DecodeString(temp, temp+strlen(temp), &keysize); + + temp = MSG_ReadString(); + val = InfoBuf_DecodeString(temp, temp+strlen(temp), &valsize); + + if (slot == 255) + InfoBuf_SyncReceive(&cl.serverinfo, key, keysize, val, valsize, offset, final); + else if (slot >= MAX_CLIENTS) + Con_Printf("INVALID SETINFO %i: %s=%s\n", slot, key, val); else { player = &cl.players[slot]; - Con_DPrintf("SETINFO %s: %s=%s\n", player->name, key, value); + if (offset) + Con_DPrintf("SETINFO %s: %s+=%s\n", player->name, key, val); + else + Con_DPrintf("SETINFO %s: %s=%s\n", player->name, key, val); - Info_SetValueForStarKey (player->userinfo, key, value, sizeof(player->userinfo)); + InfoBuf_SyncReceive(&player->userinfo, key, keysize, val, valsize, offset, final); player->userinfovalid = true; CL_ProcessUserInfo (slot, player); } + Z_Free(key); + Z_Free(val); } /* @@ -5233,7 +5265,7 @@ static void CL_ServerInfo (void) Con_DPrintf("SERVERINFO: %s=%s\n", key, value); - Info_SetValueForStarKey (cl.serverinfo, key, value, MAX_SERVERINFO_STRING); + InfoBuf_SetStarKey(&cl.serverinfo, key, value); CL_CheckServerInfo(); } @@ -5286,11 +5318,11 @@ static void CL_SetStatMovevar(int pnum, int stat, int ivalue, float value) { case STAT_FRAGLIMIT: if (cls.protocol == CP_NETQUAKE && CPNQ_IS_DP) - Info_SetValueForKey(cl.serverinfo, "fraglimit", va("%g", value), sizeof(cl.serverinfo)); + InfoBuf_SetKey(&cl.serverinfo, "fraglimit", va("%g", value)); break; case STAT_TIMELIMIT: if (cls.protocol == CP_NETQUAKE && CPNQ_IS_DP) - Info_SetValueForKey(cl.serverinfo, "timelimit", va("%g", value), sizeof(cl.serverinfo)); + InfoBuf_SetKey(&cl.serverinfo, "timelimit", va("%g", value)); break; case STAT_MOVEVARS_AIRACCEL_QW_STRETCHFACTOR: //0 case STAT_MOVEVARS_AIRCONTROL_PENALTY: //0 @@ -5714,7 +5746,7 @@ static int CL_PlayerColor(player_info_t *plr, qboolean *name_coloured) // 0-6 is standard colors (red to white) // 7-13 is using secondard charactermask // 14 and afterwards repeats - t = Info_ValueForKey(plr->userinfo, "tc"); + t = InfoBuf_ValueForKey(&plr->userinfo, "tc"); if (*t) c = atoi(t); else @@ -6194,20 +6226,20 @@ static void CL_ParseStuffCmd(char *msg, int destsplit) //this protects stuffcmds if (Cmd_Argc() == 2) { cl.haveserverinfo = true; - Q_strncpyz (cl.serverinfo, Cmd_Argv(1), sizeof(cl.serverinfo)); + InfoBuf_FromString(&cl.serverinfo, Cmd_Argv(1), false); CL_CheckServerInfo(); } #if _MSC_VER > 1200 if (cls.netchan.remote_address.type != NA_LOOPBACK) - Sys_RecentServer("+connect", cls.servername, va("%s (%s)", Info_ValueForKey(cl.serverinfo, "hostname"), cls.servername), "Join QW Server"); + Sys_RecentServer("+connect", cls.servername, va("%s (%s)", InfoBuf_ValueForKey(&cl.serverinfo, "hostname"), cls.servername), "Join QW Server"); #endif } else if (!strncmp(stufftext, "//svi ", 6)) //for serverinfo over NQ protocols { Cmd_TokenizeString(stufftext+2, false, false); Con_DPrintf("SERVERINFO: %s=%s\n", Cmd_Argv(1), Cmd_Argv(2)); - Info_SetValueForStarKey (cl.serverinfo, Cmd_Argv(1), Cmd_Argv(2), MAX_SERVERINFO_STRING); + InfoBuf_SetStarKey(&cl.serverinfo, Cmd_Argv(1), Cmd_Argv(2)); CL_CheckServerInfo(); } @@ -6241,8 +6273,8 @@ static void CL_ParseStuffCmd(char *msg, int destsplit) //this protects stuffcmds { if (!cl.haveserverinfo) { - Info_SetValueForStarKey(cl.serverinfo, "maxpitch", (atoi(stufftext+13))? "90":"", sizeof(cl.serverinfo)); - Info_SetValueForStarKey(cl.serverinfo, "minpitch", (atoi(stufftext+13))?"-90":"", sizeof(cl.serverinfo)); + InfoBuf_SetKey(&cl.serverinfo, "maxpitch", (atoi(stufftext+13))? "90":""); + InfoBuf_SetKey(&cl.serverinfo, "minpitch", (atoi(stufftext+13))?"-90":""); CL_CheckServerInfo(); } } @@ -6363,12 +6395,12 @@ static void CL_ParseStuffCmd(char *msg, int destsplit) //this protects stuffcmds { player_info_t *player = &cl.players[slot]; Con_DPrintf("SETINFO %s: %s\n", player->name, value); - Q_strncpyz(player->userinfo, value, sizeof(player->userinfo)); + InfoBuf_FromString(&player->userinfo, value, false); player->userinfovalid = true; CL_ProcessUserInfo (slot, player); } } - else if (!strncmp(stufftext, "//ui ", 5)) //ui . Full user info updates. + else if (!strncmp(stufftext, "//ui ", 5)) //ui . Partial user info updates. { unsigned int slot; const char *key, *value; @@ -6380,7 +6412,7 @@ static void CL_ParseStuffCmd(char *msg, int destsplit) //this protects stuffcmds { player_info_t *player = &cl.players[slot]; Con_DPrintf("SETINFO %s: %s=%s\n", player->name, key, value); - Info_SetValueForStarKey (player->userinfo, key, value, sizeof(player->userinfo)); + InfoBuf_SetValueForStarKey (&player->userinfo, key, value); CL_ProcessUserInfo (slot, player); } } @@ -7871,7 +7903,7 @@ void CLNQ_ParseServerMessage (void) strcpy(cl.players[i].name, MSG_ReadString()); if (*cl.players[i].name) cl.players[i].userid = i+1; - Info_SetValueForKey(cl.players[i].userinfo, "name", cl.players[i].name, sizeof(cl.players[i].userinfo)); + InfoBuf_SetValueForKey(&cl.players[i].userinfo, "name", cl.players[i].name); if (!cl.nqplayernamechanged) cl.nqplayernamechanged = realtime+2; @@ -7901,9 +7933,9 @@ void CLNQ_ParseServerMessage (void) // cl.players[i].rbottomcolor = (a&0xf0)>>4; // sprintf(cl.players[i].team, "%2d", cl.players[i].rbottomcolor); - Info_SetValueForKey(cl.players[i].userinfo, "topcolor", va("%i", a&0x0f), sizeof(cl.players[i].userinfo)); - Info_SetValueForKey(cl.players[i].userinfo, "bottomcolor", va("%i", (a&0xf0)>>4), sizeof(cl.players[i].userinfo)); - Info_SetValueForKey(cl.players[i].userinfo, "team", va("%i", (a&0xf0)>>4), sizeof(cl.players[i].userinfo)); + InfoBuf_SetValueForKey(&cl.players[i].userinfo, "topcolor", va("%i", a&0x0f)); + InfoBuf_SetValueForKey(&cl.players[i].userinfo, "bottomcolor", va("%i", (a&0xf0)>>4)); + InfoBuf_SetValueForKey(&cl.players[i].userinfo, "team", va("%i", (a&0xf0)>>4)); CL_ProcessUserInfo (i, &cl.players[i]); // CLNQ_CheckPlayerIsSpectator(i); diff --git a/engine/client/cl_plugin.inc b/engine/client/cl_plugin.inc index 5fd0211fe..ce8644aaa 100644 --- a/engine/client/cl_plugin.inc +++ b/engine/client/cl_plugin.inc @@ -544,7 +544,7 @@ static qintptr_t VARGS Plug_GetPlayerInfo(void *offset, quintptr_t mask, const q out->activetime = realtime - cl.players[i].realentertime; out->userid = cl.players[i].userid; out->spectator = cl.players[i].spectator; - Q_strncpyz(out->userinfo, cl.players[i].userinfo, sizeof(out->userinfo)); + InfoBuf_ToString(&cl.players[i].userinfo, out->userinfo, sizeof(out->userinfo), basicuserinfos, NULL, NULL, NULL, NULL); Q_strncpyz(out->team, cl.players[i].team, sizeof(out->team)); } @@ -589,7 +589,7 @@ static qintptr_t VARGS Plug_GetServerInfo(void *offset, quintptr_t mask, const q if (VM_OOB(arg[0], outlen)) return false; - Q_strncpyz(outptr, cl.serverinfo, outlen); + InfoBuf_ToString(&cl.serverinfo, outptr, outlen, NULL, NULL, NULL, NULL, NULL); Q_strncatz(outptr, va("\\intermission\\%i", cl.intermissionmode), outlen); switch(cls.demoplayback) { diff --git a/engine/client/cl_screen.c b/engine/client/cl_screen.c index 479e7d17f..534350f5b 100644 --- a/engine/client/cl_screen.c +++ b/engine/client/cl_screen.c @@ -1769,7 +1769,7 @@ void SCR_DrawGameClock(void) flags = (show_gameclock.value-1); if (flags & 1) - timelimit = 60 * atof(Info_ValueForKey(cl.serverinfo, "timelimit")); + timelimit = 60 * atof(InfoBuf_ValueForKey(&cl.serverinfo, "timelimit")); else timelimit = 0; diff --git a/engine/client/cl_ui.c b/engine/client/cl_ui.c index 758282dd6..3dde29d69 100644 --- a/engine/client/cl_ui.c +++ b/engine/client/cl_ui.c @@ -664,7 +664,7 @@ void UI_RegisterFont(char *fontName, int pointSize, fontInfo_t *font) snprintf(name, sizeof(name), "fonts/fontImage_%i.dat",pointSize); - in.c = COM_LoadTempFile(name, &sz); + in.c = COM_LoadTempFile(name, 0, &sz); if (sz == sizeof(fontInfo_t)) { for(i=0; i 0 && entnum <= MAX_CLIENTS) { - char *model = Info_ValueForKey(cl.players[entnum-1].userinfo, "skin"); + char *model = InfoBuf_ValueForKey(&cl.players[entnum-1].userinfo, "skin"); char *skin; skin = strchr(model, '/'); if (skin) @@ -2140,7 +2140,7 @@ static void CLQ2_AddPacketEntities (q2frame_t *frame) ent.model=NULL; player = &cl.players[(s1->skinnum&0xff)%MAX_CLIENTS]; - modelname = Info_ValueForKey(player->userinfo, "skin"); + modelname = InfoBuf_ValueForKey(&player->userinfo, "skin"); if (!modelname[0]) modelname = "male"; skin = strchr(modelname, '/'); diff --git a/engine/client/clq3_parse.c b/engine/client/clq3_parse.c index bdb487dd6..966795eb5 100644 --- a/engine/client/clq3_parse.c +++ b/engine/client/clq3_parse.c @@ -513,7 +513,7 @@ qboolean CLQ3_SystemInfoChanged(char *str) value = "baseq3"; COM_Gamedir(value, NULL); #ifndef CLIENTONLY - Info_SetValueForStarKey (svs.info, "*gamedir", value, MAX_SERVERINFO_STRING); + InfoBuf_SetStarKey (&svs.info, "*gamedir", value); #endif } @@ -899,12 +899,6 @@ void CLQ3_SendCmd(usercmd_t *cmd) usercmd_t *to, *from; extern int keycatcher; - if (cls.resendinfo) - { - cls.resendinfo = false; - CLQ3_SendClientCommand("userinfo \"%s\"", cls.userinfo[0]); - } - //reuse the q1 array cmd->servertime = cl.servertime*1000; cmd->weapon = ccs.selected_weapon; @@ -1044,19 +1038,23 @@ void CLQ3_SendAuthPacket(netadr_t *gameserver) void CLQ3_SendConnectPacket(netadr_t *to, int challenge, int qport) { + char infostr[1024]; char data[2048]; char adrbuf[MAX_ADR_SIZE]; sizebuf_t msg; + static const char *nonq3[] = {"challenge", "qport", "protocol", "ip", "chat", NULL}; memset(&ccs, 0, sizeof(ccs)); + InfoBuf_ToString(&cls.userinfo[0], infostr, sizeof(infostr), basicuserinfos, nonq3, NULL, &cls.userinfosync, &cls.userinfo[0]); + cl.splitclients = 1; msg.data = data; msg.cursize = 0; msg.overflowed = msg.allowoverflow = 0; msg.maxsize = sizeof(data); MSG_WriteLong(&msg, -1); - MSG_WriteString(&msg, va("connect \"\\challenge\\%i\\qport\\%i\\protocol\\%i\\ip\\%s%s\"", challenge, qport, PROTOCOL_VERSION_Q3, NET_AdrToString (adrbuf, sizeof(adrbuf), &net_local_cl_ipadr), cls.userinfo[0])); + MSG_WriteString(&msg, va("connect \"\\challenge\\%i\\qport\\%i\\protocol\\%i\\ip\\%s%s\"", challenge, qport, PROTOCOL_VERSION_Q3, NET_AdrToString (adrbuf, sizeof(adrbuf), &net_local_cl_ipadr), infostr)); #ifdef HUFFNETWORK Huff_EncryptPacket(&msg, 12); if (!Huff_CompressionCRC(HUFFCRC_QUAKE3)) diff --git a/engine/client/console.c b/engine/client/console.c index 367bc4a34..eb7436356 100644 --- a/engine/client/console.c +++ b/engine/client/console.c @@ -1440,15 +1440,16 @@ int Con_DrawInput (console_t *con, qboolean focused, int left, int right, int y, for (i = 0; i < c->num; i++) { + int col = (con_commandmatch == i+1)?3:2; s = (conchar_t*)(con->completionline+1); //note: if cl_chatmode is 0, then we shouldn't show the leading /, however that is how the console link stuff recognises it as command text, so we always display it. cmd = c->completions[i].text; // desc = c->completions[i].desc; // if (desc) -// end = COM_ParseFunString((COLOR_GREEN<completionline->length, (con->completionline->maxlength-con->completionline->length)*sizeof(maskedtext[0]), true); +// end = COM_ParseFunString((COLOR_GREEN<completionline->length, (con->completionline->maxlength-con->completionline->length)*sizeof(maskedtext[0]), true); // else - end = COM_ParseFunString((COLOR_GREEN<completionline->length, (con->completionline->maxlength-con->completionline->length)*sizeof(maskedtext[0]), true); + end = COM_ParseFunString((COLOR_GREEN<completionline->length, (con->completionline->maxlength-con->completionline->length)*sizeof(maskedtext[0]), true); con->completionline->length = end - s; } if (c->extra) @@ -2645,7 +2646,7 @@ void Con_DrawConsole (int lines, qboolean noback) size_t fsize; char *buf; shader->defaulttextures->base = Image_CreateTexture(key, NULL, IF_NOREPLACE|IF_PREMULTIPLYALPHA); - if ((buf = COM_LoadFile (key, 5, &fsize))) + if ((buf = FS_LoadMallocFile (key, &fsize))) Image_LoadTextureFromMemory(shader->defaulttextures->base, shader->defaulttextures->base->flags|IF_NOWORKER, key, key, buf, fsize); } shader->width = shader->defaulttextures->base->width; diff --git a/engine/client/fragstats.c b/engine/client/fragstats.c index fc790e55a..247a22a4f 100644 --- a/engine/client/fragstats.c +++ b/engine/client/fragstats.c @@ -618,7 +618,7 @@ static void Stats_LoadFragFile(char *name) strcpy(filename, name); COM_DefaultExtension(filename, ".dat", sizeof(filename)); - file = COM_LoadTempFile(filename, NULL); + file = COM_LoadTempFile(filename, 0, NULL); if (!file || !*file) { Con_DPrintf("Couldn't load %s\n", filename); diff --git a/engine/client/image.c b/engine/client/image.c index 412fc1bb8..a0492568b 100644 --- a/engine/client/image.c +++ b/engine/client/image.c @@ -2801,7 +2801,7 @@ void Image_WriteKTXFile(const char *filename, struct pendingtextureinfo *mips) VFS_CLOSE(file); } -static struct pendingtextureinfo *Image_ReadKTXFile(unsigned int flags, char *fname, qbyte *filedata, size_t filesize) +static struct pendingtextureinfo *Image_ReadKTXFile(unsigned int flags, const char *fname, qbyte *filedata, size_t filesize) { static const char magic[12] = {0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A}; ktxheader_t *header; @@ -3038,7 +3038,7 @@ static struct pendingtextureinfo *Image_ReadKTXFile(unsigned int flags, char *fn #endif #ifdef IMAGEFMT_PKM -static struct pendingtextureinfo *Image_ReadPKMFile(unsigned int flags, char *fname, qbyte *filedata, size_t filesize) +static struct pendingtextureinfo *Image_ReadPKMFile(unsigned int flags, const char *fname, qbyte *filedata, size_t filesize) { struct pendingtextureinfo *mips; unsigned int encoding, blockbytes; @@ -3157,7 +3157,7 @@ typedef struct { unsigned int miscflags2; } dds10header_t; -static struct pendingtextureinfo *Image_ReadDDSFile(unsigned int flags, char *fname, qbyte *filedata, size_t filesize) +static struct pendingtextureinfo *Image_ReadDDSFile(unsigned int flags, const char *fname, qbyte *filedata, size_t filesize) { int nummips; int mipnum; @@ -3362,7 +3362,7 @@ static struct pendingtextureinfo *Image_ReadDDSFile(unsigned int flags, char *fn #endif #ifdef IMAGEFMT_BLP -static struct pendingtextureinfo *Image_ReadBLPFile(unsigned int flags, char *fname, qbyte *filedata, size_t filesize) +static struct pendingtextureinfo *Image_ReadBLPFile(unsigned int flags, const char *fname, qbyte *filedata, size_t filesize) { //FIXME: cba with endian. int miplevel; @@ -6212,7 +6212,7 @@ static qboolean Image_LoadRawTexture(texid_t tex, unsigned int flags, void *rawd #if 1 //always frees filedata, even on failure. //also frees the textures fallback data, but only on success -static struct pendingtextureinfo *Image_LoadMipsFromMemory(int flags, const char *iname, char *fname, qbyte *filedata, int filesize) +static struct pendingtextureinfo *Image_LoadMipsFromMemory(int flags, const char *iname, const char *fname, qbyte *filedata, int filesize) { qboolean hasalpha; qbyte *rgbadata; @@ -6267,7 +6267,7 @@ static struct pendingtextureinfo *Image_LoadMipsFromMemory(int flags, const char COM_FileExtension(fname, ext, sizeof(ext)); Q_strncatz(aname, "_alpha.", sizeof(aname)); Q_strncatz(aname, ext, sizeof(aname)); - if (!strchr(aname, ':') && (alph = COM_LoadFile (aname, 5, &alphsize))) + if (!strchr(aname, ':') && (alph = FS_LoadMallocFile (aname, &alphsize))) { if ((alphadata = Read32BitImageFile(alph, alphsize, &alpha_width, &alpha_height, &hasalpha, aname))) { @@ -6324,7 +6324,7 @@ static struct pendingtextureinfo *Image_LoadMipsFromMemory(int flags, const char //always frees filedata, even on failure. //also frees the textures fallback data, but only on success -qboolean Image_LoadTextureFromMemory(texid_t tex, int flags, const char *iname, char *fname, qbyte *filedata, int filesize) +qboolean Image_LoadTextureFromMemory(texid_t tex, int flags, const char *iname, const char *fname, qbyte *filedata, int filesize) { struct pendingtextureinfo *mips = Image_LoadMipsFromMemory(flags, iname, fname, filedata, filesize); if (mips) @@ -6406,7 +6406,7 @@ qboolean Image_LoadTextureFromMemory(texid_t tex, int flags, const char *iname, COM_FileExtension(fname, ext, sizeof(ext)); Q_strncatz(aname, "_alpha.", sizeof(aname)); Q_strncatz(aname, ext, sizeof(aname)); - if (!strchr(aname, ':') && (alph = COM_LoadFile (aname, 5, &alphsize))) + if (!strchr(aname, ':') && (alph = FS_LoadMallocFile (aname, &alphsize))) { if ((alphadata = Read32BitImageFile(alph, alphsize, &alpha_width, &alpha_height, &hasalpha, aname))) { @@ -6465,7 +6465,7 @@ qboolean Image_LoadTextureFromMemory(texid_t tex, int flags, const char *iname, } #endif -struct pendingtextureinfo *Image_LoadCubemapTextureData(const char *nicename, char *subpath, unsigned int texflags) +static struct pendingtextureinfo *Image_LoadCubemapTextureData(const char *nicename, char *subpath, unsigned int texflags) { static struct { @@ -6529,12 +6529,12 @@ struct pendingtextureinfo *Image_LoadCubemapTextureData(const char *nicename, ch for (j = 0; j < countof(cmscheme); j++) { Q_snprintfz(fname+prefixlen, sizeof(fname)-prefixlen, "%s_%s%s", nicename, cmscheme[j][i].suffix, tex_extensions[e].name); - buf = COM_LoadFile(fname, 5, &filesize); + buf = FS_LoadMallocFile(fname, &filesize); if (buf) break; Q_snprintfz(fname+prefixlen, sizeof(fname)-prefixlen, "%s%s%s", nicename, cmscheme[j][i].suffix, tex_extensions[e].name); - buf = COM_LoadFile(fname, 5, &filesize); + buf = FS_LoadMallocFile(fname, &filesize); if (buf) break; } @@ -6592,7 +6592,7 @@ nextface:; return mips; } -static qboolean Image_LocateHighResTexture(image_t *tex, flocation_t *bestloc, char *bestname, size_t bestnamesize, unsigned int *bestflags) +qboolean Image_LocateHighResTexture(image_t *tex, flocation_t *bestloc, char *bestname, size_t bestnamesize, unsigned int *bestflags) { char fname[MAX_QPATH], nicename[MAX_QPATH]; int i, e; @@ -6827,8 +6827,6 @@ static void Image_LoadHiResTextureWorker(void *ctx, void *data, size_t a, size_t int imgheight; qboolean alphaed; -// Sys_Sleep(0.3); - if ((tex->flags & IF_TEXTYPE) == IF_CUBEMAP) { //cubemaps require special handling because they are (normally) 6 files instead of 1. //the exception is single-file dds cubemaps, but we don't support those. @@ -6963,7 +6961,7 @@ static void Image_LoadHiResTextureWorker(void *ctx, void *data, size_t a, size_t if (Image_LoadTextureFromMemory(tex, tex->flags, tex->ident, fname, buf, fsize)) { BZ_Free(tex->fallbackdata); - tex->fallbackdata = NULL; + tex->fallbackdata = NULL; return; } } @@ -7057,7 +7055,10 @@ static image_t *Image_CreateTexture_Internal (const char *identifier, const char tex->next = imagelist; imagelist = tex; - tex->flags = flags; + if ((vid.flags & VID_SRGBAWARE) && !(flags & IF_NOSRGB)) + tex->flags = flags | IF_SRGB; //guess... + else + tex->flags = flags; tex->width = 0; tex->height = 0; tex->regsequence = r_regsequence; @@ -7597,7 +7598,7 @@ texid_t R_LoadBumpmapTexture(const char *name, const char *subpath) TRACE(("dbg: Mod_LoadBumpmapTexture: opening %s\n", fname)); - if ((buf = COM_LoadFile (fname, 5, &fsize))) + if ((buf = FS_LoadMallocFile (fname, &fsize))) { if ((data = ReadTargaFile(buf, fsize, &image_width, &image_height, &hasalpha, 2))) //Only load a greyscale image. { diff --git a/engine/client/keys.c b/engine/client/keys.c index 599e8be5f..7498c9b37 100644 --- a/engine/client/keys.c +++ b/engine/client/keys.c @@ -455,7 +455,7 @@ void Key_UpdateCompletionDesc(void) } } -void CompleteCommand (qboolean force) +void CompleteCommand (qboolean force, int direction) { const char *cmd, *s; const char *desc; @@ -535,7 +535,9 @@ void CompleteCommand (qboolean force) } } - con_commandmatch++; + con_commandmatch += direction; + if (con_commandmatch <= 0) + con_commandmatch += c->num; Key_UpdateCompletionDesc(); } @@ -1695,14 +1697,15 @@ qboolean Key_Console (console_t *con, int key, unsigned int unicode) Cbuf_AddText("\nvid_toggle\n", RESTRICT_LOCAL); #endif - if (con_commandmatch) + if ((con_commandmatch && !strchr(key_lines[edit_line], ' ')) || shift) { //if that isn't actually a command, and we can actually complete it to something, then lets try to complete it. char *txt = key_lines[edit_line]; if (*txt == '/') txt++; - if (!Cmd_IsCommand(txt) && Cmd_CompleteCommand(txt, true, true, con_commandmatch, NULL)) + + if ((shift||!Cmd_IsCommand(txt)) && Cmd_CompleteCommand(txt, true, true, con_commandmatch, NULL)) { - CompleteCommand (true); + CompleteCommand (true, 1); return true; } Con_Footerf(con, false, ""); @@ -1723,6 +1726,7 @@ qboolean Key_Console (console_t *con, int key, unsigned int unicode) key_lines[edit_line] = BZ_Malloc(1); key_lines[edit_line][0] = '\0'; key_linepos = 0; + con_commandmatch = 0; return true; } @@ -1733,21 +1737,21 @@ qboolean Key_Console (console_t *con, int key, unsigned int unicode) txt++; if (Cmd_CompleteCommand(txt, true, true, con->commandcompletion, NULL)) { - CompleteCommand (true); + CompleteCommand (true, 1); return true; } } if (key == K_TAB) { // command completion - if (shift) + if (ctrl&&shift) { Con_CycleConsole(); return true; } if (con->commandcompletion) - CompleteCommand (ctrl); + CompleteCommand (ctrl, shift?-1:1); return true; } @@ -1802,9 +1806,29 @@ qboolean Key_Console (console_t *con, int key, unsigned int unicode) if (rkey != '`' || key_linepos==0) return false; } + if (con_commandmatch) - con_commandmatch = 1; - Key_EntryLine(&key_lines[edit_line], 0, &key_linepos, key, unicode); + { //if they're typing, try to retain the current completion guess. + cmd_completion_t *c; + char *txt = key_lines[edit_line]; + char *guess = Cmd_CompleteCommand(*txt=='/'?txt+1:txt, true, true, con_commandmatch, NULL); + Key_EntryLine(&key_lines[edit_line], 0, &key_linepos, key, unicode); + if (guess) + { + guess = Z_StrDup(guess); + txt = key_lines[edit_line]; + c = Cmd_Complete(*txt=='/'?txt+1:txt, true); + for (con_commandmatch = c->num; con_commandmatch > 1; con_commandmatch--) + { + if (!strcmp(guess, c->completions[con_commandmatch-1].text)) + break; + } + Z_Free(guess); + } + } + else + Key_EntryLine(&key_lines[edit_line], 0, &key_linepos, key, unicode); + return true; } @@ -1999,9 +2023,9 @@ static char *Key_KeynumToStringRaw (int keynum) return ""; } -char *Key_KeynumToString (int keynum, int modifier) +const char *Key_KeynumToString (int keynum, int modifier) { - char *r = Key_KeynumToStringRaw(keynum); + const char *r = Key_KeynumToStringRaw(keynum); if (r[0] == '<' && r[1]) modifier = 0; //would be too weird. switch(modifier) diff --git a/engine/client/m_items.c b/engine/client/m_items.c index 3a226ac18..bb044aadc 100644 --- a/engine/client/m_items.c +++ b/engine/client/m_items.c @@ -567,7 +567,7 @@ static void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu int y = ypos+option->common.posy; int keys[8], keymods[countof(keys)]; int keycount; - char *keyname; + const char *keyname; int j; Draw_FunStringWidth(x, y, option->bind.caption, option->bind.captionwidth, true, !menu->cursoritem && menu->selecteditem == option); diff --git a/engine/client/m_mp3.c b/engine/client/m_mp3.c index a60f2d2a2..c076eee8e 100644 --- a/engine/client/m_mp3.c +++ b/engine/client/m_mp3.c @@ -1390,7 +1390,7 @@ void Media_LoadTrackNames (char *listname) char *trackname; mediatrack_t *newtrack; size_t fsize; - char *data = COM_LoadTempFile(listname, &fsize); + char *data = COM_LoadTempFile(listname, FSLF_IGNOREPURE, &fsize); loadedtracknames=true; @@ -3210,13 +3210,16 @@ static void QDECL capture_avi_video(void *vctx, int frame, void *vdata, int stri qbyte *data, *in, *out; int x, y; + if (stride < 0) //if stride is negative, then its bottom-up, but the data pointer is at the start of the buffer (rather than 'first row') + vdata = (char*)vdata - stride*(height-1); + //we need to output a packed bottom-up bgr image. - //switch the input from logically top-down to bottom-up (regardless of the physical ordering of its rows) + //switch the input from logical-top-down to bottom-up (regardless of the physical ordering of its rows) in = (qbyte*)vdata + stride*(height-1); stride = -stride; - if (fmt == TF_BGR24 && stride == width*3) + if (fmt == TF_BGR24 && stride == width*-3) { //no work needed! data = in; } diff --git a/engine/client/m_native.c b/engine/client/m_native.c index 1eb2c9a63..472948fa7 100644 --- a/engine/client/m_native.c +++ b/engine/client/m_native.c @@ -76,7 +76,7 @@ static shader_t *MN_CachePic(const char *picname) { return R2D_SafeCachePic(picname); } -static qboolean MN_DrawGetImageSize(void *pic, int *w, int *h) +static qboolean MN_DrawGetImageSize(struct shader_s *pic, int *w, int *h) { return R_GetShaderSizes(pic, w, h, true)>0; } @@ -234,8 +234,8 @@ static void MN_RenderScene(menuscene_t *scene) ent.keynum = i; ent.model = scene->entlist[i].model; VectorCopy(e->matrix[0], ent.axis[0]); ent.origin[0] = e->matrix[0][3]; - VectorCopy(e->matrix[1], ent.axis[1]); ent.origin[1] = e->matrix[0][7]; - VectorCopy(e->matrix[2], ent.axis[2]); ent.origin[2] = e->matrix[0][11]; + VectorCopy(e->matrix[1], ent.axis[1]); ent.origin[1] = e->matrix[1][3]; + VectorCopy(e->matrix[2], ent.axis[2]); ent.origin[2] = e->matrix[2][3]; ent.scale = 1; ent.framestate.g[FS_REG].frame[0] = e->frame[0]; @@ -263,8 +263,8 @@ static void MN_RenderScene(menuscene_t *scene) } VectorCopy(scene->viewmatrix[0], r_refdef.viewaxis[0]); r_refdef.vieworg[0] = scene->viewmatrix[0][3]; - VectorCopy(scene->viewmatrix[1], r_refdef.viewaxis[1]); r_refdef.vieworg[1] = scene->viewmatrix[0][7]; - VectorCopy(scene->viewmatrix[2], r_refdef.viewaxis[2]); r_refdef.vieworg[2] = scene->viewmatrix[0][11]; + VectorCopy(scene->viewmatrix[1], r_refdef.viewaxis[1]); r_refdef.vieworg[1] = scene->viewmatrix[1][3]; + VectorCopy(scene->viewmatrix[2], r_refdef.viewaxis[2]); r_refdef.vieworg[2] = scene->viewmatrix[2][3]; r_refdef.viewangles[0] = -(atan2(r_refdef.viewaxis[0][2], sqrt(r_refdef.viewaxis[0][1]*r_refdef.viewaxis[0][1]+r_refdef.viewaxis[0][0]*r_refdef.viewaxis[0][0])) * 180 / M_PI); r_refdef.viewangles[1] = (atan2(r_refdef.viewaxis[0][1], r_refdef.viewaxis[0][0]) * 180 / M_PI); diff --git a/engine/client/m_options.c b/engine/client/m_options.c index 444978874..7851bb024 100644 --- a/engine/client/m_options.c +++ b/engine/client/m_options.c @@ -763,7 +763,7 @@ const char *presetexec[] = "seta gl_polyblend 0;" "seta gl_flashblend 0;" "seta gl_specular 0;" - "seta r_deluxmapping 0;" + "seta r_deluxemapping 0;" "seta r_loadlit 0;" "seta r_fastsky 1;" "seta r_drawflame 0;" @@ -893,12 +893,12 @@ const char *presetexec[] = "r_shadow_realtime_dlight 1;" // "gl_detail 1;" "r_lightstylesmooth 1;" - "r_deluxmapping 2;" + "r_deluxemapping 2;" "gl_texture_anisotropic_filtering 4;" , // realtime options "r_bloom 1;" - "r_deluxmapping 0;" //won't be seen anyway + "r_deluxemapping 0;" //won't be seen anyway "r_particledesc \"high tsshaft\";" "r_waterstyle 3;" "r_glsl_offsetmapping 1;" @@ -959,7 +959,7 @@ void M_Menu_Preset_f (void) #else bias = 1; #endif - if (r_deluxmapping_cvar.ival) + if (r_deluxemapping_cvar.ival) item = 2; //nice else if (gl_load24bit.ival) item = 3; //normal @@ -1571,7 +1571,7 @@ void M_Menu_Lighting_f (void) #endif MB_COMBOCVAR("Lightmap Format", r_lightmap_format, lightmapformatopts, lightmapformatvalues, "Selects which format to use for lightmaps."), MB_COMBOCVAR("LIT Loading", r_loadlits, loadlitopts, loadlitvalues, "Determines if the engine should use external colored lighting for maps. The generated setting will cause the engine to generate colored lighting for maps that don't have the associated data."), - MB_COMBOCVAR("Deluxmapping", r_deluxmapping_cvar, loadlitopts, loadlitvalues, "Controls whether static lighting should respond to lighting directions."), + MB_COMBOCVAR("Deluxemapping", r_deluxemapping_cvar, loadlitopts, loadlitvalues, "Controls whether static lighting should respond to lighting directions."), MB_CHECKBOXCVAR("Lightstyle Lerp", r_lightstylesmooth, 0), MB_SPACING(4), MB_COMBOCVAR("Flash Blend", r_flashblend, fbopts, fbvalues, "Disables or enables the spherical light effect for dynamic lights. Traced means the sphere effect will be line of sight checked before displaying the effect."), diff --git a/engine/client/merged.h b/engine/client/merged.h index 769e74198..5135bfda2 100644 --- a/engine/client/merged.h +++ b/engine/client/merged.h @@ -385,7 +385,7 @@ typedef enum backendmode_e typedef struct rendererinfo_s { char *description; - char *name[4]; + char *name[5]; r_qrenderer_t rtype; //FIXME: all but the vid stuff really should be filled in by the video code, simplifying system-specific stuff. diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index 77c0a9841..4c110fc63 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -1531,7 +1531,7 @@ void QCBUILTIN PF_R_PolygonBegin(pubprogfuncs_t *prinst, struct globalvars_s *pr } else twod = qcflags & DRAWFLAG_2D; - + if ((qcflags & 3) == DRAWFLAG_ADD) beflags = BEF_NOSHADOWS|BEF_FORCEADDITIVE; else @@ -2053,7 +2053,7 @@ nogameaccess: break; } } -static uploadfmt_t PR_TranslateTextureFormat(int qcformat) +uploadfmt_t PR_TranslateTextureFormat(int qcformat) { switch(qcformat) { @@ -2291,7 +2291,7 @@ void QCBUILTIN PF_R_SetViewFlag(pubprogfuncs_t *prinst, struct globalvars_s *pr_ break; case VF_ENVMAP: - Q_strncpyz(r_refdef.nearenvmap.texname, PR_GetStringOfs(prinst, OFS_PARM1), sizeof(r_refdef.rt_sourcecolour)); + Q_strncpyz(r_refdef.nearenvmap.texname, PR_GetStringOfs(prinst, OFS_PARM1), sizeof(r_refdef.nearenvmap.texname)); BE_RenderToTextureUpdate2d(false); break; @@ -3694,13 +3694,13 @@ static const char *PF_cs_serverkey_internal(const char *keyname) #ifndef CLIENTONLY if (sv.state >= ss_loading) { - ret = Info_ValueForKey(svs.info, keyname); + ret = InfoBuf_ValueForKey(&svs.info, keyname); if (!*ret) - ret = Info_ValueForKey(localinfo, keyname); + ret = InfoBuf_ValueForKey(&svs.localinfo, keyname); } else #endif - ret = Info_ValueForKey(cl.serverinfo, keyname); + ret = InfoBuf_ValueForKey(&cl.serverinfo, keyname); } return ret; } @@ -3810,7 +3810,7 @@ static const char *PF_cs_getplayerkey_internal (unsigned int pnum, const char *k #endif else { - ret = Info_ValueForKey(cl.players[pnum].userinfo, keyname); + ret = InfoBuf_ValueForKey(&cl.players[pnum].userinfo, keyname); } return ret; } @@ -3834,6 +3834,34 @@ static void QCBUILTIN PF_cs_serverkeyfloat (pubprogfuncs_t *prinst, struct globa else G_FLOAT(OFS_RETURN) = (prinst->callargc >= 2)?G_FLOAT(OFS_PARM1):0; } +static void QCBUILTIN PF_cs_serverkeyblob (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) +{ + const char *keyname = PR_GetStringOfs(prinst, OFS_PARM0); + int qcptr = G_INT(OFS_PARM1); + int qcsize = G_INT(OFS_PARM2); + void *ptr; + size_t blobsize = 0; + const char *blob; + + if (qcptr < 0 || qcptr+qcsize >= prinst->stringtablesize) + { + PR_BIError(prinst, "PF_cs_serverkeyblob: invalid pointer\n"); + return; + } + ptr = (struct reverbproperties_s*)(prinst->stringtable + qcptr); + + blob = InfoBuf_BlobForKey(&cl.serverinfo, keyname, &blobsize); + + if (qcptr) + { + blobsize = min(blobsize, qcsize); + memcpy(ptr, blob, blobsize); + G_INT(OFS_RETURN) = blobsize; + } + else + G_INT(OFS_RETURN) = blobsize; +} + //string(float pnum, string keyname) static void QCBUILTIN PF_cs_getplayerkeystring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { @@ -3883,6 +3911,50 @@ static void QCBUILTIN PF_cs_getplayerkeyfloat (pubprogfuncs_t *prinst, struct gl else G_FLOAT(OFS_RETURN) = (prinst->callargc >= 3)?G_FLOAT(OFS_PARM2):0; } +static void QCBUILTIN PF_cs_getplayerkeyblob (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) +{ + int pnum = G_FLOAT(OFS_PARM0); + const char *keyname = PR_GetStringOfs(prinst, OFS_PARM1); + int qcptr = G_INT(OFS_PARM2); + int qcsize = G_INT(OFS_PARM3); + void *ptr; + if (pnum < 0) + { + if (csqc_resortfrags) + { + Sbar_SortFrags(true, false); + csqc_resortfrags = false; + } + if (pnum >= -scoreboardlines) + {//sort by + pnum = fragsort[-(pnum+1)]; + } + } + + if (qcptr < 0 || qcptr+qcsize >= prinst->stringtablesize) + { + PR_BIError(prinst, "PF_cs_getplayerkeyblob: invalid pointer\n"); + return; + } + ptr = (struct reverbproperties_s*)(prinst->stringtable + qcptr); + + if ((unsigned int)pnum >= (unsigned int)cl.allocated_client_slots) + G_INT(OFS_RETURN) = 0; + else + { + size_t blobsize = 0; + const char *blob = InfoBuf_BlobForKey(&cl.players[pnum].userinfo, keyname, &blobsize); + + if (qcptr) + { + blobsize = min(blobsize, qcsize); + memcpy(ptr, blob, blobsize); + G_INT(OFS_RETURN) = blobsize; + } + else + G_INT(OFS_RETURN) = blobsize; + } +} static void QCBUILTIN PF_cs_infokey (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { @@ -6092,6 +6164,7 @@ static struct { {"abort", PF_Abort, 211}, //#211 void() abort (FTE_MULTITHREADED) // {"sleep", PF_Fixme, 212},//{"sleep", PF_Sleep, 0, 0, 0, 212}, {"forceinfokey", PF_NoCSQC, 213},//{"forceinfokey", PF_ForceInfoKey, 0, 0, 0, 213}, + {"forceinfokeyblob", PF_NoCSQC, 0},//{"forceinfokey", PF_ForceInfoKey, 0, 0, 0, 213}, {"chat", PF_NoCSQC, 214},//{"chat", PF_chat, 0, 0, 0, 214},// #214 void(string filename, float starttag, entity edict) SV_Chat (FTE_NPCCHAT) {"particle2", PF_cs_particle2, 215}, //215 (FTE_PEXT_HEXEN2) @@ -6296,7 +6369,8 @@ static struct { {"runstandardplayerphysics",PF_cs_runplayerphysics, 347}, // #347 void() runstandardplayerphysics (EXT_CSQC) {"getplayerkeyvalue", PF_cs_getplayerkeystring, 348}, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC) - {"getplayerkeyfloat", PF_cs_getplayerkeyfloat, 0}, // #348 string(float playernum, string keyname) getplayerkeyvalue + {"getplayerkeyfloat", PF_cs_getplayerkeyfloat, 0}, // #348 string(float playernum, string keyname) getplayerkeyvalue + {"getplayerkeyblob", PF_cs_getplayerkeyblob, 0}, // #0 int(float playernum, string keyname, optional void *outptr, int size) getplayerkeyblob {"isdemo", PF_cl_playingdemo, 349}, // #349 float() isdemo (EXT_CSQC) //350 @@ -6309,6 +6383,7 @@ static struct { {"serverkey", PF_cs_serverkey, 354}, // #354 string(string key) serverkey; {"serverkeyfloat", PF_cs_serverkeyfloat, 0}, // #0 float(string key) serverkeyfloat; + {"serverkeyblob", PF_cs_serverkeyblob, 0}, {"getentitytoken", PF_cs_getentitytoken, 355}, // #355 string() getentitytoken; {"findfont", PF_CL_findfont, 356}, {"loadfont", PF_CL_loadfont, 357}, @@ -6618,6 +6693,7 @@ static struct { {"setbindmaps", PF_cl_SetBindMap, 632}, {"digest_hex", PF_digest_hex, 639}, + {"digest_ptr", PF_digest_ptr, 0}, {"V_CalcRefdef", PF_V_CalcRefdef, 640}, {NULL} @@ -6901,9 +6977,11 @@ void *PDECL CSQC_PRLoadFile (const char *path, unsigned char *(PDECL *buf_get)(v char newname[MAX_QPATH]; snprintf(newname, MAX_QPATH, "csprogsvers/%x.dat", csprogs_checksum); + //we can use FSLF_IGNOREPURE because we have our own hashes/size checks instead. + //this should make it slightly easier for server admins if (csprogs_checksum) { - file = COM_LoadTempFile (newname, sz); + file = COM_LoadTempFile (newname, FSLF_IGNOREPURE, sz); if (file) { if (cls.protocol == CP_NETQUAKE && !(cls.fteprotocolextensions2 & PEXT2_PREDINFO)) @@ -6921,7 +6999,7 @@ void *PDECL CSQC_PRLoadFile (const char *path, unsigned char *(PDECL *buf_get)(v if (!file) { - file = COM_LoadTempFile (path, sz); + file = COM_LoadTempFile (path, FSLF_IGNOREPURE, sz); if (file && !cls.demoplayback) //allow them to use csprogs.dat if playing a demo, and don't care about the checksum { @@ -6956,7 +7034,7 @@ void *PDECL CSQC_PRLoadFile (const char *path, unsigned char *(PDECL *buf_get)(v } } else - file = COM_LoadTempFile (path, sz); + file = COM_LoadTempFile (path, 0, sz); if (file) { @@ -7137,7 +7215,7 @@ qboolean CSQC_Init (qboolean anycsqc, qboolean csdatenabled, unsigned int checks csqc_mayread = false; csqc_singlecheats = cls.demoplayback; - cheats = Info_ValueForKey(cl.serverinfo, "*cheats"); + cheats = InfoBuf_ValueForKey(&cl.serverinfo, "*cheats"); if (!Q_strcasecmp(cheats, "ON") || atoi(cheats)) csqc_singlecheats = true; #ifndef CLIENTONLY @@ -7353,7 +7431,7 @@ qboolean CSQC_Init (qboolean anycsqc, qboolean csdatenabled, unsigned int checks str = (string_t*)PR_FindGlobal(csqcprogs, "mapname", 0, NULL); if (str) { - char *s = Info_ValueForKey(cl.serverinfo, "map"); + char *s = InfoBuf_ValueForKey(&cl.serverinfo, "map"); if (!*s) s = cl.model_name[1]; if (!*s) diff --git a/engine/client/pr_menu.c b/engine/client/pr_menu.c index f78a0fed8..ba659f67a 100644 --- a/engine/client/pr_menu.c +++ b/engine/client/pr_menu.c @@ -711,7 +711,8 @@ void QCBUILTIN PF_CL_uploadimage (pubprogfuncs_t *prinst, struct globalvars_s *p int width = G_INT(OFS_PARM1); int height = G_INT(OFS_PARM2); int src = G_INT(OFS_PARM3); //ptr - int size = width * height * 4; + int size = (prinst->callargc > 4)?G_INT(OFS_PARM4):(width * height * 4); + uploadfmt_t format = (prinst->callargc > 5)?PR_TranslateTextureFormat(G_INT(OFS_PARM5)):TF_RGBA32; void *imgptr; texid_t tid; @@ -735,11 +736,30 @@ void QCBUILTIN PF_CL_uploadimage (pubprogfuncs_t *prinst, struct globalvars_s *p if (!TEXVALID(tid)) tid = Image_CreateTexture(imagename, NULL, RT_IMAGEFLAGS); - Image_Upload(tid, TF_RGBA32, imgptr, NULL, width, height, RT_IMAGEFLAGS); - tid->width = width; - tid->height = height; - - G_INT(OFS_RETURN) = 1; + if (!format) + { + void *data = BZ_Malloc(size); + memcpy(data, imgptr, size); + G_INT(OFS_RETURN) = Image_LoadTextureFromMemory(tid, tid->flags, tid->ident, imagename, data, size); + } + else + { + unsigned int blockbytes, blockwidth, blockheight; + //get format info + Image_BlockSizeForEncoding(format, &blockbytes, &blockwidth, &blockheight); + //round up as appropriate + blockwidth = ((width+blockwidth-1)/blockwidth)*blockwidth; + blockheight = ((height+blockheight-1)/blockheight)*blockheight; + if (size != blockwidth*blockheight*blockbytes) + G_INT(OFS_RETURN) = 0; //size isn't right. which means the pointer might be invalid too. + else + { + Image_Upload(tid, format, imgptr, NULL, width, height, RT_IMAGEFLAGS); + tid->width = width; + tid->height = height; + G_INT(OFS_RETURN) = 1; + } + } } //warning: not threadable. hopefully noone abuses it. @@ -2152,6 +2172,9 @@ static struct { //unproject 310 //project 311 + {"r_uploadimage", PF_CL_uploadimage, 0}, + {"r_readimage", PF_CL_readimage, 0}, + {"print_csqc", PF_print, 339}, {"keynumtostring_csqc", PF_cl_keynumtostring, 340}, @@ -2317,6 +2340,7 @@ static struct { {"crypto_getmykeyfp", PF_crypto_getmykeyfp, 636}, {"crypto_getmyidfp", PF_crypto_getmyidfp, 637}, {"digest_hex", PF_digest_hex, 639}, + {"digest_ptr", PF_digest_ptr, 0}, {"crypto_getmyidstatus", PF_crypto_getmyidfp, 641}, {NULL} }; diff --git a/engine/client/r_surf.c b/engine/client/r_surf.c index 8d608b0b2..6dbc9b4d8 100644 --- a/engine/client/r_surf.c +++ b/engine/client/r_surf.c @@ -4293,7 +4293,7 @@ TRACE(("dbg: Surf_NewMap: tp\n")); void Surf_PreNewMap(void) { - r_loadbumpmapping = r_deluxmapping || r_glsl_offsetmapping.ival; + r_loadbumpmapping = r_deluxemapping || r_glsl_offsetmapping.ival; #ifdef RTLIGHTS r_loadbumpmapping |= r_shadow_realtime_world.ival || r_shadow_realtime_dlight.ival; #endif diff --git a/engine/client/render.h b/engine/client/render.h index ab3a85060..ce30c69c1 100644 --- a/engine/client/render.h +++ b/engine/client/render.h @@ -447,7 +447,8 @@ image_t *Image_CreateTexture(const char *identifier, const char *subpath, unsign image_t *QDECL Image_GetTexture (const char *identifier, const char *subpath, unsigned int flags, void *fallbackdata, void *fallbackpalette, int fallbackwidth, int fallbackheight, uploadfmt_t fallbackfmt); qboolean Image_UnloadTexture(image_t *tex); //true if it did something. void Image_DestroyTexture (image_t *tex); -qboolean Image_LoadTextureFromMemory(texid_t tex, int flags, const char *iname, char *fname, qbyte *filedata, int filesize); //intended really for worker threads, but should be fine from the main thread too +qboolean Image_LoadTextureFromMemory(texid_t tex, int flags, const char *iname, const char *fname, qbyte *filedata, int filesize); //intended really for worker threads, but should be fine from the main thread too +qboolean Image_LocateHighResTexture(image_t *tex, flocation_t *bestloc, char *bestname, size_t bestnamesize, unsigned int *bestflags); void Image_Upload (texid_t tex, uploadfmt_t fmt, void *data, void *palette, int width, int height, unsigned int flags); void Image_Purge(void); //purge any textures which are not needed any more (releases memory, but doesn't give null pointers). void Image_Init(void); @@ -626,8 +627,8 @@ extern cvar_t r_telestyle; extern cvar_t r_dynamic; extern cvar_t r_novis; extern cvar_t r_netgraph; -extern cvar_t r_deluxmapping_cvar; -extern qboolean r_deluxmapping; +extern cvar_t r_deluxemapping_cvar; +extern qboolean r_deluxemapping; extern cvar_t r_softwarebanding_cvar; extern qboolean r_softwarebanding; extern cvar_t r_lightprepass_cvar; diff --git a/engine/client/renderer.c b/engine/client/renderer.c index f7167cb38..26ded947f 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -120,7 +120,7 @@ cvar_t r_wireframe = CVARFD ("r_wireframe", "0", CVAR_CHEAT, "Developer feature where everything is drawn with wireframe over the top. Only active where cheats are permitted."); cvar_t r_wireframe_smooth = CVAR ("r_wireframe_smooth", "0"); cvar_t r_refract_fbo = CVARD ("r_refract_fbo", "1", "Use an fbo for refraction. If 0, just renders as a portal and uses a copy of the current framebuffer."); -cvar_t r_refractreflect_scale = CVARD ("r_refractreflect_scale", "0.5", "Use a different scale for refraction and reflection. Because $reasons."); +cvar_t r_refractreflect_scale = CVARD ("r_refractreflect_scale", "0.5", "Use a different scale for refraction and reflection texturemaps. Because $reasons."); cvar_t gl_miptexLevel = CVAR ("gl_miptexLevel", "0"); cvar_t r_drawviewmodel = CVARF ("r_drawviewmodel", "1", CVAR_ARCHIVE); cvar_t r_drawviewmodelinvis = CVAR ("r_drawviewmodelinvis", "0"); @@ -344,9 +344,9 @@ cvar_t gl_ati_truform_type = CVAR ("gl_ati_truform_type", "1"); cvar_t r_tessellation_level = CVAR ("r_tessellation_level", "5"); cvar_t gl_blend2d = CVAR ("gl_blend2d", "1"); cvar_t gl_blendsprites = CVARD ("gl_blendsprites", "0", "Blend sprites instead of alpha testing them"); -cvar_t r_deluxmapping_cvar = CVARAFD ("r_deluxemapping", "0", "r_glsl_deluxemapping", +cvar_t r_deluxemapping_cvar = CVARAFD ("r_deluxemapping", "1", "r_glsl_deluxemapping", CVAR_ARCHIVE|CVAR_RENDERERLATCH, "Enables bumpmapping based upon precomputed light directions.\n0=off\n1=use if available\n2=auto-generate (if possible)"); -qboolean r_deluxmapping; +qboolean r_deluxemapping; cvar_t r_shaderblobs = CVARD ("r_shaderblobs", "0", "If enabled, can massively accelerate vid restarts / loading (especially with the d3d renderer). Can cause issues when upgrading engine versions, so this is disabled by default."); cvar_t gl_compress = CVARFD ("gl_compress", "0", CVAR_ARCHIVE, "Enable automatic texture compression even for textures which are not pre-compressed."); cvar_t gl_conback = CVARFCD ("gl_conback", "", @@ -529,7 +529,7 @@ void GLRenderer_Init(void) Cvar_Register (&gl_smoothcrosshair, GRAPHICALNICETIES); - Cvar_Register (&r_deluxmapping_cvar, GRAPHICALNICETIES); + Cvar_Register (&r_deluxemapping_cvar, GRAPHICALNICETIES); #ifdef R_XFLIP Cvar_Register (&r_xflip, GLRENDEREROPTIONS); @@ -1464,7 +1464,7 @@ qboolean R_ApplyRenderer_Load (rendererstate_t *newr) if (host_basepal) Z_Free(host_basepal); host_basepal = BZ_Malloc(768); - pcx = COM_LoadTempFile("pics/colormap.pcx", &sz); + pcx = COM_LoadTempFile("pics/colormap.pcx", 0, &sz); if (!pcx || !ReadPCXPalette(pcx, sz, host_basepal)) { memcpy(host_basepal, default_quakepal, 768); @@ -1522,7 +1522,7 @@ TRACE(("dbg: R_ApplyRenderer: vid applied\n")); R_GenPaletteLookup(); r_softwarebanding = false; - r_deluxmapping = false; + r_deluxemapping = false; r_lightprepass = false; W_LoadWadFile("gfx.wad"); diff --git a/engine/client/sbar.c b/engine/client/sbar.c index 8c62f25ca..6f6de70c3 100644 --- a/engine/client/sbar.c +++ b/engine/client/sbar.c @@ -346,7 +346,7 @@ char *Get_Q2ConfigString(int i) if (i >= Q2CS_SOUNDS && i < Q2CS_SOUNDS + Q2MAX_SOUNDS) return cl.sound_name [i-Q2CS_SOUNDS]; if (i == Q2CS_AIRACCEL) - return "4"; + return cl.q2airaccel; if (i >= Q2CS_PLAYERSKINS && i < Q2CS_GENERAL+Q2MAX_GENERAL) return cl.configstring_general[i-Q2CS_PLAYERSKINS]?cl.configstring_general[i-Q2CS_PLAYERSKINS]:""; //#define Q2CS_LIGHTS (Q2CS_IMAGES +Q2MAX_IMAGES) @@ -465,7 +465,7 @@ void Sbar_ExecuteLayoutString (char *s, int seat) Draw_FunString (x+32, y+16, va("Ping: %i", ping)); Draw_FunString (x+32, y+24, va("Time: %i", time)); - p = R2D_SafeCachePic(va("players/%s_i.pcx", Info_ValueForKey(cl.players[value].userinfo, "skin"))); + p = R2D_SafeCachePic(va("players/%s_i.pcx", InfoBuf_ValueForKey(&cl.players[value].userinfo, "skin"))); if (!p || !R_GetShaderSizes(p, NULL, NULL, false)) //display a default if the icon couldn't be found. p = R2D_SafeCachePic("players/male/grunt_i.pcx"); R2D_ScalePic (x, y, 32, 32, p); @@ -3289,7 +3289,7 @@ ping time frags name #define COLUMN_DEATHS COLUMN(dths, 4*8, {Draw_FunStringWidth(x, y, va("%4i", Stats_GetDeaths(k)), 4*8, false, false);},NOFILL) #define COLUMN_TOUCHES COLUMN(tchs, 4*8, {Draw_FunStringWidth(x, y, va("%4i", Stats_GetTouches(k)), 4*8, false, false);},NOFILL) #define COLUMN_CAPS COLUMN(caps, 4*8, {Draw_FunStringWidth(x, y, va("%4i", Stats_GetCaptures(k)), 4*8, false, false);},NOFILL) -#define COLUMN_AFK COLUMN(afk, 0, {int cs = atoi(Info_ValueForKey(s->userinfo, "chat")); if (cs)Draw_FunStringWidth(x+4, y, (cs&2)?"afk":"msg", 4*8, false, false);},NOFILL) +#define COLUMN_AFK COLUMN(afk, 0, {int cs = atoi(InfoBuf_ValueForKey(&s->userinfo, "chat")); if (cs)Draw_FunStringWidth(x+4, y, (cs&2)?"afk":"msg", 4*8, false, false);},NOFILL) //columns are listed here in display order @@ -3519,7 +3519,7 @@ if (showcolumns & (1<userinfo, "team"), sizeof(team)); + Q_strncpyz (team, InfoBuf_ValueForKey(&s->userinfo, "team"), sizeof(team)); if (S_Voip_Speaking(k)) background_color = 0x00ff00; diff --git a/engine/client/screen.h b/engine/client/screen.h index 5435d4430..34c989bda 100644 --- a/engine/client/screen.h +++ b/engine/client/screen.h @@ -181,6 +181,7 @@ typedef enum uploadfmt PTI_DEPTH32, PTI_DEPTH24_8, + //non-native formats (generally requiring weird palettes that are not supported by hardware) TF_BGR24_FLIP, /*bgr byte order, no alpha channel nor pad, and bottom up*/ TF_MIP4_R8, /*8bit 4-mip greyscale image*/ TF_MIP4_SOLID8, /*8bit 4-mip image in default palette*/ diff --git a/engine/client/skin.c b/engine/client/skin.c index 304c8f1b7..29b18bb7b 100644 --- a/engine/client/skin.c +++ b/engine/client/skin.c @@ -49,7 +49,7 @@ char *Skin_FindName (player_info_t *sc) } else { - s = Info_ValueForKey(sc->userinfo, "skin"); + s = InfoBuf_ValueForKey(&sc->userinfo, "skin"); if (s && s[0]) Q_strncpyz(name, s, sizeof(name)); else @@ -212,7 +212,7 @@ void Skin_WorkerLoad(void *skinptr, void *data, size_t a, size_t b) size_t pcxsize; Q_snprintfz (name, sizeof(name), "skins/%s.pcx", skin->name); - raw = COM_LoadTempFile (name, &pcxsize); + raw = COM_LoadTempFile (name, FSLF_IGNOREPURE, &pcxsize); if (!raw) { //use 24bit skins even if gl_load24bit is failed @@ -223,7 +223,7 @@ void Skin_WorkerLoad(void *skinptr, void *data, size_t a, size_t b) if (*baseskin.string) { Q_snprintfz (name, sizeof(name), "skins/%s.pcx", baseskin.string); - raw = COM_LoadTempFile (name, &pcxsize); + raw = COM_LoadTempFile (name, FSLF_IGNOREPURE, &pcxsize); } } if (!raw) @@ -463,7 +463,7 @@ void Skin_NextDownload (void) sc = &cl.players[i]; if (!sc->name[0]) continue; - skinname = Info_ValueForKey(sc->userinfo, "skin"); + skinname = InfoBuf_ValueForKey(&sc->userinfo, "skin"); slash = strchr(skinname, '/'); if (slash) { diff --git a/engine/client/snd_al.c b/engine/client/snd_al.c index 760e08f77..d97dc6c04 100644 --- a/engine/client/snd_al.c +++ b/engine/client/snd_al.c @@ -842,6 +842,7 @@ static void OpenAL_ChannelUpdate(soundcardinfo_t *sc, channel_t *chan, unsigned } pitch = (float)chan->rate/(1<=0 palSourcef(src, AL_PITCH, pitch); #ifdef USEEFX diff --git a/engine/client/snd_mem.c b/engine/client/snd_mem.c index 2e14a974d..99f072e82 100644 --- a/engine/client/snd_mem.c +++ b/engine/client/snd_mem.c @@ -907,7 +907,7 @@ static void S_LoadSoundWorker (void *ctx, void *ctxdata, size_t a, size_t b) else Q_snprintfz(namebuffer, sizeof(namebuffer), "%s%s", prefixes[pre], name); - data = COM_LoadFile(namebuffer, 5, &filesize); + data = FS_LoadMallocFile(namebuffer, &filesize); if (data) break; COM_FileExtension(namebuffer, orig, sizeof(orig)); @@ -917,7 +917,7 @@ static void S_LoadSoundWorker (void *ctx, void *ctxdata, size_t a, size_t b) if (!strcmp(orig, extensions[ex]+1)) continue; Q_snprintfz(namebuffer, sizeof(namebuffer), "%s%s", altname, extensions[ex]); - data = COM_LoadFile(namebuffer, 5, &filesize); + data = FS_LoadMallocFile(namebuffer, &filesize); if (data) { Con_DPrintf("found a mangled name: %s\n", namebuffer); diff --git a/engine/client/sys_win.c b/engine/client/sys_win.c index ebda88ea2..7e8a0a599 100644 --- a/engine/client/sys_win.c +++ b/engine/client/sys_win.c @@ -2396,7 +2396,6 @@ int global_nCmdShow; HWND hwnd_dialog; static const IID qIID_IShellLinkW = {0x000214F9L, 0, 0, {0xc0,0,0,0,0,0,0,0x46}}; -static const IID qIID_IPersistFile = {0x0000010BL, 0, 0, {0xc0,0,0,0,0,0,0,0x46}}; #include #if defined(_MSC_VER) && _MSC_VER <= 1200 @@ -2764,11 +2763,11 @@ void Win7_TaskListInit(void) #define UPD_BUILDTYPE "test" //WARNING: Security comes from the fact that the triptohell.info certificate is hardcoded in the tls code. //this will correctly detect insecure tls proxies also. - #define UPDATE_URL_ROOT "https://triptohell.info/moodles/" - #define UPDATE_URL_TESTED UPDATE_URL_ROOT "autoup/" - #define UPDATE_URL_NIGHTLY UPDATE_URL_ROOT - #define UPDATE_URL_VERSION "%sversion.txt" - #ifdef NOLEGACY +// #define UPDATE_URL_ROOT "https://triptohell.info/moodles/" +// #define UPDATE_URL_TESTED UPDATE_URL_ROOT "autoup/" +// #define UPDATE_URL_NIGHTLY UPDATE_URL_ROOT +// #define UPDATE_URL_VERSION "%sversion.txt" +/* #ifdef NOLEGACY #ifdef _WIN64 #define UPDATE_URL_BUILD "%snocompat64/fte" EXETYPE "64.exe" #else @@ -2780,7 +2779,7 @@ void Win7_TaskListInit(void) #else #define UPDATE_URL_BUILD "%swin32/fte" EXETYPE ".exe" #endif - #endif + #endif*/ #endif #if defined(SERVERONLY) @@ -3150,6 +3149,7 @@ static BOOL microsoft_accessU(LPCSTR pszFolder, DWORD dwAccessDesired) #define BFFM_SETOKTEXT (WM_USER + 105) //v6 #define BFFM_SETEXPANDED (WM_USER + 106) //v6 #endif +static const IID qIID_IPersistFile = {0x0000010BL, 0, 0, {0xc0,0,0,0,0,0,0,0x46}}; static WNDPROC omgwtfwhyohwhy; static LRESULT CALLBACK stoopidstoopidstoopid(HWND w, UINT m, WPARAM wp, LPARAM lp) @@ -4297,6 +4297,8 @@ void *WIN_CreateCursor(const char *filename, float hotx, float hoty, float scale } } + // FIXME: CreateIconIndirect does NOT understand DPI scaling, and will show a tiny cursor in such cases. + // we should rescale scale by vid_conautoscale etc. if (scale != 1) { int nw,nh; @@ -4363,8 +4365,8 @@ void *WIN_CreateCursor(const char *filename, float hotx, float hoty, float scale // Create the alpha cursor with the alpha DIB section. hAlphaCursor = CreateIconIndirect(&ii); - DeleteObject(ii.hbmColor); - DeleteObject(ii.hbmMask); + DeleteObject(ii.hbmColor); + DeleteObject(ii.hbmMask); return hAlphaCursor; } diff --git a/engine/client/textedit.c b/engine/client/textedit.c index 9ba025217..136cf68c6 100644 --- a/engine/client/textedit.c +++ b/engine/client/textedit.c @@ -393,6 +393,86 @@ void Con_EditorMoveCursor(console_t *con, conline_t *newline, int newoffset, qbo con->userline = newline; con->useroffset = newoffset; } +static conchar_t *Con_Editor_Equals(conchar_t *start, conchar_t *end, const char *match) +{ + conchar_t *n; + unsigned int ccode, flags; + + for (; start < end; start = n) + { + n = Font_Decode(start, &flags, &ccode); + if (*match) + { + if (ccode != *(unsigned char*)match++) + return NULL; + } + else if (ccode == ' ' || ccode == '\t') + break; //found whitespace after the token, its complete. + else + return NULL; + } + if (*match) + return NULL; //truncated + + //and skip any trailing whitespace, because we can. + for (; start < end; start = n) + { + n = Font_Decode(start, &flags, &ccode); + if (ccode == ' ' || ccode == '\t') + continue; + else + break; + } + return start; +} +static conchar_t *Con_Editor_SkipWhite(conchar_t *start, conchar_t *end) +{ + conchar_t *n; + unsigned int ccode, flags; + for (; start < end; start = n) + { + n = Font_Decode(start, &flags, &ccode); + if (ccode == ' ' || ccode == '\t') + continue; + else + break; + } + return start; +} +static void Con_Editor_LineChanged_Shader(conline_t *line) +{ + static const char *maplines[] = {"map", "clampmap"}; + size_t i; + conchar_t *start = (conchar_t*)(line+1), *end = start + line->length, *n; + + start = Con_Editor_SkipWhite(start, end); + + line->flags &= ~(CONL_BREAKPOINT|CONL_EXECUTION); + + for (i = 0; i < countof(maplines); i++) + { + n = Con_Editor_Equals(start, end, maplines[i]); + if (n) + { + char mapname[8192]; + char fname[MAX_QPATH]; + flocation_t loc; + unsigned int flags; + image_t img; + memset(&img, 0, sizeof(img)); + img.ident = mapname; + COM_DeFunString(n, end, mapname, sizeof(mapname), true, true); + if (!Image_LocateHighResTexture(&img, &loc, fname, sizeof(fname), &flags)) + line->flags |= CONL_BREAKPOINT; + return; + } + } +} +static void Con_Editor_LineChanged(console_t *con, conline_t *line) +{ + if (!Q_strncasecmp(con->name, "scripts/", 8)) + Con_Editor_LineChanged_Shader(line); +} qboolean Con_Editor_Key(console_t *con, unsigned int unicode, int key) { extern qboolean keydown[K_MAX]; @@ -430,6 +510,7 @@ qboolean Con_Editor_Key(console_t *con, unsigned int unicode, int key) con->useroffset--; memmove((conchar_t*)(con->userline+1)+con->useroffset, (conchar_t*)(con->userline+1)+con->useroffset+1, (con->userline->length - con->useroffset)*sizeof(conchar_t)); con->userline->length -= 1; + Con_Editor_LineChanged(con, con->userline); } return true; case K_DEL: @@ -444,6 +525,7 @@ qboolean Con_Editor_Key(console_t *con, unsigned int unicode, int key) { memmove((conchar_t*)(con->userline+1)+con->useroffset, (conchar_t*)(con->userline+1)+con->useroffset+1, (con->userline->length - con->useroffset)*sizeof(conchar_t)); con->userline->length -= 1; + Con_Editor_LineChanged(con, con->userline); } break; case K_ENTER: /*split the line into two, selecting the new line*/ @@ -553,7 +635,7 @@ qboolean Con_Editor_Key(console_t *con, unsigned int unicode, int key) // "F12: Go to definition\n" ); Cbuf_AddText("toggleconsole\n", RESTRICT_LOCAL); - break; + return true; case K_F2: /*{ char file[1024]; @@ -721,7 +803,10 @@ qboolean Con_Editor_Key(console_t *con, unsigned int unicode, int key) if (con->flags & CONF_KEEPSELECTION) Con_Editor_DeleteSelection(con); if (Con_InsertConChars(con, con->userline, con->useroffset, c, l)) + { con->useroffset += l; + Con_Editor_LineChanged(con, con->userline); + } break; } return false; @@ -782,6 +867,7 @@ console_t *Con_TextEditor(const char *fname, const char *line, qboolean newfile) { static int editorcascade; console_t *con; + conline_t *l; con = Con_FindConsole(fname); if (con) { @@ -820,7 +906,7 @@ console_t *Con_TextEditor(const char *fname, const char *line, qboolean newfile) con->redirect = Con_Editor_Key; con->mouseover = Con_Editor_MouseOver; con->close = Con_Editor_Close; - con->maxlines = 0x7fffffff; //line limit is effectively unbounded. + con->maxlines = 0x7fffffff; //line limit is effectively unbounded, for a 31-bit process. if (!newfile) { @@ -835,6 +921,9 @@ console_t *Con_TextEditor(const char *fname, const char *line, qboolean newfile) } VFS_CLOSE(file); } + + for (l = con->oldest; l; l = l->newer) + Con_Editor_LineChanged(con, l); } con->display = con->oldest; diff --git a/engine/client/valid.c b/engine/client/valid.c index ae3cb5523..2d1d47ad1 100644 --- a/engine/client/valid.c +++ b/engine/client/valid.c @@ -96,7 +96,7 @@ static void Validation_Version(void) { signed_buffer_t *resp; - resp = Security_Generate_Crc(cl.playerview[0].playernum, cl.players[cl.playerview[0].playernum].userinfo, cl.serverinfo); + resp = NULL;//Security_Generate_Crc(cl.playerview[0].playernum, cl.players[cl.playerview[0].playernum].userinfo, cl.serverinfo); if (!resp || !resp->buf) auth = ""; else @@ -186,7 +186,7 @@ void Validation_CheckIfResponse(char *text) { signed_buffer_t *resp; - resp = Security_Verify_Response(f_query_client, crc, cl.players[f_query_client].userinfo, cl.serverinfo); + resp = NULL;//Security_Verify_Response(f_query_client, crc, cl.players[f_query_client].userinfo, cl.serverinfo); if (resp && resp->size && *resp->buf) Con_Printf(CON_NOTICE "Authentication Successful.\n"); diff --git a/engine/client/vid.h b/engine/client/vid.h index 230b57160..486351941 100644 --- a/engine/client/vid.h +++ b/engine/client/vid.h @@ -115,23 +115,3 @@ extern unsigned int d_8to24rgbtable[256]; extern unsigned int d_8to24srgbtable[256]; extern unsigned int d_8to24bgrtable[256]; extern unsigned int d_quaketo24srgbtable[256]; - -#ifdef GLQUAKE -//called when gamma ramps need to be reapplied -qboolean GLVID_ApplyGammaRamps (unsigned int size, unsigned short *ramps); - -qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette); -// Called at startup to set up translation tables, takes 256 8 bit RGB values -// the palette data will go away after the call, so it must be copied off if -// the video driver will need it again - -void GLVID_Crashed(void); - -void GLVID_Update (vrect_t *rects); -// flushes the given rectangles from the view buffer to the screen - -void GLVID_SwapBuffers(void); -enum uploadfmt; -char *GLVID_GetRGBInfo(int *bytestride, int *truewidth, int *trueheight, enum uploadfmt *fmt); -void GLVID_SetCaption(const char *caption); -#endif diff --git a/engine/client/wad.c b/engine/client/wad.c index 155fe0375..00db76dc2 100644 --- a/engine/client/wad.c +++ b/engine/client/wad.c @@ -100,7 +100,7 @@ void W_LoadWadFile (char *filename) if (wad_base) Z_Free(wad_base); - wad_base = COM_LoadFile (filename, 0, NULL); + wad_base = COM_LoadFile (filename, 0, 0, NULL); if (!wad_base) { wad_numlumps = 0; diff --git a/engine/client/winquake.h b/engine/client/winquake.h index a51ad5b23..2460d3935 100644 --- a/engine/client/winquake.h +++ b/engine/client/winquake.h @@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define WINQUAKE_H #ifdef _WIN32 +void GLVID_Crashed(void); #if defined(_WIN32) && !defined(WIN32) #define WIN32 _WIN32 diff --git a/engine/client/zqtp.c b/engine/client/zqtp.c index 22206e9a9..8ec7ca198 100644 --- a/engine/client/zqtp.c +++ b/engine/client/zqtp.c @@ -727,7 +727,7 @@ static char *Skin_To_TFSkin (char *myskin) static char *Macro_TF_Skin (void) { - return Skin_To_TFSkin(Info_ValueForKey(cl.players[cl.playerview[SP].playernum].userinfo, "skin")); + return Skin_To_TFSkin(InfoBuf_ValueForKey(&cl.players[cl.playerview[SP].playernum].userinfo, "skin")); } //Spike: added these: @@ -1485,7 +1485,7 @@ static void TP_LoadLocFile (char *filename, qbool quiet) Q_snprintfz (fullpath, sizeof(fullpath) - 4, "locs/%s", filename); COM_DefaultExtension (fullpath, ".loc", sizeof(fullpath)); - buf = (char *) COM_LoadTempFile (fullpath, NULL); + buf = (char *) COM_LoadTempFile (fullpath, 0, NULL); if (!buf) { if (!quiet) @@ -3189,19 +3189,19 @@ char *Utils_TF_ColorToTeam(int color) switch (color) { case 13: - if (*(s = Info_ValueForKey(cl.serverinfo, "team1")) || *(s = Info_ValueForKey(cl.serverinfo, "t1"))) + if (*(s = InfoBuf_ValueForKey(&cl.serverinfo, "team1")) || *(s = InfoBuf_ValueForKey(&cl.serverinfo, "t1"))) return s; break; case 4: - if (*(s = Info_ValueForKey(cl.serverinfo, "team2")) || *(s = Info_ValueForKey(cl.serverinfo, "t2"))) + if (*(s = InfoBuf_ValueForKey(&cl.serverinfo, "team2")) || *(s = InfoBuf_ValueForKey(&cl.serverinfo, "t2"))) return s; break; case 12: - if (*(s = Info_ValueForKey(cl.serverinfo, "team3")) || *(s = Info_ValueForKey(cl.serverinfo, "t3"))) + if (*(s = InfoBuf_ValueForKey(&cl.serverinfo, "team3")) || *(s = InfoBuf_ValueForKey(&cl.serverinfo, "t3"))) return s; break; case 11: - if (*(s = Info_ValueForKey(cl.serverinfo, "team4")) || *(s = Info_ValueForKey(cl.serverinfo, "t4"))) + if (*(s = InfoBuf_ValueForKey(&cl.serverinfo, "team4")) || *(s = InfoBuf_ValueForKey(&cl.serverinfo, "t4"))) return s; break; default: @@ -3343,7 +3343,7 @@ static void TP_FindPoint (void) name = tp_name_enemy.string; if (!eyes) - name = va("%s%s%s", name, name[0] ? " " : "", Skin_To_TFSkin(Info_ValueForKey(bestinfo->userinfo, "skin"))); + name = va("%s%s%s", name, name[0] ? " " : "", Skin_To_TFSkin(InfoBuf_ValueForKey(&bestinfo->userinfo, "skin"))); } else { diff --git a/engine/common/bothdefs.h b/engine/common/bothdefs.h index 712d54bd4..1a1a586cd 100644 --- a/engine/common/bothdefs.h +++ b/engine/common/bothdefs.h @@ -725,7 +725,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #endif -#if (defined(CSQC_DAT) || !defined(CLIENTONLY)) && defined(PLUGINS) //use ode only if we have a constant world state, and the library is enbled in some form. +#if (defined(CSQC_DAT) || !defined(CLIENTONLY)) && (defined(PLUGINS)||defined(USE_INTERNAL_BULLET)||defined(USE_INTERNAL_ODE)) //use ode only if we have a constant world state, and the library is enbled in some form. #define USERBE #endif diff --git a/engine/common/cmd.c b/engine/common/cmd.c index e4fa29797..e81f98365 100644 --- a/engine/common/cmd.c +++ b/engine/common/cmd.c @@ -2336,7 +2336,7 @@ void Cmd_Complete_End(cmd_completion_t *c) int QDECL Cmd_Complete_Sort(const void *a, const void *b) { //FIXME: its possible that they're equal (eg: filesystem searches). we should strip one in that case, but gah. const struct cmd_completion_opt_s *c1 = a, *c2 = b; - return strcmp(c1->text, c2->text); + return Q_strcasecmp(c1->text, c2->text); } cmd_completion_t *Cmd_Complete(const char *partial, qboolean caseinsens) { @@ -2351,7 +2351,7 @@ cmd_completion_t *Cmd_Complete(const char *partial, qboolean caseinsens) qboolean quoted = false; static cmd_completion_t c; - + if (!partial) { Cmd_Complete_End(&c); @@ -2725,7 +2725,7 @@ void Cmd_ExecuteString (const char *text, int level) return; //let the csqc handle it if it wants. #endif #if defined(MENU_NATIVECODE) - if (mn_entry && mn_entry->ConsoleCommand(text, cmd_argc, cmd_argv)) + if (mn_entry && mn_entry->ConsoleCommand(text, cmd_argc, (char const*const*)cmd_argv)) return; #endif Cmd_ForwardToServer (); @@ -2890,7 +2890,7 @@ void Cmd_ExecuteString (const char *text, int level) return; //let the csqc handle it if it wants. #endif #if defined(MENU_NATIVECODE) - if (mn_entry && mn_entry->ConsoleCommand(text, cmd_argc, cmd_argv)) + if (mn_entry && mn_entry->ConsoleCommand(text, cmd_argc, (char const*const*)cmd_argv)) return; #endif diff --git a/engine/common/com_mesh.c b/engine/common/com_mesh.c index cb3812380..51eee857b 100644 --- a/engine/common/com_mesh.c +++ b/engine/common/com_mesh.c @@ -39,9 +39,9 @@ void Mod_UpdateCRC(void *ctx, void *data, size_t a, size_t b) { char st[40]; Q_snprintfz(st, sizeof(st), "%d", (int) a); - if (strcmp(st, Info_ValueForKey(cls.userinfo[0], ctx))) + if (strcmp(st, InfoBuf_ValueForKey(&cls.userinfo[0], ctx))) { - Info_SetValueForKey (cls.userinfo[0], ctx, st, sizeof(cls.userinfo[0])); + InfoBuf_SetKey(&cls.userinfo[0], ctx, st); if (cls.state >= ca_connected && (cls.protocol == CP_QUAKEWORLD || (cls.fteprotocolextensions2 & PEXT2_PREDINFO))) CL_SendClientCommand(true, "setinfo %s %s", (char*)ctx, st); } @@ -2571,7 +2571,7 @@ static frameinfo_t *ParseFrameInfo(char *modelname, int *numgroups) size_t fsize; com_tokentype_t ttype; Q_snprintfz(fname, sizeof(fname), "%s.framegroups", modelname); - line = file = COM_LoadFile(fname, 5, &fsize); + line = file = FS_LoadMallocFile(fname, &fsize); if (!file) return NULL; while(line && *line) @@ -2650,7 +2650,7 @@ static qboolean Mod_ParseModelEvents(model_t *mod, galiasanimation_t *anims, uns size_t fsize; char *line, *file, *eol; Q_snprintfz(fname, sizeof(fname), "%s.events", modelname); - line = file = COM_LoadFile(fname, 5, &fsize); + line = file = FS_LoadMallocFile(fname, &fsize); if (!file) return false; while(line && *line) @@ -3914,7 +3914,7 @@ int Mod_ReadFlagsFromMD1(char *name, int md3version) return 0; } - pinmodel = (dmdl_t *)COM_LoadFile(fname, 5, &fsize); + pinmodel = (dmdl_t *)FS_LoadMallocFile(fname, &fsize); if (pinmodel) { if (fsize >= sizeof(dmdl_t) && LittleLong(pinmodel->ident) == IDPOLYHEADER) @@ -5812,7 +5812,7 @@ qboolean QDECL Mod_LoadPSKModel(model_t *mod, void *buffer, size_t fsize) COM_StripExtension(mod->name, psaname, sizeof(psaname)); Q_strncatz(psaname, ".psa", sizeof(psaname)); buffer = NULL;//test - psabuffer = COM_LoadFile(psaname, 5, &psasize); + psabuffer = FS_LoadMallocFile(psaname, &psasize); if (psabuffer) { pos = 0; diff --git a/engine/common/com_phys_bullet.cpp b/engine/common/com_phys_bullet.cpp index db786c52a..3497b82ae 100644 --- a/engine/common/com_phys_bullet.cpp +++ b/engine/common/com_phys_bullet.cpp @@ -1,1759 +1,3 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -//can either be built as a separate dll or statically linked in the engine (will still be treated as if dynamically) -//to enable as static, add the file to the makefile/project and edit engine/common/plugin.c to list Plug_$foo_Init - - -#ifndef FTEPLUGIN #define FTEENGINE -#define FTEPLUGIN -#define pCvar_Register Cvar_Get -#define pCvar_GetFloat(x) Cvar_FindVar(x)->value -#define pSys_Error Sys_Error -#define Plug_Init Plug_Bullet_Init -#pragma comment(lib,"../../plugins/bullet/libs/bullet_dbg.lib") -#endif - -#include "../../plugins/plugin.h" -#include "../../plugins/engine.h" - -#include "pr_common.h" -#include "com_mesh.h" - -#ifndef FTEENGINE -#define BZ_Malloc malloc -#define BZ_Free free -#define Z_Free BZ_Free -static vec3_t vec3_origin; -static int VectorCompare (const vec3_t v1, const vec3_t v2) -{ - int i; - for (i=0 ; i<3 ; i++) - if (v1[i] != v2[i]) - return 0; - return 1; -} - -#endif -static modplugfuncs_t *modfuncs; - - -//============================================================================ -// physics engine support -//============================================================================ - -#define DEG2RAD(d) (d * M_PI * (1/180.0f)) -#define RAD2DEG(d) ((d*180) / M_PI) - -#include - - -static void World_Bullet_RunCmd(world_t *world, rbecommandqueue_t *cmd); - -void World_Bullet_Init(void) -{ - pCvar_Register("physics_bullet_enable", "1", 0, "Bullet"); - pCvar_Register("physics_bullet_maxiterationsperframe", "10", 0, "Bullet"); - pCvar_Register("physics_bullet_framerate", "60", 0, "Bullet"); -} - -void World_Bullet_Shutdown(void) -{ -} - -typedef struct bulletcontext_s -{ - rigidbodyengine_t funcs; - - qboolean hasextraobjs; -// void *ode_space; -// void *ode_contactgroup; - // number of constraint solver iterations to use (for dWorldStepFast) -// int ode_iterations; - // actual step (server frametime / ode_iterations) -// vec_t ode_step; - // max velocity for a 1-unit radius object at current step to prevent - // missed collisions -// vec_t ode_movelimit; - rbecommandqueue_t *cmdqueuehead; - rbecommandqueue_t *cmdqueuetail; - - - world_t *gworld; - - - btBroadphaseInterface *broadphase; - btDefaultCollisionConfiguration *collisionconfig; - btCollisionDispatcher *collisiondispatcher; - btSequentialImpulseConstraintSolver *solver; - btDiscreteDynamicsWorld *dworld; - btOverlapFilterCallback *ownerfilter; -} bulletcontext_t; - -class QCFilterCallback : public btOverlapFilterCallback -{ - // return true when pairs need collision - virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const - { - //dimensions don't collide - bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0; - collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask); - - //owners don't collide (unless one is world, obviouslyish) - if (collides) - { - btRigidBody *b1 = (btRigidBody*)proxy0->m_clientObject; - btRigidBody *b2 = (btRigidBody*)proxy1->m_clientObject; - //don't let two qc-controlled entities collide in Bullet, that's the job of quake. - if (b1->isStaticOrKinematicObject() && b2->isStaticOrKinematicObject()) - return false; - wedict_t *e1 = (wedict_t*)b1->getUserPointer(); - wedict_t *e2 = (wedict_t*)b2->getUserPointer(); - if ((e1->v->solid == SOLID_TRIGGER && e2->v->solid != SOLID_BSP) || - (e2->v->solid == SOLID_TRIGGER && e1->v->solid != SOLID_BSP)) - return false; //triggers only collide with bsp objects. - if (e1->entnum && e2->entnum) - collides = e1->v->owner != e2->entnum && e2->v->owner != e1->entnum; - } - - return collides; - } -}; - -static void QDECL World_Bullet_End(world_t *world) -{ - struct bulletcontext_s *ctx = (struct bulletcontext_s*)world->rbe; - world->rbe = NULL; - delete ctx->dworld; - delete ctx->solver; - delete ctx->collisionconfig; - delete ctx->collisiondispatcher; - delete ctx->broadphase; - delete ctx->ownerfilter; - Z_Free(ctx); -} - -static void QDECL World_Bullet_RemoveJointFromEntity(world_t *world, wedict_t *ed) -{ - ed->ode.ode_joint_type = 0; -// if(ed->ode.ode_joint) -// dJointDestroy((dJointID)ed->ode.ode_joint); - ed->ode.ode_joint = NULL; -} - -static void QDECL World_Bullet_RemoveFromEntity(world_t *world, wedict_t *ed) -{ - struct bulletcontext_s *ctx = (struct bulletcontext_s*)world->rbe; - btRigidBody *body; - btCollisionShape *geom; - if (!ed->ode.ode_physics) - return; - - // entity is not physics controlled, free any physics data - ed->ode.ode_physics = qfalse; - - body = (btRigidBody*)ed->ode.ode_body; - ed->ode.ode_body = NULL; - if (body) - ctx->dworld->removeRigidBody (body); - - geom = (btCollisionShape*)ed->ode.ode_geom; - ed->ode.ode_geom = NULL; - if (ed->ode.ode_geom) - delete geom; - - //FIXME: joints - modfuncs->ReleaseCollisionMesh(ed); - if(ed->ode.ode_massbuf) - BZ_Free(ed->ode.ode_massbuf); - ed->ode.ode_massbuf = NULL; -} - -static void World_Bullet_Frame_BodyToEntity(world_t *world, wedict_t *ed) -{ - return; - -#if 0 - model_t *model; - const float *avel; - const float *o; - const float *r; // for some reason dBodyGetRotation returns a [3][4] matrix - const float *vel; - btRigidBody *body = (btRigidBody*)ed->ode.ode_body; - int movetype; - float bodymatrix[16]; - float entitymatrix[16]; - vec3_t angles; - vec3_t avelocity; - vec3_t forward, left, up; - vec3_t origin; - vec3_t spinvelocity; - vec3_t velocity; - if (!body) - return; - - movetype = (int)ed->v->movetype; - if (movetype != MOVETYPE_PHYSICS) - { - switch((int)ed->xv->jointtype) - { - // TODO feed back data from physics - case JOINTTYPE_POINT: - break; - case JOINTTYPE_HINGE: - break; - case JOINTTYPE_SLIDER: - break; - case JOINTTYPE_UNIVERSAL: - break; - case JOINTTYPE_HINGE2: - break; - case JOINTTYPE_FIXED: - break; - } - return; - } - // store the physics engine data into the entity - - btTransform trans; - body->getMotionState()->getWorldTransform(trans); -// o = dBodyGetPosition(body); -// r = dBodyGetRotation(body); -// vel = dBodyGetLinearVel(body); -// avel = dBodyGetAngularVel(body); -// VectorCopy(o, origin); -// forward[0] = r[0]; -// forward[1] = r[4]; -// forward[2] = r[8]; -// left[0] = r[1]; -// left[1] = r[5]; -// left[2] = r[9]; -// up[0] = r[2]; -// up[1] = r[6]; -// up[2] = r[10]; - vel = body->getLinearVelocity(); - avel = body->getAngularVelocity(); - VectorCopy(vel, velocity); - VectorCopy(avel, spinvelocity); - trans.getBasis().getOpenGLSubMatrix(bodymatrix); - foo Matrix4x4_RM_FromVectors(bodymatrix, forward, left, up, origin); - foo Matrix4_Multiply(ed->ode.ode_offsetimatrix, bodymatrix, entitymatrix); - foo Matrix3x4_RM_ToVectors(entitymatrix, forward, left, up, origin); - - VectorAngles(forward, up, angles); - angles[0]*=r_meshpitch.value; - - avelocity[PITCH] = RAD2DEG(spinvelocity[PITCH]); - avelocity[YAW] = RAD2DEG(spinvelocity[ROLL]); - avelocity[ROLL] = RAD2DEG(spinvelocity[YAW]); - - if (ed->v->modelindex) - { - model = world->Get_CModel(world, ed->v->modelindex); - if (!model || model->type == mod_alias) - { - angles[PITCH] *= r_meshpitch.value; - avelocity[PITCH] *= r_meshpitch.value; - } - } - - VectorCopy(origin, ed->v->origin); - VectorCopy(velocity, ed->v->velocity); - //VectorCopy(forward, ed->xv->axis_forward); - //VectorCopy(left, ed->xv->axis_left); - //VectorCopy(up, ed->xv->axis_up); - //VectorCopy(spinvelocity, ed->xv->spinvelocity); - VectorCopy(angles, ed->v->angles); - VectorCopy(avelocity, ed->v->avelocity); - - // values for BodyFromEntity to check if the qc modified anything later - VectorCopy(origin, ed->ode.ode_origin); - VectorCopy(velocity, ed->ode.ode_velocity); - VectorCopy(angles, ed->ode.ode_angles); - VectorCopy(avelocity, ed->ode.ode_avelocity); -// ed->ode.ode_gravity = (qboolean)dBodyGetGravityMode(body); - - World_LinkEdict(world, ed, true); -#endif -} - -static void World_Bullet_Frame_JointFromEntity(world_t *world, wedict_t *ed) -{ -#if 0 - dJointID j = 0; - dBodyID b1 = 0; - dBodyID b2 = 0; - int movetype = 0; - int jointtype = 0; - int enemy = 0, aiment = 0; - wedict_t *o; - vec3_t origin, velocity, angles, forward, left, up, movedir; - vec_t CFM, ERP, FMax, Stop, Vel; - VectorClear(origin); - VectorClear(velocity); - VectorClear(angles); - VectorClear(movedir); - movetype = (int)ed->v->movetype; - jointtype = (int)ed->xv->jointtype; - enemy = ed->v->enemy; - aiment = ed->v->aiment; - VectorCopy(ed->v->origin, origin); - VectorCopy(ed->v->velocity, velocity); - VectorCopy(ed->v->angles, angles); - VectorCopy(ed->v->movedir, movedir); - if(movetype == MOVETYPE_PHYSICS) - jointtype = 0; // can't have both - - o = (wedict_t*)PROG_TO_EDICT(world->progs, enemy); - if(o->isfree || o->ode.ode_body == 0) - enemy = 0; - o = (wedict_t*)PROG_TO_EDICT(world->progs, aiment); - if(o->isfree || o->ode.ode_body == 0) - aiment = 0; - // see http://www.ode.org/old_list_archives/2006-January/017614.html - // we want to set ERP? make it fps independent and work like a spring constant - // note: if movedir[2] is 0, it becomes ERP = 1, CFM = 1.0 / (H * K) - if(movedir[0] > 0 && movedir[1] > 0) - { - float K = movedir[0]; - float D = movedir[1]; - float R = 2.0 * D * sqrt(K); // we assume D is premultiplied by sqrt(sprungMass) - CFM = 1.0 / (world->ode.ode_step * K + R); // always > 0 - ERP = world->ode.ode_step * K * CFM; - Vel = 0; - FMax = 0; - Stop = movedir[2]; - } - else if(movedir[1] < 0) - { - CFM = 0; - ERP = 0; - Vel = movedir[0]; - FMax = -movedir[1]; // TODO do we need to multiply with world.physics.ode_step? - Stop = movedir[2] > 0 ? movedir[2] : dInfinity; - } - else // movedir[0] > 0, movedir[1] == 0 or movedir[0] < 0, movedir[1] >= 0 - { - CFM = 0; - ERP = 0; - Vel = 0; - FMax = 0; - Stop = dInfinity; - } - if(jointtype == ed->ode.ode_joint_type && VectorCompare(origin, ed->ode.ode_joint_origin) && VectorCompare(velocity, ed->ode.ode_joint_velocity) && VectorCompare(angles, ed->ode.ode_joint_angles) && enemy == ed->ode.ode_joint_enemy && aiment == ed->ode.ode_joint_aiment && VectorCompare(movedir, ed->ode.ode_joint_movedir)) - return; // nothing to do - AngleVectorsFLU(angles, forward, left, up); - switch(jointtype) - { - case JOINTTYPE_POINT: - j = dJointCreateBall(world->ode.ode_world, 0); - break; - case JOINTTYPE_HINGE: - j = dJointCreateHinge(world->ode.ode_world, 0); - break; - case JOINTTYPE_SLIDER: - j = dJointCreateSlider(world->ode.ode_world, 0); - break; - case JOINTTYPE_UNIVERSAL: - j = dJointCreateUniversal(world->ode.ode_world, 0); - break; - case JOINTTYPE_HINGE2: - j = dJointCreateHinge2(world->ode.ode_world, 0); - break; - case JOINTTYPE_FIXED: - j = dJointCreateFixed(world->ode.ode_world, 0); - break; - case 0: - default: - // no joint - j = 0; - break; - } - if(ed->ode.ode_joint) - { - //Con_Printf("deleted old joint %i\n", (int) (ed - prog->edicts)); - dJointAttach(ed->ode.ode_joint, 0, 0); - dJointDestroy(ed->ode.ode_joint); - } - ed->ode.ode_joint = (void *) j; - ed->ode.ode_joint_type = jointtype; - ed->ode.ode_joint_enemy = enemy; - ed->ode.ode_joint_aiment = aiment; - VectorCopy(origin, ed->ode.ode_joint_origin); - VectorCopy(velocity, ed->ode.ode_joint_velocity); - VectorCopy(angles, ed->ode.ode_joint_angles); - VectorCopy(movedir, ed->ode.ode_joint_movedir); - if(j) - { - //Con_Printf("made new joint %i\n", (int) (ed - prog->edicts)); - dJointSetData(j, (void *) ed); - if(enemy) - b1 = (dBodyID)((WEDICT_NUM(world->progs, enemy))->ode.ode_body); - if(aiment) - b2 = (dBodyID)((WEDICT_NUM(world->progs, aiment))->ode.ode_body); - dJointAttach(j, b1, b2); - - switch(jointtype) - { - case JOINTTYPE_POINT: - dJointSetBallAnchor(j, origin[0], origin[1], origin[2]); - break; - case JOINTTYPE_HINGE: - dJointSetHingeAnchor(j, origin[0], origin[1], origin[2]); - dJointSetHingeAxis(j, forward[0], forward[1], forward[2]); - dJointSetHingeParam(j, dParamFMax, FMax); - dJointSetHingeParam(j, dParamHiStop, Stop); - dJointSetHingeParam(j, dParamLoStop, -Stop); - dJointSetHingeParam(j, dParamStopCFM, CFM); - dJointSetHingeParam(j, dParamStopERP, ERP); - dJointSetHingeParam(j, dParamVel, Vel); - break; - case JOINTTYPE_SLIDER: - dJointSetSliderAxis(j, forward[0], forward[1], forward[2]); - dJointSetSliderParam(j, dParamFMax, FMax); - dJointSetSliderParam(j, dParamHiStop, Stop); - dJointSetSliderParam(j, dParamLoStop, -Stop); - dJointSetSliderParam(j, dParamStopCFM, CFM); - dJointSetSliderParam(j, dParamStopERP, ERP); - dJointSetSliderParam(j, dParamVel, Vel); - break; - case JOINTTYPE_UNIVERSAL: - dJointSetUniversalAnchor(j, origin[0], origin[1], origin[2]); - dJointSetUniversalAxis1(j, forward[0], forward[1], forward[2]); - dJointSetUniversalAxis2(j, up[0], up[1], up[2]); - dJointSetUniversalParam(j, dParamFMax, FMax); - dJointSetUniversalParam(j, dParamHiStop, Stop); - dJointSetUniversalParam(j, dParamLoStop, -Stop); - dJointSetUniversalParam(j, dParamStopCFM, CFM); - dJointSetUniversalParam(j, dParamStopERP, ERP); - dJointSetUniversalParam(j, dParamVel, Vel); - dJointSetUniversalParam(j, dParamFMax2, FMax); - dJointSetUniversalParam(j, dParamHiStop2, Stop); - dJointSetUniversalParam(j, dParamLoStop2, -Stop); - dJointSetUniversalParam(j, dParamStopCFM2, CFM); - dJointSetUniversalParam(j, dParamStopERP2, ERP); - dJointSetUniversalParam(j, dParamVel2, Vel); - break; - case JOINTTYPE_HINGE2: - dJointSetHinge2Anchor(j, origin[0], origin[1], origin[2]); - dJointSetHinge2Axis1(j, forward[0], forward[1], forward[2]); - dJointSetHinge2Axis2(j, velocity[0], velocity[1], velocity[2]); - dJointSetHinge2Param(j, dParamFMax, FMax); - dJointSetHinge2Param(j, dParamHiStop, Stop); - dJointSetHinge2Param(j, dParamLoStop, -Stop); - dJointSetHinge2Param(j, dParamStopCFM, CFM); - dJointSetHinge2Param(j, dParamStopERP, ERP); - dJointSetHinge2Param(j, dParamVel, Vel); - dJointSetHinge2Param(j, dParamFMax2, FMax); - dJointSetHinge2Param(j, dParamHiStop2, Stop); - dJointSetHinge2Param(j, dParamLoStop2, -Stop); - dJointSetHinge2Param(j, dParamStopCFM2, CFM); - dJointSetHinge2Param(j, dParamStopERP2, ERP); - dJointSetHinge2Param(j, dParamVel2, Vel); - break; - case JOINTTYPE_FIXED: - break; - case 0: - default: - break; - } -#undef SETPARAMS - - } -#endif -} - -static qboolean QDECL World_Bullet_RagMatrixToBody(rbebody_t *bodyptr, float *mat) -{ - btRigidBody *body; - -/* - dVector3 r[3]; - - r[0][0] = mat[0]; - r[0][1] = mat[1]; - r[0][2] = mat[2]; - r[1][0] = mat[4]; - r[1][1] = mat[5]; - r[1][2] = mat[6]; - r[2][0] = mat[8]; - r[2][1] = mat[9]; - r[2][2] = mat[10]; - - dBodySetPosition(bodyptr->ode_body, mat[3], mat[7], mat[11]); - dBodySetRotation(bodyptr->ode_body, r[0]); - dBodySetLinearVel(bodyptr->ode_body, 0, 0, 0); - dBodySetAngularVel(bodyptr->ode_body, 0, 0, 0); -*/ - return qtrue; -} -static qboolean QDECL World_Bullet_RagCreateBody(world_t *world, rbebody_t *bodyptr, rbebodyinfo_t *bodyinfo, float *mat, wedict_t *ent) -{ -/* - dMass mass; - float radius; - if (!world->ode.ode_space) - return false; - world->ode.hasodeents = true; //I don't like this, but we need the world etc to be solid. - world->ode.hasextraobjs = true; - - switch(bodyinfo->geomshape) - { - case GEOMTYPE_CAPSULE: - radius = (bodyinfo->dimensions[0] + bodyinfo->dimensions[1]) * 0.5; - bodyptr->ode_geom = (void *)dCreateCapsule(world->ode.ode_space, radius, bodyinfo->dimensions[2]); - dMassSetCapsuleTotal(&mass, bodyinfo->mass, 3, radius, bodyinfo->dimensions[2]); - //aligned along the geom's local z axis - break; - case GEOMTYPE_SPHERE: - //radius - radius = (bodyinfo->dimensions[0] + bodyinfo->dimensions[1] + bodyinfo->dimensions[2]) / 3; - bodyptr->ode_geom = dCreateSphere(world->ode.ode_space, radius); - dMassSetSphereTotal(&mass, bodyinfo->mass, radius); - //aligned along the geom's local z axis - break; - case GEOMTYPE_CYLINDER: - //radius, length - radius = (bodyinfo->dimensions[0] + bodyinfo->dimensions[1]) * 0.5; - bodyptr->ode_geom = dCreateCylinder(world->ode.ode_space, radius, bodyinfo->dimensions[2]); - dMassSetCylinderTotal(&mass, bodyinfo->mass, 3, radius, bodyinfo->dimensions[2]); - //alignment is irreleevnt, thouse I suppose it might be scaled wierdly. - break; - default: - case GEOMTYPE_BOX: - //diameter - bodyptr->ode_geom = dCreateBox(world->ode.ode_space, bodyinfo->dimensions[0], bodyinfo->dimensions[1], bodyinfo->dimensions[2]); - dMassSetBoxTotal(&mass, bodyinfo->mass, bodyinfo->dimensions[0], bodyinfo->dimensions[1], bodyinfo->dimensions[2]); - //monkey - break; - } - bodyptr->ode_body = dBodyCreate(world->ode.ode_world); - dBodySetMass(bodyptr->ode_body, &mass); - dGeomSetBody(bodyptr->ode_geom, bodyptr->ode_body); - dGeomSetData(bodyptr->ode_geom, (void*)ent); -*/ - return World_Bullet_RagMatrixToBody(bodyptr, mat); -} - -static void QDECL World_Bullet_RagMatrixFromJoint(rbejoint_t *joint, rbejointinfo_t *info, float *mat) -{ -/* - dVector3 dr3; - switch(info->type) - { - case JOINTTYPE_POINT: - dJointGetBallAnchor(joint->ode_joint, dr3); - mat[3] = dr3[0]; - mat[7] = dr3[1]; - mat[11] = dr3[2]; - VectorClear(mat+4); - VectorClear(mat+8); - break; - - case JOINTTYPE_HINGE: - dJointGetHingeAnchor(joint->ode_joint, dr3); - mat[3] = dr3[0]; - mat[7] = dr3[1]; - mat[11] = dr3[2]; - - dJointGetHingeAxis(joint->ode_joint, dr3); - VectorCopy(dr3, mat+4); - VectorClear(mat+8); - - CrossProduct(mat+4, mat+8, mat+0); - return; - break; - case JOINTTYPE_HINGE2: - dJointGetHinge2Anchor(joint->ode_joint, dr3); - mat[3] = dr3[0]; - mat[7] = dr3[1]; - mat[11] = dr3[2]; - - dJointGetHinge2Axis1(joint->ode_joint, dr3); - VectorCopy(dr3, mat+4); - dJointGetHinge2Axis2(joint->ode_joint, dr3); - VectorCopy(dr3, mat+8); - break; - - case JOINTTYPE_SLIDER: - //no anchor point... - //get the two bodies and average their origin for a somewhat usable representation of an anchor. - { - const dReal *p1, *p2; - dReal n[3]; - dBodyID b1 = dJointGetBody(joint->ode_joint, 0), b2 = dJointGetBody(joint->ode_joint, 1); - if (b1) - p1 = dBodyGetPosition(b1); - else - { - p1 = n; - VectorClear(n); - } - if (b2) - p2 = dBodyGetPosition(b2); - else - p2 = p1; - dJointGetSliderAxis(joint->ode_joint, dr3 + 0); - VectorInterpolate(p1, 0.5, p2, dr3); - mat[3] = dr3[0]; - mat[7] = dr3[1]; - mat[11] = dr3[2]; - - VectorClear(mat+4); - VectorClear(mat+8); - } - break; - - case JOINTTYPE_UNIVERSAL: - dJointGetUniversalAnchor(joint->ode_joint, dr3); - mat[3] = dr3[0]; - mat[7] = dr3[1]; - mat[11] = dr3[2]; - - dJointGetUniversalAxis1(joint->ode_joint, dr3); - VectorCopy(dr3, mat+4); - dJointGetUniversalAxis2(joint->ode_joint, dr3); - VectorCopy(dr3, mat+8); - - CrossProduct(mat+4, mat+8, mat+0); - return; - break; - } - AngleVectorsFLU(vec3_origin, mat+0, mat+4, mat+8); -*/ -} - -static void QDECL World_Bullet_RagMatrixFromBody(world_t *world, rbebody_t *bodyptr, float *mat) -{ -/* - const dReal *o = dBodyGetPosition(bodyptr->ode_body); - const dReal *r = dBodyGetRotation(bodyptr->ode_body); - mat[0] = r[0]; - mat[1] = r[1]; - mat[2] = r[2]; - mat[3] = o[0]; - - mat[4] = r[4]; - mat[5] = r[5]; - mat[6] = r[6]; - mat[7] = o[1]; - - mat[8] = r[8]; - mat[9] = r[9]; - mat[10] = r[10]; - mat[11] = o[2]; -*/ -} -static void QDECL World_Bullet_RagEnableJoint(rbejoint_t *joint, qboolean enabled) -{ -/* - if (enabled) - dJointEnable(joint->ode_joint); - else - dJointDisable(joint->ode_joint); -*/ -} -static void QDECL World_Bullet_RagCreateJoint(world_t *world, rbejoint_t *joint, rbejointinfo_t *info, rbebody_t *body1, rbebody_t *body2, vec3_t aaa2[3]) -{ -/* - switch(info->type) - { - case JOINTTYPE_POINT: - joint->ode_joint = dJointCreateBall(world->ode.ode_world, 0); - break; - case JOINTTYPE_HINGE: - joint->ode_joint = dJointCreateHinge(world->ode.ode_world, 0); - break; - case JOINTTYPE_SLIDER: - joint->ode_joint = dJointCreateSlider(world->ode.ode_world, 0); - break; - case JOINTTYPE_UNIVERSAL: - joint->ode_joint = dJointCreateUniversal(world->ode.ode_world, 0); - break; - case JOINTTYPE_HINGE2: - joint->ode_joint = dJointCreateHinge2(world->ode.ode_world, 0); - break; - case JOINTTYPE_FIXED: - joint->ode_joint = dJointCreateFixed(world->ode.ode_world, 0); - break; - default: - joint->ode_joint = NULL; - break; - } - if (joint->ode_joint) - { - //Con_Printf("made new joint %i\n", (int) (ed - prog->edicts)); -// dJointSetData(joint->ode_joint, NULL); - dJointAttach(joint->ode_joint, body1?body1->ode_body:NULL, body2?body2->ode_body:NULL); - - switch(info->type) - { - case JOINTTYPE_POINT: - dJointSetBallAnchor(joint->ode_joint, aaa2[0][0], aaa2[0][1], aaa2[0][2]); - break; - case JOINTTYPE_HINGE: - dJointSetHingeAnchor(joint->ode_joint, aaa2[0][0], aaa2[0][1], aaa2[0][2]); - dJointSetHingeAxis(joint->ode_joint, aaa2[1][0], aaa2[1][1], aaa2[1][2]); - dJointSetHingeParam(joint->ode_joint, dParamFMax, info->FMax); - dJointSetHingeParam(joint->ode_joint, dParamHiStop, info->HiStop); - dJointSetHingeParam(joint->ode_joint, dParamLoStop, info->LoStop); - dJointSetHingeParam(joint->ode_joint, dParamStopCFM, info->CFM); - dJointSetHingeParam(joint->ode_joint, dParamStopERP, info->ERP); - dJointSetHingeParam(joint->ode_joint, dParamVel, info->Vel); - break; - case JOINTTYPE_SLIDER: - dJointSetSliderAxis(joint->ode_joint, aaa2[1][0], aaa2[1][1], aaa2[1][2]); - dJointSetSliderParam(joint->ode_joint, dParamFMax, info->FMax); - dJointSetSliderParam(joint->ode_joint, dParamHiStop, info->HiStop); - dJointSetSliderParam(joint->ode_joint, dParamLoStop, info->LoStop); - dJointSetSliderParam(joint->ode_joint, dParamStopCFM, info->CFM); - dJointSetSliderParam(joint->ode_joint, dParamStopERP, info->ERP); - dJointSetSliderParam(joint->ode_joint, dParamVel, info->Vel); - break; - case JOINTTYPE_UNIVERSAL: - dJointSetUniversalAnchor(joint->ode_joint, aaa2[0][0], aaa2[0][1], aaa2[0][2]); - dJointSetUniversalAxis1(joint->ode_joint, aaa2[1][0], aaa2[1][1], aaa2[1][2]); - dJointSetUniversalAxis2(joint->ode_joint, aaa2[2][0], aaa2[2][1], aaa2[2][2]); - dJointSetUniversalParam(joint->ode_joint, dParamFMax, info->FMax); - dJointSetUniversalParam(joint->ode_joint, dParamHiStop, info->HiStop); - dJointSetUniversalParam(joint->ode_joint, dParamLoStop, info->LoStop); - dJointSetUniversalParam(joint->ode_joint, dParamStopCFM, info->CFM); - dJointSetUniversalParam(joint->ode_joint, dParamStopERP, info->ERP); - dJointSetUniversalParam(joint->ode_joint, dParamVel, info->Vel); - dJointSetUniversalParam(joint->ode_joint, dParamFMax2, info->FMax2); - dJointSetUniversalParam(joint->ode_joint, dParamHiStop2, info->HiStop2); - dJointSetUniversalParam(joint->ode_joint, dParamLoStop2, info->LoStop2); - dJointSetUniversalParam(joint->ode_joint, dParamStopCFM2, info->CFM2); - dJointSetUniversalParam(joint->ode_joint, dParamStopERP2, info->ERP2); - dJointSetUniversalParam(joint->ode_joint, dParamVel2, info->Vel2); - break; - case JOINTTYPE_HINGE2: - dJointSetHinge2Anchor(joint->ode_joint, aaa2[0][0], aaa2[0][1], aaa2[0][2]); - dJointSetHinge2Axis1(joint->ode_joint, aaa2[1][0], aaa2[1][1], aaa2[1][2]); - dJointSetHinge2Axis2(joint->ode_joint, aaa2[2][0], aaa2[2][1], aaa2[2][2]); - dJointSetHinge2Param(joint->ode_joint, dParamFMax, info->FMax); - dJointSetHinge2Param(joint->ode_joint, dParamHiStop, info->HiStop); - dJointSetHinge2Param(joint->ode_joint, dParamLoStop, info->LoStop); - dJointSetHinge2Param(joint->ode_joint, dParamStopCFM, info->CFM); - dJointSetHinge2Param(joint->ode_joint, dParamStopERP, info->ERP); - dJointSetHinge2Param(joint->ode_joint, dParamVel, info->Vel); - dJointSetHinge2Param(joint->ode_joint, dParamFMax2, info->FMax2); - dJointSetHinge2Param(joint->ode_joint, dParamHiStop2, info->HiStop2); - dJointSetHinge2Param(joint->ode_joint, dParamLoStop2, info->LoStop2); - dJointSetHinge2Param(joint->ode_joint, dParamStopCFM2, info->CFM2); - dJointSetHinge2Param(joint->ode_joint, dParamStopERP2, info->ERP2); - dJointSetHinge2Param(joint->ode_joint, dParamVel2, info->Vel2); - break; - case JOINTTYPE_FIXED: - dJointSetFixed(joint->ode_joint); - break; - } - } -*/ -} - -static void QDECL World_Bullet_RagDestroyBody(world_t *world, rbebody_t *bodyptr) -{ -/* - if (bodyptr->ode_geom) - dGeomDestroy(bodyptr->ode_geom); - bodyptr->ode_geom = NULL; - if (bodyptr->ode_body) - dBodyDestroy(bodyptr->ode_body); - bodyptr->ode_body = NULL; -*/ -} - -static void QDECL World_Bullet_RagDestroyJoint(world_t *world, rbejoint_t *joint) -{ -/* - if (joint->ode_joint) - dJointDestroy(joint->ode_joint); - joint->ode_joint = NULL; -*/ -} - -//bullet gives us a handy way to get/set motion states. we can cheesily update entity fields this way. -class QCMotionState : public btMotionState -{ - wedict_t *edict; - qboolean dirty; - btTransform trans; - world_t *world; - - -public: - void ReloadMotionState(void) - { - vec3_t offset; - vec3_t axis[3]; - btVector3 org; - modfuncs->AngleVectors(edict->v->angles, axis[0], axis[1], axis[2]); - VectorNegate(axis[1], axis[1]); - VectorAvg(edict->ode.ode_mins, edict->ode.ode_maxs, offset); - VectorMA(edict->v->origin, offset[0]*1, axis[0], org); - VectorMA(org, offset[1]*1, axis[1], org); - VectorMA(org, offset[2]*1, axis[2], org); - - trans.setBasis(btMatrix3x3(axis[0][0], axis[1][0], axis[2][0], - axis[0][1], axis[1][1], axis[2][1], - axis[0][2], axis[1][2], axis[2][2])); - trans.setOrigin(org); - } - QCMotionState(wedict_t *ed, world_t *w) - { - dirty = qtrue; - edict = ed; - world = w; - - ReloadMotionState(); - } - virtual ~QCMotionState() - { - } - - virtual void getWorldTransform(btTransform &worldTrans) const - { - worldTrans = trans; - } - - virtual void setWorldTransform(const btTransform &worldTrans) - { - vec3_t fwd, left, up, offset; - trans = worldTrans; - - btVector3 pos = worldTrans.getOrigin(); - VectorCopy(worldTrans.getBasis().getColumn(0), fwd); - VectorCopy(worldTrans.getBasis().getColumn(1), left); - VectorCopy(worldTrans.getBasis().getColumn(2), up); - VectorAvg(edict->ode.ode_mins, edict->ode.ode_maxs, offset); - VectorMA(pos, offset[0]*-1, fwd, pos); - VectorMA(pos, offset[1]*-1, left, pos); - VectorMA(pos, offset[2]*-1, up, edict->v->origin); - - modfuncs->VectorAngles(fwd, up, edict->v->angles); - if (edict->v->modelindex) - { - model_t *model = world->Get_CModel(world, edict->v->modelindex); - if (!model || model->type == mod_alias) - ; - else - edict->v->angles[PITCH] *= r_meshpitch.value; - } - - //so it doesn't get rebuilt - VectorCopy(edict->v->origin, edict->ode.ode_origin); - VectorCopy(edict->v->angles, edict->ode.ode_angles); - -// World_LinkEdict(world, edict, false); - -// if(mSceneNode == nullptr) -// return; // silently return before we set a node - -// btQuaternion rot = worldTrans.getRotation(); -// mSceneNode ->setOrientation(rot.w(), rot.x(), rot.y(), rot.z()); -// btVector3 pos = worldTrans.getOrigin(); -// mSceneNode ->setPosition(pos.x(), pos.y(), pos.z()); - } -}; - -static void World_Bullet_Frame_BodyFromEntity(world_t *world, wedict_t *ed) -{ - bulletcontext_t *ctx = (bulletcontext_t*)world->rbe; - btRigidBody *body = NULL; - btScalar mass; - float test; - void *dataID; - model_t *model; - int axisindex; - int modelindex = 0; - int movetype = MOVETYPE_NONE; - int solid = SOLID_NOT; - int geomtype = GEOMTYPE_SOLID; - qboolean modified = qfalse; - vec3_t angles; - vec3_t avelocity; - vec3_t entmaxs; - vec3_t entmins; - vec3_t forward; - vec3_t geomcenter; - vec3_t geomsize; - vec3_t left; - vec3_t origin; - vec3_t spinvelocity; - vec3_t up; - vec3_t velocity; - vec_t f; - vec_t length; - vec_t massval = 1.0f; -// vec_t movelimit; - vec_t radius; - vec_t scale; - vec_t spinlimit; - qboolean gravity; - - geomtype = (int)ed->xv->geomtype; - solid = (int)ed->v->solid; - movetype = (int)ed->v->movetype; - scale = ed->xv->scale?ed->xv->scale:1; - modelindex = 0; - model = NULL; - - if (!geomtype) - { - switch((int)ed->v->solid) - { - case SOLID_NOT: geomtype = GEOMTYPE_NONE; break; - case SOLID_TRIGGER: geomtype = GEOMTYPE_NONE; break; - case SOLID_BSP: geomtype = GEOMTYPE_TRIMESH; break; - case SOLID_PHYSICS_TRIMESH: geomtype = GEOMTYPE_TRIMESH; break; - case SOLID_PHYSICS_BOX: geomtype = GEOMTYPE_BOX; break; - case SOLID_PHYSICS_SPHERE: geomtype = GEOMTYPE_SPHERE; break; - case SOLID_PHYSICS_CAPSULE: geomtype = GEOMTYPE_CAPSULE; break; - case SOLID_PHYSICS_CYLINDER:geomtype = GEOMTYPE_CYLINDER; break; - default: geomtype = GEOMTYPE_BOX; break; - } - } - - switch(geomtype) - { - case GEOMTYPE_TRIMESH: - modelindex = (int)ed->v->modelindex; - model = world->Get_CModel(world, modelindex); - if (!model || model->loadstate != MLS_LOADED) - { - model = NULL; - modelindex = 0; - } - if (model) - { - VectorScale(model->mins, scale, entmins); - VectorScale(model->maxs, scale, entmaxs); - if (ed->xv->mass) - massval = ed->xv->mass; - } - else - { - modelindex = 0; - massval = 1.0f; - } - massval = 0; //bullet does not support trisoup moving through the world. - break; - case GEOMTYPE_BOX: - case GEOMTYPE_SPHERE: - case GEOMTYPE_CAPSULE: - case GEOMTYPE_CAPSULE_X: - case GEOMTYPE_CAPSULE_Y: - case GEOMTYPE_CAPSULE_Z: - case GEOMTYPE_CYLINDER: - case GEOMTYPE_CYLINDER_X: - case GEOMTYPE_CYLINDER_Y: - case GEOMTYPE_CYLINDER_Z: - VectorCopy(ed->v->mins, entmins); - VectorCopy(ed->v->maxs, entmaxs); - if (ed->xv->mass) - massval = ed->xv->mass; - break; - default: -// case GEOMTYPE_NONE: - if (ed->ode.ode_physics) - World_Bullet_RemoveFromEntity(world, ed); - return; - } - - VectorSubtract(entmaxs, entmins, geomsize); - if (DotProduct(geomsize,geomsize) == 0) - { - // we don't allow point-size physics objects... - if (ed->ode.ode_physics) - World_Bullet_RemoveFromEntity(world, ed); - return; - } - - // check if we need to create or replace the geom - if (!ed->ode.ode_physics - || !VectorCompare(ed->ode.ode_mins, entmins) - || !VectorCompare(ed->ode.ode_maxs, entmaxs) - || ed->ode.ode_modelindex != modelindex) - { - btCollisionShape *geom; - - modified = qtrue; - World_Bullet_RemoveFromEntity(world, ed); - ed->ode.ode_physics = qtrue; - VectorCopy(entmins, ed->ode.ode_mins); - VectorCopy(entmaxs, ed->ode.ode_maxs); - ed->ode.ode_modelindex = modelindex; - VectorAvg(entmins, entmaxs, geomcenter); - ed->ode.ode_movelimit = min(geomsize[0], min(geomsize[1], geomsize[2])); - -/* memset(ed->ode.ode_offsetmatrix, 0, sizeof(ed->ode.ode_offsetmatrix)); - ed->ode.ode_offsetmatrix[0] = 1; - ed->ode.ode_offsetmatrix[5] = 1; - ed->ode.ode_offsetmatrix[10] = 1; - ed->ode.ode_offsetmatrix[3] = -geomcenter[0]; - ed->ode.ode_offsetmatrix[7] = -geomcenter[1]; - ed->ode.ode_offsetmatrix[11] = -geomcenter[2]; -*/ - ed->ode.ode_mass = massval; - - switch(geomtype) - { - case GEOMTYPE_TRIMESH: -// foo Matrix4x4_Identity(ed->ode.ode_offsetmatrix); - geom = NULL; - if (!model) - { - Con_Printf("entity %i (classname %s) has no model\n", NUM_FOR_EDICT(world->progs, (edict_t*)ed), PR_GetString(world->progs, ed->v->classname)); - if (ed->ode.ode_physics) - World_Bullet_RemoveFromEntity(world, ed); - return; - } - if (!modfuncs->GenerateCollisionMesh(world, model, ed, geomcenter)) - { - if (ed->ode.ode_physics) - World_Bullet_RemoveFromEntity(world, ed); - return; - } - -// foo Matrix4x4_RM_CreateTranslate(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2]); - - { - btTriangleIndexVertexArray *tiva = new btTriangleIndexVertexArray(); - btIndexedMesh mesh; - mesh.m_vertexType = PHY_FLOAT; - mesh.m_indexType = PHY_INTEGER; - mesh.m_numTriangles = ed->ode.ode_numtriangles; - mesh.m_numVertices = ed->ode.ode_numvertices; - mesh.m_triangleIndexBase = (const unsigned char*)ed->ode.ode_element3i; - mesh.m_triangleIndexStride = sizeof(*ed->ode.ode_element3i)*3; - mesh.m_vertexBase = (const unsigned char*)ed->ode.ode_vertex3f; - mesh.m_vertexStride = sizeof(*ed->ode.ode_vertex3f)*3; - tiva->addIndexedMesh(mesh); - geom = new btBvhTriangleMeshShape(tiva, true); - } - break; - - case GEOMTYPE_BOX: - geom = new btBoxShape(btVector3(geomsize[0], geomsize[1], geomsize[2]) * 0.5); - break; - - case GEOMTYPE_SPHERE: - geom = new btSphereShape(geomsize[0] * 0.5f); - break; - - case GEOMTYPE_CAPSULE: - case GEOMTYPE_CAPSULE_X: - case GEOMTYPE_CAPSULE_Y: - case GEOMTYPE_CAPSULE_Z: - if (geomtype == GEOMTYPE_CAPSULE) - { - // the qc gives us 3 axis radius, the longest axis is the capsule axis - axisindex = 0; - if (geomsize[axisindex] < geomsize[1]) - axisindex = 1; - if (geomsize[axisindex] < geomsize[2]) - axisindex = 2; - } - else - axisindex = geomtype-GEOMTYPE_CAPSULE_X; - if (axisindex == 0) - radius = min(geomsize[1], geomsize[2]) * 0.5f; - else if (axisindex == 1) - radius = min(geomsize[0], geomsize[2]) * 0.5f; - else - radius = min(geomsize[0], geomsize[1]) * 0.5f; - length = geomsize[axisindex] - radius*2; - if (length <= 0) - { - radius -= (1 - length)*0.5; - length = 1; - } - if (axisindex == 0) - geom = new btCapsuleShapeX(radius, length); - else if (axisindex == 1) - geom = new btCapsuleShape(radius, length); - else - geom = new btCapsuleShapeZ(radius, length); - break; - - case GEOMTYPE_CYLINDER: - case GEOMTYPE_CYLINDER_X: - case GEOMTYPE_CYLINDER_Y: - case GEOMTYPE_CYLINDER_Z: - if (geomtype == GEOMTYPE_CYLINDER) - { - // the qc gives us 3 axis radius, the longest axis is the capsule axis - axisindex = 0; - if (geomsize[axisindex] < geomsize[1]) - axisindex = 1; - if (geomsize[axisindex] < geomsize[2]) - axisindex = 2; - } - else - axisindex = geomtype-GEOMTYPE_CYLINDER_X; - if (axisindex == 0) - geom = new btCylinderShapeX(btVector3(geomsize[0], geomsize[1], geomsize[2])*0.5); - else if (axisindex == 1) - geom = new btCylinderShape(btVector3(geomsize[0], geomsize[1], geomsize[2])*0.5); - else - geom = new btCylinderShapeZ(btVector3(geomsize[0], geomsize[1], geomsize[2])*0.5); - break; - - default: -// Con_Printf("World_Bullet_BodyFromEntity: unrecognized solid value %i was accepted by filter\n", solid); - if (ed->ode.ode_physics) - World_Bullet_RemoveFromEntity(world, ed); - return; - } -// Matrix3x4_InvertTo4x4_Simple(ed->ode.ode_offsetmatrix, ed->ode.ode_offsetimatrix); -// ed->ode.ode_massbuf = BZ_Malloc(sizeof(dMass)); -// memcpy(ed->ode.ode_massbuf, &mass, sizeof(dMass)); - - ed->ode.ode_geom = (void *)geom; - } - - //non-moving objects need to be static objects (and thus need 0 mass) - if (movetype != MOVETYPE_PHYSICS && movetype != MOVETYPE_WALK) //enabling kinematic objects for everything else destroys framerates (!movetype || movetype == MOVETYPE_PUSH) - massval = 0; - - //if the mass changes, we'll need to create a new body (but not the shape, so invalidate the current one) - if (ed->ode.ode_mass != massval) - { - ed->ode.ode_mass = massval; - body = (btRigidBody*)ed->ode.ode_body; - if (body) - ctx->dworld->removeRigidBody(body); - ed->ode.ode_body = NULL; - } - -// if(ed->ode.ode_geom) -// dGeomSetData(ed->ode.ode_geom, (void*)ed); - if (movetype == MOVETYPE_PHYSICS && ed->ode.ode_mass) - { - if (ed->ode.ode_body == NULL) - { -// ed->ode.ode_body = (void *)(body = dBodyCreate(world->ode.ode_world)); -// dGeomSetBody(ed->ode.ode_geom, body); -// dBodySetData(body, (void*)ed); -// dBodySetMass(body, (dMass *) ed->ode.ode_massbuf); - - btVector3 fallInertia(0, 0, 0); - ((btCollisionShape*)ed->ode.ode_geom)->calculateLocalInertia(ed->ode.ode_mass, fallInertia); - btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(ed->ode.ode_mass, new QCMotionState(ed,world), (btCollisionShape*)ed->ode.ode_geom, fallInertia); - body = new btRigidBody(fallRigidBodyCI); - body->setUserPointer(ed); -// btTransform trans; -// trans.setFromOpenGLMatrix(ed->ode.ode_offsetmatrix); -// body->setCenterOfMassTransform(trans); - ed->ode.ode_body = (void*)body; - - //continuous collision detection prefers using a sphere within the object. tbh I have no idea what values to specify. - body->setCcdMotionThreshold((geomsize[0]+geomsize[1]+geomsize[2])*(4/3)); - body->setCcdSweptSphereRadius((geomsize[0]+geomsize[1]+geomsize[2])*(0.5/3)); - - ctx->dworld->addRigidBody(body, ed->xv->dimension_solid, ed->xv->dimension_hit); - - modified = qtrue; - } - } - else - { - if (ed->ode.ode_body == NULL) - { - btRigidBody::btRigidBodyConstructionInfo rbci(ed->ode.ode_mass, new QCMotionState(ed,world), (btCollisionShape*)ed->ode.ode_geom, btVector3(0, 0, 0)); - body = new btRigidBody(rbci); - body->setUserPointer(ed); -// btTransform trans; -// trans.setFromOpenGLMatrix(ed->ode.ode_offsetmatrix); -// body->setCenterOfMassTransform(trans); - ed->ode.ode_body = (void*)body; - if (ed->ode.ode_mass) - body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); - else - body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT); - ctx->dworld->addRigidBody(body, ed->xv->dimension_solid, ed->xv->dimension_hit); - - modified = qtrue; - } - } - - body = (btRigidBody*)ed->ode.ode_body; - - // get current data from entity - gravity = qtrue; - VectorCopy(ed->v->origin, origin); - VectorCopy(ed->v->velocity, velocity); - VectorCopy(ed->v->angles, angles); - VectorCopy(ed->v->avelocity, avelocity); - if (ed == world->edicts || (ed->xv->gravity && ed->xv->gravity <= 0.01)) - gravity = qfalse; - - // compatibility for legacy entities -// if (!DotProduct(forward,forward) || solid == SOLID_BSP) - { - vec3_t qangles, qavelocity; - VectorCopy(angles, qangles); - VectorCopy(avelocity, qavelocity); - - if (ed->v->modelindex) - { - model = world->Get_CModel(world, ed->v->modelindex); - if (!model || model->type == mod_alias) - { - qangles[PITCH] *= r_meshpitch.value; - qavelocity[PITCH] *= r_meshpitch.value; - } - } - - modfuncs->AngleVectors(qangles, forward, left, up); - VectorNegate(left,left); - // convert single-axis rotations in avelocity to spinvelocity - // FIXME: untested math - check signs - VectorSet(spinvelocity, DEG2RAD(qavelocity[PITCH]), DEG2RAD(qavelocity[ROLL]), DEG2RAD(qavelocity[YAW])); - } - - // compatibility for legacy entities - switch (solid) - { - case SOLID_BBOX: - case SOLID_SLIDEBOX: - case SOLID_CORPSE: - VectorSet(forward, 1, 0, 0); - VectorSet(left, 0, 1, 0); - VectorSet(up, 0, 0, 1); - VectorSet(spinvelocity, 0, 0, 0); - break; - } - - - // we must prevent NANs... - test = DotProduct(origin,origin) + DotProduct(forward,forward) + DotProduct(left,left) + DotProduct(up,up) + DotProduct(velocity,velocity) + DotProduct(spinvelocity,spinvelocity); - if (IS_NAN(test)) - { - modified = qtrue; - //Con_Printf("Fixing NAN values on entity %i : .classname = \"%s\" .origin = '%f %f %f' .velocity = '%f %f %f' .axis_forward = '%f %f %f' .axis_left = '%f %f %f' .axis_up = %f %f %f' .spinvelocity = '%f %f %f'\n", PRVM_NUM_FOR_EDICT(ed), PRVM_GetString(PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.classname)->string), origin[0], origin[1], origin[2], velocity[0], velocity[1], velocity[2], forward[0], forward[1], forward[2], left[0], left[1], left[2], up[0], up[1], up[2], spinvelocity[0], spinvelocity[1], spinvelocity[2]); - Con_Printf("Fixing NAN values on entity %i : .classname = \"%s\" .origin = '%f %f %f' .velocity = '%f %f %f' .angles = '%f %f %f' .avelocity = '%f %f %f'\n", NUM_FOR_EDICT(world->progs, (edict_t*)ed), PR_GetString(world->progs, ed->v->classname), origin[0], origin[1], origin[2], velocity[0], velocity[1], velocity[2], angles[0], angles[1], angles[2], avelocity[0], avelocity[1], avelocity[2]); - test = DotProduct(origin,origin); - if (IS_NAN(test)) - VectorClear(origin); - test = DotProduct(forward,forward) * DotProduct(left,left) * DotProduct(up,up); - if (IS_NAN(test)) - { - VectorSet(angles, 0, 0, 0); - VectorSet(forward, 1, 0, 0); - VectorSet(left, 0, 1, 0); - VectorSet(up, 0, 0, 1); - } - test = DotProduct(velocity,velocity); - if (IS_NAN(test)) - VectorClear(velocity); - test = DotProduct(spinvelocity,spinvelocity); - if (IS_NAN(test)) - { - VectorClear(avelocity); - VectorClear(spinvelocity); - } - } - - // check if the qc edited any position data - if ( - 0//!VectorCompare(origin, ed->ode.ode_origin) - || !VectorCompare(velocity, ed->ode.ode_velocity) - //|| !VectorCompare(angles, ed->ode.ode_angles) - || !VectorCompare(avelocity, ed->ode.ode_avelocity) - || gravity != ed->ode.ode_gravity) - modified = qtrue; - - // store the qc values into the physics engine - body = (btRigidBody*)ed->ode.ode_body; - if (modified && body) - { -// dVector3 r[3]; - float entitymatrix[16]; - float bodymatrix[16]; - -#if 0 - Con_Printf("entity %i got changed by QC\n", (int) (ed - prog->edicts)); - if(!VectorCompare(origin, ed->ode.ode_origin)) - Con_Printf(" origin: %f %f %f -> %f %f %f\n", ed->ode.ode_origin[0], ed->ode.ode_origin[1], ed->ode.ode_origin[2], origin[0], origin[1], origin[2]); - if(!VectorCompare(velocity, ed->ode.ode_velocity)) - Con_Printf(" velocity: %f %f %f -> %f %f %f\n", ed->ode.ode_velocity[0], ed->ode.ode_velocity[1], ed->ode.ode_velocity[2], velocity[0], velocity[1], velocity[2]); - if(!VectorCompare(angles, ed->ode.ode_angles)) - Con_Printf(" angles: %f %f %f -> %f %f %f\n", ed->ode.ode_angles[0], ed->ode.ode_angles[1], ed->ode.ode_angles[2], angles[0], angles[1], angles[2]); - if(!VectorCompare(avelocity, ed->ode.ode_avelocity)) - Con_Printf(" avelocity: %f %f %f -> %f %f %f\n", ed->ode.ode_avelocity[0], ed->ode.ode_avelocity[1], ed->ode.ode_avelocity[2], avelocity[0], avelocity[1], avelocity[2]); - if(gravity != ed->ode.ode_gravity) - Con_Printf(" gravity: %i -> %i\n", ed->ide.ode_gravity, gravity); -#endif - - // values for BodyFromEntity to check if the qc modified anything later - VectorCopy(origin, ed->ode.ode_origin); - VectorCopy(velocity, ed->ode.ode_velocity); - VectorCopy(angles, ed->ode.ode_angles); - VectorCopy(avelocity, ed->ode.ode_avelocity); - ed->ode.ode_gravity = gravity; - -// foo Matrix4x4_RM_FromVectors(entitymatrix, forward, left, up, origin); -// foo Matrix4_Multiply(ed->ode.ode_offsetmatrix, entitymatrix, bodymatrix); -// foo Matrix3x4_RM_ToVectors(bodymatrix, forward, left, up, origin); - -// r[0][0] = forward[0]; -// r[1][0] = forward[1]; -// r[2][0] = forward[2]; -// r[0][1] = left[0]; -// r[1][1] = left[1]; -// r[2][1] = left[2]; -// r[0][2] = up[0]; -// r[1][2] = up[1]; -// r[2][2] = up[2]; - - QCMotionState *ms = (QCMotionState*)body->getMotionState(); - ms->ReloadMotionState(); - body->setMotionState(ms); - body->setLinearVelocity(btVector3(velocity[0], velocity[1], velocity[2])); - body->setAngularVelocity(btVector3(spinvelocity[0], spinvelocity[1], spinvelocity[2])); -// body->setGravity(btVector3(ed->xv->gravitydir[0], ed->xv->gravitydir[1], ed->xv->gravitydir[2]) * ed->xv->gravity); - - //something changed. make sure it still falls over appropriately - body->setActivationState(1); - } - -/* FIXME: check if we actually need this insanity with bullet (ode sucks). - if(body) - { - // limit movement speed to prevent missed collisions at high speed - btVector3 ovelocity = body->getLinearVelocity(); - btVector3 ospinvelocity = body->getAngularVelocity(); - movelimit = ed->ode.ode_movelimit * world->ode.ode_movelimit; - test = DotProduct(ovelocity,ovelocity); - if (test > movelimit*movelimit) - { - // scale down linear velocity to the movelimit - // scale down angular velocity the same amount for consistency - f = movelimit / sqrt(test); - VectorScale(ovelocity, f, velocity); - VectorScale(ospinvelocity, f, spinvelocity); - body->setLinearVelocity(btVector3(velocity[0], velocity[1], velocity[2])); - body->setAngularVelocity(btVector3(spinvelocity[0], spinvelocity[1], spinvelocity[2])); - } - - // make sure the angular velocity is not exploding - spinlimit = physics_bullet_spinlimit.value; - test = DotProduct(ospinvelocity,ospinvelocity); - if (test > spinlimit) - { - body->setAngularVelocity(btVector3(0, 0, 0)); - } - } -*/ -} - -/* -#define MAX_CONTACTS 16 -static void VARGS nearCallback (void *data, dGeomID o1, dGeomID o2) -{ - world_t *world = (world_t *)data; - dContact contact[MAX_CONTACTS]; // max contacts per collision pair - dBodyID b1; - dBodyID b2; - dJointID c; - int i; - int numcontacts; - - float bouncefactor1 = 0.0f; - float bouncestop1 = 60.0f / 800.0f; - float bouncefactor2 = 0.0f; - float bouncestop2 = 60.0f / 800.0f; - float erp; - dVector3 grav; - wedict_t *ed1, *ed2; - - if (dGeomIsSpace(o1) || dGeomIsSpace(o2)) - { - // colliding a space with something - dSpaceCollide2(o1, o2, data, &nearCallback); - // Note we do not want to test intersections within a space, - // only between spaces. - //if (dGeomIsSpace(o1)) dSpaceCollide(o1, data, &nearCallback); - //if (dGeomIsSpace(o2)) dSpaceCollide(o2, data, &nearCallback); - return; - } - - b1 = dGeomGetBody(o1); - b2 = dGeomGetBody(o2); - - // at least one object has to be using MOVETYPE_PHYSICS or we just don't care - if (!b1 && !b2) - return; - - // exit without doing anything if the two bodies are connected by a joint - if (b1 && b2 && dAreConnectedExcluding(b1, b2, dJointTypeContact)) - return; - - ed1 = (wedict_t *) dGeomGetData(o1); - ed2 = (wedict_t *) dGeomGetData(o2); - if (ed1 == ed2 && ed1) - { - //ragdolls don't make contact with the bbox of the doll entity - //the origional entity should probably not be solid anyway. - //these bodies should probably not collide against bboxes of other entities with ragdolls either, but meh. - if (ed1->ode.ode_body == b1 || ed2->ode.ode_body == b2) - return; - } - if(!ed1 || ed1->isfree) - ed1 = world->edicts; - if(!ed2 || ed2->isfree) - ed2 = world->edicts; - - // generate contact points between the two non-space geoms - numcontacts = dCollide(o1, o2, MAX_CONTACTS, &(contact[0].geom), sizeof(contact[0])); - if (numcontacts) - { - if(ed1 && ed1->v->touch) - { - world->Event_Touch(world, ed1, ed2); - } - if(ed2 && ed2->v->touch) - { - world->Event_Touch(world, ed2, ed1); - } - - // if either ent killed itself, don't collide - if ((ed1&&ed1->isfree) || (ed2&&ed2->isfree)) - return; - } - - if(ed1) - { - if (ed1->xv->bouncefactor) - bouncefactor1 = ed1->xv->bouncefactor; - - if (ed1->xv->bouncestop) - bouncestop1 = ed1->xv->bouncestop; - } - - if(ed2) - { - if (ed2->xv->bouncefactor) - bouncefactor2 = ed2->xv->bouncefactor; - - if (ed2->xv->bouncestop) - bouncestop2 = ed2->xv->bouncestop; - } - - if ((ed2->entnum&&ed1->v->owner == ed2->entnum) || (ed1->entnum&&ed2->v->owner == ed1->entnum)) - return; - - // merge bounce factors and bounce stop - if(bouncefactor2 > 0) - { - if(bouncefactor1 > 0) - { - // TODO possibly better logic to merge bounce factor data? - if(bouncestop2 < bouncestop1) - bouncestop1 = bouncestop2; - if(bouncefactor2 > bouncefactor1) - bouncefactor1 = bouncefactor2; - } - else - { - bouncestop1 = bouncestop2; - bouncefactor1 = bouncefactor2; - } - } - dWorldGetGravity(world->ode.ode_world, grav); - bouncestop1 *= fabs(grav[2]); - - erp = (DotProduct(ed1->v->velocity, ed1->v->velocity) > DotProduct(ed2->v->velocity, ed2->v->velocity)) ? ed1->xv->erp : ed2->xv->erp; - - // add these contact points to the simulation - for (i = 0;i < numcontacts;i++) - { - contact[i].surface.mode = (physics_bullet_contact_mu.value != -1 ? dContactApprox1 : 0) | - (physics_bullet_contact_erp.value != -1 ? dContactSoftERP : 0) | - (physics_bullet_contact_cfm.value != -1 ? dContactSoftCFM : 0) | - (bouncefactor1 > 0 ? dContactBounce : 0); - contact[i].surface.mu = physics_bullet_contact_mu.value; - if (ed1->xv->friction) - contact[i].surface.mu *= ed1->xv->friction; - if (ed2->xv->friction) - contact[i].surface.mu *= ed2->xv->friction; - contact[i].surface.mu2 = 0; - contact[i].surface.soft_erp = physics_bullet_contact_erp.value + erp; - contact[i].surface.soft_cfm = physics_bullet_contact_cfm.value; - contact[i].surface.bounce = bouncefactor1; - contact[i].surface.bounce_vel = bouncestop1; - c = dJointCreateContact(world->ode.ode_world, world->ode.ode_contactgroup, contact + i); - dJointAttach(c, b1, b2); - } -} -*/ - -static void QDECL World_Bullet_Frame(world_t *world, double frametime, double gravity) -{ - struct bulletcontext_s *ctx = (struct bulletcontext_s*)world->rbe; - if (world->rbe_hasphysicsents || ctx->hasextraobjs) - { - int i; - wedict_t *ed; - -// world->ode.ode_iterations = bound(1, physics_bullet_iterationsperframe.ival, 1000); -// world->ode.ode_step = frametime / world->ode.ode_iterations; -// world->ode.ode_movelimit = physics_bullet_movelimit.value / world->ode.ode_step; - - - // copy physics properties from entities to physics engine - for (i = 0;i < world->num_edicts;i++) - { - ed = (wedict_t*)EDICT_NUM(world->progs, i); - if (!ed->isfree) - World_Bullet_Frame_BodyFromEntity(world, ed); - } - // oh, and it must be called after all bodies were created - for (i = 0;i < world->num_edicts;i++) - { - ed = (wedict_t*)EDICT_NUM(world->progs, i); - if (!ed->isfree) - World_Bullet_Frame_JointFromEntity(world, ed); - } - while(ctx->cmdqueuehead) - { - rbecommandqueue_t *cmd = ctx->cmdqueuehead; - ctx->cmdqueuehead = cmd->next; - if (!cmd->next) - ctx->cmdqueuetail = NULL; - World_Bullet_RunCmd(world, cmd); - Z_Free(cmd); - } - - ctx->dworld->setGravity(btVector3(0, 0, -gravity)); - - ctx->dworld->stepSimulation(frametime, max(0, pCvar_GetFloat("physics_bullet_maxiterationsperframe")), 1/bound(1, pCvar_GetFloat("physics_bullet_framerate"), 500)); - - // set the tolerance for closeness of objects -// dWorldSetContactSurfaceLayer(world->ode.ode_world, max(0, physics_bullet_contactsurfacelayer.value)); - - // run collisions for the current world state, creating JointGroup -// dSpaceCollide(world->ode.ode_space, (void *)world, nearCallback); - - // run physics (move objects, calculate new velocities) -// if (physics_bullet_worldquickstep.ival) -// { -// dWorldSetQuickStepNumIterations(world->ode.ode_world, bound(1, physics_bullet_worldquickstep_iterations.ival, 200)); -// dWorldQuickStep(world->ode.ode_world, world->ode.ode_step); -// } -// else -// dWorldStep(world->ode.ode_world, world->ode.ode_step); - - // clear the JointGroup now that we're done with it -// dJointGroupEmpty(world->ode.ode_contactgroup); - - if (world->rbe_hasphysicsents) - { - // copy physics properties from physics engine to entities - for (i = 1;i < world->num_edicts;i++) - { - ed = (wedict_t*)EDICT_NUM(world->progs, i); - if (!ed->isfree) - World_Bullet_Frame_BodyToEntity(world, ed); - } - } - } -} - -static void World_Bullet_RunCmd(world_t *world, rbecommandqueue_t *cmd) -{ - btRigidBody *body = (btRigidBody*)(cmd->edict->ode.ode_body); - switch(cmd->command) - { - case RBECMD_ENABLE: - if (body) - body->setActivationState(1); - break; - case RBECMD_DISABLE: - if (body) - body->setActivationState(0); - break; - case RBECMD_FORCE: - if (body) - { - body->setActivationState(1); - body->applyForce(btVector3(cmd->v1[0], cmd->v1[1], cmd->v1[2]), btVector3(cmd->v2[0], cmd->v2[1], cmd->v2[2])); - } - break; - case RBECMD_TORQUE: - if (cmd->edict->ode.ode_body) - { - body->setActivationState(1); - body->applyTorque(btVector3(cmd->v1[0], cmd->v1[1], cmd->v1[2])); - } - break; - } -} - -static void QDECL World_Bullet_PushCommand(world_t *world, rbecommandqueue_t *val) -{ - struct bulletcontext_s *ctx = (struct bulletcontext_s*)world->rbe; - rbecommandqueue_t *cmd = (rbecommandqueue_t*)BZ_Malloc(sizeof(*cmd)); - world->rbe_hasphysicsents = qtrue; //just in case. - memcpy(cmd, val, sizeof(*cmd)); - cmd->next = NULL; - //add on the end of the queue, so that order is preserved. - if (ctx->cmdqueuehead) - { - rbecommandqueue_t *ot = ctx->cmdqueuetail; - ot->next = ctx->cmdqueuetail = cmd; - } - else - ctx->cmdqueuetail = ctx->cmdqueuehead = cmd; -} - -static void QDECL World_Bullet_TraceEntity(world_t *world, vec3_t start, vec3_t end, wedict_t *ed) -{ - struct bulletcontext_s *ctx = (struct bulletcontext_s*)world->rbe; - btCollisionShape *shape = (btCollisionShape*)ed->ode.ode_geom; - - class myConvexResultCallback : public btCollisionWorld::ConvexResultCallback - { - public: - virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult,bool normalInWorldSpace) - { - return 0; - } - } result; - - btTransform from(btMatrix3x3(1, 0, 0, 0, 1, 0, 0, 0, 1), btVector3(start[0], start[1], start[2])); - btTransform to(btMatrix3x3(1, 0, 0, 0, 1, 0, 0, 0, 1), btVector3(end[0], end[1], end[2])); - ctx->dworld->convexSweepTest((btConvexShape*)shape, from, to, result, 1); -} - -static void QDECL World_Bullet_Start(world_t *world) -{ - struct bulletcontext_s *ctx; - if (world->rbe) - return; //no thanks, we already have one. somehow. - - if (!pCvar_GetFloat("physics_bullet_enable")) - return; - - ctx = (struct bulletcontext_s*)BZ_Malloc(sizeof(*ctx)); - memset(ctx, 0, sizeof(*ctx)); - ctx->gworld = world; - ctx->funcs.End = World_Bullet_End; - ctx->funcs.RemoveJointFromEntity = World_Bullet_RemoveJointFromEntity; - ctx->funcs.RemoveFromEntity = World_Bullet_RemoveFromEntity; - ctx->funcs.RagMatrixToBody = World_Bullet_RagMatrixToBody; - ctx->funcs.RagCreateBody = World_Bullet_RagCreateBody; - ctx->funcs.RagMatrixFromJoint = World_Bullet_RagMatrixFromJoint; - ctx->funcs.RagMatrixFromBody = World_Bullet_RagMatrixFromBody; - ctx->funcs.RagEnableJoint = World_Bullet_RagEnableJoint; - ctx->funcs.RagCreateJoint = World_Bullet_RagCreateJoint; - ctx->funcs.RagDestroyBody = World_Bullet_RagDestroyBody; - ctx->funcs.RagDestroyJoint = World_Bullet_RagDestroyJoint; - ctx->funcs.Frame = World_Bullet_Frame; - ctx->funcs.PushCommand = World_Bullet_PushCommand; - world->rbe = &ctx->funcs; - - - ctx->broadphase = new btDbvtBroadphase(); - ctx->collisionconfig = new btDefaultCollisionConfiguration(); - ctx->collisiondispatcher = new btCollisionDispatcher(ctx->collisionconfig); - ctx->solver = new btSequentialImpulseConstraintSolver; - ctx->dworld = new btDiscreteDynamicsWorld(ctx->collisiondispatcher, ctx->broadphase, ctx->solver, ctx->collisionconfig); - - ctx->ownerfilter = new QCFilterCallback(); - ctx->dworld->getPairCache()->setOverlapFilterCallback(ctx->ownerfilter); - - - - ctx->dworld->setGravity(btVector3(0, -10, 0)); - -/* - if(physics_bullet_world_erp.value >= 0) - dWorldSetERP(world->ode.ode_world, physics_bullet_world_erp.value); - if(physics_bullet_world_cfm.value >= 0) - dWorldSetCFM(world->ode.ode_world, physics_bullet_world_cfm.value); - if (physics_bullet_world_damping.ival) - { - dWorldSetLinearDamping(world->ode.ode_world, (physics_bullet_world_damping_linear.value >= 0) ? (physics_bullet_world_damping_linear.value * physics_bullet_world_damping.value) : 0); - dWorldSetLinearDampingThreshold(world->ode.ode_world, (physics_bullet_world_damping_linear_threshold.value >= 0) ? (physics_bullet_world_damping_linear_threshold.value * physics_bullet_world_damping.value) : 0); - dWorldSetAngularDamping(world->ode.ode_world, (physics_bullet_world_damping_angular.value >= 0) ? (physics_bullet_world_damping_angular.value * physics_bullet_world_damping.value) : 0); - dWorldSetAngularDampingThreshold(world->ode.ode_world, (physics_bullet_world_damping_angular_threshold.value >= 0) ? (physics_bullet_world_damping_angular_threshold.value * physics_bullet_world_damping.value) : 0); - } - else - { - dWorldSetLinearDamping(world->ode.ode_world, 0); - dWorldSetLinearDampingThreshold(world->ode.ode_world, 0); - dWorldSetAngularDamping(world->ode.ode_world, 0); - dWorldSetAngularDampingThreshold(world->ode.ode_world, 0); - } - if (physics_bullet_autodisable.ival) - { - dWorldSetAutoDisableSteps(world->ode.ode_world, bound(1, physics_bullet_autodisable_steps.ival, 100)); - dWorldSetAutoDisableTime(world->ode.ode_world, physics_bullet_autodisable_time.value); - dWorldSetAutoDisableAverageSamplesCount(world->ode.ode_world, bound(1, physics_bullet_autodisable_threshold_samples.ival, 100)); - dWorldSetAutoDisableLinearThreshold(world->ode.ode_world, physics_bullet_autodisable_threshold_linear.value); - dWorldSetAutoDisableAngularThreshold(world->ode.ode_world, physics_bullet_autodisable_threshold_angular.value); - dWorldSetAutoDisableFlag (world->ode.ode_world, true); - } - else - dWorldSetAutoDisableFlag (world->ode.ode_world, false); - */ -} - -static qintptr_t QDECL World_Bullet_Shutdown(qintptr_t *args) -{ - if (modfuncs) - modfuncs->UnregisterPhysicsEngine("Bullet"); - return 0; -} - -static bool World_Bullet_DoInit(void) -{ - if (!modfuncs || !modfuncs->RegisterPhysicsEngine) - Con_Printf("Bullet plugin failed: Engine doesn't support physics engine plugins.\n"); - else if (!modfuncs->RegisterPhysicsEngine("Bullet", World_Bullet_Start)) - Con_Printf("Bullet plugin failed: Engine already has a physics plugin active.\n"); - else - { - World_Bullet_Init(); - return true; - } - return false; -} - -extern "C" qintptr_t Plug_Init(qintptr_t *args) -{ - CHECKBUILTIN(Mod_GetPluginModelFuncs); - - if (BUILTINISVALID(Mod_GetPluginModelFuncs)) - { - modfuncs = pMod_GetPluginModelFuncs(sizeof(modplugfuncs_t)); - if (modfuncs && modfuncs->version < MODPLUGFUNCS_VERSION) - modfuncs = NULL; - } - - Plug_Export("Shutdown", World_Bullet_Shutdown); - return World_Bullet_DoInit(); -} - - +#undef FTEPLUGIN +#include "../../plugins/bullet/bulletplug.cpp" diff --git a/engine/common/common.c b/engine/common/common.c index 5c101bdf7..0b9b6a574 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -2119,12 +2119,12 @@ const char *COM_GetFileExtension (const char *in, const char *term) if (!term) term = in + strlen(in); - for (dot = term; dot >= in && *dot != '.' && *dot != '/' && *dot != '\\'; dot--) - ; - if (dot < in) - return ""; - in = dot; - return in; + for (dot = term; dot >= in && *dot != '/' && *dot != '\\'; dot--) + { + if (*dot == '.') + return dot; + } + return ""; } //Quake 2's tank model has a borked skin (or two). @@ -2805,6 +2805,7 @@ conchar_t q3codemasks[MAXQ3COLOURS] = { //Converts a conchar_t string into a char string. returns the null terminator. pass NULL for stop to calc it char *COM_DeFunString(conchar_t *str, conchar_t *stop, char *out, int outsize, qboolean ignoreflags, qboolean forceutf8) { + static char tohex[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; unsigned int codeflags, codepoint; if (!stop) { @@ -2828,15 +2829,22 @@ char *COM_DeFunString(conchar_t *str, conchar_t *stop, char *out, int outsize, q } else*/ { - int fl, d; + unsigned int fl, d; unsigned int c; int prelinkflags = CON_WHITEMASK; //if used, its already an error. //FIXME: TEST! fl = CON_WHITEMASK; - while(str < stop) + while(str <= stop) { - str = Font_Decode(str, &codeflags, &codepoint); + if (str == stop) + { + codeflags = CON_WHITEMASK; + codepoint = 0; + str++; + } + else + str = Font_Decode(str, &codeflags, &codepoint); if ((codeflags & CON_HIDDEN) && ignoreflags) { continue; @@ -2871,7 +2879,6 @@ char *COM_DeFunString(conchar_t *str, conchar_t *stop, char *out, int outsize, q else if (codeflags != fl && !ignoreflags) { d = fl^codeflags; -// if (fl & CON_NONCLEARBG) //not represented. if (d & CON_BLINKTEXT) { if (outsize<=2) @@ -2881,60 +2888,85 @@ char *COM_DeFunString(conchar_t *str, conchar_t *stop, char *out, int outsize, q *out++ = 'b'; } if (d & CON_2NDCHARSETTEXT) - { - if (outsize<=2) - break; - outsize -= 2; - *out++ = '^'; - *out++ = 'a'; - } - if (d & CON_HALFALPHA) - { - if (outsize<=2) - break; - outsize -= 2; - *out++ = '^'; - *out++ = 'h'; - } - - if (d & (CON_FGMASK | CON_BGMASK | CON_NONCLEARBG)) - { - static char q3[16] = { '0', 0, 0, 0, - 0, 0, 0, 0, - 0, '4', '2', '5', - '1', '6', '3', '7'}; - if (!(d & (CON_BGMASK | CON_NONCLEARBG)) && q3[(codeflags & CON_FGMASK) >> CON_FGSHIFT] && !((d|fl) & CON_HALFALPHA)) + { //FIXME: convert to quake glyphs... + if (!com_parseutf8.ival && !forceutf8 && codepoint >= 0 && codepoint <= 255) + { //strip the flag and encode it in private use (so it gets encoded as quake-compatible) + d &= ~CON_2NDCHARSETTEXT; + codepoint |= 0xe000; + } + else { if (outsize<=2) break; outsize -= 2; - - d = codeflags; *out++ = '^'; - *out++ = q3[(codeflags & CON_FGMASK) >> CON_FGSHIFT]; - } - else - { - if (outsize<=4) - break; - outsize -= 4; - - d = codeflags; - *out++ = '^'; - *out++ = '&'; - if ((d & CON_FGMASK) == CON_WHITEMASK) - *out = '-'; - else - sprintf(out, "%X", d>>24); - out++; - if (d & CON_NONCLEARBG) - sprintf(out, "%X", d>>28); - else - *out = '-'; - out++; + *out++ = 'a'; } } + if (codeflags & CON_RICHFORECOLOUR) + { + if (d & (CON_RICHFORECOLOUR|CON_RICHFOREMASK)) + { + if (outsize<=5) + break; + outsize -= 5; + *out++ = '^'; + *out++ = 'x'; + *out++ = tohex[(codeflags>>CON_RICHRSHIFT)&15]; + *out++ = tohex[(codeflags>>CON_RICHGSHIFT)&15]; + *out++ = tohex[(codeflags>>CON_RICHBSHIFT)&15]; + } + } + else + { + if (d & (CON_RICHFORECOLOUR | CON_FGMASK | CON_BGMASK | CON_NONCLEARBG)) + { + static char q3[16] = { '0', 0, 0, 0, + 0, 0, 0, 0, + 0, '4', '2', '5', + '1', '6', '3', '7'}; + if (d & CON_RICHFORECOLOUR) + d = (d&~CON_RICHFOREMASK) | (CON_WHITEMASK&CON_RICHFOREMASK); + if (!(d & (CON_BGMASK | CON_NONCLEARBG)) && q3[(codeflags & CON_FGMASK) >> CON_FGSHIFT]) + { + if (outsize<=2) + break; + outsize -= 2; + + d = codeflags; + *out++ = '^'; + *out++ = q3[(codeflags & CON_FGMASK) >> CON_FGSHIFT]; + } + else + { + if (outsize<=4) + break; + outsize -= 4; + + *out++ = '^'; + *out++ = '&'; + if ((codeflags & CON_FGMASK) == CON_WHITEMASK) + *out = '-'; + else + *out = tohex[(codeflags>>24)&0xf]; + out++; + if (codeflags & CON_NONCLEARBG) + *out = tohex[(codeflags>>28)&0xf]; + else + *out = '-'; + out++; + } + } + if (d & CON_HALFALPHA) + { + if (outsize<=2) + break; + outsize -= 2; + *out++ = '^'; + *out++ = 'h'; + } + } fl = codeflags; } @@ -2942,6 +2974,9 @@ char *COM_DeFunString(conchar_t *str, conchar_t *stop, char *out, int outsize, q if (ignoreflags && (codeflags & CON_HIDDEN)) continue; + if (str > stop) + break; + if (forceutf8) c = utf8_encode(out, codepoint, outsize-1); else @@ -3343,7 +3378,7 @@ conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t str+=2; continue; } - else if (str[1] == ']' && linkstart) + else if (str[1] == ']') { if (keepmarkup) { @@ -3354,20 +3389,24 @@ conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t if (!--outsize) break; + if (linkstart) + { + *out++ = ']'|CON_HIDDEN|CON_LINKSPECIAL; + + //its a valid link, so we can hide it all now + *linkstart++ |= CON_HIDDEN|CON_LINKSPECIAL; //leading [ is hidden + while(linkstart < out-1 && (*linkstart&CON_CHARMASK) != '\\') //link text is NOT hidden + linkstart++; + while(linkstart < out) //but the infostring behind it is, as well as the terminator + *linkstart++ |= CON_HIDDEN; - *out++ = ']'|CON_HIDDEN|CON_LINKSPECIAL; - - //its a valid link, so we can hide it all now - *linkstart++ |= CON_HIDDEN|CON_LINKSPECIAL; //leading [ is hidden - while(linkstart < out-1 && (*linkstart&CON_CHARMASK) != '\\') //link text is NOT hidden - linkstart++; - while(linkstart < out) //but the infostring behind it is, as well as the terminator - *linkstart++ |= CON_HIDDEN; - - //reset colours to how they used to be - ext = linkinitflags; - linkstart = NULL; - keepmarkup = linkkeep; + //reset colours to how they used to be + ext = linkinitflags; + linkstart = NULL; + keepmarkup = linkkeep; + } + else + *out++ = ']'|CON_LINKSPECIAL; //never keep the markup str+=2; @@ -5892,110 +5931,358 @@ unsigned int COM_RemapMapChecksum(model_t *model, unsigned int checksum) return checksum; } +static char Base64_Encode(int byt) +{ + if (byt >= 0 && byt < 26) + return 'A' + byt - 0; + if (byt >= 26 && byt < 52) + return 'a' + byt - 26; + if (byt >= 52 && byt < 62) + return '0' + byt - 52; + if (byt == 62) + return '+'; + if (byt == 63) + return '/'; + return '!'; +} +static int Base64_Decode(char inp) +{ + if (inp >= 'A' && inp <= 'Z') + return (inp-'A') + 0; + if (inp >= 'a' && inp <= 'z') + return (inp-'a') + 26; + if (inp >= '0' && inp <= '9') + return (inp-'0') + 52; + if (inp == '+') + return 62; + if (inp == '/') + return 63; + //if (inp == '=') //padding char + return 0; //invalid +} /* Info Buffers */ -/* -typedef struct +const char *basicuserinfos[] = { + "*", + "name", + "team", + "skin", + "topcolor", + "bottomcolor", + "chat", //ezquake's afk indicators + NULL}; +const char *privateuserinfos[] = { - struct infobuf_s - { - char *name; - char *value; - } *keys; - size_t numkeys; - qboolean nolegacy; //no \\ or \" limitations. -} infobuf_t; -char *InfoBuf_GetValue (infobuf_t *info, const char *key, char *outbuf, size_t outsize) + "_", //ignore comments + "password", //many users will forget to clear it after. + "prx", //if someone has this set, don't bother broadcasting it. + "*ip", //this is the ip the client used to connect to the server. this isn't useful as any proxy that would affect it can trivially strip/rewrite it anyway. + NULL +}; + +void InfoSync_Remove(infosync_t *sync, size_t k) +{ + sync->numkeys--; + Z_Free(sync->keys[k].name); + memmove(sync->keys + k, sync->keys + k + 1, sizeof(*sync->keys)*(sync->numkeys-k)); +} +void InfoSync_Clear(infosync_t *sync) { size_t k; - for (k = 0; k < info->numkeys; k++) + for (k = 0; k < sync->numkeys; k++) + Z_Free(sync->keys[k].name); + Z_Free(sync->keys); + sync->keys = NULL; + sync->numkeys = 0; +} +void InfoSync_Strip(infosync_t *sync, void *context) +{ + size_t k; + if (!sync->numkeys) + return; + + for (k = 0; k < sync->numkeys; ) { - if (!strcmp(info->keys[k].name, key)) + if (sync->keys[k].context == context) { - Q_strncpyz(outbuf, info->keys[k].value, outsize); - return outbuf; + sync->numkeys--; + Z_Free(sync->keys[k].name); + memmove(sync->keys + k, sync->keys + k + 1, sizeof(*sync->keys)*(sync->numkeys-k)); + } + else + k++; + } +} +void InfoSync_Add(infosync_t *sync, void *context, const char *name) +{ + size_t k; + + for (k = 0; k < sync->numkeys; k++) + { + if (sync->keys[k].context == context && !strcmp(sync->keys[k].name, name)) + { //urr, it changed while we were sending it. reset! + sync->keys[k].syncpos = 0; + return; } } - *outbuf = 0; - return outbuf; + + if (!ZF_ReallocElements((void**)&sync->keys, &sync->numkeys, sync->numkeys+1, sizeof(*sync->keys))) + return; //out of memory! + sync->keys[k].context = context; + sync->keys[k].name = Z_StrDup(name); + sync->keys[k].syncpos = 0; } -char *InfoBuf_GetValueTmp (infobuf_t *info, const char *key) -{ - static char value[4][1024]; // use multiple buffers so compares work without stomping on each other - static int valueindex; - COM_AssertMainThread("InfoBuf_GetValue"); - valueindex = (valueindex+1)&3; - return InfoBuf_GetValue(info, key, value[valueindex], sizeof(value[valueindex])); -} -qboolean InfoBuf_RemoveKey (infobuf_t *info, const char *key) + +qboolean InfoBuf_FindKey (infobuf_t *info, const char *key, size_t *idx) { size_t k; for (k = 0; k < info->numkeys; k++) { if (!strcmp(info->keys[k].name, key)) { - Z_Free(info->keys[k].name); - Z_Free(info->keys[k].value); - info->numkeys--; - memmove(info->keys+k+0, info->keys+k+1, sizeof(*info->keys) * (info->numkeys-k)); - return true; //only one entry per key, so we can give up here + *idx = k; + return true; } } return false; } -void InfoBuf_SetKey (infobuf_t *info, const char *key, const char *val, qboolean force) +const char *InfoBuf_KeyForNumber(infobuf_t *info, int idx) +{ //allows itteration, removal can change the names of this/higher keys, but not lower keys. + if (idx >= 0 && idx < info->numkeys) + return info->keys[idx].name; + return NULL; +} +char *InfoBuf_ReadKey (infobuf_t *info, const char *key, char *outbuf, size_t outsize) //not to be used with blobs. writes to a user-supplied buffer { - qboolean removed; size_t k; - - if (!val) - val = ""; - - if (!info->nolegacy) + if (InfoBuf_FindKey(info, key, &k) && !info->keys[k].partial) { - //block invalid keys - //\\ makes parsing really really messy and isn't supported by most clients (although we could do it anyway) - //\" requires string escapes, again compat issues. - //0xff bugs out vanilla. - if (strchr(key, '\\') || strchr(key, '\"') || strchr(key, 0xff)) - return; - if (strchr(val, '\\') || strchr(val, '\"') || strchr(val, 0xff)) - return; + Q_strncpyz(outbuf, info->keys[k].value, outsize); + return outbuf; + } + *outbuf = 0; + return outbuf; +} +char *InfoBuf_ValueForKey (infobuf_t *info, const char *key) //not to be used with blobs. cycles buffer and imposes a length limit. +{ + static char value[4][1024]; // use multiple buffers so compares work without stomping on each other + static int valueindex; + COM_AssertMainThread("InfoBuf_ValueForKey"); + valueindex = (valueindex+1)&3; + return InfoBuf_ReadKey(info, key, value[valueindex], sizeof(value[valueindex])); +} +const char *InfoBuf_BlobForKey (infobuf_t *info, const char *key, size_t *blobsize) //obtains a direct pointer to temp memory +{ + size_t k; + if (InfoBuf_FindKey(info, key, &k) && !info->keys[k].partial) + { + *blobsize = info->keys[k].size; + return info->keys[k].value; + } + *blobsize = 0; + return NULL; +} +qboolean InfoBuf_RemoveKey (infobuf_t *info, const char *key) +{ + size_t k; + if (InfoBuf_FindKey(info, key, &k)) + { + char *kn = info->keys[k].name; //paranoid + Z_Free(info->keys[k].value); + info->numkeys--; + info->totalsize -= strlen(info->keys[k].name)+2; + info->totalsize -= info->keys[k].size; + memmove(info->keys+k+0, info->keys+k+1, sizeof(*info->keys) * (info->numkeys-k)); - if (strlen(key) >= 64) - return; //key length limits is a thing in vanilla qw. - if (strlen(val) >= 512) - return; //value length limits is a thing in vanilla qw. - //note that qw reads values up to 512, but only sets them up to 64 bytes... - //probably just so that people don't spot buffer overflows so easily. + if (info->ChangeCB) + info->ChangeCB(info->ChangeCTX, kn); + Z_Free(kn); + return true; //only one entry per key, so we can give up here + } + return false; +} +char *InfoBuf_DecodeString(const char *instart, const char *inend, size_t *sz) +{ + char *ret = Z_Malloc(inend-instart + 1); //guarenteed to end up equal or smaller + int i; + unsigned int v; + if (*instart == '\xff') + { //base64-coded + instart++; + for (i = 0; instart+1 < inend;) + { + v = Base64_Decode(*instart++)<<18; + v |= Base64_Decode(*instart++)<<12; + ret[i++] = (v>>16)&0xff; + if (instart >= inend || *instart == '=') + break; + v |= Base64_Decode(*instart++)<<6; + ret[i++] = (v>>8)&0xff; + if (instart >= inend || *instart == '=') + break; + v |= Base64_Decode(*instart++)<<0; + ret[i++] = (v>>0)&0xff; + } + ret[i] = 0; + *sz = i; + } + else + { //as-is + memcpy(ret, instart, inend-instart); + ret[inend-instart] = 0; + *sz = inend-instart; + } + return ret; +} +static qboolean InfoBuf_IsLarge(struct infokey_s *key) +{ + if (key->partial) + return true; + //detect invalid keys/values + //\\ makes parsing really really messy and isn't supported by most clients (although we could do it anyway) + //\" requires string escapes, again compat issues. + //0xff bugs out vanilla. + //nulls are bad, too... + if (strchr(key->name, '\\') || strchr(key->name, '\"') || strchr(key->name, 0xff)) + return true; + if (strchr(key->value, '\\') || strchr(key->value, '\"') || strchr(key->value, 0xff) || strlen(key->value) != key->size) + return true; + + if (key->size >= 64) + return true; //key length limits is a thing in vanilla qw. + if (strlen(key->name) >= 64) + return true; //value length limits is a thing in vanilla qw. + //note that qw reads values up to 512, but only sets them up to 64 bytes... + //probably just so that people don't spot buffer overflows so easily. + return false; +} +//like InfoBuf_SetStarBlobKey, but understands partials. +qboolean InfoBuf_SyncReceive (infobuf_t *info, const char *key, size_t keysize, const char *val, size_t valsize, size_t offset, qboolean final) +{ + size_t k; + size_t newsize; + + if (!InfoBuf_FindKey(info, key, &k)) + { //its new + if (!valsize) + return false; //and not set to anything new either + + if (offset) + return false; //was missing the initial message... + + k = info->numkeys; + if (!ZF_ReallocElements((void**)&info->keys, &info->numkeys, info->numkeys+1, sizeof(*info->keys))) + return false; //out of memory! + info->keys[k].name = Z_StrDup(key); + info->keys[k].size = 0; + info->keys[k].value = NULL; + info->totalsize += strlen(info->keys[k].name)+2; + } + else + { + if (!valsize) //probably an error. + return InfoBuf_RemoveKey(info, key); + + if (offset) + { + if (offset != info->keys[k].size) //probably an error... should be progressive. + return InfoBuf_RemoveKey(info, key); + } +// else silently truncate. + info->totalsize -= info->keys[k].size; } + newsize = offset + valsize; + if (final) + { //release any excess memory (which could potentially be in the MB) + if (!ZF_ReallocElements((void**)&info->keys[k].value, &info->keys[k].buffersize, newsize+1, 1)) + return false; + info->keys[k].buffersize = newsize+1; + } + else + { + if (info->keys[k].buffersize < newsize+1) + { + if (!ZF_ReallocElements((void**)&info->keys[k].value, &info->keys[k].buffersize, newsize*2+1, 1)) + return false; + } + } + memcpy(info->keys[k].value+offset, val, valsize); + info->keys[k].value[newsize] = 0; + info->keys[k].size = newsize; + info->keys[k].partial = !final; + info->keys[k].large = InfoBuf_IsLarge(&info->keys[k]); + info->totalsize += info->keys[k].size; + + if (final) + if (info->ChangeCB) + info->ChangeCB(info->ChangeCTX, key); + return true; +} +qboolean InfoBuf_SetStarBlobKey (infobuf_t *info, const char *key, const char *val, size_t valsize) +{ + size_t k; + if (!val) + { + val = ""; + valsize = 0; + } + + if (!InfoBuf_FindKey(info, key, &k)) + { //its new + if (!valsize) + return false; //and not set to anything new either + + k = info->numkeys; + if (!ZF_ReallocElements((void**)&info->keys, &info->numkeys, info->numkeys+1, sizeof(*info->keys))) + return false; //out of memory! + info->keys[k].name = Z_StrDup(key); + + info->totalsize += strlen(info->keys[k].name)+2; + } + else + { + if (!valsize) + return InfoBuf_RemoveKey(info, key); + + if (info->keys[k].size == valsize && !memcmp(info->keys[k].value, val, valsize)) + return false; //nothing new + Z_Free(info->keys[k].value); + info->totalsize -= info->keys[k].size; + } + + info->keys[k].buffersize = valsize+1; + info->keys[k].size = valsize; + info->keys[k].value = Z_Malloc(info->keys[k].buffersize); + memcpy(info->keys[k].value, val, valsize); + info->keys[k].value[valsize] = 0; + info->keys[k].partial = false; + info->keys[k].large = InfoBuf_IsLarge(&info->keys[k]); + info->totalsize += info->keys[k].size; + + if (info->ChangeCB) + info->ChangeCB(info->ChangeCTX, key); + return true; +} +qboolean InfoBuf_SetKey (infobuf_t *info, const char *key, const char *val) +{ // *keys are meant to be secure (or rather unsettable by the user, preventing spoofing of stuff like *ip) // but note that this is pointless as a hacked client can send whatever initial *keys it wants (they are blocked mid-connection at least) // * userinfos are always sent even to clients that can't support large infokey blobs - if (*key == '*' && !force) - return; - - removed = InfoBuf_RemoveKey(info, key); - if (*val) - { - k = info->numkeys; - if (removed) - info->numkeys+=1; //the memory is still allocated, because we're too lazy to free it. - else - { - if (!ZF_ReallocElements((void**)&info->keys, &info->numkeys, info->numkeys+1, sizeof(*info->keys))) - return; //out of memory! - } - info->keys[k].name = Z_StrDup(key); - info->keys[k].value = Z_StrDup(val); - } + if (*key == '*') + return false; + return InfoBuf_SetStarBlobKey (info, key, val, strlen(val)); } +qboolean InfoBuf_SetStarKey (infobuf_t *info, const char *key, const char *val) +{ + return InfoBuf_SetStarBlobKey (info, key, val, strlen(val)); +} + void InfoBuf_Clear(infobuf_t *info, qboolean all) {//if all is false, leaves *keys size_t k; - for (k = info->numkeys-1; k >= 0; k--) + for (k = info->numkeys; k --> 0; ) { if (all || *info->keys[k].name != '*') { @@ -6010,12 +6297,60 @@ void InfoBuf_Clear(infobuf_t *info, qboolean all) Z_Free(info->keys); info->keys = NULL; } + info->totalsize = 0; } -void InfoBuf_FromString(infobuf_t *info, const char *infostring) +//the callback reports how much data it splurged. +/*qboolean InfoBuf_SyncSend(infobuf_t *info, size_t(*cb)(void *ctx, const char *key, const char *data, size_t offset, size_t size), void *ctx) { - if (*infostring++ != '\\') - return; //invalid... not an info string - while (*infostring) + size_t k; + for (k = 0; k < info->numkeys; k++) + { + if (!info->keys[k].size) + { //null keys are actually just present to flag removals. + //the sync is meant to be reliable, so these can be stripped once the update is sent. + cb(ctx, info->keys[k].name, NULL, 0, 0); + Z_Free(info->keys[k].name); + Z_Free(info->keys[k].value); + info->numkeys--; + memmove(info->keys+k, info->keys+k+1, (info->numkeys-k)*sizeof(*info->keys)); + return true; + } + if (info->keys[k].syncedsize < info->keys[k].size) + { //regular update, possibly partial. + info->keys[k].syncedsize += cb(ctx, info->keys[k].name, info->keys[k].value, info->keys[k].syncedsize, info->keys[k].size-info->keys[k].syncedsize); + return true; + } + } + + return false; //nothing to change. +}*/ +void InfoBuf_Clone(infobuf_t *dest, infobuf_t *src) +{ + size_t k; + + InfoBuf_Clear(dest, true); + + dest->numkeys = src->numkeys; + dest->keys = BZ_Malloc(sizeof(*dest->keys) * dest->numkeys); + for (k = 0; k < dest->numkeys; k++) + { + dest->keys[k].partial = src->keys[k].partial; //this is a problem. should we just not replicate partials? + dest->keys[k].large = src->keys[k].large; + dest->keys[k].name = Z_StrDup(src->keys[k].name); + dest->keys[k].size = src->keys[k].size; + dest->keys[k].value = Z_Malloc(src->keys[k].size+1); + memcpy(dest->keys[k].value, src->keys[k].value, src->keys[k].size); + dest->keys[k].value[src->keys[k].size] = 0; + + dest->totalsize += strlen(dest->keys[k].name)+2+dest->keys[k].size; + } +} +void InfoBuf_FromString(infobuf_t *info, const char *infostring, qboolean append) +{ + if (!append) + InfoBuf_Clear(info, true); + //all keys must start with a backslash + while (*infostring++ == '\\') { const char *keystart = infostring; const char *keyend; @@ -6023,15 +6358,11 @@ void InfoBuf_FromString(infobuf_t *info, const char *infostring) const char *valend; char *key; char *val; - char *o; + size_t keysize, valsize; while (*infostring) { if (*infostring == '\\') - { - if (infostring[1] == '\\') - infostring += 2; break; - } else infostring += 1; } keyend = infostring; @@ -6041,82 +6372,135 @@ void InfoBuf_FromString(infobuf_t *info, const char *infostring) while (*infostring) { if (*infostring == '\\') - { - if (infostring[1] == '\\') - infostring += 2; break; - } else infostring += 1; } valend = infostring; - // *infostring might be '\\' or '\0'. doesn't really matter - if (!strncmp(keystart, " \\\\", 3)) - keystart += 3; - if (!strncmp(valstart, " \\\\", 3)) - valstart += 3; - - key = Z_Malloc(1+keyend-keystart); - for (o = key; keystart < keyend; ) - { - if (keystart[0] == '\\') - keystart+=1; - *o++ = *keystart++; - } - *o=0; - val = Z_Malloc(1+valend-valstart); - for (o = val; valstart < valend; ) - { - if (valstart[0] == '\\') - valstart+=1; - *o++ = *valstart++; - } - *o=0; - InfoBuf_SetKey(info, key, val, true); + key = InfoBuf_DecodeString(keystart, keyend, &keysize); + val = InfoBuf_DecodeString(valstart, valend, &valsize); + InfoBuf_SetStarBlobKey(info, key, val, valsize); Z_Free(key); Z_Free(val); } } -static size_t InfoBuf_ToStringToken(const char *n, char *out, char *end) +//internal logic +static qboolean InfoBuf_EncodeString_Internal(const char *n, size_t s, char *out, char *end) { - size_t r = 1; - if (out < end) - *out++ = '\\'; - if (*n == '\\' || (n[0] == ' ' && n[1] == '\\')) - { //" \\" prefix is stripped by the reader, and present to allow keys or values with a leading \\ in a well-defined-but-annoying way - // (vanilla qw doesn't allow double-backslash anywhere in infostrings) - r += 3; - if (out < end) - *out++ = ' '; - if (out < end) - *out++ = '\\'; - if (out < end) - *out++ = '\\'; - } - while (*n) + size_t r = 0; + const char *c; + for (c = n; c < n+s; c++) { - if (*n == '\\') + if (*c == (char)255 && c == n) + break; + if (*c == '\\') //abiguity with end-of-token + break; + if (*c == '\"') //parsing often sends these enclosed in quotes + break; + if (*c == '\n' || *c == '\r') //generally bad form + break; + if (*c == 0) //are we really doing this? + break; + if (*c == '$') //a number of engines like expanding things inside quotes. make sure that cannot ever happen. + break; + if (*c == ';') //in case someone manages to break out of quotes + break; + } + if (c != n+s) + { + unsigned int base64_cur = 0; + unsigned int base64_bits = 0; + r += 1; + if (out < end) *out++ = (char)255; + + for (c = n; c < n+s; c++) { - if (out < end) - *out++ = '\\'; + base64_cur |= *(unsigned char*)c<<(16- base64_bits);//first byte fills highest bits + base64_bits += 8; + + if (base64_bits == 24) + { + r += 4; + if (out < end) *out++ = Base64_Encode((base64_cur>>18)&63); + if (out < end) *out++ = Base64_Encode((base64_cur>>12)&63); + if (out < end) *out++ = Base64_Encode((base64_cur>>6)&63); + if (out < end) *out++ = Base64_Encode((base64_cur>>0)&63); + base64_bits = 0; + base64_cur = 0; + } + } + if (base64_bits != 0) + { + r += 4; + if (out < end) *out++ = Base64_Encode((base64_cur>>18)&63); + if (out < end) *out++ = Base64_Encode((base64_cur>>12)&63); + if (base64_bits == 8) + { + if (out < end) *out++ = '='; + if (out < end) *out++ = '='; + } + else + { + if (out < end) *out++ = Base64_Encode((base64_cur>>6)&63); + if (base64_bits == 16) + { + if (out < end) *out++ = '='; + } + else + { + if (out < end) *out++ = Base64_Encode((base64_cur>>0)&63); + } + } + } + } + else + { + for (c = n; c < n+s; c++) + { + r++; + if (out < end) *out++ = *c; } - if (out < end) - *out++ = *n; - n++; } return r; } -size_t InfoBuf_ToString(infobuf_t *info, char *infostring, size_t maxsize, const char **priority, const char **ignore, const char **exclusive) +//public interface to make things easy +qboolean InfoBuf_EncodeString(const char *n, size_t s, char *out, size_t outsize) +{ + size_t l = InfoBuf_EncodeString_Internal(n, s, out, out+outsize); + if (l < outsize) + { + out[l] = 0; + return true; + } + *out = 0; + return false; +} +void *InfoBuf_EncodeString_Malloc(const char *n, size_t s) +{ + size_t l = InfoBuf_EncodeString_Internal(n, s, NULL, NULL); + char *ret = BZ_Malloc(l+1); + if (!ret || l != InfoBuf_EncodeString_Internal(n, s, ret, ret+l)) + Sys_Error("InfoBuf_EncodeString_Malloc: error\n"); + ret[l] = 0; + return ret; +} +size_t InfoBuf_EncodeStringSlash(const char *n, size_t s, char *out, char *end) +{ + size_t l = 1+InfoBuf_EncodeString_Internal(n, s, out+1, end); + if (out < end) + *out = '\\'; + return l; +} +size_t InfoBuf_ToString(infobuf_t *info, char *infostring, size_t maxsize, const char **priority, const char **ignore, const char **exclusive, infosync_t *sync, void *synccontext) { - //if infostring is null, returns the needed buffer size - //\foo\\\bar is ambiguous. and interpreted as foo\ + bar - //\foo\ \\\\bar is interpreted as foo + \bar - leading " \\" is ignored if present. - - //FIXME: add a filter, for short/compated buffers. prioritisation or something size_t k, r = 1, l; char *o = infostring; char *e = infostring?infostring + maxsize-1:infostring; int pri, p; + + if (sync) //if we have a sync object then we just wiped whatever infostrings that were set + InfoSync_Strip(sync, synccontext); + for (pri = 0; pri < 2; pri++) { for (k = 0; k < info->numkeys; k++) @@ -6124,24 +6508,42 @@ size_t InfoBuf_ToString(infobuf_t *info, char *infostring, size_t maxsize, const if (exclusive) { for (l = 0; exclusive[l]; l++) + { if (!strcmp(exclusive[l], info->keys[k].name)) break; + else if (exclusive[l][0] == '*' && !exclusive[l][1] && *info->keys[k].name == '*') + break; //read-only + else if (exclusive[l][0] == '_' && !exclusive[l][1] && *info->keys[k].name == '_') + break; //comment + } if (!exclusive[l]) continue; //ignore when not in the list } if (ignore) { for (l = 0; ignore[l]; l++) + { if (!strcmp(ignore[l], info->keys[k].name)) break; + else if (ignore[l][0] == '*' && !ignore[l][1] && *info->keys[k].name == '*') + break; //read-only + else if (ignore[l][0] == '_' && !ignore[l][1] && *info->keys[k].name == '_') + break; //comment + } if (ignore[l]) continue; //ignore when in the list } if (priority) { for (l = 0; priority[l]; l++) + { if (!strcmp(priority[l], info->keys[k].name)) break; + else if (priority[l][0] == '*' && !priority[l][1] && *info->keys[k].name == '*') + break; //read-only + else if (priority[l][0] == '_' && !priority[l][1] && *info->keys[k].name == '_') + break; //comment + } if (priority[l]) p = 0; //high priority else @@ -6157,22 +6559,62 @@ size_t InfoBuf_ToString(infobuf_t *info, char *infostring, size_t maxsize, const if (pri != p) continue; - l = InfoBuf_ToStringToken(info->keys[k].name, o, e); - l += InfoBuf_ToStringToken(info->keys[k].value, o, e); - r += l; - if (o && o + l < e) - o += l; + if (!info->keys[k].large) //lower priorities don't bother with extended blocks. be sure to prioritise them explicitly. they'd just bug stuff out. + { + l = InfoBuf_EncodeStringSlash(info->keys[k].name, strlen(info->keys[k].name), o, e); + l += InfoBuf_EncodeStringSlash(info->keys[k].value, info->keys[k].size, o+l, e); + r += l; + if (o && o + l < e) + o += l; + else if (sync) + InfoSync_Add(sync, synccontext, info->keys[k].name); //not enough space. send this one later + } + else if (sync) + InfoSync_Add(sync, synccontext, info->keys[k].name); //don't include large/weird keys in the initial string } } *o = 0; return r; } -void InfoBuf_WriteToFile(vfsfile_t *f, infobuf_t *info, const char *commandname, int cvarflags) +void InfoBuf_Print(infobuf_t *info, const char *lineprefix) { - char buffer[1024]; const char *key; const char *val; + size_t k; + + for (k = 0; k < info->numkeys; k++) + { + char *partial = info->keys[k].partial?"":""; + key = info->keys[k].name; + val = info->keys[k].value; + + if (info->keys[k].size != strlen(info->keys[k].value)) + Con_Printf ("%s%-20s%s\n", lineprefix, key, partial, (unsigned int)info->keys[k].size); + else if (info->keys[k].size > 64 || strchr(val, '\n') || strchr(val, '\r') || strchr(val, '\t')) + Con_Printf ("%s%-20s%s<%u BYTES>\n", lineprefix, key, partial, (unsigned int)info->keys[k].size); + else + Con_Printf ("%s%-20s%s%s\n", lineprefix, key, partial, val); + } +} +void InfoBuf_Enumerate (infobuf_t *info, void *ctx, void(*cb)(void *ctx, const char *key, const char *value)) +{ + const char *key; + const char *val; + size_t k; + + for (k = 0; k < info->numkeys; k++) + { + key = info->keys[k].name; + val = info->keys[k].value; + cb(ctx, key, val); + } +} + +void InfoBuf_WriteToFile(vfsfile_t *f, infobuf_t *info, const char *commandname, int cvarflags) +{ + char *key; + char *val; cvar_t *var; size_t k; @@ -6186,21 +6628,32 @@ void InfoBuf_WriteToFile(vfsfile_t *f, infobuf_t *info, const char *commandname, if (cvarflags) { var = Cvar_FindVar(key); - if (var && var->flags & cvarflags) + if (var && (var->flags & cvarflags)) continue; //this is saved via a cvar. } - VFS_WRITE(f, commandname, strlen(commandname)); - VFS_WRITE(f, " ", 1); - key = COM_QuotedString(key, buffer, sizeof(buffer), false); - VFS_WRITE(f, key, strlen(key)); - VFS_WRITE(f, " ", 1); - val = COM_QuotedString(val, buffer, sizeof(buffer), false); - VFS_WRITE(f, val, strlen(val)); - VFS_WRITE(f, "\n", 1); + key = InfoBuf_EncodeString_Malloc(key, strlen(key)); + val = InfoBuf_EncodeString_Malloc(val, info->keys[k].size); + if (!commandname) + { //with no command name, just writes a (big) infostring that we can parse later + VFS_WRITE(f, "\\", 1); + VFS_WRITE(f, key, strlen(key)); + VFS_WRITE(f, "\\", 1); + VFS_WRITE(f, val, strlen(val)); + } + else + { + VFS_WRITE(f, commandname, strlen(commandname)); + VFS_WRITE(f, " \"", 2); + VFS_WRITE(f, key, strlen(key)); + VFS_WRITE(f, "\" \"", 3); + VFS_WRITE(f, val, strlen(val)); + VFS_WRITE(f, "\"\n", 2); + } + BZ_Free(key); + BZ_Free(val); } } -*/ /* ===================================================================== diff --git a/engine/common/common.h b/engine/common/common.h index c35ff5ebb..815bc7258 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -362,7 +362,7 @@ void deleetstring(char *result, const char *leet); extern char com_token[65536]; -typedef enum {TTP_UNKNOWN, TTP_STRING, TTP_LINEENDING, TTP_RAWTOKEN, TTP_EOF, TTP_PUNCTUATION} com_tokentype_t; +typedef enum com_tokentype_e {TTP_UNKNOWN, TTP_STRING, TTP_LINEENDING, TTP_RAWTOKEN, TTP_EOF, TTP_PUNCTUATION} com_tokentype_t; extern com_tokentype_t com_tokentype; //these cast away the const for the return value. @@ -616,7 +616,7 @@ vfsfile_t *CL_OpenFileInPackage(searchpathfuncs_t *search, char *name); qboolean CL_ListFilesInPackage(searchpathfuncs_t *search, char *name, int (QDECL *func)(const char *fname, qofs_t fsize, time_t mtime, void *parm, searchpathfuncs_t *spath), void *parm, void *recursioninfo); qbyte *QDECL COM_LoadStackFile (const char *path, void *buffer, int bufsize, size_t *fsize); -qbyte *COM_LoadTempFile (const char *path, size_t *fsize); +qbyte *COM_LoadTempFile (const char *path, unsigned int locateflags, size_t *fsize); qbyte *COM_LoadTempMoreFile (const char *path, size_t *fsize); //allocates a little bit more without freeing old temp //qbyte *COM_LoadHunkFile (const char *path); @@ -704,7 +704,7 @@ qbyte *FS_LoadMallocFile (const char *path, size_t *fsize); qofs_t FS_LoadFile(const char *name, void **file); void FS_FreeFile(void *file); -qbyte *COM_LoadFile (const char *path, int usehunk, size_t *filesize); +qbyte *COM_LoadFile (const char *path, unsigned int locateflags, int usehunk, size_t *filesize); qboolean COM_LoadMapPackFile(const char *name, qofs_t offset); void COM_FlushTempoaryPacks(void); @@ -724,15 +724,79 @@ unsigned int COM_RemapMapChecksum(struct model_s *model, unsigned int checksum); #define MAX_INFO_KEY 256 char *Info_ValueForKey (const char *s, const char *key); -void Info_RemoveKey (char *s, const char *key); -char *Info_KeyForNumber (const char *s, int num); -void Info_RemovePrefixedKeys (char *start, char prefix); -void Info_RemoveNonStarKeys (char *start); void Info_SetValueForKey (char *s, const char *key, const char *value, int maxsize); void Info_SetValueForStarKey (char *s, const char *key, const char *value, int maxsize); +void Info_RemovePrefixedKeys (char *start, char prefix); +void Info_RemoveKey (char *s, const char *key); +char *Info_KeyForNumber (const char *s, int num); void Info_Print (const char *s, const char *lineprefix); +/* +void Info_RemoveNonStarKeys (char *start); void Info_Enumerate (const char *s, void *ctx, void(*cb)(void *ctx, const char *key, const char *value)); void Info_WriteToFile(vfsfile_t *f, char *info, char *commandname, int cvarflags); +*/ + +/* + Info Buffers + Keynames are still length limited, and may not contain nulls, but neither restriction applies to values. + Using base64 encoding, we're able to encode problematic chars like quotes and newlines (and nulls). + This allows mods to store image files inside userinfo. +*/ +typedef struct +{ + struct infokey_s + { + qbyte partial:1; //partial values read as "". + qbyte large:1; //requires partial/encoded transmission + char *name; + size_t size; + size_t buffersize; //to avoid excessive reallocs + char *value; + } *keys; + size_t numkeys; + size_t totalsize; //so we can limit userinfo abuse. + + void (*ChangeCB)(void *context, const char *key); //usually calls InfoSync_Add on all the interested parties. + void *ChangeCTX; +} infobuf_t; +typedef struct +{ + struct + { + void *context; + char *name; + size_t syncpos; //reset to 0 when dirty. + } *keys; + size_t numkeys; +} infosync_t; +void InfoSync_Remove(infosync_t *sync, size_t k); +void InfoSync_Add(infosync_t *sync, void *context, const char *name); +void InfoSync_Clear(infosync_t *sync); //wipes all memory etc. +void InfoSync_Strip(infosync_t *sync, void *context); //Clears away all infos from that context. +extern const char *basicuserinfos[]; //note: has a leading * +extern const char *privateuserinfos[]; //key names that are not broadcast from the server +qboolean InfoBuf_FindKey (infobuf_t *info, const char *key, size_t *idx); +const char *InfoBuf_KeyForNumber (infobuf_t *info, int num); +const char *InfoBuf_BlobForKey (infobuf_t *info, const char *key, size_t *blobsize); +char *InfoBuf_ReadKey (infobuf_t *info, const char *key, char *outbuf, size_t outsize); +char *InfoBuf_ValueForKey (infobuf_t *info, const char *key); +qboolean InfoBuf_RemoveKey (infobuf_t *info, const char *key); +qboolean InfoBuf_SetKey (infobuf_t *info, const char *key, const char *val); //refuses to set *keys. +qboolean InfoBuf_SetStarKey (infobuf_t *info, const char *key, const char *val); +qboolean InfoBuf_SetStarBlobKey (infobuf_t *info, const char *key, const char *val, size_t valsize); +#define InfoBuf_SetValueForKey InfoBuf_SetKey +#define InfoBuf_SetValueForStarKey InfoBuf_SetStarKey +void InfoBuf_Clear(infobuf_t *info, qboolean all); +void InfoBuf_Clone(infobuf_t *dest, infobuf_t *src); +void InfoBuf_FromString(infobuf_t *info, const char *infostring, qboolean append); +char *InfoBuf_DecodeString(const char *instart, const char *inend, size_t *sz); +qboolean InfoBuf_EncodeString(const char *n, size_t s, char *out, size_t outsize); +size_t InfoBuf_ToString(infobuf_t *info, char *infostring, size_t maxsize, const char **priority, const char **ignore, const char **exclusive, infosync_t *sync, void *synccontext); //_ and * can be used to indicate ALL such keys. +qboolean InfoBuf_SyncReceive (infobuf_t *info, const char *key, size_t keysize, const char *val, size_t valsize, size_t offset, qboolean final); +void InfoBuf_Print(infobuf_t *info, const char *prefix); +void InfoBuf_WriteToFile(vfsfile_t *f, infobuf_t *info, const char *commandname, int cvarflags); +void InfoBuf_Enumerate (infobuf_t *info, void *ctx, void(*cb)(void *ctx, const char *key, const char *value)); + void Com_BlocksChecksum (int blocks, void **buffer, int *len, unsigned char *outbuf); unsigned int Com_BlockChecksum (const void *buffer, int length); diff --git a/engine/common/config_fteqw.h b/engine/common/config_fteqw.h index 253a63a4e..b35357a26 100644 --- a/engine/common/config_fteqw.h +++ b/engine/common/config_fteqw.h @@ -156,7 +156,7 @@ // Outdated stuff #define SVRANKING //legacy server-side ranking system. ////#define QTERM //qterm... adds a console command that allows running programs from within quake - bit like xterm. -#define SVCHAT //ancient lame builtin to support NPC-style chat... +//#define SVCHAT //ancient lame builtin to support NPC-style chat... ////#define SV_MASTER //Support running the server as a master server. Should probably not be used. ////#define WEBSERVER //outdated sv_http cvar. new stuff acts via sv_port_tcp instead (which also gives https). ////#define QUAKESPYAPI //define this if you want the engine to be usable via gamespy/quakespy, which has been dead for a long time now. forces the client to use a single port for all outgoing connections, which hurts reconnects. diff --git a/engine/common/config_wastes.h b/engine/common/config_wastes.h index 9d7d854fe..4ab791054 100644 --- a/engine/common/config_wastes.h +++ b/engine/common/config_wastes.h @@ -154,6 +154,8 @@ #undef HAVE_MEDIA_ENCODER //capture/capturedemo work. #undef HAVE_SPEECHTOTEXT //windows speech-to-text thing +//#define USE_INTERNAL_BULLET + #ifdef COMPILE_OPTS //things to configure qclib, which annoyingly doesn't include this file itself -DOMIT_QCC //disable the built-in qcc @@ -162,6 +164,10 @@ -DNO_ZLIB //disable zlib #endif +#ifdef USE_INTERNAL_BULLET //makefile will respond to this by trying to link bullet into the engine itself, instead of as a plugin. +-DLINK_INTERNAL_BULLET +#endif + -DNO_SPEEX //disable static speex #ifndef BOTLIB_STATIC diff --git a/engine/common/cvar.c b/engine/common/cvar.c index 65a1f7142..08b67f4b8 100644 --- a/engine/common/cvar.c +++ b/engine/common/cvar.c @@ -784,13 +784,7 @@ cvar_t *Cvar_SetCore (cvar_t *var, const char *value, qboolean force) #ifndef CLIENTONLY if (var->flags & CVAR_SERVERINFO) { -// char *old = Info_ValueForKey(svs.info, var->name); -// if (strcmp(old, value)) //only spam the server if it actually changed - { - Info_SetValueForKey (svs.info, var->name, value, MAX_SERVERINFO_STRING); - SV_SendServerInfoChange(var->name, value); -// SV_BroadcastCommand ("fullserverinfo \"%s\"\n", svs.info); - } + InfoBuf_SetKey (&svs.info, var->name, value); } #endif #ifndef SERVERONLY @@ -802,23 +796,10 @@ cvar_t *Cvar_SetCore (cvar_t *var, const char *value, qboolean force) } if (var->flags & CVAR_USERINFO) { - char *old = Info_ValueForKey(cls.userinfo[0], var->name); + char *old = InfoBuf_ValueForKey(&cls.userinfo[0], var->name); if (strcmp(old, value)) //only spam the server if it actually changed { //this helps with config execs - Info_SetValueForKey (cls.userinfo[0], var->name, value, sizeof(cls.userinfo[0])); - if (cls.state >= ca_connected) - { -#if defined(Q2CLIENT) || defined(Q3CLIENT) - if (cls.protocol == CP_QUAKE2 || cls.protocol == CP_QUAKE3) //q2 just resends the lot. Kinda bad... - { - cls.resendinfo = true; - } - else -#endif - { - CL_SendClientCommand(true, "setinfo \"%s\" \"%s\"\n", var->name, value); - } - } + InfoBuf_SetKey (&cls.userinfo[0], var->name, value); } } #endif diff --git a/engine/common/fs.c b/engine/common/fs.c index 13ef0c916..786a004db 100644 --- a/engine/common/fs.c +++ b/engine/common/fs.c @@ -2138,14 +2138,16 @@ Filename are reletive to the quake directory. Always appends a 0 qbyte to the loaded data. ============ */ -qbyte *COM_LoadFile (const char *path, int usehunk, size_t *filesize) +qbyte *COM_LoadFile (const char *path, unsigned int locateflags, int usehunk, size_t *filesize) { vfsfile_t *f; qbyte *buf; qofs_t len; flocation_t loc; - if (!FS_FLocateFile(path, FSLF_IFFOUND, &loc) || !loc.search) + locateflags &= ~FSLF_DEEPONFAILURE; //disable any flags that can't be supported here + + if (!FS_FLocateFile(path, locateflags, &loc) || !loc.search) return NULL; //wasn't found if (loc.len > 0x7fffffff) //don't malloc 5000gb sparse files or anything crazy on a 32bit system... @@ -2198,7 +2200,7 @@ qbyte *COM_LoadFile (const char *path, int usehunk, size_t *filesize) qbyte *FS_LoadMallocFile (const char *path, size_t *fsize) { - return COM_LoadFile (path, 5, fsize); + return COM_LoadFile (path, 0, 5, fsize); } void *FS_LoadMallocGroupFile(zonegroup_t *ctx, char *path, size_t *fsize) @@ -2223,13 +2225,13 @@ void *FS_LoadMallocGroupFile(zonegroup_t *ctx, char *path, size_t *fsize) return mem; } -qbyte *COM_LoadTempFile (const char *path, size_t *fsize) +qbyte *COM_LoadTempFile (const char *path, unsigned int locateflags, size_t *fsize) { - return COM_LoadFile (path, 2, fsize); + return COM_LoadFile (path, locateflags, 2, fsize); } qbyte *COM_LoadTempMoreFile (const char *path, size_t *fsize) { - return COM_LoadFile (path, 6, fsize); + return COM_LoadFile (path, 0, 6, fsize); } // uses temp hunk if larger than bufsize @@ -2241,7 +2243,7 @@ qbyte *QDECL COM_LoadStackFile (const char *path, void *buffer, int bufsize, siz loadbuf = (qbyte *)buffer; loadsize = bufsize; - buf = COM_LoadFile (path, 4, fsize); + buf = COM_LoadFile (path, 0, 4, fsize); return buf; } @@ -2251,7 +2253,7 @@ qbyte *QDECL COM_LoadStackFile (const char *path, void *buffer, int bufsize, siz qofs_t FS_LoadFile(const char *name, void **file) { size_t fsz; - *file = COM_LoadFile (name, 5, &fsz); + *file = FS_LoadMallocFile (name, &fsz); if (!*file) return (qofs_t)-1; return fsz; @@ -3119,8 +3121,8 @@ const gamemode_info_t gamemode_info[] = { #ifndef NOLEGACY //cmdline switch exename protocol name(dpmaster) identifying file exec dir1 dir2 dir3 dir(fte) full name //two quakes - one without extra game dirs which should avoid fuckups from nquake's configs (which screw over cvars that every nq progs.dat depends upon but which the ezquake id1-only less-compatible gamecode ignores). - {"-quake", "q1", "FTE-Quake DarkPlaces-Quake", {"id1/pak0.pak", "id1/quake.rc"},QCFG, {"id1", "qw", "*fte"}, "Quake", "https://fte.triptohell.info/downloadables.php" /*,"id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/}, - {"-netquake", "nq", "FTE-Quake DarkPlaces-Quake", {"id1/pak0.pak", "id1/quake.rc"},QCFG, {"id1"}, "Quake", "https://fte.triptohell.info/downloadables.php" /*,"id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/}, + {"-quake", "q1", "FTE-Quake DarkPlaces-Quake", {"id1/pak0.pak", "id1/quake.rc"},QCFG, {"id1", "qw", "*fte"}, "Quake", "https://triptohell.info/downloadables.php" /*,"id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/}, + {"-netquake", "nq", "FTE-Quake DarkPlaces-Quake", {"id1/pak0.pak", "id1/quake.rc"},QCFG, {"id1"}, "Quake", "https://triptohell.info/downloadables.php" /*,"id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/}, //quake's mission packs should not be favoured over the base game nor autodetected //third part mods also tend to depend upon the mission packs for their huds, even if they don't use any other content. //and q2 also has a rogue/pak0.pak file that we don't want to find and cause quake2 to look like dissolution of eternity diff --git a/engine/common/fs_zip.c b/engine/common/fs_zip.c index 8e409f353..4ce487434 100644 --- a/engine/common/fs_zip.c +++ b/engine/common/fs_zip.c @@ -1,6 +1,44 @@ #include "quakedef.h" #include "fs.h" +//#define AVAIL_BZLIB +//#define DYNAMIC_BZLIB + +#ifdef AVAIL_BZLIB +# include +# ifdef DYNAMIC_BZLIB +# ifndef WINAPI +# define WINAPI +# endif +# define BZ2_bzDecompressInit pBZ2_bzDecompressInit +# define BZ2_bzDecompress pBZ2_bzDecompress +# define BZ2_bzDecompressEnd pBZ2_bzDecompressEnd + static int (WINAPI *BZ2_bzDecompressInit)(bz_stream *strm, int verbosity, int small); + static int (WINAPI *BZ2_bzDecompress)(bz_stream* strm); + static int (WINAPI *BZ2_bzDecompressEnd)(bz_stream *strm); + static qboolean BZLIB_LOADED(void) + { + static qboolean tried; + static void *handle; + if (!tried) + { + static dllfunction_t funcs[] = + { + {(void*)&BZ2_bzDecompressInit, "BZ2_bzDecompressInit"}, + {(void*)&BZ2_bzDecompress, "BZ2_bzDecompress"}, + {(void*)&BZ2_bzDecompressEnd, "BZ2_bzDecompressEnd"}, + {NULL, NULL} + }; + tried = true; + handle = Sys_LoadLibrary("libbz2", funcs); + } + return handle != NULL; + } +# else +# define BZLIB_LOADED() 1 +# endif +#endif + #ifdef AVAIL_ZLIB # define ZIPCRYPT @@ -504,9 +542,6 @@ vfsfile_t *FS_GZ_WriteFilter(vfsfile_t *outfile, qboolean autoclosefile, qboolea - - - #ifdef PACKAGE_PK3 typedef struct @@ -520,11 +555,12 @@ typedef struct unsigned int crc; unsigned int flags; } zpackfile_t; -#define ZFL_DEFLATED 1 //need to use zlib -#define ZFL_STORED 2 //direct access is okay -#define ZFL_SYMLINK 4 //file is a symlink -#define ZFL_CORRUPT 8 //file is corrupt or otherwise unreadable (usually just means we don't support reading it rather than actually corrupt, but hey). -#define ZFL_WEAKENCRYPT 16 //traditional zip encryption +#define ZFL_DEFLATED (1u<<0) //need to use zlib +#define ZFL_BZIP2 (1u<<1) //bzip2 compression +#define ZFL_STORED (1u<<2) //direct access is okay +#define ZFL_SYMLINK (1u<<3) //file is a symlink +#define ZFL_CORRUPT (1u<<4) //file is corrupt or otherwise unreadable (usually just means we don't support reading it rather than actually corrupt, but hey). +#define ZFL_WEAKENCRYPT (1u<<5) //traditional zip encryption typedef struct zipfile_s @@ -712,9 +748,12 @@ static int QDECL FSZIP_GeneratePureCRC(searchpathfuncs_t *handle, int seed, int return result; } -#ifdef AVAIL_ZLIB struct decompressstate { + struct decompressstate *(*Reinit)(zipfile_t *source, qofs_t start, qofs_t csize, qofs_t usize, char *filename, char *password, unsigned int crc); + qofs_t (*Read)(struct decompressstate *st, qbyte *buffer, qofs_t bytes); + void (*Destroy)(struct decompressstate *st); + zipfile_t *source; qofs_t cstart; //position of start of data qofs_t cofs; //current read offset @@ -731,9 +770,16 @@ struct decompressstate const z_crc_t * crctable; #endif +#ifdef AVAIL_ZLIB z_stream strm; +#endif +#ifdef AVAIL_BZLIB + bz_stream bstrm; +#endif }; +#if defined(AVAIL_ZLIB) || defined(AVAIL_BZLIB) + #ifdef ZIPCRYPT #define CRC32(c, b) ((*(st->crctable+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) @@ -791,47 +837,8 @@ static void FSZIP_DecryptBlock(struct decompressstate *st, char *block, size_t b } #endif -static struct decompressstate *FSZIP_Decompress_Init(zipfile_t *source, qofs_t start, qofs_t csize, qofs_t usize, char *filename, char *password, unsigned int crc) -{ - struct decompressstate *st; - if (!ZLIB_LOADED()) - { - Con_Printf("zlib not available\n"); - return NULL; - } - st = Z_Malloc(sizeof(*st)); - st->source = source; - -#ifdef ZIPCRYPT - if (password && csize >= 12) - { - char entropy[12]; - if (Sys_LockMutex(source->mutex)) - { - VFS_SEEK(source->raw, start); - VFS_READ(source->raw, entropy, sizeof(entropy)); - Sys_UnlockMutex(source->mutex); - } - if (!FSZIP_SetupCrytoKeys(st, password, entropy, crc)) - { - Con_Printf("Invalid password, cannot decrypt %s\n", filename); - Z_Free(st); - return NULL; - } - start += sizeof(entropy); - csize -= sizeof(entropy); - } -#endif - - st->cstart = st->cofs = start; - st->cend = start + csize; - st->usize = usize; - st->strm.data_type = Z_UNKNOWN; - qinflateInit2(&st->strm, -MAX_WBITS); - return st; -} - -static qofs_t FSZIP_Decompress_Read(struct decompressstate *st, qbyte *buffer, qofs_t bytes) +#ifdef AVAIL_ZLIB +static qofs_t FSZIP_Deflate_Read(struct decompressstate *st, qbyte *buffer, qofs_t bytes) { qboolean eof = false; int err; @@ -893,11 +900,171 @@ static qofs_t FSZIP_Decompress_Read(struct decompressstate *st, qbyte *buffer, q return read; } -static void FSZIP_Decompress_Destroy(struct decompressstate *st) +static void FSZIP_Deflate_Destroy(struct decompressstate *st) { qinflateEnd(&st->strm); Z_Free(st); } + +static struct decompressstate *FSZIP_Deflate_Init(zipfile_t *source, qofs_t start, qofs_t csize, qofs_t usize, char *filename, char *password, unsigned int crc) +{ + struct decompressstate *st; + if (!ZLIB_LOADED()) + { + Con_Printf("zlib not available\n"); + return NULL; + } + st = Z_Malloc(sizeof(*st)); + st->Reinit = FSZIP_Deflate_Init; + st->Read = FSZIP_Deflate_Read; + st->Destroy = FSZIP_Deflate_Destroy; + st->source = source; + +#ifdef ZIPCRYPT + if (password && csize >= 12) + { + char entropy[12]; + if (Sys_LockMutex(source->mutex)) + { + VFS_SEEK(source->raw, start); + VFS_READ(source->raw, entropy, sizeof(entropy)); + Sys_UnlockMutex(source->mutex); + } + if (!FSZIP_SetupCrytoKeys(st, password, entropy, crc)) + { + Con_Printf("Invalid password, cannot decrypt %s\n", filename); + Z_Free(st); + return NULL; + } + start += sizeof(entropy); + csize -= sizeof(entropy); + } +#endif + + st->cstart = st->cofs = start; + st->cend = start + csize; + st->usize = usize; + + st->strm.data_type = Z_UNKNOWN; + qinflateInit2(&st->strm, -MAX_WBITS); + return st; +} +#endif + +#ifdef AVAIL_BZLIB +static qofs_t FSZIP_BZip2_Read(struct decompressstate *st, qbyte *buffer, qofs_t bytes) +{ + qboolean eof = false; + int err; + qofs_t read = 0; + while(bytes) + { + if (st->readoffset < st->bstrm.total_out_lo32) + { + unsigned int consume = st->bstrm.total_out_lo32-st->readoffset; + if (consume > bytes) + consume = bytes; + memcpy(buffer, st->outbuffer+st->readoffset, consume); + buffer += consume; + bytes -= consume; + read += consume; + st->readoffset += consume; + continue; + } + else if (eof) + break; //no input available, and nothing in the buffers. + + st->bstrm.total_out_lo32 = 0; + st->bstrm.total_out_hi32 = 0; + st->bstrm.avail_out = sizeof(st->outbuffer); + st->bstrm.next_out = st->outbuffer; + st->readoffset = 0; + if (!st->bstrm.avail_in) + { + qofs_t sz; + sz = st->cend - st->cofs; + if (sz > sizeof(st->inbuffer)) + sz = sizeof(st->inbuffer); + if (sz) + { + //feed it. + if (Sys_LockMutex(st->source->mutex)) + { + VFS_SEEK(st->source->raw, st->cofs); + st->bstrm.avail_in = VFS_READ(st->source->raw, st->inbuffer, sz); + Sys_UnlockMutex(st->source->mutex); + } + else + st->bstrm.avail_in = 0; + st->bstrm.next_in = st->inbuffer; + st->cofs += st->bstrm.avail_in; +#ifdef ZIPCRYPT + if (st->encrypted) + FSZIP_DecryptBlock(st, st->inbuffer, st->bstrm.avail_in); +#endif + } + if (!st->bstrm.avail_in) + eof = true; + } + err = BZ2_bzDecompress(&st->bstrm); + if (err == BZ_FINISH_OK) + eof = true; + else if (err < 0) + break; + } + return read; +} + +static void FSZIP_BZip2_Destroy(struct decompressstate *st) +{ + BZ2_bzDecompressEnd(&st->bstrm); + Z_Free(st); +} + +static struct decompressstate *FSZIP_BZip2_Init(zipfile_t *source, qofs_t start, qofs_t csize, qofs_t usize, char *filename, char *password, unsigned int crc) +{ + struct decompressstate *st; + if (!BZLIB_LOADED()) + { + Con_Printf("bzlib not available\n"); + return NULL; + } + st = Z_Malloc(sizeof(*st)); + st->Reinit = FSZIP_BZip2_Init; + st->Read = FSZIP_BZip2_Read; + st->Destroy = FSZIP_BZip2_Destroy; + st->source = source; + +#ifdef ZIPCRYPT + if (password && csize >= 12) + { + char entropy[12]; + if (Sys_LockMutex(source->mutex)) + { + VFS_SEEK(source->raw, start); + VFS_READ(source->raw, entropy, sizeof(entropy)); + Sys_UnlockMutex(source->mutex); + } + if (!FSZIP_SetupCrytoKeys(st, password, entropy, crc)) + { + Con_Printf("Invalid password, cannot decrypt %s\n", filename); + Z_Free(st); + return NULL; + } + start += sizeof(entropy); + csize -= sizeof(entropy); + } +#endif + + st->cstart = st->cofs = start; + st->cend = start + csize; + st->usize = usize; + + BZ2_bzDecompressInit(&st->bstrm, 0, false); + return st; +} +#endif + static vfsfile_t *FSZIP_Decompress_ToTempFile(struct decompressstate *decompress) { //if they're going to seek on a file in a zip, let's just copy it out qofs_t cstart = decompress->cstart, csize = decompress->cend - cstart; @@ -906,61 +1073,48 @@ static vfsfile_t *FSZIP_Decompress_ToTempFile(struct decompressstate *decompress struct decompressstate *nc; qbyte buffer[16384]; vfsfile_t *defer; + struct decompressstate *(*Reinit)(zipfile_t *source, qofs_t start, qofs_t csize, qofs_t usize, char *filename, char *password, unsigned int crc) = decompress->Reinit; zipfile_t *source = decompress->source; +#ifdef ZIPCRYPT //we need to preserve any crypto stuff if we're restarting the stream qboolean encrypted = decompress->encrypted; unsigned int cryptkeys[3]; const z_crc_t *crctab = decompress->crctable; memcpy(cryptkeys, decompress->initialkey, sizeof(cryptkeys)); +#endif defer = FS_OpenTemp(); if (defer) { - FSZIP_Decompress_Destroy(decompress); + decompress->Destroy(decompress); decompress = NULL; - nc = FSZIP_Decompress_Init(source, cstart, csize, usize, NULL, NULL, 0); + nc = Reinit(source, cstart, csize, usize, NULL, NULL, 0); +#ifdef ZIPCRYPT nc->encrypted = encrypted; nc->crctable = crctab; memcpy(nc->initialkey, cryptkeys, sizeof(nc->initialkey)); memcpy(nc->cryptkey, cryptkeys, sizeof(nc->cryptkey)); +#endif while (upos < usize) { chunk = usize - upos; if (chunk > sizeof(buffer)) chunk = sizeof(buffer); - if (!FSZIP_Decompress_Read(nc, buffer, chunk)) + if (!nc->Read(nc, buffer, chunk)) break; if (VFS_WRITE(defer, buffer, chunk) != chunk) break; upos += chunk; } - FSZIP_Decompress_Destroy(nc); + nc->Destroy(nc); return defer; } return NULL; } #else -struct decompressstate -{ - int nothing; -}; -struct decompressstate *FSZIP_Decompress_Init(zipfile_t *source, qofs_t start, qofs_t csize, qofs_t usize, char *filename, char *password, unsigned int crc) -{ - return NULL; -} - -qofs_t FSZIP_Decompress_Read(struct decompressstate *st, qbyte *buffer, qofs_t bytes) -{ - return 0; -} - -void FSZIP_Decompress_Destroy(struct decompressstate *st) -{ -} - vfsfile_t *FSZIP_Decompress_ToTempFile(struct decompressstate *decompress) { return NULL; @@ -992,7 +1146,7 @@ static int QDECL VFSZIP_ReadBytes (struct vfsfile_s *file, void *buffer, int byt if (vfsz->decompress) { - read = FSZIP_Decompress_Read(vfsz->decompress, buffer, bytestoread); + read = vfsz->decompress->Read(vfsz->decompress, buffer, bytestoread); } else if (Sys_LockMutex(vfsz->parent->mutex)) { @@ -1056,7 +1210,7 @@ static qboolean QDECL VFSZIP_Close (struct vfsfile_s *file) VFS_CLOSE(vfsz->defer); if (vfsz->decompress) - FSZIP_Decompress_Destroy(vfsz->decompress); + vfsz->decompress->Destroy(vfsz->decompress); FSZIP_ClosePath(&vfsz->parent->pub); Z_Free(vfsz); @@ -1131,6 +1285,7 @@ static vfsfile_t *QDECL FSZIP_OpenVFS(searchpathfuncs_t *handle, flocation_t *lo return NULL; } +#ifdef AVAIL_ZLIB if (flags & ZFL_DEFLATED) { #ifdef ZIPCRYPT @@ -1139,7 +1294,7 @@ static vfsfile_t *QDECL FSZIP_OpenVFS(searchpathfuncs_t *handle, flocation_t *lo #else char *password = NULL; #endif - vfsz->decompress = FSZIP_Decompress_Init(zip, vfsz->startpos, datasize, vfsz->length, pf->name, password, pf->crc); + vfsz->decompress = FSZIP_Deflate_Init(zip, vfsz->startpos, datasize, vfsz->length, pf->name, password, pf->crc); if (!vfsz->decompress) { /* @@ -1150,6 +1305,28 @@ static vfsfile_t *QDECL FSZIP_OpenVFS(searchpathfuncs_t *handle, flocation_t *lo return NULL; } } +#endif +#ifdef AVAIL_BZLIB + if (flags & ZFL_BZIP2) + { +#ifdef ZIPCRYPT + //FIXME: Cvar_Get is not threadsafe, and nor is accessing the cvar... + char *password = (flags & ZFL_WEAKENCRYPT)?Cvar_Get("fs_zip_password", "thisispublic", 0, "Filesystem")->string:NULL; +#else + char *password = NULL; +#endif + vfsz->decompress = FSZIP_BZip2_Init(zip, vfsz->startpos, datasize, vfsz->length, pf->name, password, pf->crc); + if (!vfsz->decompress) + { + /* + windows explorer tends to use deflate64 on large files, which zlib and thus we, do not support, thus this is a 'common' failure path + this might also trigger from other errors, of course. + */ + Z_Free(vfsz); + return NULL; + } + } +#endif if (Sys_LockMutex(zip->mutex)) { @@ -1159,7 +1336,7 @@ static vfsfile_t *QDECL FSZIP_OpenVFS(searchpathfuncs_t *handle, flocation_t *lo else { if (vfsz->decompress) - FSZIP_Decompress_Destroy(vfsz->decompress); + vfsz->decompress->Destroy(vfsz->decompress); Z_Free(vfsz); return NULL; } @@ -1376,9 +1553,15 @@ static qboolean FSZIP_ValidateLocalHeader(zipfile_t *zip, zpackfile_t *zfile, qo return false; //FIXME: proper spanned zips fragment compressed data over multiple spans, but we don't support that if (local.cmethod == 0) - return (zfile->flags & (ZFL_STORED|ZFL_CORRUPT|ZFL_DEFLATED)) == ZFL_STORED; + return (zfile->flags & (ZFL_STORED|ZFL_CORRUPT|ZFL_DEFLATED|ZFL_BZIP2)) == ZFL_STORED; +#ifdef AVAIL_ZLIB if (local.cmethod == 8) - return (zfile->flags & (ZFL_STORED|ZFL_CORRUPT|ZFL_DEFLATED)) == ZFL_DEFLATED; + return (zfile->flags & (ZFL_STORED|ZFL_CORRUPT|ZFL_DEFLATED|ZFL_BZIP2)) == ZFL_DEFLATED; +#endif +#ifdef AVAIL_BZLIB + if (local.cmethod == 12) + return (zfile->flags & (ZFL_STORED|ZFL_CORRUPT|ZFL_DEFLATED|ZFL_BZIP2)) == ZFL_BZIP2; +#endif return false; //some other method that we don't know. } @@ -1539,13 +1722,12 @@ static qboolean FSZIP_ReadCentralEntry(zipfile_t *zip, qbyte *data, struct zipce //2-5: reduce //6: implode //7: tokenize - else if (entry->cmethod == 8) + else if (entry->cmethod == 8) //8: deflate entry->flags |= ZFL_DEFLATED; - //8: deflate64 - patented. sometimes written by microsoft's crap, so this might be problematic. only minor improvements. + //9: deflate64 - patented. sometimes written by microsoft's crap, so this might be problematic. only minor improvements. //10: implode - //12: bzip2 -// else if (entry->cmethod == 12) -// entry->flags |= ZFL_BZIP2; + else if (entry->cmethod == 12) //12: bzip2 + entry->flags |= ZFL_BZIP2; // else if (entry->cmethod == 14) // entry->flags |= ZFL_LZMA; //19: lz77 diff --git a/engine/common/gl_q2bsp.c b/engine/common/gl_q2bsp.c index d89bf239d..e48926e31 100644 --- a/engine/common/gl_q2bsp.c +++ b/engine/common/gl_q2bsp.c @@ -3558,18 +3558,20 @@ static void CModQ3_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l) out += (m%loadmodel->lightmaps.merge)*mapsize; #if 1 + //q3bsp has 4-fold overbrights, so if we're not using overbrights then we basically need to scale the values up by 4 + //this will require clamping, which can result in oversaturation of channels, meaning discolouration for(s = 0; s < mapsize; ) { + float scale = (1<<(2-gl_overbright.ival)); float i; vec3_t l; l[0] = *in++; l[1] = *in++; l[2] = *in++; - i = VectorNormalize(l); - i *= (1<<(2-gl_overbright.ival)); + VectorScale(l, scale, l); //it should be noted that this maths is wrong if you're trying to use srgb lightmaps. + i = max(l[0], max(l[1], l[2])); if (i > 255) - i = 255; //don't oversaturate (clamping results in discolouration, which looks weird) - VectorScale(l, i, l); + VectorScale(l, 255/i, l); //clamp the brightest channel, scaling the others down to retain chromiance. out[s++] = l[0]; out[s++] = l[1]; out[s++] = l[2]; diff --git a/engine/common/log.c b/engine/common/log.c index a41a8e463..998ace7ae 100644 --- a/engine/common/log.c +++ b/engine/common/log.c @@ -251,11 +251,13 @@ void SV_LogPlayer(client_t *cl, char *msg) if (cl->protocol == SCP_BAD) return; //don't log botclients - snprintf(line, sizeof(line), - "%s\\%s\\%i\\%s\\%s\\%i\\guid\\%s%s\n", + Q_snprintfz(line, sizeof(line)-1, + "%s\\%s\\%i\\%s\\%s\\%i\\guid\\%s", msg, cl->name, cl->userid, NET_BaseAdrToString(remote_adr, sizeof(remote_adr), &cl->netchan.remote_address), (cl->realip_status > 0 ? NET_BaseAdrToString(realip_adr, sizeof(realip_adr), &cl->realip) : "??"), - cl->netchan.remote_address.port, cl->guid, cl->userinfo); + cl->netchan.remote_address.port, cl->guid); + InfoBuf_ToString(&cl->userinfo, line+strlen(line), sizeof(line)-1-strlen(line), NULL, NULL, NULL, NULL, NULL); + Q_strncatz(line, "\n", sizeof(line)); Log_String(LOG_PLAYER, line); } diff --git a/engine/common/net_chan.c b/engine/common/net_chan.c index 756b83734..829240bab 100644 --- a/engine/common/net_chan.c +++ b/engine/common/net_chan.c @@ -199,6 +199,7 @@ unsigned int Net_PextMask(int maskset, qboolean fornq) mask |= PEXT2_VOICECHAT; #endif mask |= PEXT2_SETANGLEDELTA; +// mask |= PEXT2_INFOBLOBS; if (pext_replacementdeltas.ival) mask |= PEXT2_REPLACEMENTDELTAS; diff --git a/engine/common/plugin.c b/engine/common/plugin.c index d59da8ac5..497852eb0 100644 --- a/engine/common/plugin.c +++ b/engine/common/plugin.c @@ -23,14 +23,15 @@ struct qintptr_t (*initfunction)(qintptr_t *args); } staticplugins[] = { -#if defined(USERBE) && !defined(QUAKETC) -// {"Bullet_internal", Plug_Bullet_Init}, -// {"ODE_internal", Plug_ODE_Init}, +#if defined(USE_INTERNAL_BULLET) + {"Bullet_internal", Plug_Bullet_Init}, +#endif +#if defined(USE_INTERNAL_ODE) + {"ODE_internal", Plug_ODE_Init}, #endif {NULL} }; - #ifdef GLQUAKE #include "glquake.h" #endif diff --git a/engine/common/pr_bgcmd.c b/engine/common/pr_bgcmd.c index 240393545..bbf61ab73 100644 --- a/engine/common/pr_bgcmd.c +++ b/engine/common/pr_bgcmd.c @@ -2780,7 +2780,7 @@ void QCBUILTIN PF_callfunction (pubprogfuncs_t *prinst, struct globalvars_s *pr_ void QCBUILTIN PF_loadfromfile (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { const char *filename = PR_GetStringOfs(prinst, OFS_PARM0); - const char *file = COM_LoadTempFile(filename, NULL); + const char *file = COM_LoadTempFile(filename, 0, NULL); size_t size; @@ -4439,14 +4439,11 @@ void QCBUILTIN PF_crc16 (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals G_FLOAT(OFS_RETURN) = QCRC_Block(str, len); } -void QCBUILTIN PF_digest_hex (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_digest_internal (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals, const char *hashtype, const void *str, size_t len) { - const char *hashtype = PR_GetStringOfs(prinst, OFS_PARM0); - const char *str = PF_VarString(prinst, 1, pr_globals); int digestsize, i; unsigned char digest[64]; unsigned char hexdig[sizeof(digest)*2+1]; - size_t len = strlen(str); if (!strcmp(hashtype, "MD4")) { @@ -4487,6 +4484,27 @@ void QCBUILTIN PF_digest_hex (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl G_INT(OFS_RETURN) = 0; } +void QCBUILTIN PF_digest_hex (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) +{ + const char *hashtype = PR_GetStringOfs(prinst, OFS_PARM0); + const char *str = PF_VarString(prinst, 1, pr_globals); + PF_digest_internal(prinst, pr_globals, hashtype, str, strlen(str)); +} + +void QCBUILTIN PF_digest_ptr (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) +{ + const char *hashtype = PR_GetStringOfs(prinst, OFS_PARM0); + int qcptr = G_INT(OFS_PARM1); + int size = G_INT(OFS_PARM2); + if (qcptr < 0 || qcptr+size >= prinst->stringtablesize) + { + PR_BIError(prinst, "PF_digest_ptr: invalid dest\n"); + G_INT(OFS_RETURN) = 0; + return; + } + PF_digest_internal(prinst, pr_globals, hashtype, prinst->stringtable + qcptr, size); +} + // #510 string(string in) uri_escape = #510; void QCBUILTIN PF_uri_escape (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { diff --git a/engine/common/pr_common.h b/engine/common/pr_common.h index 55c9eb42e..87b87fb1e 100644 --- a/engine/common/pr_common.h +++ b/engine/common/pr_common.h @@ -356,6 +356,7 @@ void QCBUILTIN PF_strpad (pubprogfuncs_t *prinst, struct globalvars_s *pr_global void QCBUILTIN PF_strtrim (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_digest_hex (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_digest_ptr (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_findradius (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_edict_for_num (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); @@ -501,12 +502,14 @@ int QDECL QCEditor (pubprogfuncs_t *prinst, const char *filename, int *line, int void PR_Common_Shutdown(pubprogfuncs_t *progs, qboolean errored); void PR_Common_SaveGame(vfsfile_t *f, pubprogfuncs_t *prinst, qboolean binary); +uploadfmt_t PR_TranslateTextureFormat(int qcformat); + //FIXME pbool PR_RunWarning (pubprogfuncs_t *ppf, char *error, ...); /*these are server ones, provided by pr_cmds.c, as required by pr_q1qvm.c*/ -int PF_ForceInfoKey_Internal(unsigned int entnum, const char *key, const char *value); +int PF_ForceInfoKey_Internal(unsigned int entnum, const char *key, const char *value, size_t valsize); #ifdef VM_Q1 void PR_SV_FillWorldGlobals(world_t *w); model_t *QDECL SVPR_GetCModel(world_t *w, int modelindex); diff --git a/engine/common/protocol.h b/engine/common/protocol.h index 282094445..04a83c46e 100644 --- a/engine/common/protocol.h +++ b/engine/common/protocol.h @@ -73,6 +73,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define PEXT2_MAXPLAYERS 0x00000010 //Client is able to cope with more players than 32. abs max becomes 255, due to colormap issues. #define PEXT2_PREDINFO 0x00000020 //movevar stats, NQ input sequences+acks. #define PEXT2_NEWSIZEENCODING 0x00000040 //richer size encoding. +#define PEXT2_INFOBLOBS 0x00000080 //serverinfo+userinfo lengths can be MUCH higher (protocol is unbounded, but expect low sanity limits on userinfo), and contain nulls etc. //EzQuake/Mvdsv extensions #define EZPEXT1_FLOATENTCOORDS 0x00000001 //quirky - doesn't apply to broadcasts, just players+ents. this gives more precision, but will bug out if you try using it to increase map bounds in ways that may not be immediately apparent. iiuc this was added instead of fixing some inconsistent rounding... diff --git a/engine/common/q3common.c b/engine/common/q3common.c index e9c2b59a6..954e9205f 100644 --- a/engine/common/q3common.c +++ b/engine/common/q3common.c @@ -8,10 +8,7 @@ typedef struct { char name[256]; - char *data; - int bufferlen; - qofs_t len; - qofs_t ofs; + vfsfile_t *file; int accessmode; int owner; } vm_fopen_files_t; @@ -20,7 +17,6 @@ vm_fopen_files_t vm_fopen_files[MAX_VM_FILES]; qofs_t VM_fopen (const char *name, int *handle, int fmode, int owner) { int i; - size_t insize; if (!handle) return !!FS_FLocateFile(name, FSLF_IFFOUND, NULL); @@ -28,7 +24,7 @@ qofs_t VM_fopen (const char *name, int *handle, int fmode, int owner) *handle = 0; for (i = 0; i < MAX_VM_FILES; i++) - if (!vm_fopen_files[i].data) + if (!vm_fopen_files[i].file) break; if (i == MAX_VM_FILES) //too many already open @@ -46,39 +42,27 @@ qofs_t VM_fopen (const char *name, int *handle, int fmode, int owner) switch (fmode) { case VM_FS_READ: - vm_fopen_files[i].data = FS_LoadMallocFile(name, &insize); - vm_fopen_files[i].bufferlen = vm_fopen_files[i].len = insize; - vm_fopen_files[i].ofs = 0; - if (vm_fopen_files[i].data) - break; - else - return -1; + vm_fopen_files[i].file = FS_OpenVFS(name, "rb", FS_GAME); break; - /* case VM_FS_APPEND: - case VM_FS_APPEND2: - vm_fopen_files[i].data = FS_LoadMallocFile(name); - vm_fopen_files[i].ofs = vm_fopen_files[i].bufferlen = vm_fopen_files[i].len = com_filesize; - if (vm_fopen_files[i].data) - break; - //fall through - case VM_FS_WRITE: - vm_fopen_files[i].bufferlen = 8192; - vm_fopen_files[i].data = BZ_Malloc(vm_fopen_files[i].bufferlen); - vm_fopen_files[i].len = 0; - vm_fopen_files[i].ofs = 0; + case VM_FS_APPEND_SYNC: + vm_fopen_files[i].file = FS_OpenVFS(name, "ab", FS_GAMEONLY); + break; + case VM_FS_WRITE: + vm_fopen_files[i].file = FS_OpenVFS(name, "wb", FS_GAMEONLY); break; - */ default: //bad return -1; } + if (!vm_fopen_files[i].file) + return -1; Q_strncpyz(vm_fopen_files[i].name, name, sizeof(vm_fopen_files[i].name)); vm_fopen_files[i].accessmode = fmode; vm_fopen_files[i].owner = owner; *handle = i+1; - return vm_fopen_files[i].len; + return VFS_GETLEN(vm_fopen_files[i].file); } void VM_fclose (int fnum, int owner) @@ -91,22 +75,10 @@ void VM_fclose (int fnum, int owner) if (vm_fopen_files[fnum].owner != owner) return; //cgs? - if (!vm_fopen_files[fnum].data) + if (!vm_fopen_files[fnum].file) return; //not open - - switch(vm_fopen_files[fnum].accessmode) - { - case VM_FS_READ: - BZ_Free(vm_fopen_files[fnum].data); - break; - case VM_FS_WRITE: - case VM_FS_APPEND: - case VM_FS_APPEND2: - COM_WriteFile(vm_fopen_files[fnum].name, FS_GAMEONLY, vm_fopen_files[fnum].data, vm_fopen_files[fnum].len); - BZ_Free(vm_fopen_files[fnum].data); - break; - } - vm_fopen_files[fnum].data = NULL; + VFS_CLOSE(vm_fopen_files[fnum].file); + vm_fopen_files[fnum].file = NULL; } int VM_FRead (char *dest, int quantity, int fnum, int owner) @@ -118,76 +90,68 @@ int VM_FRead (char *dest, int quantity, int fnum, int owner) if (vm_fopen_files[fnum].owner != owner) return 0; //cgs? - if (!vm_fopen_files[fnum].data) + if (!vm_fopen_files[fnum].file) return 0; //not open - - if (quantity > vm_fopen_files[fnum].len - vm_fopen_files[fnum].ofs) - quantity = vm_fopen_files[fnum].len - vm_fopen_files[fnum].ofs; - memcpy(dest, vm_fopen_files[fnum].data + vm_fopen_files[fnum].ofs, quantity); - vm_fopen_files[fnum].ofs += quantity; - - return quantity; + if (!vm_fopen_files[fnum].file->ReadBytes) + return 0; + return VFS_READ(vm_fopen_files[fnum].file, dest, quantity); } int VM_FWrite (const char *dest, int quantity, int fnum, int owner) { -/* - int fnum = G_FLOAT(OFS_PARM0); - char *msg = PF_VarString(prinst, 1, pr_globals); - int len = strlen(msg); - if (fnum < 0 || fnum >= MAX_QC_FILES) - return; //out of range + fnum--; + if (fnum < 0 || fnum >= MAX_VM_FILES) + return 0; //out of range - if (!pf_fopen_files[fnum].data) - return; //not open + if (vm_fopen_files[fnum].owner != owner) + return 0; //cgs? - if (pf_fopen_files[fnum].prinst != prinst) - return; //this just isn't ours. + if (!vm_fopen_files[fnum].file) + return 0; //not open + if (!vm_fopen_files[fnum].file->WriteBytes) + return 0; + quantity = VFS_WRITE(vm_fopen_files[fnum].file, dest, quantity); - if (pf_fopen_files[fnum].bufferlen < pf_fopen_files[fnum].ofs + len) - { - char *newbuf; - pf_fopen_files[fnum].bufferlen = pf_fopen_files[fnum].bufferlen*2 + len; - newbuf = BZF_Malloc(pf_fopen_files[fnum].bufferlen); - memcpy(newbuf, pf_fopen_files[fnum].data, pf_fopen_files[fnum].len); - BZ_Free(pf_fopen_files[fnum].data); - pf_fopen_files[fnum].data = newbuf; - } - - memcpy(pf_fopen_files[fnum].data + pf_fopen_files[fnum].ofs, msg, len); - if (pf_fopen_files[fnum].len < pf_fopen_files[fnum].ofs + len) - pf_fopen_files[fnum].len = pf_fopen_files[fnum].ofs + len; - pf_fopen_files[fnum].ofs+=len; -*/ - return 0; + if (vm_fopen_files[fnum].accessmode == VM_FS_APPEND_SYNC) + VFS_FLUSH(vm_fopen_files[fnum].file); + return quantity; } qboolean VM_FSeek (int fnum, qofs_t offset, int seektype, int owner) { + qofs_t fsize; fnum--; if (fnum < 0 || fnum >= MAX_VM_FILES) return false; //out of range if (vm_fopen_files[fnum].owner != owner) return false; //cgs? - if (!vm_fopen_files[fnum].data) + if (!vm_fopen_files[fnum].file) return false; //not open - - switch(seektype) + switch(vm_fopen_files[fnum].file->seekstyle) { - case 0: - offset = vm_fopen_files[fnum].ofs + offset; - case 1: - offset = vm_fopen_files[fnum].len + offset; - break; - default: - case 2: - //offset = 0 + offset; - break; + case SS_SEEKABLE: + case SS_SLOW: + fsize = VFS_GETLEN(vm_fopen_files[fnum].file); //can't cache it if we're writing + switch(seektype) + { + case 0: + offset += VFS_TELL(vm_fopen_files[fnum].file); + return 0; + case 1: + offset += fsize; + break; + default: + case 2: + offset += 0; + break; + } + if (offset > fsize) + return false; + VFS_SEEK(vm_fopen_files[fnum].file, offset); + return true; + case SS_PIPE: + case SS_UNSEEKABLE: + return false; } -// if (offset < 0) -// offset = 0; - if (offset > vm_fopen_files[fnum].len) - offset = vm_fopen_files[fnum].len; - vm_fopen_files[fnum].ofs = offset; - return true; + return false; //should be unreachable. } qofs_t VM_FTell (int fnum, int owner) { @@ -196,10 +160,10 @@ qofs_t VM_FTell (int fnum, int owner) return 0; //out of range if (vm_fopen_files[fnum].owner != owner) return 0; //cgs? - if (!vm_fopen_files[fnum].data) + if (!vm_fopen_files[fnum].file) return 0; //not open - return vm_fopen_files[fnum].ofs; + return VFS_TELL(vm_fopen_files[fnum].file); } void VM_fcloseall (int owner) { @@ -370,16 +334,14 @@ int VMQ3_Cvar_Register(q3vmcvar_t *v, char *name, char *defval, int flags) if ((flags & CVAR_USERINFO) && !(c->flags & CVAR_USERINFO)) { c->flags |= CVAR_USERINFO; - Info_SetValueForKey(cls.userinfo[0], c->name, c->string, sizeof(cls.userinfo[0])); - cls.resendinfo = true; + InfoBuf_SetKey(&cls.userinfo[0], c->name, c->string); } #endif #ifndef CLIENTONLY if ((flags & CVAR_SERVERINFO) && !(c->flags & CVAR_SERVERINFO)) { c->flags |= CVAR_SERVERINFO; - Info_SetValueForKey (svs.info, c->name, c->string, MAX_SERVERINFO_STRING); - SV_SendServerInfoChange(c->name, c->string); + InfoBuf_SetKey (&svs.info, c->name, c->string); } #endif for (i = 0; i < MAX_VMQ3_CVARS; i++) diff --git a/engine/common/vm.h b/engine/common/vm.h index 3084d2d79..e5e8daebc 100644 --- a/engine/common/vm.h +++ b/engine/common/vm.h @@ -87,7 +87,7 @@ void Script_Get_File_And_Line(int handle, char *filename, int *line); #define VM_FS_READ 0 #define VM_FS_WRITE 1 #define VM_FS_APPEND 2 -#define VM_FS_APPEND2 3 //I don't know, don't ask me. look at q3 source +#define VM_FS_APPEND_SYNC 3 //I don't know, don't ask me. look at q3 source qofs_t VM_fopen (const char *name, int *handle, int fmode, int owner); int VM_FRead (char *dest, int quantity, int fnum, int owner); int VM_FWrite (const char *dest, int quantity, int fnum, int owner); diff --git a/engine/d3d/d3d8_backend.c b/engine/d3d/d3d8_backend.c index bfd053a08..5c3e9dc98 100644 --- a/engine/d3d/d3d8_backend.c +++ b/engine/d3d/d3d8_backend.c @@ -1524,7 +1524,7 @@ static qboolean BE_DrawMeshChain_SetupPass(shaderpass_t *pass, unsigned int vert } else Vector4Set(map->colorsb, 255, 255, 255, 255); - VectorCopy(mesh->st_array[i], map->tc[0]); + Vector2Copy(mesh->st_array[i], map->tc[0]); if (mesh->lmst_array[0]) Vector2Copy(mesh->lmst_array[0][i], map->tc[1]); } diff --git a/engine/d3d/d3d_backend.c b/engine/d3d/d3d_backend.c index ffbcbfd17..6f505bc26 100644 --- a/engine/d3d/d3d_backend.c +++ b/engine/d3d/d3d_backend.c @@ -179,6 +179,7 @@ typedef struct float m_model[16]; unsigned int lastpasscount; vbo_t *batchvbo; + program_t *curprog; shader_t *shader_rtlight; IDirect3DTexture9 *curtex[MAX_TMUS]; @@ -1070,6 +1071,8 @@ static void colourgenbyte(const shaderpass_t *pass, int cnt, byte_vec4_t *srcb, break; default: identity: + case RGB_GEN_UNKNOWN: + case RGB_GEN_IDENTITY_OVERBRIGHT: case RGB_GEN_IDENTITY: block = D3DCOLOR_RGBA(255, 255, 255, 255); while((cnt)--) @@ -1459,6 +1462,11 @@ static void tcmod(const tcmod_t *tcmod, int cnt, const float *src, float *dst, c break; default: + for (j = 0; j < cnt; j++, dst+=2,src+=2) + { + dst[0] = src[0]; + dst[1] = src[1]; + } break; } } @@ -1862,109 +1870,6 @@ static void deformgen(const deformv_t *deformv, int cnt, vecV_t *src, vecV_t *ds } } - - -/*does not do the draw call, does not consider indicies (except for billboard generation) */ -static qboolean BE_DrawMeshChain_SetupPass(shaderpass_t *pass, unsigned int vertcount) -{ - int vdec; - void *map; - int i; - unsigned int passno = 0, tmu; - - int lastpass = pass->numMergedPasses; - - for (i = 0; i < lastpass; i++) - { - if (pass[i].texgen == T_GEN_UPPEROVERLAY && !TEXLOADED(shaderstate.curtexnums->upperoverlay)) - continue; - if (pass[i].texgen == T_GEN_LOWEROVERLAY && !TEXLOADED(shaderstate.curtexnums->loweroverlay)) - continue; - if (pass[i].texgen == T_GEN_FULLBRIGHT && !TEXLOADED(shaderstate.curtexnums->fullbright)) - continue; - break; - } - if (i == lastpass) - return false; - - /*all meshes in a chain must have the same features*/ - vdec = 0; - - /*we only use one colour, generated from the first pass*/ - vdec |= BE_GenerateColourMods(vertcount, pass); - - tmu = 0; - /*activate tmus*/ - for (passno = 0; passno < lastpass; passno++) - { - if (pass[passno].texgen == T_GEN_UPPEROVERLAY && !TEXLOADED(shaderstate.curtexnums->upperoverlay)) - continue; - if (pass[passno].texgen == T_GEN_LOWEROVERLAY && !TEXLOADED(shaderstate.curtexnums->loweroverlay)) - continue; - if (pass[passno].texgen == T_GEN_FULLBRIGHT && !TEXLOADED(shaderstate.curtexnums->fullbright)) - continue; - - SelectPassTexture(tmu, pass+passno); - - vdec |= D3D_VDEC_ST0<texcoord.d3d.buff, shaderstate.batchvbo->texcoord.d3d.offs, sizeof(vbovdata_t))); - else if (shaderstate.batchvbo && pass[passno].tcgen == TC_GEN_LIGHTMAP && !pass[passno].numtcmods) - d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0+tmu, shaderstate.batchvbo->lmcoord[0].d3d.buff, shaderstate.batchvbo->lmcoord[0].d3d.offs, sizeof(vbovdata_t))); - else if (pass[passno].tcgen == TC_GEN_SKYBOX) - { - vdec |= D3D_VDEC_CM; - allocvertexbuffer(shaderstate.dynst_buff[tmu], shaderstate.dynst_size, &shaderstate.dynst_offs[tmu], &map, vertcount*sizeof(vec3_t)); - GenerateTCMods3(pass+passno, map); - d3dcheck(IDirect3DVertexBuffer9_Unlock(shaderstate.dynst_buff[tmu])); - d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0+tmu, shaderstate.dynst_buff[tmu], shaderstate.dynst_offs[tmu] - vertcount*sizeof(vec3_t), sizeof(vec3_t))); - } - else - { - allocvertexbuffer(shaderstate.dynst_buff[tmu], shaderstate.dynst_size, &shaderstate.dynst_offs[tmu], &map, vertcount*sizeof(vec2_t)); - GenerateTCMods(pass+passno, map); - d3dcheck(IDirect3DVertexBuffer9_Unlock(shaderstate.dynst_buff[tmu])); - d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0+tmu, shaderstate.dynst_buff[tmu], shaderstate.dynst_offs[tmu] - vertcount*sizeof(vec2_t), sizeof(vec2_t))); - } - tmu++; - } - /*deactivate any extras*/ - for (; tmu < shaderstate.lastpasscount; ) - { - d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0+tmu, NULL, 0, 0)); - BindTexture(tmu, NULL); - d3dcheck(IDirect3DDevice9_SetTextureStageState(pD3DDev9, tmu, D3DTSS_COLOROP, D3DTOP_DISABLE)); - d3dcheck(IDirect3DDevice9_SetTextureStageState(pD3DDev9, tmu, D3DTSS_ALPHAOP, D3DTOP_DISABLE)); - tmu++; - } - shaderstate.lastpasscount = tmu; - -// if (meshchain->normals_array && -// meshchain->2 && -// meshchain->tnormals_array) -// vdec |= D3D_VDEC_NORMS; - - if (vdec != shaderstate.curvertdecl) - { - shaderstate.curvertdecl = vdec; - d3dcheck(IDirect3DDevice9_SetVertexDeclaration(pD3DDev9, vertexdecls[shaderstate.curvertdecl])); - } - - BE_ApplyShaderBits(pass->shaderbits); - return true; -} - -static void BE_SubmitMeshChain(unsigned int vertbase, unsigned int firstvert, unsigned int vertcount, unsigned int idxfirst, int unsigned idxcount) -{ - if (shaderstate.flags & BEF_LINES) - IDirect3DDevice9_DrawIndexedPrimitive(pD3DDev9, D3DPT_LINELIST, vertbase, firstvert, vertcount, idxfirst, idxcount/2); - else - IDirect3DDevice9_DrawIndexedPrimitive(pD3DDev9, D3DPT_TRIANGLELIST, vertbase, firstvert, vertcount, idxfirst, idxcount/3); - RQuantAdd(RQUANT_DRAWS, 1); - - RQuantAdd(RQUANT_PRIMITIVEINDICIES, idxcount); -} - static void R_FetchPlayerColour(unsigned int cv, vec3_t rgb) { int i; @@ -1997,7 +1902,6 @@ static void R_FetchPlayerColour(unsigned int cv, vec3_t rgb) *retblue = gammatable[*retblue]; }*/ } - static void BE_ApplyUniforms(program_t *prog, int permu) { struct programpermu_s *perm = &prog->permu[permu]; @@ -2005,8 +1909,12 @@ static void BE_ApplyUniforms(program_t *prog, int permu) vec4_t param4; int h; int i; - IDirect3DDevice9_SetVertexShader(pD3DDev9, perm->h.hlsl.vert); - IDirect3DDevice9_SetPixelShader(pD3DDev9, perm->h.hlsl.frag); + if (shaderstate.curprog != prog) + { + shaderstate.curprog = prog; + IDirect3DDevice9_SetVertexShader(pD3DDev9, perm->h.hlsl.vert); + IDirect3DDevice9_SetPixelShader(pD3DDev9, perm->h.hlsl.frag); + } for (i = 0, pp = perm->parm; i < perm->numparms; i++, pp++) { h = pp->handle; @@ -2169,6 +2077,208 @@ static void BE_ApplyUniforms(program_t *prog, int permu) } } +static unsigned int BE_DrawMeshChain_SetupProgram(program_t *p) +{ + unsigned int vdec = 0; + unsigned int perm = 0; +#ifdef SKELETALMODELS + if (shaderstate.batchvbo && shaderstate.batchvbo->numbones) + { + if (p->permu[perm|PERMUTATION_SKELETAL].h.loaded) + perm |= PERMUTATION_SKELETAL; + } +#endif + if (TEXLOADED(shaderstate.curtexnums->bump) && p->permu[perm|PERMUTATION_BUMPMAP].h.loaded) + perm |= PERMUTATION_BUMPMAP; + if (TEXLOADED(shaderstate.curtexnums->fullbright) && p->permu[perm|PERMUTATION_FULLBRIGHT].h.loaded) + perm |= PERMUTATION_FULLBRIGHT; + if (p->permu[perm|PERMUTATION_UPPERLOWER].h.loaded && (TEXLOADED(shaderstate.curtexnums->upperoverlay) || TEXLOADED(shaderstate.curtexnums->loweroverlay))) + perm |= PERMUTATION_UPPERLOWER; + if (r_refdef.globalfog.density && p->permu[perm|PERMUTATION_FOG].h.loaded) + perm |= PERMUTATION_FOG; +#ifdef NONSKELETALMODELS + if (p->permu[perm|PERMUTATION_FRAMEBLEND].h.loaded && shaderstate.batchvbo && shaderstate.batchvbo->coord2.d3d.buff) + { + perm |= PERMUTATION_FRAMEBLEND; + vdec |= D3D_VDEC_POS2; + } +#endif +// if (p->permu[perm|PERMUTATION_DELUXE].h.loaded && TEXVALID(shaderstate.curtexnums->bump) && shaderstate.curbatch->lightmap[0] >= 0 && lightmap[shaderstate.curbatch->lightmap[0]]->hasdeluxe) +// perm |= PERMUTATION_DELUXE; +#if MAXRLIGHTMAPS > 1 + if (shaderstate.curbatch && shaderstate.curbatch->lightmap[1] >= 0 && p->permu[perm|PERMUTATION_LIGHTSTYLES].h.loaded) + perm |= PERMUTATION_LIGHTSTYLES; +#endif + + vdec |= D3D_VDEC_COL4B;//BE_GenerateColourMods(vertcount, s->passes); + + BE_ApplyUniforms(p, perm); + + return vdec; +} + +/*does not do the draw call, does not consider indicies (except for billboard generation) */ +static qboolean BE_DrawMeshChain_SetupPass(shaderpass_t *pass, unsigned int vertcount) +{ + int vdec; + void *map; + int i; + unsigned int passno = 0, tmu; + + int lastpass = pass->numMergedPasses; + + for (i = 0; i < lastpass; i++) + { + if (pass[i].texgen == T_GEN_UPPEROVERLAY && !TEXLOADED(shaderstate.curtexnums->upperoverlay)) + continue; + if (pass[i].texgen == T_GEN_LOWEROVERLAY && !TEXLOADED(shaderstate.curtexnums->loweroverlay)) + continue; + if (pass[i].texgen == T_GEN_FULLBRIGHT && !TEXLOADED(shaderstate.curtexnums->fullbright)) + continue; + break; + } + if (i == lastpass) + return false; + + /*all meshes in a chain must have the same features*/ + vdec = 0; + + /*we only use one colour, generated from the first pass*/ + vdec |= BE_GenerateColourMods(vertcount, pass); + + if (pass->prog) + { + vdec |= BE_DrawMeshChain_SetupProgram(pass->prog); + + tmu = 0; + /*activate tmus*/ + for (passno = 0; passno < lastpass; passno++) + { + SelectPassTexture(tmu, pass+passno); + tmu++; + } + /*deactivate any extras*/ + for (; tmu < shaderstate.lastpasscount; ) + { + BindTexture(tmu, NULL); + d3dcheck(IDirect3DDevice9_SetTextureStageState(pD3DDev9, tmu, D3DTSS_COLOROP, D3DTOP_DISABLE)); + d3dcheck(IDirect3DDevice9_SetTextureStageState(pD3DDev9, tmu, D3DTSS_ALPHAOP, D3DTOP_DISABLE)); + tmu++; + } + + if (1) + { + vdec |= D3D_VDEC_ST0|D3D_VDEC_ST1; + if (shaderstate.batchvbo) + { + d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0, shaderstate.batchvbo->texcoord.d3d.buff, shaderstate.batchvbo->texcoord.d3d.offs, sizeof(vbovdata_t))); + d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC1, shaderstate.batchvbo->lmcoord[0].d3d.buff, shaderstate.batchvbo->lmcoord[0].d3d.offs, sizeof(vbovdata_t))); + } + else + { + mesh_t *mesh; + unsigned int mno; + float *outtc, *outlm; + + allocvertexbuffer(shaderstate.dynst_buff[0], shaderstate.dynst_size, &shaderstate.dynst_offs[0], &map, vertcount*sizeof(vec4_t)); + outtc = map; + outlm = outtc + vertcount*2; + for (mno = 0; mno < shaderstate.nummeshes; mno++) + { + mesh = shaderstate.meshlist[mno]; + + memcpy(outtc, mesh->st_array, sizeof(vec2_t)*mesh->numvertexes); + memcpy(outlm, mesh->lmst_array[0], sizeof(vec2_t)*mesh->numvertexes); + } + d3dcheck(IDirect3DVertexBuffer9_Unlock(shaderstate.dynst_buff[0])); + d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0, shaderstate.dynst_buff[0], shaderstate.dynst_offs[0] - vertcount*sizeof(vec4_t), sizeof(vec2_t))); + d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC1, shaderstate.dynst_buff[0], shaderstate.dynst_offs[0] - vertcount*sizeof(vec2_t), sizeof(vec2_t))); + } + shaderstate.lastpasscount = max(2, tmu); + } + } + else + { + if (shaderstate.curprog) + { + shaderstate.curprog = NULL; + IDirect3DDevice9_SetVertexShader(pD3DDev9, NULL); + IDirect3DDevice9_SetPixelShader(pD3DDev9, NULL); + } + + tmu = 0; + /*activate tmus*/ + for (passno = 0; passno < lastpass; passno++) + { + if (pass[passno].texgen == T_GEN_UPPEROVERLAY && !TEXLOADED(shaderstate.curtexnums->upperoverlay)) + continue; + if (pass[passno].texgen == T_GEN_LOWEROVERLAY && !TEXLOADED(shaderstate.curtexnums->loweroverlay)) + continue; + if (pass[passno].texgen == T_GEN_FULLBRIGHT && !TEXLOADED(shaderstate.curtexnums->fullbright)) + continue; + + SelectPassTexture(tmu, pass+passno); + + vdec |= D3D_VDEC_ST0<texcoord.d3d.buff, shaderstate.batchvbo->texcoord.d3d.offs, sizeof(vbovdata_t))); + else if (shaderstate.batchvbo)// && pass[passno].tcgen == TC_GEN_LIGHTMAP/* && !pass[passno].numtcmods*/) + d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0+tmu, shaderstate.batchvbo->lmcoord[0].d3d.buff, shaderstate.batchvbo->lmcoord[0].d3d.offs, sizeof(vbovdata_t))); + else if (pass[passno].tcgen == TC_GEN_SKYBOX) + { + vdec |= D3D_VDEC_CM; + allocvertexbuffer(shaderstate.dynst_buff[tmu], shaderstate.dynst_size, &shaderstate.dynst_offs[tmu], &map, vertcount*sizeof(vec3_t)); + GenerateTCMods3(pass+passno, map); + d3dcheck(IDirect3DVertexBuffer9_Unlock(shaderstate.dynst_buff[tmu])); + d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0+tmu, shaderstate.dynst_buff[tmu], shaderstate.dynst_offs[tmu] - vertcount*sizeof(vec3_t), sizeof(vec3_t))); + } + else + { + allocvertexbuffer(shaderstate.dynst_buff[tmu], shaderstate.dynst_size, &shaderstate.dynst_offs[tmu], &map, vertcount*sizeof(vec2_t)); + GenerateTCMods(pass+passno, map); + d3dcheck(IDirect3DVertexBuffer9_Unlock(shaderstate.dynst_buff[tmu])); + d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0+tmu, shaderstate.dynst_buff[tmu], shaderstate.dynst_offs[tmu] - vertcount*sizeof(vec2_t), sizeof(vec2_t))); + } + tmu++; + } + /*deactivate any extras*/ + for (; tmu < shaderstate.lastpasscount; ) + { + d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0+tmu, NULL, 0, 0)); + BindTexture(tmu, NULL); + d3dcheck(IDirect3DDevice9_SetTextureStageState(pD3DDev9, tmu, D3DTSS_COLOROP, D3DTOP_DISABLE)); + d3dcheck(IDirect3DDevice9_SetTextureStageState(pD3DDev9, tmu, D3DTSS_ALPHAOP, D3DTOP_DISABLE)); + tmu++; + } + shaderstate.lastpasscount = tmu; + } + +// if (meshchain->normals_array && +// meshchain->2 && +// meshchain->tnormals_array) +// vdec |= D3D_VDEC_NORMS; + + if (vdec != shaderstate.curvertdecl) + { + shaderstate.curvertdecl = vdec; + d3dcheck(IDirect3DDevice9_SetVertexDeclaration(pD3DDev9, vertexdecls[shaderstate.curvertdecl])); + } + + BE_ApplyShaderBits(pass->shaderbits); + return true; +} + +static void BE_SubmitMeshChain(unsigned int vertbase, unsigned int firstvert, unsigned int vertcount, unsigned int idxfirst, int unsigned idxcount) +{ + if (shaderstate.flags & BEF_LINES) + IDirect3DDevice9_DrawIndexedPrimitive(pD3DDev9, D3DPT_LINELIST, vertbase, firstvert, vertcount, idxfirst, idxcount/2); + else + IDirect3DDevice9_DrawIndexedPrimitive(pD3DDev9, D3DPT_TRIANGLELIST, vertbase, firstvert, vertcount, idxfirst, idxcount/3); + RQuantAdd(RQUANT_DRAWS, 1); + + RQuantAdd(RQUANT_PRIMITIVEINDICIES, idxcount); +} + static void BE_RenderMeshProgram(shader_t *s, unsigned int vertbase, unsigned int vertfirst, unsigned int vertcount, unsigned int idxfirst, unsigned int idxcount) { int vdec = D3D_VDEC_ST0|D3D_VDEC_ST1|D3D_VDEC_NORM; @@ -2208,7 +2318,7 @@ static void BE_RenderMeshProgram(shader_t *s, unsigned int vertbase, unsigned in perm |= PERMUTATION_LIGHTSTYLES; #endif - vdec |= BE_GenerateColourMods(vertcount, s->passes); + vdec |= D3D_VDEC_COL4B;//BE_GenerateColourMods(vertcount, s->passes); BE_ApplyUniforms(p, perm); diff --git a/engine/d3d/vid_d3d.c b/engine/d3d/vid_d3d.c index 2b118afd5..ccbb9fef6 100644 --- a/engine/d3d/vid_d3d.c +++ b/engine/d3d/vid_d3d.c @@ -796,8 +796,6 @@ static qboolean D3D9_VID_Init(rendererstate_t *info, unsigned char *palette) D3D9_Set2D(); - - // pD3DX->lpVtbl->GetBufferSize((void*)pD3DX, &width, &height); vid.pixelwidth = width; vid.pixelheight = height; @@ -1006,10 +1004,12 @@ static qboolean (D3D9_SCR_UpdateScreen) (void) if (vid_srgb.modified) { vid_srgb.modified = false; - vid.flags &= VID_SRGB_FB; - if ((vid.flags & VID_SRGBAWARE) || vid_srgb.ival) + //VID_SRGBAWARE defines whether textures are meant to be srgb or not. + //as it requires a vid_reload, we don't mess with it here. + //that said, we can still change srgb freely otherwise. + vid.flags &= VID_SRGBAWARE; + if ((vid.flags & VID_SRGBAWARE) || vid_srgb.ival<0) vid.flags |= (d3dpp.Windowed)?VID_SRGB_FB_FAKED:VID_SRGB_FB_LINEAR; - IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_SRGBWRITEENABLE, !!(vid.flags&VID_SRGB_FB_LINEAR)); } @@ -1182,8 +1182,13 @@ static void (D3D9_Draw_Init) (void) { { vid_srgb.modified = false; - vid.flags &= VID_SRGB_FB; - if ((vid.flags & VID_SRGBAWARE) || vid_srgb.ival) + //VID_SRGBAWARE defines whether textures are meant to be srgb or not. + //we're doing a vid_reload here, so we can change it here easily enough + if (vid_srgb.ival > 0) //d3d9 does srgb using post-process stuff for us. + vid.flags |= VID_SRGBAWARE; + else + vid.flags = 0; + if ((vid.flags & VID_SRGBAWARE) || vid_srgb.ival<0) vid.flags |= (d3dpp.Windowed)?VID_SRGB_FB_FAKED:VID_SRGB_FB_LINEAR; IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_SRGBWRITEENABLE, !!(vid.flags&VID_SRGB_FB_LINEAR)); @@ -1351,6 +1356,7 @@ rendererinfo_t d3d9rendererinfo = "D3D", "Direct3d", "DirectX", + "2" //this is evil, but worth a laugh. }, QR_DIRECT3D9, diff --git a/engine/d3d/vid_d3d11.c b/engine/d3d/vid_d3d11.c index df23dd2ef..332618ed9 100644 --- a/engine/d3d/vid_d3d11.c +++ b/engine/d3d/vid_d3d11.c @@ -802,7 +802,7 @@ static qboolean initD3D11Device(HWND hWnd, rendererstate_t *info, PFN_D3D11_CREA scd.BufferCount = 1+info->triplebuffer; //back buffer count if (info->srgb) { - if (info->srgb >= 3) //fixme: detect properly. + if (info->srgb >= 2) //fixme: detect properly. scd.BufferDesc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT; //on nvidia, outputs linear rgb to srgb devices, which means info->srgb is effectively set else scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; @@ -956,7 +956,7 @@ static qboolean initD3D11Device(HWND hWnd, rendererstate_t *info, PFN_D3D11_CREA //non-linear formats. break; } - if ((vid.flags & VID_SRGB_FB) && info->srgb != 1) + if ((vid.flags & VID_SRGB_FB) && info->srgb >= 0) vid.flags |= VID_SRGBAWARE; vid.numpages = scd.BufferCount; diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index 7c5a96f49..e3d475851 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -24,7 +24,6 @@ extern cvar_t gl_overbright; extern cvar_t r_tessellation; extern cvar_t r_wireframe; extern cvar_t r_refract_fbo; -extern cvar_t r_refractreflect_scale; extern texid_t missing_texture; extern texid_t missing_texture_gloss; @@ -5132,7 +5131,7 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist) if ((bs->flags & SHADER_HASREFLECT) && gl_config.ext_framebuffer_objects) { - float renderscale = r_refractreflect_scale.value; + float renderscale = bs->portalfboscale; vrect_t orect = r_refdef.vrect; pxrect_t oprect = r_refdef.pxrect; if (!shaderstate.tex_reflection[r_refdef.recurse]) @@ -5155,7 +5154,13 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist) shaderstate.tex_reflection[r_refdef.recurse]->width = r_refdef.pxrect.width; shaderstate.tex_reflection[r_refdef.recurse]->height = r_refdef.pxrect.height; GL_MTBind(0, GL_TEXTURE_2D, shaderstate.tex_reflection[r_refdef.recurse]); - qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, shaderstate.tex_reflection[r_refdef.recurse]->width, shaderstate.tex_reflection[r_refdef.recurse]->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + + if ((vid.flags&VID_FP16) && sh_config.texfmt[PTI_RGBA16F]) + qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, shaderstate.tex_reflection[r_refdef.recurse]->width, shaderstate.tex_reflection[r_refdef.recurse]->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + else if ((vid.flags&(VID_SRGBAWARE|VID_FP16)) && sh_config.texfmt[PTI_RGBA8_SRGB]) + qglTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB8_ALPHA8_EXT, shaderstate.tex_reflection[r_refdef.recurse]->width, shaderstate.tex_reflection[r_refdef.recurse]->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + else + qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, shaderstate.tex_reflection[r_refdef.recurse]->width, shaderstate.tex_reflection[r_refdef.recurse]->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); @@ -5177,7 +5182,7 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist) { if (r_refract_fboival || (bs->flags&SHADER_HASPORTAL)) { - float renderscale = min(1, r_refractreflect_scale.value); + float renderscale = min(1, bs->portalfboscale); vrect_t ovrect = r_refdef.vrect; pxrect_t oprect = r_refdef.pxrect; r_refdef.vrect.x = 0; @@ -5200,7 +5205,12 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist) shaderstate.tex_refraction[r_refdef.recurse]->width = r_refdef.pxrect.width; shaderstate.tex_refraction[r_refdef.recurse]->height = r_refdef.pxrect.height; GL_MTBind(0, GL_TEXTURE_2D, shaderstate.tex_refraction[r_refdef.recurse]); - qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, r_refdef.pxrect.width, r_refdef.pxrect.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + if ((vid.flags&VID_FP16) && sh_config.texfmt[PTI_RGBA16F]) + qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, r_refdef.pxrect.width, r_refdef.pxrect.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + else if ((vid.flags&(VID_SRGBAWARE|VID_FP16)) && sh_config.texfmt[PTI_RGBA16F]) + qglTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB8_ALPHA8_EXT, r_refdef.pxrect.width, r_refdef.pxrect.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + else + qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, r_refdef.pxrect.width, r_refdef.pxrect.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); @@ -5252,7 +5262,7 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist) } if ((bs->flags & SHADER_HASRIPPLEMAP) && gl_config.ext_framebuffer_objects) { - float renderscale = r_refractreflect_scale.value; + float renderscale = bs->portalfboscale; vrect_t orect = r_refdef.vrect; pxrect_t oprect = r_refdef.pxrect; r_refdef.vrect.x = 0; diff --git a/engine/gl/gl_draw.c b/engine/gl/gl_draw.c index 1aed5b013..804880b27 100644 --- a/engine/gl/gl_draw.c +++ b/engine/gl/gl_draw.c @@ -403,7 +403,7 @@ void GLDraw_Init (void) //figure out which extra features we can support on these drivers. - r_deluxmapping = r_deluxmapping_cvar.ival; + r_deluxemapping = r_deluxemapping_cvar.ival; r_lightprepass = r_lightprepass_cvar.ival && sh_config.progs_supported; r_softwarebanding = r_softwarebanding_cvar.ival && sh_config.progs_supported; if (gl_config.gles && gl_config.glversion < 3.0) diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index 240f96f44..650a96ce1 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -1131,7 +1131,7 @@ void Mod_ModelLoaded(void *ctx, void *data, size_t a, size_t b) char *buf; char dollname[MAX_QPATH]; Q_snprintfz(dollname, sizeof(dollname), "%s.doll", mod->name); - buf = COM_LoadFile(dollname, 5, &filesize); + buf = FS_LoadMallocFile(dollname, &filesize); if (buf) { mod->dollinfo = rag_createdollfromstring(mod, dollname, numbones, buf); @@ -1273,7 +1273,7 @@ static void Mod_LoadModelWorker (void *ctx, void *data, size_t a, size_t b) char altname[MAX_QPATH]; Q_snprintfz(altname, sizeof(altname), "%s.%s", mdlbase, token); TRACE(("Mod_LoadModel: Trying to load (replacement) model \"%s\"\n", altname)); - buf = (unsigned *)COM_LoadFile (altname, 5, &filesize); + buf = (unsigned *)FS_LoadMallocFile (altname, &filesize); if (buf) Q_strncpyz(mod->name, altname, sizeof(mod->name)); @@ -1281,7 +1281,7 @@ static void Mod_LoadModelWorker (void *ctx, void *data, size_t a, size_t b) else { TRACE(("Mod_LoadModel: Trying to load model \"%s\"\n", mod->publicname)); - buf = (unsigned *)COM_LoadFile (mod->publicname, 5, &filesize); + buf = (unsigned *)FS_LoadMallocFile (mod->publicname, &filesize); if (buf) Q_strncpyz(mod->name, mod->publicname, sizeof(mod->name)); else if (!buf) @@ -1837,7 +1837,7 @@ void Mod_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean samples = ql2->lmsize; litdata = shifts+ql2->numsurfs; - if (r_deluxmapping) + if (r_deluxemapping) luxdata = litdata+samples*3; } } @@ -1906,7 +1906,7 @@ void Mod_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean } - if (!luxdata && r_loadlits.ival && r_deluxmapping) + if (!luxdata && r_loadlits.ival && r_deluxemapping) { //the map util has a '-scalecos X' parameter. use 0 if you're going to use only just lux. without lux scalecos 0 is hideous. char luxname[MAX_QPATH]; size_t luxsz = 0; @@ -1971,14 +1971,14 @@ void Mod_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean #endif #ifdef RUNTIMELIGHTING - if (!lightmodel && r_loadlits.value == 2 && (!litdata || (!luxdata && r_deluxmapping))) + if (!lightmodel && r_loadlits.value == 2 && (!litdata || (!luxdata && r_deluxemapping))) { writelitfile = !litdata; numlightdata = l->filelen; lightmodel = loadmodel; relitsurface = 0; } - else if (!lightmodel && r_deluxmapping_cvar.value>1 && r_deluxmapping && !luxdata + else if (!lightmodel && r_deluxemapping_cvar.value>1 && r_deluxemapping && !luxdata #ifdef RTLIGHTS && !(r_shadow_realtime_world.ival && r_shadow_realtime_world_lightmaps.value<=0) #endif @@ -2008,7 +2008,7 @@ void Mod_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean } } /*if we're relighting, make sure there's the proper lux data to be updated*/ - if (lightmodel == loadmodel && r_deluxmapping && !luxdata) + if (lightmodel == loadmodel && r_deluxemapping && !luxdata) { int i; luxdata = ZG_Malloc(&loadmodel->memgroup, samples*3); diff --git a/engine/gl/gl_rlight.c b/engine/gl/gl_rlight.c index 1034227af..8b350ce1b 100644 --- a/engine/gl/gl_rlight.c +++ b/engine/gl/gl_rlight.c @@ -1064,7 +1064,7 @@ qboolean R_LoadRTLights(void) COM_StripExtension(cl.worldmodel->name, fname, sizeof(fname)); strncat(fname, ".rtlights", MAX_QPATH-1); - file = COM_LoadTempFile(fname, NULL); + file = COM_LoadTempFile(fname, 0, NULL); if (file) while(1) { diff --git a/engine/gl/gl_rmain.c b/engine/gl/gl_rmain.c index 4a67f4d37..12d4f90bf 100644 --- a/engine/gl/gl_rmain.c +++ b/engine/gl/gl_rmain.c @@ -1987,7 +1987,7 @@ void GLR_RenderView (void) } else if ((r_refdef.flags & (RDF_ALLPOSTPROC)) || forcedfb) { - unsigned int rtflags = IF_NOMIPMAP|IF_CLAMP|IF_RENDERTARGET; + unsigned int rtflags = IF_NOMIPMAP|IF_CLAMP|IF_RENDERTARGET|IF_NOSRGB; enum uploadfmt fmt; r_refdef.flags |= RDF_RENDERSCALE; diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index 40be9d55f..f60f3f0a0 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -321,7 +321,7 @@ static qboolean Shader_EvaluateCondition(shader_t *shader, char **ptr) else if (!Q_stricmp(token, "lightmap")) lhs = !r_fullbright.value; else if (!Q_stricmp(token, "deluxmap") || !Q_stricmp(token, "deluxe")) - lhs = r_deluxmapping; + lhs = r_deluxemapping; else if (!Q_stricmp(token, "softwarebanding")) lhs = r_softwarebanding; @@ -374,7 +374,7 @@ static qboolean Shader_EvaluateCondition(shader_t *shader, char **ptr) // else if (!Q_stricmp(token, "GLSL")) // lhs = 1; else if (!Q_stricmp(token, "deluxeMaps") || !Q_stricmp(token, "deluxe")) - lhs = r_deluxmapping; + lhs = r_deluxemapping; else if (!Q_stricmp(token, "portalMaps")) lhs = false; //end qfusion @@ -1149,21 +1149,21 @@ const struct sh_defaultsamplers_s sh_defaultsamplers[] = {"s_reflectcube", 1u<<9}, {"s_reflectmask", 1u<<10}, {"s_lightmap", 1u<<11}, - {"s_deluxmap", 1u<<12}, + {"s_deluxemap", 1u<<12}, #if MAXRLIGHTMAPS > 1 {"s_lightmap1", 1u<<13}, {"s_lightmap2", 1u<<14}, {"s_lightmap3", 1u<<15}, - {"s_deluxmap1", 1u<<16}, - {"s_deluxmap2", 1u<<17}, - {"s_deluxmap3", 1u<<18}, + {"s_deluxemap1", 1u<<16}, + {"s_deluxemap2", 1u<<17}, + {"s_deluxemap3", 1u<<18}, #else {"s_lightmap1", 0}, {"s_lightmap2", 0}, {"s_lightmap3", 0}, - {"s_deluxmap1", 0}, - {"s_deluxmap2", 0}, - {"s_deluxmap3", 0}, + {"s_deluxemap1", 0}, + {"s_deluxemap2", 0}, + {"s_deluxemap3", 0}, #endif {NULL} }; @@ -1258,6 +1258,7 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip script += 7; while (*script != '\n' && *script != '\r') { + size_t len; int i; char *start; while (*script == ' ' || *script == '\t') @@ -1266,9 +1267,18 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip while (*script != ' ' && *script != '\t' && *script != '\r' && *script != '\n') script++; +#ifndef NOLEGACY + if (script-start >= 8 && !strncmp(start, "deluxmap", 8)) + { //FIXME: remove this some time. + start = va("deluxemap%s",start+8); + len = strlen(start); + } + else +#endif + len = script-start; for (i = 0; sh_defaultsamplers[i].name; i++) { - if (!strncmp(start, sh_defaultsamplers[i].name+2, script-start) && sh_defaultsamplers[i].name[2+script-start] == 0) + if (!strncmp(start, sh_defaultsamplers[i].name+2, len) && sh_defaultsamplers[i].name[2+len] == 0) { prog->defaulttextures |= sh_defaultsamplers[i].defaulttexbits; break; @@ -1656,7 +1666,7 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip permutationdefines[pn++] = "#define RELIEFMAPPING\n"; } - if (r_deluxmapping) //fixme: should be per-model really + if (r_deluxemapping) //fixme: should be per-model really permutationdefines[pn++] = "#define DELUXE\n"; } permutationdefines[pn++] = NULL; @@ -1832,7 +1842,7 @@ static void Shader_LoadGeneric(sgeneric_t *g, int qrtype) if (file) { - Con_DPrintf("Loaded %s from disk\n", sh_config.progpath?va(sh_config.progpath, basicname):basicname); +// Con_DPrintf("Loaded %s from disk\n", sh_config.progpath?va(sh_config.progpath, basicname):basicname); g->failed = !Shader_LoadPermutations(g->name, &g->prog, file, qrtype, 0, blobname); FS_FreeFile(file); return; @@ -1860,6 +1870,18 @@ static void Shader_LoadGeneric(sgeneric_t *g, int qrtype) } } } + +const char *Shader_NameForGeneric(program_t *prog) +{ + sgeneric_t *g; + for (g = sgenerics; g; g = g->next) + { + if (prog == &g->prog) + return g->name; + } + return "INLINE"; +} + program_t *Shader_FindGeneric(char *name, int qrtype) { sgeneric_t *g; @@ -1982,51 +2004,55 @@ struct shader_field_names_s shader_attr_names[] = struct shader_field_names_s shader_unif_names[] = { + /**///tagged names are available to vulkan + /*matricies*/ - {"m_model", SP_M_MODEL}, - {"m_view", SP_M_VIEW}, - {"m_modelview", SP_M_MODELVIEW}, - {"m_projection", SP_M_PROJECTION}, - {"m_modelviewprojection", SP_M_MODELVIEWPROJECTION}, - {"m_bones", SP_M_ENTBONES}, - {"m_invviewprojection", SP_M_INVVIEWPROJECTION}, - {"m_invmodelviewprojection",SP_M_INVMODELVIEWPROJECTION}, +/**/{"m_model", SP_M_MODEL}, //the model matrix + {"m_view", SP_M_VIEW}, //the view matrix + {"m_modelview", SP_M_MODELVIEW},//the combined modelview matrix + {"m_projection", SP_M_PROJECTION},//projection matrix +/**/{"m_modelviewprojection", SP_M_MODELVIEWPROJECTION},//fancy mvp matrix. probably has degraded precision. + {"m_bones", SP_M_ENTBONES}, //bone matrix array. should normally be read via sys/skeletal.h + {"m_invviewprojection", SP_M_INVVIEWPROJECTION},//inverted vp matrix + {"m_invmodelviewprojection",SP_M_INVMODELVIEWPROJECTION},//inverted mvp matrix. +/**///m_modelinv /*viewer properties*/ - {"v_eyepos", SP_V_EYEPOS}, - {"w_fog", SP_W_FOG}, - {"w_user", SP_W_USER}, + {"v_eyepos", SP_V_EYEPOS}, //eye pos in worldspace +/**/{"w_fog", SP_W_FOG}, //read by sys/fog.h + {"w_user", SP_W_USER}, //set via VF_USERDATA /*ent properties*/ - {"e_vblend", SP_E_VBLEND}, - {"e_lmscale", SP_E_LMSCALE}, /*overbright shifting*/ - {"e_vlscale", SP_E_VLSCALE}, /*no lightmaps, no overbrights*/ - {"e_origin", SP_E_ORIGIN}, - {"e_time", SP_E_TIME}, - {"e_eyepos", SP_E_EYEPOS}, - {"e_colour", SP_E_COLOURS}, - {"e_colourident", SP_E_COLOURSIDENT}, - {"e_glowmod", SP_E_GLOWMOD}, - {"e_uppercolour", SP_E_TOPCOLOURS}, - {"e_lowercolour", SP_E_BOTTOMCOLOURS}, - {"e_light_dir", SP_E_L_DIR}, - {"e_light_mul", SP_E_L_MUL}, - {"e_light_ambient", SP_E_L_AMBIENT}, + {"e_vblend", SP_E_VBLEND}, //v_position1+v_position2 scalers +/**/{"e_lmscale", SP_E_LMSCALE}, /*overbright shifting*/ + {"e_vlscale", SP_E_VLSCALE}, /*no lightmaps, no overbrights*/ + {"e_origin", SP_E_ORIGIN}, //the ents origin in worldspace +/**/{"e_time", SP_E_TIME}, //r_refdef.time - entity->time +/**/{"e_eyepos", SP_E_EYEPOS}, //eye pos in modelspace + {"e_colour", SP_E_COLOURS}, //colormod/alpha, even if colormod isn't set +/**/{"e_colourident", SP_E_COLOURSIDENT}, //colormod,alpha or 1,1,1,alpha if colormod isn't set +/**/{"e_glowmod", SP_E_GLOWMOD}, //fullbright scalers (for hdr mostly) +/**/{"e_uppercolour", SP_E_TOPCOLOURS}, //q1 player colours +/**/{"e_lowercolour", SP_E_BOTTOMCOLOURS},//q1 player colours +/**/{"e_light_dir", SP_E_L_DIR}, //lightgrid light dir. dotproducts should be clamped to 0-1. +/**/{"e_light_mul", SP_E_L_MUL}, //lightgrid light scaler. +/**/{"e_light_ambient", SP_E_L_AMBIENT}, //lightgrid light value for the unlit side. - {"s_colour", SP_S_COLOUR}, + {"s_colour", SP_S_COLOUR}, //the rgbgen/alphagen stuff. obviously doesn't work with per-vertex ones. /*rtlight properties, use with caution*/ - {"l_lightscreen", SP_LIGHTSCREEN}, - {"l_lightradius", SP_LIGHTRADIUS}, - {"l_lightcolour", SP_LIGHTCOLOUR}, - {"l_lightposition", SP_LIGHTPOSITION}, - {"l_lightcolourscale", SP_LIGHTCOLOURSCALE}, - {"l_cubematrix", SP_LIGHTCUBEMATRIX}, - {"l_shadowmapproj", SP_LIGHTSHADOWMAPPROJ}, - {"l_shadowmapscale", SP_LIGHTSHADOWMAPSCALE}, + {"l_lightscreen", SP_LIGHTSCREEN}, //screenspace position of the current rtlight +/**/{"l_lightradius", SP_LIGHTRADIUS}, //radius of the current rtlight +/**/{"l_lightcolour", SP_LIGHTCOLOUR}, //rgb values of the current rtlight +/**/{"l_lightposition", SP_LIGHTPOSITION}, //light position in modelspace +/**/{"l_lightcolourscale", SP_LIGHTCOLOURSCALE},//ambient/diffuse/specular scalers +/**/{"l_cubematrix", SP_LIGHTCUBEMATRIX},//matrix used to control the rtlight's cubemap projection +/**/{"l_shadowmapproj", SP_LIGHTSHADOWMAPPROJ}, //compacted projection matrix for shadowmaps +/**/{"l_shadowmapscale", SP_LIGHTSHADOWMAPSCALE},//should probably use a samplerRect instead... + + {"e_sourcesize", SP_SOURCESIZE}, //size of VF_SOURCECOLOUR image + {"e_rendertexturescale", SP_RENDERTEXTURESCALE}, //scaler for $currentrender, when npot isn't supported. - {"e_sourcesize", SP_SOURCESIZE}, - {"e_rendertexturescale", SP_RENDERTEXTURESCALE}, {NULL} }; @@ -2434,6 +2460,12 @@ static void Shader_Translucent(shader_t *shader, shaderpass_t *pass, char **ptr) shader->flags |= SHADER_BLEND; } +static void Shader_PortalFBOScale(shader_t *shader, shaderpass_t *pass, char **ptr) +{ + shader->portalfboscale = Shader_ParseFloat(shader, ptr, 0); + shader->portalfboscale = max(shader->portalfboscale, 0); +} + static void Shader_DP_Camera(shader_t *shader, shaderpass_t *pass, char **ptr) { shader->sort = SHADER_SORT_PORTAL; @@ -2623,6 +2655,7 @@ static shaderkey_t shaderkeys[] = {"uppermap", Shader_UpperMap, "fte"}, {"lowermap", Shader_LowerMap, "fte"}, {"reflectmask", Shader_ReflectMask, "fte"}, + {"portalfboscale", Shader_PortalFBOScale, "fte"}, //portal/mirror/refraction/reflection FBOs are resized by this scale /*program stuff at the material level is an outdated practise.*/ {"program", Shader_ProgramName, "fte"}, //usable with any renderer that has a usable shader language... @@ -4087,6 +4120,7 @@ char *Shader_Skip ( char *ptr ) void Shader_Reset(shader_t *s) { + extern cvar_t r_refractreflect_scale; char name[MAX_QPATH]; int id = s->id; int uses = s->uses; @@ -4103,6 +4137,7 @@ void Shader_Reset(shader_t *s) s->defaulttextures = NULL; Shader_Free(s); memset(s, 0, sizeof(*s)); + s->portalfboscale = r_refractreflect_scale.value; //unless otherwise specified, this cvar specifies the value. s->remapto = s; s->id = id; @@ -6819,15 +6854,42 @@ static qboolean Shader_ParseShader(char *parsename, shader_t *s) size_t offset = 0, length; char *buf = NULL; shadercachefile_t *sourcefile = NULL; + char *file; + const char *token; + + //if the named shader is a .shader file then just directly load it. + token = COM_GetFileExtension(parsename, NULL); + if (!strcmp(token, ".shader") || !*token) + { + char shaderfile[MAX_QPATH]; + if (!*token) + { + Q_snprintfz(shaderfile, sizeof(shaderfile), "%s.shader", parsename); + file = COM_LoadTempMoreFile(shaderfile, &length); + } + else + file = COM_LoadTempMoreFile(parsename, &length); + if (file) + { + Shader_Reset(s); + token = COM_ParseExt (&file, true, false); //we need to skip over the leading {. + if (*token != '{') + token = COM_ParseExt (&file, true, false); //try again, in case we found some legacy name. + if (*token == '{') + { + Shader_ReadShader(s, file, NULL); + return true; + } + else + Con_Printf("file %s.shader does not appear to contain a shader\n", shaderfile); + } + } if (Shader_LocateSource(parsename, &buf, &length, &offset, &sourcefile)) { // the shader is in the shader scripts if (buf && offset < length ) { - char *file, *token; - - file = buf + offset; token = COM_ParseExt (&file, true, true); if ( !file || token[0] != '{' ) @@ -6974,8 +7036,9 @@ static shader_t *R_LoadShader (const char *name, unsigned int usageflags, shader } if (Shader_ParseShader(cleanname, s)) return s; - if (Shader_ParseShader(shortname, s)) - return s; + if (strcmp(cleanname, shortname)) + if (Shader_ParseShader(shortname, s)) + return s; } // make a default shader @@ -7045,7 +7108,7 @@ static char *Shader_DecomposePass(char *o, shaderpass_t *p, qboolean simple) if (p->prog) { - sprintf(o, "program\n"); + sprintf(o, "program %s\n", Shader_NameForGeneric(p->prog)); o+=strlen(o); } @@ -7277,7 +7340,7 @@ char *Shader_Decompose(shader_t *s) if (s->prog) { - sprintf(o, "program\n"); + sprintf(o, "program %s\n", Shader_NameForGeneric(s->prog)); o+=strlen(o); p = s->passes; @@ -7396,6 +7459,8 @@ char *Shader_GetShaderBody(shader_t *s, char *fname, size_t fnamesize) } } #endif + + saveshaderbody = NULL; return adr; } @@ -7526,8 +7591,9 @@ void Shader_DoReload(void) } if (Shader_ParseShader(cleanname, s)) continue; - if (Shader_ParseShader(shortname, s)) - continue; + if (strcmp(cleanname, shortname)) + if (Shader_ParseShader(shortname, s)) + continue; } if (s->generator) { @@ -7666,7 +7732,7 @@ void Shader_RemapShader_f(void) char *destname = Cmd_Argv(2); float timeoffset = atof(Cmd_Argv(3)); - if (!Cmd_FromGamecode() && strcmp(Info_ValueForKey(cl.serverinfo, "*cheats"), "ON")) + if (!Cmd_FromGamecode() && strcmp(InfoBuf_ValueForKey(&cl.serverinfo, "*cheats"), "ON")) { Con_Printf("%s may only be used from gamecode, or when cheats are enabled\n", Cmd_Argv(0)); return; diff --git a/engine/gl/gl_vidcommon.c b/engine/gl/gl_vidcommon.c index 5348412a9..eee1dd0bb 100644 --- a/engine/gl/gl_vidcommon.c +++ b/engine/gl/gl_vidcommon.c @@ -1353,16 +1353,23 @@ static const char *glsl_hdrs[] = "uniform samplerCube s_reflectcube;" "uniform sampler2D s_reflectmask;" "uniform sampler2D s_lightmap;" - "uniform sampler2D s_deluxmap;" + "uniform sampler2D s_deluxemap;" "\n#define s_lightmap0 s_lightmap\n" - "#define s_deluxmap0 s_deluxmap\n" + "#define s_deluxemap0 s_deluxemap\n" #if MAXRLIGHTMAPS > 1 "uniform sampler2D s_lightmap1;" "uniform sampler2D s_lightmap2;" "uniform sampler2D s_lightmap3;" - "uniform sampler2D s_deluxmap1;" - "uniform sampler2D s_deluxmap2;" - "uniform sampler2D s_deluxmap3;\n" + "uniform sampler2D s_deluxemap1;" + "uniform sampler2D s_deluxemap2;" + "uniform sampler2D s_deluxemap3;\n" + + //FIXME: remove these some time. +// "#define s_deluxmap s_deluxemap\n" +// "#define s_deluxmap0 s_deluxemap0\n" +// "#define s_deluxmap1 s_deluxemap1\n" +// "#define s_deluxmap2 s_deluxemap2\n" +// "#define s_deluxmap3 s_deluxemap3\n" #endif #endif "#ifdef USEUBOS\n" @@ -2107,14 +2114,14 @@ static GLhandleARB GLSlang_CreateShader (program_t *prog, const char *name, int "uniform samplerCube s_reflectcube;\n", "uniform sampler2D s_reflectmask;\n", "uniform sampler2D s_lightmap;\n#define s_lightmap0 s_lightmap\n", - "uniform sampler2D s_deluxmap;\n#define s_deluxmap0 s_deluxmap\n", + "uniform sampler2D s_deluxemap;\n#define s_deluxemap0 s_deluxemap\n", "uniform sampler2D s_lightmap1;\n", "uniform sampler2D s_lightmap2;\n", "uniform sampler2D s_lightmap3;\n", - "uniform sampler2D s_deluxmap1;\n", - "uniform sampler2D s_deluxmap2;\n", - "uniform sampler2D s_deluxmap3;\n", + "uniform sampler2D s_deluxemap1;\n", + "uniform sampler2D s_deluxemap2;\n", + "uniform sampler2D s_deluxemap3;\n", }; for (i = 0; i < countof(defaultsamplernames); i++) { diff --git a/engine/gl/gl_vidnt.c b/engine/gl/gl_vidnt.c index e0c2b2d5a..4cf4f8bdf 100644 --- a/engine/gl/gl_vidnt.c +++ b/engine/gl/gl_vidnt.c @@ -1506,6 +1506,19 @@ static int GLVID_SetMode (rendererstate_t *info, unsigned char *palette) if (!GL_Init(info, getglfunc)) return false; + + if (qwglGetPixelFormatAttribfvARB) //just for debugging info. + { + int iAttributeNames[] = {WGL_RED_BITS_ARB, WGL_GREEN_BITS_ARB, WGL_BLUE_BITS_ARB, WGL_ALPHA_BITS_ARB, WGL_PIXEL_TYPE_ARB, WGL_DEPTH_BITS_ARB, WGL_STENCIL_BITS_ARB}; + float fAttributeValues[countof(iAttributeNames)] = {0}; + if (qwglGetPixelFormatAttribfvARB(maindc, currentpixelformat, 0, countof(iAttributeNames), iAttributeNames, fAttributeValues)) + { + Con_DPrintf("Colour buffer: GL_R%gG%gB%gA%g%s\n", fAttributeValues[0], fAttributeValues[1], fAttributeValues[2], fAttributeValues[3], fAttributeValues[5]==WGL_TYPE_RGBA_FLOAT_ARB?"F":((vid.flags & VID_SRGBAWARE)?"_SRGB":"")); + Con_DPrintf("Depth buffer: GL_DEPTH%g_STENCIL%g\n", fAttributeValues[5], fAttributeValues[6]); + } + } + + qSwapBuffers(maindc); #ifdef VKQUAKE @@ -2299,7 +2312,7 @@ static BOOL CheckForcePixelFormat(rendererstate_t *info) iAttribute[iAttributes++] = WGL_SUPPORT_OPENGL_ARB; iAttribute[iAttributes++] = GL_TRUE; iAttribute[iAttributes++] = WGL_ACCELERATION_ARB; iAttribute[iAttributes++] = WGL_FULL_ACCELERATION_ARB; - if (info->srgb>=3 && modestate != MS_WINDOWED) + if (info->srgb>=2 && modestate != MS_WINDOWED) { //half-float backbuffers! //'as has been the case since Windows Vista, fp16 swap chains are expected to have linear color data' diff --git a/engine/gl/r_bishaders.h b/engine/gl/r_bishaders.h index 754755d98..31d7c0475 100644 --- a/engine/gl/r_bishaders.h +++ b/engine/gl/r_bishaders.h @@ -558,7 +558,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "\x4C\xCC\xCD\x01\x0D\x42\x31\x72\x69\x70\x70\x6C\x65\x6D\x61\x70\x00\x00\x00\x00\x00\x01\x0E\x46\x33\x74\x69\x6E\x74\x5F\x72\x65" "\x66\x72\x00\x3F\x33\x33\x33\x3F\x4C\xCC\xCD\x3F\x33\x33\x33\x01\x11\x46\x33\x74\x69\x6E\x74\x5F\x72\x65\x66\x6C\x00\x3F\x33\x33" "\x33\x3F\x4C\xCC\xCD\x3F\x33\x33\x33\x01\x14\x42\x31\x64\x65\x70\x74\x68\x00\x00\x00\x00\x00\x01\x15\x46\x31\x61\x6C\x70\x68\x61" -"\x00\x00\x00\x00\x00\x01\x16\x46\x33\x66\x6F\x67\x74\x69\x6E\x74\x00\x3E\x4C\xCC\xCD\x3E\x99\x99\x9A\x3E\x4C\xCC\xCD\x70\x74\x68" +"\x00\x00\x00\x00\x00\x01\x16\x46\x33\x66\x6F\x67\x74\x69\x6E\x74\x00\x3E\x4C\xCC\xCD\x3E\x99\x99\x9A\x3E\x4C\xCC\xCD\x00\x00\x00" "\x03\x02\x23\x07\x00\x00\x01\x00\x01\x00\x08\x00\x79\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\x11\x00\x00\x00\x00\x00\x04\x00\x00\x00\x6D\x61\x69\x6E\x00\x00\x00\x00\x2C\x00\x00\x00\x49\x00\x00\x00\x4B\x00\x00\x00" @@ -1208,7 +1208,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND #ifdef VKQUAKE {QR_VULKAN, -1, "bloom_blur", "\xFF\x53\x50\x56\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x2C\x00\x00\x00\x00\x00\x00\x00\x2C\x00\x00\x00" -"\x80\x0E\x00\x00\xAC\x0E\x00\x00\xF8\x0B\x00\x00\x03\x02\x23\x07\x00\x00\x01\x00\x01\x00\x08\x00\x4C\x00\x00\x00\x00\x00\x00\x00" +"\x90\x0E\x00\x00\xBC\x0E\x00\x00\x08\x0C\x00\x00\x03\x02\x23\x07\x00\x00\x01\x00\x01\x00\x08\x00\x4C\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\x3B\x00\x00\x00\x3F\x00\x00\x00\x47\x00\x00\x00\x48\x00\x00\x00\x49\x00\x00\x00\x4A\x00\x00\x00" @@ -1268,97 +1268,98 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "\x23\x00\x00\x00\x90\x01\x00\x00\x48\x00\x05\x00\x13\x00\x00\x00\x15\x00\x00\x00\x23\x00\x00\x00\x94\x01\x00\x00\x48\x00\x05\x00" "\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\x3B\x00\x00\x00\x1E\x00\x00\x00\x01\x00\x00\x00\x48\x00\x05\x00" -"\x3D\x00\x00\x00\x00\x00\x00\x00\x0B\x00\x00\x00\x00\x00\x00\x00\x47\x00\x03\x00\x3D\x00\x00\x00\x02\x00\x00\x00\x48\x00\x04\x00" -"\x43\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00" -"\x48\x00\x05\x00\x43\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00\x01\x00\x00\x00" -"\x23\x00\x00\x00\x40\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00\x02\x00\x00\x00\x23\x00\x00\x00\x4C\x00\x00\x00\x48\x00\x05\x00" -"\x43\x00\x00\x00\x03\x00\x00\x00\x23\x00\x00\x00\x50\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00" -"\x5C\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00\x05\x00\x00\x00\x23\x00\x00\x00\x60\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00" -"\x06\x00\x00\x00\x23\x00\x00\x00\x6C\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00\x07\x00\x00\x00\x23\x00\x00\x00\x70\x00\x00\x00" -"\x48\x00\x05\x00\x43\x00\x00\x00\x08\x00\x00\x00\x23\x00\x00\x00\x80\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00\x09\x00\x00\x00" -"\x23\x00\x00\x00\x88\x00\x00\x00\x47\x00\x03\x00\x43\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x45\x00\x00\x00\x22\x00\x00\x00" -"\x00\x00\x00\x00\x47\x00\x04\x00\x45\x00\x00\x00\x21\x00\x00\x00\x01\x00\x00\x00\x47\x00\x04\x00\x47\x00\x00\x00\x1E\x00\x00\x00" -"\x02\x00\x00\x00\x47\x00\x04\x00\x48\x00\x00\x00\x1E\x00\x00\x00\x03\x00\x00\x00\x47\x00\x04\x00\x49\x00\x00\x00\x1E\x00\x00\x00" -"\x04\x00\x00\x00\x47\x00\x04\x00\x4A\x00\x00\x00\x1E\x00\x00\x00\x05\x00\x00\x00\x47\x00\x04\x00\x4B\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\x15\x00\x04\x00\x0F\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00" -"\x2B\x00\x04\x00\x0F\x00\x00\x00\x10\x00\x00\x00\x04\x00\x00\x00\x1C\x00\x04\x00\x11\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00" -"\x17\x00\x04\x00\x12\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x1E\x00\x19\x00\x13\x00\x00\x00\x0D\x00\x00\x00\x0D\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\x0E\x00\x00\x00" -"\x06\x00\x00\x00\x11\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\x07\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x12\x00\x00\x00\x20\x00\x04\x00\x14\x00\x00\x00\x02\x00\x00\x00" -"\x13\x00\x00\x00\x3B\x00\x04\x00\x14\x00\x00\x00\x15\x00\x00\x00\x02\x00\x00\x00\x15\x00\x04\x00\x16\x00\x00\x00\x20\x00\x00\x00" -"\x01\x00\x00\x00\x2B\x00\x04\x00\x16\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x20\x00\x04\x00\x18\x00\x00\x00\x02\x00\x00\x00" -"\x0D\x00\x00\x00\x20\x00\x04\x00\x1B\x00\x00\x00\x01\x00\x00\x00\x0E\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x1C\x00\x00\x00" -"\x01\x00\x00\x00\x2B\x00\x04\x00\x06\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x80\x3F\x2B\x00\x04\x00\x06\x00\x00\x00\x24\x00\x00\x00" -"\x00\x00\x80\xBF\x2B\x00\x04\x00\x0F\x00\x00\x00\x25\x00\x00\x00\x01\x00\x00\x00\x20\x00\x04\x00\x26\x00\x00\x00\x07\x00\x00\x00" -"\x06\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00\x2B\x00\x00\x00\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" -"\x12\x00\x00\x00\x3B\x00\x04\x00\x38\x00\x00\x00\x39\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00\x3A\x00\x00\x00\x01\x00\x00\x00" -"\x12\x00\x00\x00\x3B\x00\x04\x00\x3A\x00\x00\x00\x3B\x00\x00\x00\x01\x00\x00\x00\x1E\x00\x03\x00\x3D\x00\x00\x00\x07\x00\x00\x00" -"\x20\x00\x04\x00\x3E\x00\x00\x00\x03\x00\x00\x00\x3D\x00\x00\x00\x3B\x00\x04\x00\x3E\x00\x00\x00\x3F\x00\x00\x00\x03\x00\x00\x00" -"\x20\x00\x04\x00\x41\x00\x00\x00\x03\x00\x00\x00\x07\x00\x00\x00\x1E\x00\x0C\x00\x43\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\x44\x00\x00\x00\x02\x00\x00\x00\x43\x00\x00\x00\x3B\x00\x04\x00\x44\x00\x00\x00\x45\x00\x00\x00\x02\x00\x00\x00" -"\x20\x00\x04\x00\x46\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00\x46\x00\x00\x00\x47\x00\x00\x00\x01\x00\x00\x00" -"\x3B\x00\x04\x00\x3A\x00\x00\x00\x48\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x49\x00\x00\x00\x01\x00\x00\x00" -"\x3B\x00\x04\x00\x1B\x00\x00\x00\x4A\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x4B\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" -"\x12\x00\x00\x00\x3C\x00\x00\x00\x3B\x00\x00\x00\x3E\x00\x03\x00\x39\x00\x00\x00\x3C\x00\x00\x00\x39\x00\x04\x00\x07\x00\x00\x00" -"\x40\x00\x00\x00\x09\x00\x00\x00\x41\x00\x05\x00\x41\x00\x00\x00\x42\x00\x00\x00\x3F\x00\x00\x00\x17\x00\x00\x00\x3E\x00\x03\x00" -"\x42\x00\x00\x00\x40\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\x01\x00\x08\x00\x37\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\x07\x00\x04\x00\x00\x00\x04\x00\x00\x00\x6D\x61\x69\x6E\x00\x00\x00\x00" -"\x09\x00\x00\x00\x12\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\x09\x00\x00\x00\x6F\x75\x74\x63\x6F\x6C\x6F\x75" -"\x72\x00\x00\x00\x05\x00\x04\x00\x0E\x00\x00\x00\x73\x5F\x74\x30\x00\x00\x00\x00\x05\x00\x03\x00\x12\x00\x00\x00\x74\x63\x00\x00" -"\x05\x00\x05\x00\x19\x00\x00\x00\x65\x6E\x74\x69\x74\x79\x62\x6C\x6F\x63\x6B\x00\x06\x00\x07\x00\x19\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\x19\x00\x00\x00\x01\x00\x00\x00\x6D\x5F\x6D\x6F" -"\x64\x65\x6C\x00\x06\x00\x06\x00\x19\x00\x00\x00\x02\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x69\x6E\x76\x00\x00\x06\x00\x06\x00" -"\x19\x00\x00\x00\x03\x00\x00\x00\x65\x5F\x65\x79\x65\x70\x6F\x73\x00\x00\x00\x00\x06\x00\x05\x00\x19\x00\x00\x00\x04\x00\x00\x00" -"\x65\x5F\x74\x69\x6D\x65\x00\x00\x06\x00\x07\x00\x19\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\x19\x00\x00\x00\x06\x00\x00\x00\x65\x70\x61\x64\x31\x00\x00\x00\x06\x00\x06\x00\x19\x00\x00\x00" -"\x07\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x64\x69\x72\x00\x06\x00\x05\x00\x19\x00\x00\x00\x08\x00\x00\x00\x65\x70\x61\x64" -"\x32\x00\x00\x00\x06\x00\x06\x00\x19\x00\x00\x00\x09\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x6D\x75\x6C\x00\x06\x00\x05\x00" -"\x19\x00\x00\x00\x0A\x00\x00\x00\x65\x70\x61\x64\x33\x00\x00\x00\x06\x00\x06\x00\x19\x00\x00\x00\x0B\x00\x00\x00\x65\x5F\x6C\x6D" -"\x73\x63\x61\x6C\x65\x73\x00\x00\x06\x00\x07\x00\x19\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\x19\x00\x00\x00\x0D\x00\x00\x00\x65\x70\x61\x64\x34\x00\x00\x00\x06\x00\x07\x00\x19\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\x19\x00\x00\x00\x0F\x00\x00\x00" -"\x65\x70\x61\x64\x35\x00\x00\x00\x06\x00\x06\x00\x19\x00\x00\x00\x10\x00\x00\x00\x65\x5F\x67\x6C\x6F\x77\x6D\x6F\x64\x00\x00\x00" -"\x06\x00\x05\x00\x19\x00\x00\x00\x11\x00\x00\x00\x65\x70\x61\x64\x36\x00\x00\x00\x06\x00\x07\x00\x19\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\x19\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\x19\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\x19\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\x19\x00\x00\x00\x16\x00\x00\x00\x65\x70\x61\x64\x37\x00\x00\x00\x05\x00\x03\x00\x1B\x00\x00\x00" -"\x00\x00\x00\x00\x05\x00\x05\x00\x34\x00\x00\x00\x6C\x69\x67\x68\x74\x62\x6C\x6F\x63\x6B\x00\x00\x06\x00\x07\x00\x34\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\x34\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\x34\x00\x00\x00\x02\x00\x00\x00\x6C\x70\x61\x64" -"\x31\x00\x00\x00\x06\x00\x07\x00\x34\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\x34\x00\x00\x00\x04\x00\x00\x00\x6C\x70\x61\x64\x32\x00\x00\x00\x06\x00\x08\x00\x34\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\x34\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\x34\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\x34\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\x34\x00\x00\x00\x09\x00\x00\x00\x6C\x70\x61\x64\x33\x00\x00\x00" -"\x05\x00\x03\x00\x36\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x09\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00" -"\x0E\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x0E\x00\x00\x00\x21\x00\x00\x00\x02\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\x47\x00\x04\x00" +"\x3B\x00\x00\x00\x1E\x00\x00\x00\x01\x00\x00\x00\x48\x00\x05\x00\x3D\x00\x00\x00\x00\x00\x00\x00\x0B\x00\x00\x00\x00\x00\x00\x00" +"\x47\x00\x03\x00\x3D\x00\x00\x00\x02\x00\x00\x00\x48\x00\x04\x00\x43\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00" +"\x43\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00" +"\x10\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00\x01\x00\x00\x00\x23\x00\x00\x00\x40\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00" +"\x02\x00\x00\x00\x23\x00\x00\x00\x4C\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00\x03\x00\x00\x00\x23\x00\x00\x00\x50\x00\x00\x00" +"\x48\x00\x05\x00\x43\x00\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00\x5C\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00\x05\x00\x00\x00" +"\x23\x00\x00\x00\x60\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00\x06\x00\x00\x00\x23\x00\x00\x00\x6C\x00\x00\x00\x48\x00\x05\x00" +"\x43\x00\x00\x00\x07\x00\x00\x00\x23\x00\x00\x00\x70\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00\x08\x00\x00\x00\x23\x00\x00\x00" +"\x80\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00\x09\x00\x00\x00\x23\x00\x00\x00\x88\x00\x00\x00\x47\x00\x03\x00\x43\x00\x00\x00" +"\x02\x00\x00\x00\x47\x00\x04\x00\x45\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x45\x00\x00\x00\x21\x00\x00\x00" +"\x01\x00\x00\x00\x47\x00\x04\x00\x47\x00\x00\x00\x1E\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x48\x00\x00\x00\x1E\x00\x00\x00" +"\x03\x00\x00\x00\x47\x00\x04\x00\x49\x00\x00\x00\x1E\x00\x00\x00\x04\x00\x00\x00\x47\x00\x04\x00\x4A\x00\x00\x00\x1E\x00\x00\x00" +"\x05\x00\x00\x00\x47\x00\x04\x00\x4B\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" +"\x15\x00\x04\x00\x0F\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00\x10\x00\x00\x00\x04\x00\x00\x00" +"\x1C\x00\x04\x00\x11\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x17\x00\x04\x00\x12\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00" +"\x1E\x00\x19\x00\x13\x00\x00\x00\x0D\x00\x00\x00\x0D\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\x0E\x00\x00\x00\x06\x00\x00\x00\x11\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\x07\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00" +"\x12\x00\x00\x00\x20\x00\x04\x00\x14\x00\x00\x00\x02\x00\x00\x00\x13\x00\x00\x00\x3B\x00\x04\x00\x14\x00\x00\x00\x15\x00\x00\x00" +"\x02\x00\x00\x00\x15\x00\x04\x00\x16\x00\x00\x00\x20\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00\x16\x00\x00\x00\x17\x00\x00\x00" +"\x00\x00\x00\x00\x20\x00\x04\x00\x18\x00\x00\x00\x02\x00\x00\x00\x0D\x00\x00\x00\x20\x00\x04\x00\x1B\x00\x00\x00\x01\x00\x00\x00" +"\x0E\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x1C\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00\x06\x00\x00\x00\x1E\x00\x00\x00" +"\x00\x00\x80\x3F\x2B\x00\x04\x00\x06\x00\x00\x00\x24\x00\x00\x00\x00\x00\x80\xBF\x2B\x00\x04\x00\x0F\x00\x00\x00\x25\x00\x00\x00" +"\x01\x00\x00\x00\x20\x00\x04\x00\x26\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00\x2B\x00\x00\x00" +"\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\x12\x00\x00\x00\x3B\x00\x04\x00\x38\x00\x00\x00\x39\x00\x00\x00" +"\x03\x00\x00\x00\x20\x00\x04\x00\x3A\x00\x00\x00\x01\x00\x00\x00\x12\x00\x00\x00\x3B\x00\x04\x00\x3A\x00\x00\x00\x3B\x00\x00\x00" +"\x01\x00\x00\x00\x1E\x00\x03\x00\x3D\x00\x00\x00\x07\x00\x00\x00\x20\x00\x04\x00\x3E\x00\x00\x00\x03\x00\x00\x00\x3D\x00\x00\x00" +"\x3B\x00\x04\x00\x3E\x00\x00\x00\x3F\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00\x41\x00\x00\x00\x03\x00\x00\x00\x07\x00\x00\x00" +"\x1E\x00\x0C\x00\x43\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\x44\x00\x00\x00\x02\x00\x00\x00\x43\x00\x00\x00" +"\x3B\x00\x04\x00\x44\x00\x00\x00\x45\x00\x00\x00\x02\x00\x00\x00\x20\x00\x04\x00\x46\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00" +"\x3B\x00\x04\x00\x46\x00\x00\x00\x47\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x3A\x00\x00\x00\x48\x00\x00\x00\x01\x00\x00\x00" +"\x3B\x00\x04\x00\x1B\x00\x00\x00\x49\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x4A\x00\x00\x00\x01\x00\x00\x00" +"\x3B\x00\x04\x00\x1B\x00\x00\x00\x4B\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\x12\x00\x00\x00\x3C\x00\x00\x00\x3B\x00\x00\x00\x3E\x00\x03\x00" +"\x39\x00\x00\x00\x3C\x00\x00\x00\x39\x00\x04\x00\x07\x00\x00\x00\x40\x00\x00\x00\x09\x00\x00\x00\x41\x00\x05\x00\x41\x00\x00\x00" +"\x42\x00\x00\x00\x3F\x00\x00\x00\x17\x00\x00\x00\x3E\x00\x03\x00\x42\x00\x00\x00\x40\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\x01\x00\x08\x00\x37\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\x07\x00" +"\x04\x00\x00\x00\x04\x00\x00\x00\x6D\x61\x69\x6E\x00\x00\x00\x00\x09\x00\x00\x00\x12\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\x09\x00\x00\x00\x6F\x75\x74\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x04\x00\x0E\x00\x00\x00\x73\x5F\x74\x30" +"\x00\x00\x00\x00\x05\x00\x03\x00\x12\x00\x00\x00\x74\x63\x00\x00\x05\x00\x05\x00\x19\x00\x00\x00\x65\x6E\x74\x69\x74\x79\x62\x6C" +"\x6F\x63\x6B\x00\x06\x00\x07\x00\x19\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\x19\x00\x00\x00\x01\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x00\x06\x00\x06\x00\x19\x00\x00\x00\x02\x00\x00\x00" +"\x6D\x5F\x6D\x6F\x64\x65\x6C\x69\x6E\x76\x00\x00\x06\x00\x06\x00\x19\x00\x00\x00\x03\x00\x00\x00\x65\x5F\x65\x79\x65\x70\x6F\x73" +"\x00\x00\x00\x00\x06\x00\x05\x00\x19\x00\x00\x00\x04\x00\x00\x00\x65\x5F\x74\x69\x6D\x65\x00\x00\x06\x00\x07\x00\x19\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\x19\x00\x00\x00\x06\x00\x00\x00" +"\x65\x70\x61\x64\x31\x00\x00\x00\x06\x00\x06\x00\x19\x00\x00\x00\x07\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x64\x69\x72\x00" +"\x06\x00\x05\x00\x19\x00\x00\x00\x08\x00\x00\x00\x65\x70\x61\x64\x32\x00\x00\x00\x06\x00\x06\x00\x19\x00\x00\x00\x09\x00\x00\x00" +"\x65\x5F\x6C\x69\x67\x68\x74\x5F\x6D\x75\x6C\x00\x06\x00\x05\x00\x19\x00\x00\x00\x0A\x00\x00\x00\x65\x70\x61\x64\x33\x00\x00\x00" +"\x06\x00\x06\x00\x19\x00\x00\x00\x0B\x00\x00\x00\x65\x5F\x6C\x6D\x73\x63\x61\x6C\x65\x73\x00\x00\x06\x00\x07\x00\x19\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\x19\x00\x00\x00\x0D\x00\x00\x00" +"\x65\x70\x61\x64\x34\x00\x00\x00\x06\x00\x07\x00\x19\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\x19\x00\x00\x00\x0F\x00\x00\x00\x65\x70\x61\x64\x35\x00\x00\x00\x06\x00\x06\x00\x19\x00\x00\x00" +"\x10\x00\x00\x00\x65\x5F\x67\x6C\x6F\x77\x6D\x6F\x64\x00\x00\x00\x06\x00\x05\x00\x19\x00\x00\x00\x11\x00\x00\x00\x65\x70\x61\x64" +"\x36\x00\x00\x00\x06\x00\x07\x00\x19\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\x19\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" +"\x19\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\x19\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\x19\x00\x00\x00\x16\x00\x00\x00" +"\x65\x70\x61\x64\x37\x00\x00\x00\x05\x00\x03\x00\x1B\x00\x00\x00\x00\x00\x00\x00\x05\x00\x05\x00\x34\x00\x00\x00\x6C\x69\x67\x68" +"\x74\x62\x6C\x6F\x63\x6B\x00\x00\x06\x00\x07\x00\x34\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\x34\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\x34\x00\x00\x00\x02\x00\x00\x00\x6C\x70\x61\x64\x31\x00\x00\x00\x06\x00\x07\x00\x34\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\x34\x00\x00\x00\x04\x00\x00\x00\x6C\x70\x61\x64" +"\x32\x00\x00\x00\x06\x00\x08\x00\x34\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\x34\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\x34\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" +"\x34\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" +"\x34\x00\x00\x00\x09\x00\x00\x00\x6C\x70\x61\x64\x33\x00\x00\x00\x05\x00\x03\x00\x36\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00" +"\x09\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x0E\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00" +"\x0E\x00\x00\x00\x21\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x12\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00" "\x18\x00\x00\x00\x06\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00\x19\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00" "\x19\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00\x19\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00" "\x10\x00\x00\x00\x48\x00\x04\x00\x19\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x19\x00\x00\x00\x01\x00\x00\x00" @@ -1451,8 +1452,8 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND #ifdef VKQUAKE {QR_VULKAN, -1, "bloom_filter", "\xFF\x53\x50\x56\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x2C\x00\x00\x00\x1F\x00\x00\x00\x4C\x00\x00\x00" -"\x40\x0F\x00\x00\x8C\x0F\x00\x00\xCC\x0B\x00\x00\x01\x00\x66\x33\x72\x5F\x62\x6C\x6F\x6F\x6D\x5F\x66\x69\x6C\x74\x65\x72\x00\x3F" -"\x33\x33\x33\x3F\x33\x33\x33\x3F\x33\x33\x33\x67\x03\x02\x23\x07\x00\x00\x01\x00\x01\x00\x08\x00\x52\x00\x00\x00\x00\x00\x00\x00" +"\x50\x0F\x00\x00\x9C\x0F\x00\x00\xDC\x0B\x00\x00\x01\x00\x66\x33\x72\x5F\x62\x6C\x6F\x6F\x6D\x5F\x66\x69\x6C\x74\x65\x72\x00\x3F" +"\x33\x33\x33\x3F\x33\x33\x33\x3F\x33\x33\x33\x00\x03\x02\x23\x07\x00\x00\x01\x00\x01\x00\x08\x00\x52\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" "\x22\x00\x00\x00\x3F\x00\x00\x00\x41\x00\x00\x00\x45\x00\x00\x00\x4D\x00\x00\x00\x4E\x00\x00\x00\x4F\x00\x00\x00\x50\x00\x00\x00" @@ -1514,104 +1515,105 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "\x48\x00\x05\x00\x19\x00\x00\x00\x14\x00\x00\x00\x23\x00\x00\x00\x90\x01\x00\x00\x48\x00\x05\x00\x19\x00\x00\x00\x15\x00\x00\x00" "\x23\x00\x00\x00\x94\x01\x00\x00\x48\x00\x05\x00\x19\x00\x00\x00\x16\x00\x00\x00\x23\x00\x00\x00\x98\x01\x00\x00\x47\x00\x03\x00" "\x19\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x1B\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x1B\x00\x00\x00" -"\x21\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x22\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x41\x00\x00\x00" -"\x1E\x00\x00\x00\x01\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00\x00\x00\x00\x00\x0B\x00\x00\x00\x00\x00\x00\x00\x47\x00\x03\x00" -"\x43\x00\x00\x00\x02\x00\x00\x00\x48\x00\x04\x00\x49\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x49\x00\x00\x00" -"\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00\x49\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00" -"\x48\x00\x05\x00\x49\x00\x00\x00\x01\x00\x00\x00\x23\x00\x00\x00\x40\x00\x00\x00\x48\x00\x05\x00\x49\x00\x00\x00\x02\x00\x00\x00" -"\x23\x00\x00\x00\x4C\x00\x00\x00\x48\x00\x05\x00\x49\x00\x00\x00\x03\x00\x00\x00\x23\x00\x00\x00\x50\x00\x00\x00\x48\x00\x05\x00" -"\x49\x00\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00\x5C\x00\x00\x00\x48\x00\x05\x00\x49\x00\x00\x00\x05\x00\x00\x00\x23\x00\x00\x00" -"\x60\x00\x00\x00\x48\x00\x05\x00\x49\x00\x00\x00\x06\x00\x00\x00\x23\x00\x00\x00\x6C\x00\x00\x00\x48\x00\x05\x00\x49\x00\x00\x00" -"\x07\x00\x00\x00\x23\x00\x00\x00\x70\x00\x00\x00\x48\x00\x05\x00\x49\x00\x00\x00\x08\x00\x00\x00\x23\x00\x00\x00\x80\x00\x00\x00" -"\x48\x00\x05\x00\x49\x00\x00\x00\x09\x00\x00\x00\x23\x00\x00\x00\x88\x00\x00\x00\x47\x00\x03\x00\x49\x00\x00\x00\x02\x00\x00\x00" -"\x47\x00\x04\x00\x4B\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x4B\x00\x00\x00\x21\x00\x00\x00\x01\x00\x00\x00" -"\x47\x00\x04\x00\x4D\x00\x00\x00\x1E\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x4E\x00\x00\x00\x1E\x00\x00\x00\x03\x00\x00\x00" -"\x47\x00\x04\x00\x4F\x00\x00\x00\x1E\x00\x00\x00\x04\x00\x00\x00\x47\x00\x04\x00\x50\x00\x00\x00\x1E\x00\x00\x00\x05\x00\x00\x00" -"\x47\x00\x04\x00\x51\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\x17\x00\x04\x00\x0B\x00\x00\x00\x06\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00" -"\x0C\x00\x00\x00\x06\x00\x00\x00\x0B\x00\x00\x00\x3B\x00\x04\x00\x0C\x00\x00\x00\x0D\x00\x00\x00\x06\x00\x00\x00\x32\x00\x04\x00" -"\x06\x00\x00\x00\x0E\x00\x00\x00\x00\x00\x80\x43\x32\x00\x04\x00\x06\x00\x00\x00\x0F\x00\x00\x00\x00\x80\x80\x43\x32\x00\x04\x00" -"\x06\x00\x00\x00\x10\x00\x00\x00\x00\x00\x81\x43\x20\x00\x04\x00\x12\x00\x00\x00\x07\x00\x00\x00\x07\x00\x00\x00\x18\x00\x04\x00" -"\x14\x00\x00\x00\x07\x00\x00\x00\x04\x00\x00\x00\x15\x00\x04\x00\x15\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x2B\x00\x04\x00" -"\x15\x00\x00\x00\x16\x00\x00\x00\x04\x00\x00\x00\x1C\x00\x04\x00\x17\x00\x00\x00\x07\x00\x00\x00\x16\x00\x00\x00\x17\x00\x04\x00" -"\x18\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x1E\x00\x19\x00\x19\x00\x00\x00\x14\x00\x00\x00\x14\x00\x00\x00\x14\x00\x00\x00" -"\x0B\x00\x00\x00\x06\x00\x00\x00\x0B\x00\x00\x00\x06\x00\x00\x00\x0B\x00\x00\x00\x06\x00\x00\x00\x0B\x00\x00\x00\x06\x00\x00\x00" -"\x17\x00\x00\x00\x0B\x00\x00\x00\x06\x00\x00\x00\x0B\x00\x00\x00\x06\x00\x00\x00\x0B\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00" -"\x07\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x18\x00\x00\x00\x20\x00\x04\x00\x1A\x00\x00\x00\x02\x00\x00\x00\x19\x00\x00\x00" -"\x3B\x00\x04\x00\x1A\x00\x00\x00\x1B\x00\x00\x00\x02\x00\x00\x00\x15\x00\x04\x00\x1C\x00\x00\x00\x20\x00\x00\x00\x01\x00\x00\x00" -"\x2B\x00\x04\x00\x1C\x00\x00\x00\x1D\x00\x00\x00\x00\x00\x00\x00\x20\x00\x04\x00\x1E\x00\x00\x00\x02\x00\x00\x00\x14\x00\x00\x00" -"\x20\x00\x04\x00\x21\x00\x00\x00\x01\x00\x00\x00\x0B\x00\x00\x00\x3B\x00\x04\x00\x21\x00\x00\x00\x22\x00\x00\x00\x01\x00\x00\x00" -"\x2B\x00\x04\x00\x06\x00\x00\x00\x24\x00\x00\x00\x00\x00\x80\x3F\x2B\x00\x04\x00\x06\x00\x00\x00\x2A\x00\x00\x00\x00\x00\x80\xBF" -"\x2B\x00\x04\x00\x15\x00\x00\x00\x2B\x00\x00\x00\x01\x00\x00\x00\x20\x00\x04\x00\x2C\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00" -"\x2B\x00\x04\x00\x15\x00\x00\x00\x31\x00\x00\x00\x02\x00\x00\x00\x2B\x00\x04\x00\x15\x00\x00\x00\x34\x00\x00\x00\x03\x00\x00\x00" -"\x2B\x00\x04\x00\x06\x00\x00\x00\x38\x00\x00\x00\x00\x00\x00\x40\x20\x00\x04\x00\x3E\x00\x00\x00\x03\x00\x00\x00\x18\x00\x00\x00" -"\x3B\x00\x04\x00\x3E\x00\x00\x00\x3F\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00\x40\x00\x00\x00\x01\x00\x00\x00\x18\x00\x00\x00" -"\x3B\x00\x04\x00\x40\x00\x00\x00\x41\x00\x00\x00\x01\x00\x00\x00\x1E\x00\x03\x00\x43\x00\x00\x00\x07\x00\x00\x00\x20\x00\x04\x00" -"\x44\x00\x00\x00\x03\x00\x00\x00\x43\x00\x00\x00\x3B\x00\x04\x00\x44\x00\x00\x00\x45\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00" -"\x47\x00\x00\x00\x03\x00\x00\x00\x07\x00\x00\x00\x1E\x00\x0C\x00\x49\x00\x00\x00\x14\x00\x00\x00\x0B\x00\x00\x00\x06\x00\x00\x00" -"\x0B\x00\x00\x00\x06\x00\x00\x00\x0B\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x18\x00\x00\x00\x18\x00\x00\x00\x20\x00\x04\x00" -"\x4A\x00\x00\x00\x02\x00\x00\x00\x49\x00\x00\x00\x3B\x00\x04\x00\x4A\x00\x00\x00\x4B\x00\x00\x00\x02\x00\x00\x00\x20\x00\x04\x00" -"\x4C\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00\x4C\x00\x00\x00\x4D\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00" -"\x40\x00\x00\x00\x4E\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x21\x00\x00\x00\x4F\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00" -"\x21\x00\x00\x00\x50\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x21\x00\x00\x00\x51\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\x50\x00\x06\x00\x0B\x00\x00\x00" -"\x11\x00\x00\x00\x0E\x00\x00\x00\x0F\x00\x00\x00\x10\x00\x00\x00\x3E\x00\x03\x00\x0D\x00\x00\x00\x11\x00\x00\x00\x3D\x00\x04\x00" -"\x18\x00\x00\x00\x42\x00\x00\x00\x41\x00\x00\x00\x3E\x00\x03\x00\x3F\x00\x00\x00\x42\x00\x00\x00\x39\x00\x04\x00\x07\x00\x00\x00" -"\x46\x00\x00\x00\x09\x00\x00\x00\x41\x00\x05\x00\x47\x00\x00\x00\x48\x00\x00\x00\x45\x00\x00\x00\x1D\x00\x00\x00\x3E\x00\x03\x00" -"\x48\x00\x00\x00\x46\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\x12\x00\x00\x00\x13\x00\x00\x00\x07\x00\x00\x00\x41\x00\x05\x00" -"\x1E\x00\x00\x00\x1F\x00\x00\x00\x1B\x00\x00\x00\x1D\x00\x00\x00\x3D\x00\x04\x00\x14\x00\x00\x00\x20\x00\x00\x00\x1F\x00\x00\x00" -"\x3D\x00\x04\x00\x0B\x00\x00\x00\x23\x00\x00\x00\x22\x00\x00\x00\x51\x00\x05\x00\x06\x00\x00\x00\x25\x00\x00\x00\x23\x00\x00\x00" -"\x00\x00\x00\x00\x51\x00\x05\x00\x06\x00\x00\x00\x26\x00\x00\x00\x23\x00\x00\x00\x01\x00\x00\x00\x51\x00\x05\x00\x06\x00\x00\x00" -"\x27\x00\x00\x00\x23\x00\x00\x00\x02\x00\x00\x00\x50\x00\x07\x00\x07\x00\x00\x00\x28\x00\x00\x00\x25\x00\x00\x00\x26\x00\x00\x00" -"\x27\x00\x00\x00\x24\x00\x00\x00\x91\x00\x05\x00\x07\x00\x00\x00\x29\x00\x00\x00\x20\x00\x00\x00\x28\x00\x00\x00\x3E\x00\x03\x00" -"\x13\x00\x00\x00\x29\x00\x00\x00\x41\x00\x05\x00\x2C\x00\x00\x00\x2D\x00\x00\x00\x13\x00\x00\x00\x2B\x00\x00\x00\x3D\x00\x04\x00" -"\x06\x00\x00\x00\x2E\x00\x00\x00\x2D\x00\x00\x00\x85\x00\x05\x00\x06\x00\x00\x00\x2F\x00\x00\x00\x2E\x00\x00\x00\x2A\x00\x00\x00" -"\x41\x00\x05\x00\x2C\x00\x00\x00\x30\x00\x00\x00\x13\x00\x00\x00\x2B\x00\x00\x00\x3E\x00\x03\x00\x30\x00\x00\x00\x2F\x00\x00\x00" -"\x41\x00\x05\x00\x2C\x00\x00\x00\x32\x00\x00\x00\x13\x00\x00\x00\x31\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x33\x00\x00\x00" -"\x32\x00\x00\x00\x41\x00\x05\x00\x2C\x00\x00\x00\x35\x00\x00\x00\x13\x00\x00\x00\x34\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00" -"\x36\x00\x00\x00\x35\x00\x00\x00\x81\x00\x05\x00\x06\x00\x00\x00\x37\x00\x00\x00\x33\x00\x00\x00\x36\x00\x00\x00\x88\x00\x05\x00" -"\x06\x00\x00\x00\x39\x00\x00\x00\x37\x00\x00\x00\x38\x00\x00\x00\x41\x00\x05\x00\x2C\x00\x00\x00\x3A\x00\x00\x00\x13\x00\x00\x00" -"\x31\x00\x00\x00\x3E\x00\x03\x00\x3A\x00\x00\x00\x39\x00\x00\x00\x3D\x00\x04\x00\x07\x00\x00\x00\x3B\x00\x00\x00\x13\x00\x00\x00" -"\xFE\x00\x02\x00\x3B\x00\x00\x00\x38\x00\x01\x00\x03\x02\x23\x07\x00\x00\x01\x00\x01\x00\x08\x00\x2F\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\x07\x00\x04\x00\x00\x00\x04\x00\x00\x00\x6D\x61\x69\x6E\x00\x00\x00\x00" -"\x10\x00\x00\x00\x18\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\x07\x00\x09\x00\x00\x00\x63\x76\x61\x72\x5F\x72\x5F\x62" -"\x6C\x6F\x6F\x6D\x5F\x66\x69\x6C\x74\x65\x72\x00\x05\x00\x05\x00\x10\x00\x00\x00\x6F\x75\x74\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00" -"\x05\x00\x04\x00\x14\x00\x00\x00\x73\x5F\x74\x30\x00\x00\x00\x00\x05\x00\x03\x00\x18\x00\x00\x00\x74\x63\x00\x00\x05\x00\x05\x00" -"\x29\x00\x00\x00\x65\x6E\x74\x69\x74\x79\x62\x6C\x6F\x63\x6B\x00\x06\x00\x07\x00\x29\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\x29\x00\x00\x00\x01\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x00" -"\x06\x00\x06\x00\x29\x00\x00\x00\x02\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x69\x6E\x76\x00\x00\x06\x00\x06\x00\x29\x00\x00\x00" -"\x03\x00\x00\x00\x65\x5F\x65\x79\x65\x70\x6F\x73\x00\x00\x00\x00\x06\x00\x05\x00\x29\x00\x00\x00\x04\x00\x00\x00\x65\x5F\x74\x69" -"\x6D\x65\x00\x00\x06\x00\x07\x00\x29\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\x29\x00\x00\x00\x06\x00\x00\x00\x65\x70\x61\x64\x31\x00\x00\x00\x06\x00\x06\x00\x29\x00\x00\x00\x07\x00\x00\x00" -"\x65\x5F\x6C\x69\x67\x68\x74\x5F\x64\x69\x72\x00\x06\x00\x05\x00\x29\x00\x00\x00\x08\x00\x00\x00\x65\x70\x61\x64\x32\x00\x00\x00" -"\x06\x00\x06\x00\x29\x00\x00\x00\x09\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x6D\x75\x6C\x00\x06\x00\x05\x00\x29\x00\x00\x00" -"\x0A\x00\x00\x00\x65\x70\x61\x64\x33\x00\x00\x00\x06\x00\x06\x00\x29\x00\x00\x00\x0B\x00\x00\x00\x65\x5F\x6C\x6D\x73\x63\x61\x6C" -"\x65\x73\x00\x00\x06\x00\x07\x00\x29\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\x29\x00\x00\x00\x0D\x00\x00\x00\x65\x70\x61\x64\x34\x00\x00\x00\x06\x00\x07\x00\x29\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\x29\x00\x00\x00\x0F\x00\x00\x00\x65\x70\x61\x64" -"\x35\x00\x00\x00\x06\x00\x06\x00\x29\x00\x00\x00\x10\x00\x00\x00\x65\x5F\x67\x6C\x6F\x77\x6D\x6F\x64\x00\x00\x00\x06\x00\x05\x00" -"\x29\x00\x00\x00\x11\x00\x00\x00\x65\x70\x61\x64\x36\x00\x00\x00\x06\x00\x07\x00\x29\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\x29\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\x29\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\x29\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\x29\x00\x00\x00\x16\x00\x00\x00\x65\x70\x61\x64\x37\x00\x00\x00\x05\x00\x03\x00\x2B\x00\x00\x00\x00\x00\x00\x00" -"\x05\x00\x05\x00\x2C\x00\x00\x00\x6C\x69\x67\x68\x74\x62\x6C\x6F\x63\x6B\x00\x00\x06\x00\x07\x00\x2C\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\x2C\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\x2C\x00\x00\x00\x02\x00\x00\x00\x6C\x70\x61\x64\x31\x00\x00\x00" -"\x06\x00\x07\x00\x2C\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" -"\x2C\x00\x00\x00\x04\x00\x00\x00\x6C\x70\x61\x64\x32\x00\x00\x00\x06\x00\x08\x00\x2C\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\x2C\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\x2C\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\x2C\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\x2C\x00\x00\x00\x09\x00\x00\x00\x6C\x70\x61\x64\x33\x00\x00\x00\x05\x00\x03\x00" -"\x2E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x0A\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x47\x00\x04\x00\x0B\x00\x00\x00" -"\x01\x00\x00\x00\x01\x01\x00\x00\x47\x00\x04\x00\x0C\x00\x00\x00\x01\x00\x00\x00\x02\x01\x00\x00\x47\x00\x04\x00\x10\x00\x00\x00" -"\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x14\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x14\x00\x00\x00" -"\x21\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x28\x00\x00\x00\x06\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00\x29\x00\x00\x00" +"\x21\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x22\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x3F\x00\x00\x00" +"\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x41\x00\x00\x00\x1E\x00\x00\x00\x01\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00" +"\x00\x00\x00\x00\x0B\x00\x00\x00\x00\x00\x00\x00\x47\x00\x03\x00\x43\x00\x00\x00\x02\x00\x00\x00\x48\x00\x04\x00\x49\x00\x00\x00" +"\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x49\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00" +"\x49\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x05\x00\x49\x00\x00\x00\x01\x00\x00\x00\x23\x00\x00\x00" +"\x40\x00\x00\x00\x48\x00\x05\x00\x49\x00\x00\x00\x02\x00\x00\x00\x23\x00\x00\x00\x4C\x00\x00\x00\x48\x00\x05\x00\x49\x00\x00\x00" +"\x03\x00\x00\x00\x23\x00\x00\x00\x50\x00\x00\x00\x48\x00\x05\x00\x49\x00\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00\x5C\x00\x00\x00" +"\x48\x00\x05\x00\x49\x00\x00\x00\x05\x00\x00\x00\x23\x00\x00\x00\x60\x00\x00\x00\x48\x00\x05\x00\x49\x00\x00\x00\x06\x00\x00\x00" +"\x23\x00\x00\x00\x6C\x00\x00\x00\x48\x00\x05\x00\x49\x00\x00\x00\x07\x00\x00\x00\x23\x00\x00\x00\x70\x00\x00\x00\x48\x00\x05\x00" +"\x49\x00\x00\x00\x08\x00\x00\x00\x23\x00\x00\x00\x80\x00\x00\x00\x48\x00\x05\x00\x49\x00\x00\x00\x09\x00\x00\x00\x23\x00\x00\x00" +"\x88\x00\x00\x00\x47\x00\x03\x00\x49\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x4B\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00" +"\x47\x00\x04\x00\x4B\x00\x00\x00\x21\x00\x00\x00\x01\x00\x00\x00\x47\x00\x04\x00\x4D\x00\x00\x00\x1E\x00\x00\x00\x02\x00\x00\x00" +"\x47\x00\x04\x00\x4E\x00\x00\x00\x1E\x00\x00\x00\x03\x00\x00\x00\x47\x00\x04\x00\x4F\x00\x00\x00\x1E\x00\x00\x00\x04\x00\x00\x00" +"\x47\x00\x04\x00\x50\x00\x00\x00\x1E\x00\x00\x00\x05\x00\x00\x00\x47\x00\x04\x00\x51\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\x17\x00\x04\x00" +"\x0B\x00\x00\x00\x06\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00\x0C\x00\x00\x00\x06\x00\x00\x00\x0B\x00\x00\x00\x3B\x00\x04\x00" +"\x0C\x00\x00\x00\x0D\x00\x00\x00\x06\x00\x00\x00\x32\x00\x04\x00\x06\x00\x00\x00\x0E\x00\x00\x00\x00\x00\x80\x43\x32\x00\x04\x00" +"\x06\x00\x00\x00\x0F\x00\x00\x00\x00\x80\x80\x43\x32\x00\x04\x00\x06\x00\x00\x00\x10\x00\x00\x00\x00\x00\x81\x43\x20\x00\x04\x00" +"\x12\x00\x00\x00\x07\x00\x00\x00\x07\x00\x00\x00\x18\x00\x04\x00\x14\x00\x00\x00\x07\x00\x00\x00\x04\x00\x00\x00\x15\x00\x04\x00" +"\x15\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x2B\x00\x04\x00\x15\x00\x00\x00\x16\x00\x00\x00\x04\x00\x00\x00\x1C\x00\x04\x00" +"\x17\x00\x00\x00\x07\x00\x00\x00\x16\x00\x00\x00\x17\x00\x04\x00\x18\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x1E\x00\x19\x00" +"\x19\x00\x00\x00\x14\x00\x00\x00\x14\x00\x00\x00\x14\x00\x00\x00\x0B\x00\x00\x00\x06\x00\x00\x00\x0B\x00\x00\x00\x06\x00\x00\x00" +"\x0B\x00\x00\x00\x06\x00\x00\x00\x0B\x00\x00\x00\x06\x00\x00\x00\x17\x00\x00\x00\x0B\x00\x00\x00\x06\x00\x00\x00\x0B\x00\x00\x00" +"\x06\x00\x00\x00\x0B\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x18\x00\x00\x00" +"\x20\x00\x04\x00\x1A\x00\x00\x00\x02\x00\x00\x00\x19\x00\x00\x00\x3B\x00\x04\x00\x1A\x00\x00\x00\x1B\x00\x00\x00\x02\x00\x00\x00" +"\x15\x00\x04\x00\x1C\x00\x00\x00\x20\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00\x1C\x00\x00\x00\x1D\x00\x00\x00\x00\x00\x00\x00" +"\x20\x00\x04\x00\x1E\x00\x00\x00\x02\x00\x00\x00\x14\x00\x00\x00\x20\x00\x04\x00\x21\x00\x00\x00\x01\x00\x00\x00\x0B\x00\x00\x00" +"\x3B\x00\x04\x00\x21\x00\x00\x00\x22\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00\x06\x00\x00\x00\x24\x00\x00\x00\x00\x00\x80\x3F" +"\x2B\x00\x04\x00\x06\x00\x00\x00\x2A\x00\x00\x00\x00\x00\x80\xBF\x2B\x00\x04\x00\x15\x00\x00\x00\x2B\x00\x00\x00\x01\x00\x00\x00" +"\x20\x00\x04\x00\x2C\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x2B\x00\x04\x00\x15\x00\x00\x00\x31\x00\x00\x00\x02\x00\x00\x00" +"\x2B\x00\x04\x00\x15\x00\x00\x00\x34\x00\x00\x00\x03\x00\x00\x00\x2B\x00\x04\x00\x06\x00\x00\x00\x38\x00\x00\x00\x00\x00\x00\x40" +"\x20\x00\x04\x00\x3E\x00\x00\x00\x03\x00\x00\x00\x18\x00\x00\x00\x3B\x00\x04\x00\x3E\x00\x00\x00\x3F\x00\x00\x00\x03\x00\x00\x00" +"\x20\x00\x04\x00\x40\x00\x00\x00\x01\x00\x00\x00\x18\x00\x00\x00\x3B\x00\x04\x00\x40\x00\x00\x00\x41\x00\x00\x00\x01\x00\x00\x00" +"\x1E\x00\x03\x00\x43\x00\x00\x00\x07\x00\x00\x00\x20\x00\x04\x00\x44\x00\x00\x00\x03\x00\x00\x00\x43\x00\x00\x00\x3B\x00\x04\x00" +"\x44\x00\x00\x00\x45\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00\x47\x00\x00\x00\x03\x00\x00\x00\x07\x00\x00\x00\x1E\x00\x0C\x00" +"\x49\x00\x00\x00\x14\x00\x00\x00\x0B\x00\x00\x00\x06\x00\x00\x00\x0B\x00\x00\x00\x06\x00\x00\x00\x0B\x00\x00\x00\x06\x00\x00\x00" +"\x07\x00\x00\x00\x18\x00\x00\x00\x18\x00\x00\x00\x20\x00\x04\x00\x4A\x00\x00\x00\x02\x00\x00\x00\x49\x00\x00\x00\x3B\x00\x04\x00" +"\x4A\x00\x00\x00\x4B\x00\x00\x00\x02\x00\x00\x00\x20\x00\x04\x00\x4C\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00" +"\x4C\x00\x00\x00\x4D\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x40\x00\x00\x00\x4E\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00" +"\x21\x00\x00\x00\x4F\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x21\x00\x00\x00\x50\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00" +"\x21\x00\x00\x00\x51\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\x50\x00\x06\x00\x0B\x00\x00\x00\x11\x00\x00\x00\x0E\x00\x00\x00\x0F\x00\x00\x00\x10\x00\x00\x00" +"\x3E\x00\x03\x00\x0D\x00\x00\x00\x11\x00\x00\x00\x3D\x00\x04\x00\x18\x00\x00\x00\x42\x00\x00\x00\x41\x00\x00\x00\x3E\x00\x03\x00" +"\x3F\x00\x00\x00\x42\x00\x00\x00\x39\x00\x04\x00\x07\x00\x00\x00\x46\x00\x00\x00\x09\x00\x00\x00\x41\x00\x05\x00\x47\x00\x00\x00" +"\x48\x00\x00\x00\x45\x00\x00\x00\x1D\x00\x00\x00\x3E\x00\x03\x00\x48\x00\x00\x00\x46\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" +"\x12\x00\x00\x00\x13\x00\x00\x00\x07\x00\x00\x00\x41\x00\x05\x00\x1E\x00\x00\x00\x1F\x00\x00\x00\x1B\x00\x00\x00\x1D\x00\x00\x00" +"\x3D\x00\x04\x00\x14\x00\x00\x00\x20\x00\x00\x00\x1F\x00\x00\x00\x3D\x00\x04\x00\x0B\x00\x00\x00\x23\x00\x00\x00\x22\x00\x00\x00" +"\x51\x00\x05\x00\x06\x00\x00\x00\x25\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x51\x00\x05\x00\x06\x00\x00\x00\x26\x00\x00\x00" +"\x23\x00\x00\x00\x01\x00\x00\x00\x51\x00\x05\x00\x06\x00\x00\x00\x27\x00\x00\x00\x23\x00\x00\x00\x02\x00\x00\x00\x50\x00\x07\x00" +"\x07\x00\x00\x00\x28\x00\x00\x00\x25\x00\x00\x00\x26\x00\x00\x00\x27\x00\x00\x00\x24\x00\x00\x00\x91\x00\x05\x00\x07\x00\x00\x00" +"\x29\x00\x00\x00\x20\x00\x00\x00\x28\x00\x00\x00\x3E\x00\x03\x00\x13\x00\x00\x00\x29\x00\x00\x00\x41\x00\x05\x00\x2C\x00\x00\x00" +"\x2D\x00\x00\x00\x13\x00\x00\x00\x2B\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x2E\x00\x00\x00\x2D\x00\x00\x00\x85\x00\x05\x00" +"\x06\x00\x00\x00\x2F\x00\x00\x00\x2E\x00\x00\x00\x2A\x00\x00\x00\x41\x00\x05\x00\x2C\x00\x00\x00\x30\x00\x00\x00\x13\x00\x00\x00" +"\x2B\x00\x00\x00\x3E\x00\x03\x00\x30\x00\x00\x00\x2F\x00\x00\x00\x41\x00\x05\x00\x2C\x00\x00\x00\x32\x00\x00\x00\x13\x00\x00\x00" +"\x31\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x33\x00\x00\x00\x32\x00\x00\x00\x41\x00\x05\x00\x2C\x00\x00\x00\x35\x00\x00\x00" +"\x13\x00\x00\x00\x34\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x36\x00\x00\x00\x35\x00\x00\x00\x81\x00\x05\x00\x06\x00\x00\x00" +"\x37\x00\x00\x00\x33\x00\x00\x00\x36\x00\x00\x00\x88\x00\x05\x00\x06\x00\x00\x00\x39\x00\x00\x00\x37\x00\x00\x00\x38\x00\x00\x00" +"\x41\x00\x05\x00\x2C\x00\x00\x00\x3A\x00\x00\x00\x13\x00\x00\x00\x31\x00\x00\x00\x3E\x00\x03\x00\x3A\x00\x00\x00\x39\x00\x00\x00" +"\x3D\x00\x04\x00\x07\x00\x00\x00\x3B\x00\x00\x00\x13\x00\x00\x00\xFE\x00\x02\x00\x3B\x00\x00\x00\x38\x00\x01\x00\x03\x02\x23\x07" +"\x00\x00\x01\x00\x01\x00\x08\x00\x2F\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\x07\x00" +"\x04\x00\x00\x00\x04\x00\x00\x00\x6D\x61\x69\x6E\x00\x00\x00\x00\x10\x00\x00\x00\x18\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\x07\x00\x09\x00\x00\x00\x63\x76\x61\x72\x5F\x72\x5F\x62\x6C\x6F\x6F\x6D\x5F\x66\x69\x6C\x74\x65\x72\x00\x05\x00\x05\x00" +"\x10\x00\x00\x00\x6F\x75\x74\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x04\x00\x14\x00\x00\x00\x73\x5F\x74\x30\x00\x00\x00\x00" +"\x05\x00\x03\x00\x18\x00\x00\x00\x74\x63\x00\x00\x05\x00\x05\x00\x29\x00\x00\x00\x65\x6E\x74\x69\x74\x79\x62\x6C\x6F\x63\x6B\x00" +"\x06\x00\x07\x00\x29\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" +"\x29\x00\x00\x00\x01\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x00\x06\x00\x06\x00\x29\x00\x00\x00\x02\x00\x00\x00\x6D\x5F\x6D\x6F" +"\x64\x65\x6C\x69\x6E\x76\x00\x00\x06\x00\x06\x00\x29\x00\x00\x00\x03\x00\x00\x00\x65\x5F\x65\x79\x65\x70\x6F\x73\x00\x00\x00\x00" +"\x06\x00\x05\x00\x29\x00\x00\x00\x04\x00\x00\x00\x65\x5F\x74\x69\x6D\x65\x00\x00\x06\x00\x07\x00\x29\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\x29\x00\x00\x00\x06\x00\x00\x00\x65\x70\x61\x64" +"\x31\x00\x00\x00\x06\x00\x06\x00\x29\x00\x00\x00\x07\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x64\x69\x72\x00\x06\x00\x05\x00" +"\x29\x00\x00\x00\x08\x00\x00\x00\x65\x70\x61\x64\x32\x00\x00\x00\x06\x00\x06\x00\x29\x00\x00\x00\x09\x00\x00\x00\x65\x5F\x6C\x69" +"\x67\x68\x74\x5F\x6D\x75\x6C\x00\x06\x00\x05\x00\x29\x00\x00\x00\x0A\x00\x00\x00\x65\x70\x61\x64\x33\x00\x00\x00\x06\x00\x06\x00" +"\x29\x00\x00\x00\x0B\x00\x00\x00\x65\x5F\x6C\x6D\x73\x63\x61\x6C\x65\x73\x00\x00\x06\x00\x07\x00\x29\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\x29\x00\x00\x00\x0D\x00\x00\x00\x65\x70\x61\x64" +"\x34\x00\x00\x00\x06\x00\x07\x00\x29\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\x29\x00\x00\x00\x0F\x00\x00\x00\x65\x70\x61\x64\x35\x00\x00\x00\x06\x00\x06\x00\x29\x00\x00\x00\x10\x00\x00\x00" +"\x65\x5F\x67\x6C\x6F\x77\x6D\x6F\x64\x00\x00\x00\x06\x00\x05\x00\x29\x00\x00\x00\x11\x00\x00\x00\x65\x70\x61\x64\x36\x00\x00\x00" +"\x06\x00\x07\x00\x29\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" +"\x29\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\x29\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\x29\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\x29\x00\x00\x00\x16\x00\x00\x00\x65\x70\x61\x64" +"\x37\x00\x00\x00\x05\x00\x03\x00\x2B\x00\x00\x00\x00\x00\x00\x00\x05\x00\x05\x00\x2C\x00\x00\x00\x6C\x69\x67\x68\x74\x62\x6C\x6F" +"\x63\x6B\x00\x00\x06\x00\x07\x00\x2C\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\x2C\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" +"\x2C\x00\x00\x00\x02\x00\x00\x00\x6C\x70\x61\x64\x31\x00\x00\x00\x06\x00\x07\x00\x2C\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\x2C\x00\x00\x00\x04\x00\x00\x00\x6C\x70\x61\x64\x32\x00\x00\x00" +"\x06\x00\x08\x00\x2C\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\x2C\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" +"\x2C\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\x2C\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\x2C\x00\x00\x00" +"\x09\x00\x00\x00\x6C\x70\x61\x64\x33\x00\x00\x00\x05\x00\x03\x00\x2E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x0A\x00\x00\x00" +"\x01\x00\x00\x00\x00\x01\x00\x00\x47\x00\x04\x00\x0B\x00\x00\x00\x01\x00\x00\x00\x01\x01\x00\x00\x47\x00\x04\x00\x0C\x00\x00\x00" +"\x01\x00\x00\x00\x02\x01\x00\x00\x47\x00\x04\x00\x10\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x14\x00\x00\x00" +"\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x14\x00\x00\x00\x21\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x18\x00\x00\x00" +"\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x28\x00\x00\x00\x06\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00\x29\x00\x00\x00" "\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x29\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00" "\x29\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00\x29\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00" "\x48\x00\x05\x00\x29\x00\x00\x00\x01\x00\x00\x00\x23\x00\x00\x00\x40\x00\x00\x00\x48\x00\x05\x00\x29\x00\x00\x00\x01\x00\x00\x00" @@ -1710,8 +1712,8 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND #ifdef VKQUAKE {QR_VULKAN, -1, "bloom_final", "\xFF\x53\x50\x56\x01\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x2C\x00\x00\x00\x27\x00\x00\x00\x54\x00\x00\x00" -"\xC0\x0E\x00\x00\x14\x0F\x00\x00\x34\x0C\x00\x00\x01\x00\x66\x31\x72\x5F\x62\x6C\x6F\x6F\x6D\x00\x00\x00\x00\x00\x01\x01\x66\x31" -"\x72\x5F\x62\x6C\x6F\x6F\x6D\x5F\x72\x65\x74\x61\x69\x6E\x00\x3F\x80\x00\x00\x6C\x03\x02\x23\x07\x00\x00\x01\x00\x01\x00\x08\x00" +"\xD0\x0E\x00\x00\x24\x0F\x00\x00\x44\x0C\x00\x00\x01\x00\x66\x31\x72\x5F\x62\x6C\x6F\x6F\x6D\x00\x00\x00\x00\x00\x01\x01\x66\x31" +"\x72\x5F\x62\x6C\x6F\x6F\x6D\x5F\x72\x65\x74\x61\x69\x6E\x00\x3F\x80\x00\x00\x00\x03\x02\x23\x07\x00\x00\x01\x00\x01\x00\x08\x00" "\x4E\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\x3B\x00\x00\x00\x3F\x00\x00\x00\x49\x00\x00\x00\x4A\x00\x00\x00" @@ -1771,102 +1773,103 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "\x13\x00\x00\x00\x14\x00\x00\x00\x23\x00\x00\x00\x90\x01\x00\x00\x48\x00\x05\x00\x13\x00\x00\x00\x15\x00\x00\x00\x23\x00\x00\x00" "\x94\x01\x00\x00\x48\x00\x05\x00\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\x3B\x00\x00\x00\x1E\x00\x00\x00" -"\x01\x00\x00\x00\x48\x00\x05\x00\x3D\x00\x00\x00\x00\x00\x00\x00\x0B\x00\x00\x00\x00\x00\x00\x00\x47\x00\x03\x00\x3D\x00\x00\x00" -"\x02\x00\x00\x00\x47\x00\x04\x00\x43\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x47\x00\x04\x00\x44\x00\x00\x00\x01\x00\x00\x00" -"\x01\x01\x00\x00\x48\x00\x04\x00\x45\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x45\x00\x00\x00\x00\x00\x00\x00" -"\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00\x45\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x05\x00" -"\x45\x00\x00\x00\x01\x00\x00\x00\x23\x00\x00\x00\x40\x00\x00\x00\x48\x00\x05\x00\x45\x00\x00\x00\x02\x00\x00\x00\x23\x00\x00\x00" -"\x4C\x00\x00\x00\x48\x00\x05\x00\x45\x00\x00\x00\x03\x00\x00\x00\x23\x00\x00\x00\x50\x00\x00\x00\x48\x00\x05\x00\x45\x00\x00\x00" -"\x04\x00\x00\x00\x23\x00\x00\x00\x5C\x00\x00\x00\x48\x00\x05\x00\x45\x00\x00\x00\x05\x00\x00\x00\x23\x00\x00\x00\x60\x00\x00\x00" -"\x48\x00\x05\x00\x45\x00\x00\x00\x06\x00\x00\x00\x23\x00\x00\x00\x6C\x00\x00\x00\x48\x00\x05\x00\x45\x00\x00\x00\x07\x00\x00\x00" -"\x23\x00\x00\x00\x70\x00\x00\x00\x48\x00\x05\x00\x45\x00\x00\x00\x08\x00\x00\x00\x23\x00\x00\x00\x80\x00\x00\x00\x48\x00\x05\x00" -"\x45\x00\x00\x00\x09\x00\x00\x00\x23\x00\x00\x00\x88\x00\x00\x00\x47\x00\x03\x00\x45\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00" -"\x47\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x47\x00\x00\x00\x21\x00\x00\x00\x01\x00\x00\x00\x47\x00\x04\x00" -"\x49\x00\x00\x00\x1E\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x4A\x00\x00\x00\x1E\x00\x00\x00\x03\x00\x00\x00\x47\x00\x04\x00" -"\x4B\x00\x00\x00\x1E\x00\x00\x00\x04\x00\x00\x00\x47\x00\x04\x00\x4C\x00\x00\x00\x1E\x00\x00\x00\x05\x00\x00\x00\x47\x00\x04\x00" -"\x4D\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\x15\x00\x04\x00\x0F\x00\x00\x00" -"\x20\x00\x00\x00\x00\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00\x10\x00\x00\x00\x04\x00\x00\x00\x1C\x00\x04\x00\x11\x00\x00\x00" -"\x07\x00\x00\x00\x10\x00\x00\x00\x17\x00\x04\x00\x12\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x1E\x00\x19\x00\x13\x00\x00\x00" -"\x0D\x00\x00\x00\x0D\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\x0E\x00\x00\x00\x06\x00\x00\x00\x11\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\x07\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x12\x00\x00\x00\x20\x00\x04\x00" -"\x14\x00\x00\x00\x02\x00\x00\x00\x13\x00\x00\x00\x3B\x00\x04\x00\x14\x00\x00\x00\x15\x00\x00\x00\x02\x00\x00\x00\x15\x00\x04\x00" -"\x16\x00\x00\x00\x20\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00\x16\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x20\x00\x04\x00" -"\x18\x00\x00\x00\x02\x00\x00\x00\x0D\x00\x00\x00\x20\x00\x04\x00\x1B\x00\x00\x00\x01\x00\x00\x00\x0E\x00\x00\x00\x3B\x00\x04\x00" -"\x1B\x00\x00\x00\x1C\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00\x06\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x80\x3F\x2B\x00\x04\x00" -"\x06\x00\x00\x00\x24\x00\x00\x00\x00\x00\x80\xBF\x2B\x00\x04\x00\x0F\x00\x00\x00\x25\x00\x00\x00\x01\x00\x00\x00\x20\x00\x04\x00" -"\x26\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00\x2B\x00\x00\x00\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\x12\x00\x00\x00\x3B\x00\x04\x00\x38\x00\x00\x00\x39\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00" -"\x3A\x00\x00\x00\x01\x00\x00\x00\x12\x00\x00\x00\x3B\x00\x04\x00\x3A\x00\x00\x00\x3B\x00\x00\x00\x01\x00\x00\x00\x1E\x00\x03\x00" -"\x3D\x00\x00\x00\x07\x00\x00\x00\x20\x00\x04\x00\x3E\x00\x00\x00\x03\x00\x00\x00\x3D\x00\x00\x00\x3B\x00\x04\x00\x3E\x00\x00\x00" -"\x3F\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00\x41\x00\x00\x00\x03\x00\x00\x00\x07\x00\x00\x00\x32\x00\x04\x00\x06\x00\x00\x00" -"\x43\x00\x00\x00\x00\x00\x80\x43\x32\x00\x04\x00\x06\x00\x00\x00\x44\x00\x00\x00\x00\x80\x80\x43\x1E\x00\x0C\x00\x45\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\x46\x00\x00\x00\x02\x00\x00\x00\x45\x00\x00\x00\x3B\x00\x04\x00\x46\x00\x00\x00" -"\x47\x00\x00\x00\x02\x00\x00\x00\x20\x00\x04\x00\x48\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00\x48\x00\x00\x00" -"\x49\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x3A\x00\x00\x00\x4A\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00" -"\x4B\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x4C\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00" -"\x4D\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\x12\x00\x00\x00\x3C\x00\x00\x00\x3B\x00\x00\x00\x3E\x00\x03\x00\x39\x00\x00\x00\x3C\x00\x00\x00" -"\x39\x00\x04\x00\x07\x00\x00\x00\x40\x00\x00\x00\x09\x00\x00\x00\x41\x00\x05\x00\x41\x00\x00\x00\x42\x00\x00\x00\x3F\x00\x00\x00" -"\x17\x00\x00\x00\x3E\x00\x03\x00\x42\x00\x00\x00\x40\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\x01\x00\x08\x00" -"\x32\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\x07\x00\x04\x00\x00\x00\x04\x00\x00\x00" -"\x6D\x61\x69\x6E\x00\x00\x00\x00\x09\x00\x00\x00\x12\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\x09\x00\x00\x00" -"\x6F\x75\x74\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x04\x00\x0E\x00\x00\x00\x73\x5F\x74\x30\x00\x00\x00\x00\x05\x00\x03\x00" -"\x12\x00\x00\x00\x74\x63\x00\x00\x05\x00\x04\x00\x17\x00\x00\x00\x73\x5F\x74\x31\x00\x00\x00\x00\x05\x00\x04\x00\x1B\x00\x00\x00" -"\x73\x5F\x74\x32\x00\x00\x00\x00\x05\x00\x04\x00\x20\x00\x00\x00\x73\x5F\x74\x33\x00\x00\x00\x00\x05\x00\x05\x00\x2C\x00\x00\x00" -"\x65\x6E\x74\x69\x74\x79\x62\x6C\x6F\x63\x6B\x00\x06\x00\x07\x00\x2C\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\x2C\x00\x00\x00\x01\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x00\x06\x00\x06\x00" -"\x2C\x00\x00\x00\x02\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x69\x6E\x76\x00\x00\x06\x00\x06\x00\x2C\x00\x00\x00\x03\x00\x00\x00" -"\x65\x5F\x65\x79\x65\x70\x6F\x73\x00\x00\x00\x00\x06\x00\x05\x00\x2C\x00\x00\x00\x04\x00\x00\x00\x65\x5F\x74\x69\x6D\x65\x00\x00" -"\x06\x00\x07\x00\x2C\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" -"\x2C\x00\x00\x00\x06\x00\x00\x00\x65\x70\x61\x64\x31\x00\x00\x00\x06\x00\x06\x00\x2C\x00\x00\x00\x07\x00\x00\x00\x65\x5F\x6C\x69" -"\x67\x68\x74\x5F\x64\x69\x72\x00\x06\x00\x05\x00\x2C\x00\x00\x00\x08\x00\x00\x00\x65\x70\x61\x64\x32\x00\x00\x00\x06\x00\x06\x00" -"\x2C\x00\x00\x00\x09\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x6D\x75\x6C\x00\x06\x00\x05\x00\x2C\x00\x00\x00\x0A\x00\x00\x00" -"\x65\x70\x61\x64\x33\x00\x00\x00\x06\x00\x06\x00\x2C\x00\x00\x00\x0B\x00\x00\x00\x65\x5F\x6C\x6D\x73\x63\x61\x6C\x65\x73\x00\x00" -"\x06\x00\x07\x00\x2C\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" -"\x2C\x00\x00\x00\x0D\x00\x00\x00\x65\x70\x61\x64\x34\x00\x00\x00\x06\x00\x07\x00\x2C\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\x2C\x00\x00\x00\x0F\x00\x00\x00\x65\x70\x61\x64\x35\x00\x00\x00" -"\x06\x00\x06\x00\x2C\x00\x00\x00\x10\x00\x00\x00\x65\x5F\x67\x6C\x6F\x77\x6D\x6F\x64\x00\x00\x00\x06\x00\x05\x00\x2C\x00\x00\x00" -"\x11\x00\x00\x00\x65\x70\x61\x64\x36\x00\x00\x00\x06\x00\x07\x00\x2C\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\x2C\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\x2C\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\x2C\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" -"\x2C\x00\x00\x00\x16\x00\x00\x00\x65\x70\x61\x64\x37\x00\x00\x00\x05\x00\x03\x00\x2E\x00\x00\x00\x00\x00\x00\x00\x05\x00\x05\x00" -"\x2F\x00\x00\x00\x6C\x69\x67\x68\x74\x62\x6C\x6F\x63\x6B\x00\x00\x06\x00\x07\x00\x2F\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\x2F\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\x2F\x00\x00\x00\x02\x00\x00\x00\x6C\x70\x61\x64\x31\x00\x00\x00\x06\x00\x07\x00" -"\x2F\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\x2F\x00\x00\x00" -"\x04\x00\x00\x00\x6C\x70\x61\x64\x32\x00\x00\x00\x06\x00\x08\x00\x2F\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\x2F\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\x2F\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\x2F\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\x2F\x00\x00\x00\x09\x00\x00\x00\x6C\x70\x61\x64\x33\x00\x00\x00\x05\x00\x03\x00\x31\x00\x00\x00" -"\x00\x00\x00\x00\x47\x00\x04\x00\x09\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x0A\x00\x00\x00\x01\x00\x00\x00" -"\x01\x01\x00\x00\x47\x00\x04\x00\x0E\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x0E\x00\x00\x00\x21\x00\x00\x00" -"\x02\x00\x00\x00\x47\x00\x04\x00\x16\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x47\x00\x04\x00\x17\x00\x00\x00\x22\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\x47\x00\x04\x00\x3B\x00\x00\x00\x1E\x00\x00\x00\x01\x00\x00\x00\x48\x00\x05\x00\x3D\x00\x00\x00\x00\x00\x00\x00" +"\x0B\x00\x00\x00\x00\x00\x00\x00\x47\x00\x03\x00\x3D\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x43\x00\x00\x00\x01\x00\x00\x00" +"\x00\x01\x00\x00\x47\x00\x04\x00\x44\x00\x00\x00\x01\x00\x00\x00\x01\x01\x00\x00\x48\x00\x04\x00\x45\x00\x00\x00\x00\x00\x00\x00" +"\x05\x00\x00\x00\x48\x00\x05\x00\x45\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00\x45\x00\x00\x00" +"\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x05\x00\x45\x00\x00\x00\x01\x00\x00\x00\x23\x00\x00\x00\x40\x00\x00\x00" +"\x48\x00\x05\x00\x45\x00\x00\x00\x02\x00\x00\x00\x23\x00\x00\x00\x4C\x00\x00\x00\x48\x00\x05\x00\x45\x00\x00\x00\x03\x00\x00\x00" +"\x23\x00\x00\x00\x50\x00\x00\x00\x48\x00\x05\x00\x45\x00\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00\x5C\x00\x00\x00\x48\x00\x05\x00" +"\x45\x00\x00\x00\x05\x00\x00\x00\x23\x00\x00\x00\x60\x00\x00\x00\x48\x00\x05\x00\x45\x00\x00\x00\x06\x00\x00\x00\x23\x00\x00\x00" +"\x6C\x00\x00\x00\x48\x00\x05\x00\x45\x00\x00\x00\x07\x00\x00\x00\x23\x00\x00\x00\x70\x00\x00\x00\x48\x00\x05\x00\x45\x00\x00\x00" +"\x08\x00\x00\x00\x23\x00\x00\x00\x80\x00\x00\x00\x48\x00\x05\x00\x45\x00\x00\x00\x09\x00\x00\x00\x23\x00\x00\x00\x88\x00\x00\x00" +"\x47\x00\x03\x00\x45\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x47\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00" +"\x47\x00\x00\x00\x21\x00\x00\x00\x01\x00\x00\x00\x47\x00\x04\x00\x49\x00\x00\x00\x1E\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00" +"\x4A\x00\x00\x00\x1E\x00\x00\x00\x03\x00\x00\x00\x47\x00\x04\x00\x4B\x00\x00\x00\x1E\x00\x00\x00\x04\x00\x00\x00\x47\x00\x04\x00" +"\x4C\x00\x00\x00\x1E\x00\x00\x00\x05\x00\x00\x00\x47\x00\x04\x00\x4D\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\x15\x00\x04\x00\x0F\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00" +"\x10\x00\x00\x00\x04\x00\x00\x00\x1C\x00\x04\x00\x11\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x17\x00\x04\x00\x12\x00\x00\x00" +"\x06\x00\x00\x00\x02\x00\x00\x00\x1E\x00\x19\x00\x13\x00\x00\x00\x0D\x00\x00\x00\x0D\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\x0E\x00\x00\x00\x06\x00\x00\x00\x11\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\x07\x00\x00\x00" +"\x06\x00\x00\x00\x06\x00\x00\x00\x12\x00\x00\x00\x20\x00\x04\x00\x14\x00\x00\x00\x02\x00\x00\x00\x13\x00\x00\x00\x3B\x00\x04\x00" +"\x14\x00\x00\x00\x15\x00\x00\x00\x02\x00\x00\x00\x15\x00\x04\x00\x16\x00\x00\x00\x20\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00" +"\x16\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x20\x00\x04\x00\x18\x00\x00\x00\x02\x00\x00\x00\x0D\x00\x00\x00\x20\x00\x04\x00" +"\x1B\x00\x00\x00\x01\x00\x00\x00\x0E\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x1C\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00" +"\x06\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x80\x3F\x2B\x00\x04\x00\x06\x00\x00\x00\x24\x00\x00\x00\x00\x00\x80\xBF\x2B\x00\x04\x00" +"\x0F\x00\x00\x00\x25\x00\x00\x00\x01\x00\x00\x00\x20\x00\x04\x00\x26\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x2B\x00\x04\x00" +"\x0F\x00\x00\x00\x2B\x00\x00\x00\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\x12\x00\x00\x00\x3B\x00\x04\x00" +"\x38\x00\x00\x00\x39\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00\x3A\x00\x00\x00\x01\x00\x00\x00\x12\x00\x00\x00\x3B\x00\x04\x00" +"\x3A\x00\x00\x00\x3B\x00\x00\x00\x01\x00\x00\x00\x1E\x00\x03\x00\x3D\x00\x00\x00\x07\x00\x00\x00\x20\x00\x04\x00\x3E\x00\x00\x00" +"\x03\x00\x00\x00\x3D\x00\x00\x00\x3B\x00\x04\x00\x3E\x00\x00\x00\x3F\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00\x41\x00\x00\x00" +"\x03\x00\x00\x00\x07\x00\x00\x00\x32\x00\x04\x00\x06\x00\x00\x00\x43\x00\x00\x00\x00\x00\x80\x43\x32\x00\x04\x00\x06\x00\x00\x00" +"\x44\x00\x00\x00\x00\x80\x80\x43\x1E\x00\x0C\x00\x45\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\x46\x00\x00\x00" +"\x02\x00\x00\x00\x45\x00\x00\x00\x3B\x00\x04\x00\x46\x00\x00\x00\x47\x00\x00\x00\x02\x00\x00\x00\x20\x00\x04\x00\x48\x00\x00\x00" +"\x01\x00\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00\x48\x00\x00\x00\x49\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x3A\x00\x00\x00" +"\x4A\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x4B\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00" +"\x4C\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x4D\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\x12\x00\x00\x00\x3C\x00\x00\x00" +"\x3B\x00\x00\x00\x3E\x00\x03\x00\x39\x00\x00\x00\x3C\x00\x00\x00\x39\x00\x04\x00\x07\x00\x00\x00\x40\x00\x00\x00\x09\x00\x00\x00" +"\x41\x00\x05\x00\x41\x00\x00\x00\x42\x00\x00\x00\x3F\x00\x00\x00\x17\x00\x00\x00\x3E\x00\x03\x00\x42\x00\x00\x00\x40\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\x01\x00\x08\x00\x32\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\x07\x00\x04\x00\x00\x00\x04\x00\x00\x00\x6D\x61\x69\x6E\x00\x00\x00\x00\x09\x00\x00\x00\x12\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\x09\x00\x00\x00\x6F\x75\x74\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x04\x00" +"\x0E\x00\x00\x00\x73\x5F\x74\x30\x00\x00\x00\x00\x05\x00\x03\x00\x12\x00\x00\x00\x74\x63\x00\x00\x05\x00\x04\x00\x17\x00\x00\x00" +"\x73\x5F\x74\x31\x00\x00\x00\x00\x05\x00\x04\x00\x1B\x00\x00\x00\x73\x5F\x74\x32\x00\x00\x00\x00\x05\x00\x04\x00\x20\x00\x00\x00" +"\x73\x5F\x74\x33\x00\x00\x00\x00\x05\x00\x05\x00\x2C\x00\x00\x00\x65\x6E\x74\x69\x74\x79\x62\x6C\x6F\x63\x6B\x00\x06\x00\x07\x00" +"\x2C\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\x2C\x00\x00\x00" +"\x01\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x00\x06\x00\x06\x00\x2C\x00\x00\x00\x02\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x69" +"\x6E\x76\x00\x00\x06\x00\x06\x00\x2C\x00\x00\x00\x03\x00\x00\x00\x65\x5F\x65\x79\x65\x70\x6F\x73\x00\x00\x00\x00\x06\x00\x05\x00" +"\x2C\x00\x00\x00\x04\x00\x00\x00\x65\x5F\x74\x69\x6D\x65\x00\x00\x06\x00\x07\x00\x2C\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\x2C\x00\x00\x00\x06\x00\x00\x00\x65\x70\x61\x64\x31\x00\x00\x00" +"\x06\x00\x06\x00\x2C\x00\x00\x00\x07\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x64\x69\x72\x00\x06\x00\x05\x00\x2C\x00\x00\x00" +"\x08\x00\x00\x00\x65\x70\x61\x64\x32\x00\x00\x00\x06\x00\x06\x00\x2C\x00\x00\x00\x09\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F" +"\x6D\x75\x6C\x00\x06\x00\x05\x00\x2C\x00\x00\x00\x0A\x00\x00\x00\x65\x70\x61\x64\x33\x00\x00\x00\x06\x00\x06\x00\x2C\x00\x00\x00" +"\x0B\x00\x00\x00\x65\x5F\x6C\x6D\x73\x63\x61\x6C\x65\x73\x00\x00\x06\x00\x07\x00\x2C\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\x2C\x00\x00\x00\x0D\x00\x00\x00\x65\x70\x61\x64\x34\x00\x00\x00" +"\x06\x00\x07\x00\x2C\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" +"\x2C\x00\x00\x00\x0F\x00\x00\x00\x65\x70\x61\x64\x35\x00\x00\x00\x06\x00\x06\x00\x2C\x00\x00\x00\x10\x00\x00\x00\x65\x5F\x67\x6C" +"\x6F\x77\x6D\x6F\x64\x00\x00\x00\x06\x00\x05\x00\x2C\x00\x00\x00\x11\x00\x00\x00\x65\x70\x61\x64\x36\x00\x00\x00\x06\x00\x07\x00" +"\x2C\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\x2C\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\x2C\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\x2C\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\x2C\x00\x00\x00\x16\x00\x00\x00\x65\x70\x61\x64\x37\x00\x00\x00" +"\x05\x00\x03\x00\x2E\x00\x00\x00\x00\x00\x00\x00\x05\x00\x05\x00\x2F\x00\x00\x00\x6C\x69\x67\x68\x74\x62\x6C\x6F\x63\x6B\x00\x00" +"\x06\x00\x07\x00\x2F\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" +"\x2F\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\x2F\x00\x00\x00" +"\x02\x00\x00\x00\x6C\x70\x61\x64\x31\x00\x00\x00\x06\x00\x07\x00\x2F\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\x2F\x00\x00\x00\x04\x00\x00\x00\x6C\x70\x61\x64\x32\x00\x00\x00\x06\x00\x08\x00" +"\x2F\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" +"\x2F\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\x2F\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\x2F\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\x2F\x00\x00\x00\x09\x00\x00\x00" +"\x6C\x70\x61\x64\x33\x00\x00\x00\x05\x00\x03\x00\x31\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x09\x00\x00\x00\x1E\x00\x00\x00" +"\x00\x00\x00\x00\x47\x00\x04\x00\x0A\x00\x00\x00\x01\x00\x00\x00\x01\x01\x00\x00\x47\x00\x04\x00\x0E\x00\x00\x00\x22\x00\x00\x00" +"\x00\x00\x00\x00\x47\x00\x04\x00\x0E\x00\x00\x00\x21\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x12\x00\x00\x00\x1E\x00\x00\x00" +"\x00\x00\x00\x00\x47\x00\x04\x00\x16\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x47\x00\x04\x00\x17\x00\x00\x00\x22\x00\x00\x00" "\x00\x00\x00\x00\x47\x00\x04\x00\x17\x00\x00\x00\x21\x00\x00\x00\x03\x00\x00\x00\x47\x00\x04\x00\x1B\x00\x00\x00\x22\x00\x00\x00" "\x00\x00\x00\x00\x47\x00\x04\x00\x1B\x00\x00\x00\x21\x00\x00\x00\x04\x00\x00\x00\x47\x00\x04\x00\x20\x00\x00\x00\x22\x00\x00\x00" "\x00\x00\x00\x00\x47\x00\x04\x00\x20\x00\x00\x00\x21\x00\x00\x00\x05\x00\x00\x00\x47\x00\x04\x00\x2B\x00\x00\x00\x06\x00\x00\x00" @@ -2457,7 +2460,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND #ifdef VKQUAKE {QR_VULKAN, -1, "default2d", "\xFF\x53\x50\x56\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x2C\x00\x00\x00\x0F\x00\x00\x00\x3C\x00\x00\x00" -"\xFC\x0E\x00\x00\x38\x0F\x00\x00\x64\x0C\x00\x00\x01\x00\x42\x31\x50\x52\x45\x4D\x55\x4C\x00\x00\x00\x00\x00\x20\x03\x02\x23\x07" +"\xFC\x0E\x00\x00\x38\x0F\x00\x00\x64\x0C\x00\x00\x01\x00\x42\x31\x50\x52\x45\x4D\x55\x4C\x00\x00\x00\x00\x00\x00\x03\x02\x23\x07" "\x00\x00\x01\x00\x01\x00\x08\x00\x4F\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\x0F\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\x3B\x00\x00\x00\x3E\x00\x00\x00" @@ -3050,7 +3053,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "\x9C\x1A\x00\x00\x30\x1B\x00\x00\x10\x3E\x00\x00\x01\x00\x66\x31\x72\x5F\x67\x6C\x73\x6C\x5F\x6F\x66\x66\x73\x65\x74\x6D\x61\x70" "\x70\x69\x6E\x67\x00\x00\x00\x00\x00\x01\x01\x66\x31\x72\x5F\x67\x6C\x73\x6C\x5F\x6F\x66\x66\x73\x65\x74\x6D\x61\x70\x70\x69\x6E" "\x67\x5F\x73\x63\x61\x6C\x65\x00\x3D\x23\xD7\x0A\x01\x02\x66\x31\x67\x6C\x5F\x73\x70\x65\x63\x75\x6C\x61\x72\x00\x00\x00\x00\x00" -"\x01\x03\x62\x31\x72\x5F\x66\x6F\x67\x5F\x65\x78\x70\x32\x00\x00\x00\x00\x00\x61\x03\x02\x23\x07\x00\x00\x01\x00\x01\x00\x08\x00" +"\x01\x03\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\x01\x00\x08\x00" "\xCC\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\x11\x00\x00\x00\x00\x00\x04\x00\x00\x00" "\x6D\x61\x69\x6E\x00\x00\x00\x00\x2E\x00\x00\x00\x4A\x00\x00\x00\x4C\x00\x00\x00\x4E\x00\x00\x00\x6C\x00\x00\x00\x84\x00\x00\x00" @@ -3967,7 +3970,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND #ifdef VKQUAKE {QR_VULKAN, -1, "defaultsky", "\xFF\x53\x50\x56\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x20\x00\x00\x00\x2C\x00\x00\x00\x13\x00\x00\x00\x40\x00\x00\x00" -"\xC0\x0E\x00\x00\x00\x0F\x00\x00\x34\x24\x00\x00\x01\x00\x62\x31\x72\x5F\x66\x6F\x67\x5F\x65\x78\x70\x32\x00\x00\x00\x00\x00\x43" +"\xD0\x0E\x00\x00\x10\x0F\x00\x00\x44\x24\x00\x00\x01\x00\x62\x31\x72\x5F\x66\x6F\x67\x5F\x65\x78\x70\x32\x00\x00\x00\x00\x00\x23" "\x03\x02\x23\x07\x00\x00\x01\x00\x01\x00\x08\x00\x4E\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\x3D\x00\x00\x00" @@ -4028,133 +4031,134 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "\x13\x00\x00\x00\x15\x00\x00\x00\x23\x00\x00\x00\x94\x01\x00\x00\x48\x00\x05\x00\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" -"\x48\x00\x05\x00\x3B\x00\x00\x00\x00\x00\x00\x00\x0B\x00\x00\x00\x00\x00\x00\x00\x47\x00\x03\x00\x3B\x00\x00\x00\x02\x00\x00\x00" -"\x47\x00\x04\x00\x41\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x47\x00\x04\x00\x42\x00\x00\x00\x01\x00\x00\x00\x15\x00\x00\x00" -"\x48\x00\x04\x00\x43\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00" -"\x00\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00" -"\x01\x00\x00\x00\x23\x00\x00\x00\x40\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00\x02\x00\x00\x00\x23\x00\x00\x00\x4C\x00\x00\x00" -"\x48\x00\x05\x00\x43\x00\x00\x00\x03\x00\x00\x00\x23\x00\x00\x00\x50\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00\x04\x00\x00\x00" -"\x23\x00\x00\x00\x5C\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00\x05\x00\x00\x00\x23\x00\x00\x00\x60\x00\x00\x00\x48\x00\x05\x00" -"\x43\x00\x00\x00\x06\x00\x00\x00\x23\x00\x00\x00\x6C\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00\x07\x00\x00\x00\x23\x00\x00\x00" -"\x70\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00\x08\x00\x00\x00\x23\x00\x00\x00\x80\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00" -"\x09\x00\x00\x00\x23\x00\x00\x00\x88\x00\x00\x00\x47\x00\x03\x00\x43\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x45\x00\x00\x00" -"\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x45\x00\x00\x00\x21\x00\x00\x00\x01\x00\x00\x00\x47\x00\x04\x00\x47\x00\x00\x00" -"\x1E\x00\x00\x00\x01\x00\x00\x00\x47\x00\x04\x00\x49\x00\x00\x00\x1E\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x4A\x00\x00\x00" -"\x1E\x00\x00\x00\x03\x00\x00\x00\x47\x00\x04\x00\x4B\x00\x00\x00\x1E\x00\x00\x00\x04\x00\x00\x00\x47\x00\x04\x00\x4C\x00\x00\x00" -"\x1E\x00\x00\x00\x05\x00\x00\x00\x47\x00\x04\x00\x4D\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\x15\x00\x04\x00\x0F\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00\x10\x00\x00\x00" -"\x04\x00\x00\x00\x1C\x00\x04\x00\x11\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x17\x00\x04\x00\x12\x00\x00\x00\x06\x00\x00\x00" -"\x02\x00\x00\x00\x1E\x00\x19\x00\x13\x00\x00\x00\x0D\x00\x00\x00\x0D\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\x0E\x00\x00\x00\x06\x00\x00\x00\x11\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\x07\x00\x00\x00\x06\x00\x00\x00" -"\x06\x00\x00\x00\x12\x00\x00\x00\x20\x00\x04\x00\x14\x00\x00\x00\x02\x00\x00\x00\x13\x00\x00\x00\x3B\x00\x04\x00\x14\x00\x00\x00" -"\x15\x00\x00\x00\x02\x00\x00\x00\x15\x00\x04\x00\x16\x00\x00\x00\x20\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00\x16\x00\x00\x00" -"\x17\x00\x00\x00\x00\x00\x00\x00\x20\x00\x04\x00\x18\x00\x00\x00\x02\x00\x00\x00\x0D\x00\x00\x00\x20\x00\x04\x00\x1B\x00\x00\x00" -"\x01\x00\x00\x00\x0E\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x1C\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00\x06\x00\x00\x00" -"\x1E\x00\x00\x00\x00\x00\x80\x3F\x2B\x00\x04\x00\x06\x00\x00\x00\x24\x00\x00\x00\x00\x00\x80\xBF\x2B\x00\x04\x00\x0F\x00\x00\x00" -"\x25\x00\x00\x00\x01\x00\x00\x00\x20\x00\x04\x00\x26\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00" -"\x2B\x00\x00\x00\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\x1E\x00\x03\x00\x3B\x00\x00\x00\x07\x00\x00\x00\x20\x00\x04\x00\x3C\x00\x00\x00\x03\x00\x00\x00" -"\x3B\x00\x00\x00\x3B\x00\x04\x00\x3C\x00\x00\x00\x3D\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00\x3F\x00\x00\x00\x03\x00\x00\x00" -"\x07\x00\x00\x00\x32\x00\x04\x00\x16\x00\x00\x00\x41\x00\x00\x00\x00\x01\x00\x00\x32\x00\x04\x00\x16\x00\x00\x00\x42\x00\x00\x00" -"\x15\x00\x00\x00\x1E\x00\x0C\x00\x43\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\x44\x00\x00\x00\x02\x00\x00\x00" -"\x43\x00\x00\x00\x3B\x00\x04\x00\x44\x00\x00\x00\x45\x00\x00\x00\x02\x00\x00\x00\x20\x00\x04\x00\x46\x00\x00\x00\x01\x00\x00\x00" -"\x12\x00\x00\x00\x3B\x00\x04\x00\x46\x00\x00\x00\x47\x00\x00\x00\x01\x00\x00\x00\x20\x00\x04\x00\x48\x00\x00\x00\x01\x00\x00\x00" -"\x07\x00\x00\x00\x3B\x00\x04\x00\x48\x00\x00\x00\x49\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x46\x00\x00\x00\x4A\x00\x00\x00" -"\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x4B\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x4C\x00\x00\x00" -"\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x4D\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" -"\x3E\x00\x03\x00\x39\x00\x00\x00\x3A\x00\x00\x00\x39\x00\x04\x00\x07\x00\x00\x00\x3E\x00\x00\x00\x09\x00\x00\x00\x41\x00\x05\x00" -"\x3F\x00\x00\x00\x40\x00\x00\x00\x3D\x00\x00\x00\x17\x00\x00\x00\x3E\x00\x03\x00\x40\x00\x00\x00\x3E\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\x01\x00\x08\x00\x58\x01\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\x35\x00\x00\x00\x08\x01\x00\x00\x43\x01\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\x07\x00\x0E\x00\x00\x00\x66\x6F\x67\x33" -"\x61\x64\x64\x69\x74\x69\x76\x65\x28\x76\x66\x33\x3B\x00\x00\x00\x05\x00\x06\x00\x0D\x00\x00\x00\x72\x65\x67\x75\x6C\x61\x72\x63" -"\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x05\x00\x14\x00\x00\x00\x66\x6F\x67\x34\x28\x76\x66\x34\x3B\x00\x00\x00\x05\x00\x06\x00" -"\x13\x00\x00\x00\x72\x65\x67\x75\x6C\x61\x72\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x07\x00\x17\x00\x00\x00\x66\x6F\x67\x34" -"\x61\x64\x64\x69\x74\x69\x76\x65\x28\x76\x66\x34\x3B\x00\x00\x00\x05\x00\x06\x00\x16\x00\x00\x00\x72\x65\x67\x75\x6C\x61\x72\x63" -"\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x06\x00\x1A\x00\x00\x00\x66\x6F\x67\x34\x62\x6C\x65\x6E\x64\x28\x76\x66\x34\x3B\x00\x00" -"\x05\x00\x06\x00\x19\x00\x00\x00\x72\x65\x67\x75\x6C\x61\x72\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x03\x00\x27\x00\x00\x00" -"\x7A\x00\x00\x00\x05\x00\x05\x00\x2D\x00\x00\x00\x65\x6E\x74\x69\x74\x79\x62\x6C\x6F\x63\x6B\x00\x06\x00\x07\x00\x2D\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\x2D\x00\x00\x00\x01\x00\x00\x00" -"\x6D\x5F\x6D\x6F\x64\x65\x6C\x00\x06\x00\x06\x00\x2D\x00\x00\x00\x02\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x69\x6E\x76\x00\x00" -"\x06\x00\x06\x00\x2D\x00\x00\x00\x03\x00\x00\x00\x65\x5F\x65\x79\x65\x70\x6F\x73\x00\x00\x00\x00\x06\x00\x05\x00\x2D\x00\x00\x00" -"\x04\x00\x00\x00\x65\x5F\x74\x69\x6D\x65\x00\x00\x06\x00\x07\x00\x2D\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\x2D\x00\x00\x00\x06\x00\x00\x00\x65\x70\x61\x64\x31\x00\x00\x00\x06\x00\x06\x00" -"\x2D\x00\x00\x00\x07\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x64\x69\x72\x00\x06\x00\x05\x00\x2D\x00\x00\x00\x08\x00\x00\x00" -"\x65\x70\x61\x64\x32\x00\x00\x00\x06\x00\x06\x00\x2D\x00\x00\x00\x09\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x6D\x75\x6C\x00" -"\x06\x00\x05\x00\x2D\x00\x00\x00\x0A\x00\x00\x00\x65\x70\x61\x64\x33\x00\x00\x00\x06\x00\x06\x00\x2D\x00\x00\x00\x0B\x00\x00\x00" -"\x65\x5F\x6C\x6D\x73\x63\x61\x6C\x65\x73\x00\x00\x06\x00\x07\x00\x2D\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\x2D\x00\x00\x00\x0D\x00\x00\x00\x65\x70\x61\x64\x34\x00\x00\x00\x06\x00\x07\x00" -"\x2D\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\x2D\x00\x00\x00" -"\x0F\x00\x00\x00\x65\x70\x61\x64\x35\x00\x00\x00\x06\x00\x06\x00\x2D\x00\x00\x00\x10\x00\x00\x00\x65\x5F\x67\x6C\x6F\x77\x6D\x6F" -"\x64\x00\x00\x00\x06\x00\x05\x00\x2D\x00\x00\x00\x11\x00\x00\x00\x65\x70\x61\x64\x36\x00\x00\x00\x06\x00\x07\x00\x2D\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\x2D\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\x2D\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\x2D\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\x2D\x00\x00\x00\x16\x00\x00\x00\x65\x70\x61\x64\x37\x00\x00\x00\x05\x00\x03\x00" -"\x2F\x00\x00\x00\x00\x00\x00\x00\x05\x00\x06\x00\x35\x00\x00\x00\x67\x6C\x5F\x46\x72\x61\x67\x43\x6F\x6F\x72\x64\x00\x00\x00\x00" -"\x05\x00\x03\x00\x4D\x00\x00\x00\x66\x61\x63\x00\x05\x00\x03\x00\x6E\x00\x00\x00\x7A\x00\x00\x00\x05\x00\x03\x00\x82\x00\x00\x00" -"\x66\x61\x63\x00\x05\x00\x04\x00\x9B\x00\x00\x00\x70\x61\x72\x61\x6D\x00\x00\x00\x05\x00\x03\x00\xAE\x00\x00\x00\x7A\x00\x00\x00" -"\x05\x00\x03\x00\xC2\x00\x00\x00\x66\x61\x63\x00\x05\x00\x03\x00\xDE\x00\x00\x00\x7A\x00\x00\x00\x05\x00\x03\x00\xF2\x00\x00\x00" -"\x66\x61\x63\x00\x05\x00\x03\x00\x06\x01\x00\x00\x64\x69\x72\x00\x05\x00\x03\x00\x08\x01\x00\x00\x70\x6F\x73\x00\x05\x00\x04\x00" -"\x1F\x01\x00\x00\x74\x63\x63\x6F\x6F\x72\x64\x00\x05\x00\x04\x00\x29\x01\x00\x00\x73\x6F\x6C\x69\x64\x00\x00\x00\x05\x00\x04\x00" -"\x2D\x01\x00\x00\x73\x5F\x74\x30\x00\x00\x00\x00\x05\x00\x04\x00\x3D\x01\x00\x00\x63\x6C\x6F\x75\x64\x73\x00\x00\x05\x00\x04\x00" -"\x3E\x01\x00\x00\x73\x5F\x74\x31\x00\x00\x00\x00\x05\x00\x05\x00\x43\x01\x00\x00\x6F\x75\x74\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00" -"\x05\x00\x04\x00\x4F\x01\x00\x00\x70\x61\x72\x61\x6D\x00\x00\x00\x05\x00\x05\x00\x55\x01\x00\x00\x6C\x69\x67\x68\x74\x62\x6C\x6F" -"\x63\x6B\x00\x00\x06\x00\x07\x00\x55\x01\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\x55\x01\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" -"\x55\x01\x00\x00\x02\x00\x00\x00\x6C\x70\x61\x64\x31\x00\x00\x00\x06\x00\x07\x00\x55\x01\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\x55\x01\x00\x00\x04\x00\x00\x00\x6C\x70\x61\x64\x32\x00\x00\x00" -"\x06\x00\x08\x00\x55\x01\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\x55\x01\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" -"\x55\x01\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\x55\x01\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\x55\x01\x00\x00" -"\x09\x00\x00\x00\x6C\x70\x61\x64\x33\x00\x00\x00\x05\x00\x03\x00\x57\x01\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x1D\x00\x00\x00" -"\x01\x00\x00\x00\x15\x00\x00\x00\x47\x00\x04\x00\x2B\x00\x00\x00\x06\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00\x2D\x00\x00\x00" -"\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00" -"\x2D\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00\x2D\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00" -"\x48\x00\x05\x00\x2D\x00\x00\x00\x01\x00\x00\x00\x23\x00\x00\x00\x40\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x01\x00\x00\x00" -"\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00\x2D\x00\x00\x00\x02\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00" -"\x02\x00\x00\x00\x23\x00\x00\x00\x80\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00" -"\x48\x00\x05\x00\x2D\x00\x00\x00\x03\x00\x00\x00\x23\x00\x00\x00\xC0\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x04\x00\x00\x00" -"\x23\x00\x00\x00\xCC\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x05\x00\x00\x00\x23\x00\x00\x00\xD0\x00\x00\x00\x48\x00\x05\x00" -"\x2D\x00\x00\x00\x06\x00\x00\x00\x23\x00\x00\x00\xDC\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x07\x00\x00\x00\x23\x00\x00\x00" -"\xE0\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x08\x00\x00\x00\x23\x00\x00\x00\xEC\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00" -"\x09\x00\x00\x00\x23\x00\x00\x00\xF0\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x0A\x00\x00\x00\x23\x00\x00\x00\xFC\x00\x00\x00" -"\x48\x00\x05\x00\x2D\x00\x00\x00\x0B\x00\x00\x00\x23\x00\x00\x00\x00\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x0C\x00\x00\x00" -"\x23\x00\x00\x00\x40\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x0D\x00\x00\x00\x23\x00\x00\x00\x4C\x01\x00\x00\x48\x00\x05\x00" -"\x2D\x00\x00\x00\x0E\x00\x00\x00\x23\x00\x00\x00\x50\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x0F\x00\x00\x00\x23\x00\x00\x00" -"\x5C\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x10\x00\x00\x00\x23\x00\x00\x00\x60\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00" -"\x11\x00\x00\x00\x23\x00\x00\x00\x6C\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x12\x00\x00\x00\x23\x00\x00\x00\x70\x01\x00\x00" -"\x48\x00\x05\x00\x2D\x00\x00\x00\x13\x00\x00\x00\x23\x00\x00\x00\x80\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x14\x00\x00\x00" -"\x23\x00\x00\x00\x90\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x15\x00\x00\x00\x23\x00\x00\x00\x94\x01\x00\x00\x48\x00\x05\x00" -"\x2D\x00\x00\x00\x16\x00\x00\x00\x23\x00\x00\x00\x98\x01\x00\x00\x47\x00\x03\x00\x2D\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00" -"\x2F\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x2F\x00\x00\x00\x21\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00" -"\x35\x00\x00\x00\x0B\x00\x00\x00\x0F\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\x04\x00\x39\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00\x3B\x00\x00\x00\x00\x00\x00\x00\x0B\x00\x00\x00" +"\x00\x00\x00\x00\x47\x00\x03\x00\x3B\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x41\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00" +"\x47\x00\x04\x00\x42\x00\x00\x00\x01\x00\x00\x00\x15\x00\x00\x00\x48\x00\x04\x00\x43\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00" +"\x48\x00\x05\x00\x43\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00\x00\x00\x00\x00" +"\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00\x01\x00\x00\x00\x23\x00\x00\x00\x40\x00\x00\x00\x48\x00\x05\x00" +"\x43\x00\x00\x00\x02\x00\x00\x00\x23\x00\x00\x00\x4C\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00\x03\x00\x00\x00\x23\x00\x00\x00" +"\x50\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00\x5C\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00" +"\x05\x00\x00\x00\x23\x00\x00\x00\x60\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00\x06\x00\x00\x00\x23\x00\x00\x00\x6C\x00\x00\x00" +"\x48\x00\x05\x00\x43\x00\x00\x00\x07\x00\x00\x00\x23\x00\x00\x00\x70\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00\x08\x00\x00\x00" +"\x23\x00\x00\x00\x80\x00\x00\x00\x48\x00\x05\x00\x43\x00\x00\x00\x09\x00\x00\x00\x23\x00\x00\x00\x88\x00\x00\x00\x47\x00\x03\x00" +"\x43\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x45\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x45\x00\x00\x00" +"\x21\x00\x00\x00\x01\x00\x00\x00\x47\x00\x04\x00\x47\x00\x00\x00\x1E\x00\x00\x00\x01\x00\x00\x00\x47\x00\x04\x00\x49\x00\x00\x00" +"\x1E\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x4A\x00\x00\x00\x1E\x00\x00\x00\x03\x00\x00\x00\x47\x00\x04\x00\x4B\x00\x00\x00" +"\x1E\x00\x00\x00\x04\x00\x00\x00\x47\x00\x04\x00\x4C\x00\x00\x00\x1E\x00\x00\x00\x05\x00\x00\x00\x47\x00\x04\x00\x4D\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\x15\x00\x04\x00\x0F\x00\x00\x00\x20\x00\x00\x00" +"\x00\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00\x10\x00\x00\x00\x04\x00\x00\x00\x1C\x00\x04\x00\x11\x00\x00\x00\x07\x00\x00\x00" +"\x10\x00\x00\x00\x17\x00\x04\x00\x12\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x1E\x00\x19\x00\x13\x00\x00\x00\x0D\x00\x00\x00" +"\x0D\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" +"\x0E\x00\x00\x00\x06\x00\x00\x00\x11\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\x07\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x12\x00\x00\x00\x20\x00\x04\x00\x14\x00\x00\x00" +"\x02\x00\x00\x00\x13\x00\x00\x00\x3B\x00\x04\x00\x14\x00\x00\x00\x15\x00\x00\x00\x02\x00\x00\x00\x15\x00\x04\x00\x16\x00\x00\x00" +"\x20\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00\x16\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x20\x00\x04\x00\x18\x00\x00\x00" +"\x02\x00\x00\x00\x0D\x00\x00\x00\x20\x00\x04\x00\x1B\x00\x00\x00\x01\x00\x00\x00\x0E\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00" +"\x1C\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00\x06\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x80\x3F\x2B\x00\x04\x00\x06\x00\x00\x00" +"\x24\x00\x00\x00\x00\x00\x80\xBF\x2B\x00\x04\x00\x0F\x00\x00\x00\x25\x00\x00\x00\x01\x00\x00\x00\x20\x00\x04\x00\x26\x00\x00\x00" +"\x07\x00\x00\x00\x06\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00\x2B\x00\x00\x00\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\x1E\x00\x03\x00\x3B\x00\x00\x00" +"\x07\x00\x00\x00\x20\x00\x04\x00\x3C\x00\x00\x00\x03\x00\x00\x00\x3B\x00\x00\x00\x3B\x00\x04\x00\x3C\x00\x00\x00\x3D\x00\x00\x00" +"\x03\x00\x00\x00\x20\x00\x04\x00\x3F\x00\x00\x00\x03\x00\x00\x00\x07\x00\x00\x00\x32\x00\x04\x00\x16\x00\x00\x00\x41\x00\x00\x00" +"\x00\x01\x00\x00\x32\x00\x04\x00\x16\x00\x00\x00\x42\x00\x00\x00\x15\x00\x00\x00\x1E\x00\x0C\x00\x43\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\x44\x00\x00\x00\x02\x00\x00\x00\x43\x00\x00\x00\x3B\x00\x04\x00\x44\x00\x00\x00\x45\x00\x00\x00" +"\x02\x00\x00\x00\x20\x00\x04\x00\x46\x00\x00\x00\x01\x00\x00\x00\x12\x00\x00\x00\x3B\x00\x04\x00\x46\x00\x00\x00\x47\x00\x00\x00" +"\x01\x00\x00\x00\x20\x00\x04\x00\x48\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00\x48\x00\x00\x00\x49\x00\x00\x00" +"\x01\x00\x00\x00\x3B\x00\x04\x00\x46\x00\x00\x00\x4A\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x4B\x00\x00\x00" +"\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x4C\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x4D\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\x3E\x00\x03\x00\x39\x00\x00\x00\x3A\x00\x00\x00\x39\x00\x04\x00" +"\x07\x00\x00\x00\x3E\x00\x00\x00\x09\x00\x00\x00\x41\x00\x05\x00\x3F\x00\x00\x00\x40\x00\x00\x00\x3D\x00\x00\x00\x17\x00\x00\x00" +"\x3E\x00\x03\x00\x40\x00\x00\x00\x3E\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\x01\x00\x08\x00\x58\x01\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\x35\x00\x00\x00\x08\x01\x00\x00\x43\x01\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\x07\x00\x0E\x00\x00\x00\x66\x6F\x67\x33\x61\x64\x64\x69\x74\x69\x76\x65\x28\x76\x66\x33\x3B\x00\x00\x00" +"\x05\x00\x06\x00\x0D\x00\x00\x00\x72\x65\x67\x75\x6C\x61\x72\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x05\x00\x14\x00\x00\x00" +"\x66\x6F\x67\x34\x28\x76\x66\x34\x3B\x00\x00\x00\x05\x00\x06\x00\x13\x00\x00\x00\x72\x65\x67\x75\x6C\x61\x72\x63\x6F\x6C\x6F\x75" +"\x72\x00\x00\x00\x05\x00\x07\x00\x17\x00\x00\x00\x66\x6F\x67\x34\x61\x64\x64\x69\x74\x69\x76\x65\x28\x76\x66\x34\x3B\x00\x00\x00" +"\x05\x00\x06\x00\x16\x00\x00\x00\x72\x65\x67\x75\x6C\x61\x72\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x06\x00\x1A\x00\x00\x00" +"\x66\x6F\x67\x34\x62\x6C\x65\x6E\x64\x28\x76\x66\x34\x3B\x00\x00\x05\x00\x06\x00\x19\x00\x00\x00\x72\x65\x67\x75\x6C\x61\x72\x63" +"\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x03\x00\x27\x00\x00\x00\x7A\x00\x00\x00\x05\x00\x05\x00\x2D\x00\x00\x00\x65\x6E\x74\x69" +"\x74\x79\x62\x6C\x6F\x63\x6B\x00\x06\x00\x07\x00\x2D\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\x2D\x00\x00\x00\x01\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x00\x06\x00\x06\x00\x2D\x00\x00\x00" +"\x02\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x69\x6E\x76\x00\x00\x06\x00\x06\x00\x2D\x00\x00\x00\x03\x00\x00\x00\x65\x5F\x65\x79" +"\x65\x70\x6F\x73\x00\x00\x00\x00\x06\x00\x05\x00\x2D\x00\x00\x00\x04\x00\x00\x00\x65\x5F\x74\x69\x6D\x65\x00\x00\x06\x00\x07\x00" +"\x2D\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\x2D\x00\x00\x00" +"\x06\x00\x00\x00\x65\x70\x61\x64\x31\x00\x00\x00\x06\x00\x06\x00\x2D\x00\x00\x00\x07\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F" +"\x64\x69\x72\x00\x06\x00\x05\x00\x2D\x00\x00\x00\x08\x00\x00\x00\x65\x70\x61\x64\x32\x00\x00\x00\x06\x00\x06\x00\x2D\x00\x00\x00" +"\x09\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x6D\x75\x6C\x00\x06\x00\x05\x00\x2D\x00\x00\x00\x0A\x00\x00\x00\x65\x70\x61\x64" +"\x33\x00\x00\x00\x06\x00\x06\x00\x2D\x00\x00\x00\x0B\x00\x00\x00\x65\x5F\x6C\x6D\x73\x63\x61\x6C\x65\x73\x00\x00\x06\x00\x07\x00" +"\x2D\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\x2D\x00\x00\x00" +"\x0D\x00\x00\x00\x65\x70\x61\x64\x34\x00\x00\x00\x06\x00\x07\x00\x2D\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\x2D\x00\x00\x00\x0F\x00\x00\x00\x65\x70\x61\x64\x35\x00\x00\x00\x06\x00\x06\x00" +"\x2D\x00\x00\x00\x10\x00\x00\x00\x65\x5F\x67\x6C\x6F\x77\x6D\x6F\x64\x00\x00\x00\x06\x00\x05\x00\x2D\x00\x00\x00\x11\x00\x00\x00" +"\x65\x70\x61\x64\x36\x00\x00\x00\x06\x00\x07\x00\x2D\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\x2D\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\x2D\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" +"\x2D\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\x2D\x00\x00\x00" +"\x16\x00\x00\x00\x65\x70\x61\x64\x37\x00\x00\x00\x05\x00\x03\x00\x2F\x00\x00\x00\x00\x00\x00\x00\x05\x00\x06\x00\x35\x00\x00\x00" +"\x67\x6C\x5F\x46\x72\x61\x67\x43\x6F\x6F\x72\x64\x00\x00\x00\x00\x05\x00\x03\x00\x4D\x00\x00\x00\x66\x61\x63\x00\x05\x00\x03\x00" +"\x6E\x00\x00\x00\x7A\x00\x00\x00\x05\x00\x03\x00\x82\x00\x00\x00\x66\x61\x63\x00\x05\x00\x04\x00\x9B\x00\x00\x00\x70\x61\x72\x61" +"\x6D\x00\x00\x00\x05\x00\x03\x00\xAE\x00\x00\x00\x7A\x00\x00\x00\x05\x00\x03\x00\xC2\x00\x00\x00\x66\x61\x63\x00\x05\x00\x03\x00" +"\xDE\x00\x00\x00\x7A\x00\x00\x00\x05\x00\x03\x00\xF2\x00\x00\x00\x66\x61\x63\x00\x05\x00\x03\x00\x06\x01\x00\x00\x64\x69\x72\x00" +"\x05\x00\x03\x00\x08\x01\x00\x00\x70\x6F\x73\x00\x05\x00\x04\x00\x1F\x01\x00\x00\x74\x63\x63\x6F\x6F\x72\x64\x00\x05\x00\x04\x00" +"\x29\x01\x00\x00\x73\x6F\x6C\x69\x64\x00\x00\x00\x05\x00\x04\x00\x2D\x01\x00\x00\x73\x5F\x74\x30\x00\x00\x00\x00\x05\x00\x04\x00" +"\x3D\x01\x00\x00\x63\x6C\x6F\x75\x64\x73\x00\x00\x05\x00\x04\x00\x3E\x01\x00\x00\x73\x5F\x74\x31\x00\x00\x00\x00\x05\x00\x05\x00" +"\x43\x01\x00\x00\x6F\x75\x74\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x04\x00\x4F\x01\x00\x00\x70\x61\x72\x61\x6D\x00\x00\x00" +"\x05\x00\x05\x00\x55\x01\x00\x00\x6C\x69\x67\x68\x74\x62\x6C\x6F\x63\x6B\x00\x00\x06\x00\x07\x00\x55\x01\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\x55\x01\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\x55\x01\x00\x00\x02\x00\x00\x00\x6C\x70\x61\x64\x31\x00\x00\x00" +"\x06\x00\x07\x00\x55\x01\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" +"\x55\x01\x00\x00\x04\x00\x00\x00\x6C\x70\x61\x64\x32\x00\x00\x00\x06\x00\x08\x00\x55\x01\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\x55\x01\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\x55\x01\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\x55\x01\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\x55\x01\x00\x00\x09\x00\x00\x00\x6C\x70\x61\x64\x33\x00\x00\x00\x05\x00\x03\x00" +"\x57\x01\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x1D\x00\x00\x00\x01\x00\x00\x00\x15\x00\x00\x00\x47\x00\x04\x00\x2B\x00\x00\x00" +"\x06\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00\x2D\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00" +"\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00" +"\x48\x00\x04\x00\x2D\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x01\x00\x00\x00\x23\x00\x00\x00" +"\x40\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00\x2D\x00\x00\x00" +"\x02\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x02\x00\x00\x00\x23\x00\x00\x00\x80\x00\x00\x00\x48\x00\x05\x00" +"\x2D\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x03\x00\x00\x00\x23\x00\x00\x00" +"\xC0\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00\xCC\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00" +"\x05\x00\x00\x00\x23\x00\x00\x00\xD0\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x06\x00\x00\x00\x23\x00\x00\x00\xDC\x00\x00\x00" +"\x48\x00\x05\x00\x2D\x00\x00\x00\x07\x00\x00\x00\x23\x00\x00\x00\xE0\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x08\x00\x00\x00" +"\x23\x00\x00\x00\xEC\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x09\x00\x00\x00\x23\x00\x00\x00\xF0\x00\x00\x00\x48\x00\x05\x00" +"\x2D\x00\x00\x00\x0A\x00\x00\x00\x23\x00\x00\x00\xFC\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x0B\x00\x00\x00\x23\x00\x00\x00" +"\x00\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x0C\x00\x00\x00\x23\x00\x00\x00\x40\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00" +"\x0D\x00\x00\x00\x23\x00\x00\x00\x4C\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x0E\x00\x00\x00\x23\x00\x00\x00\x50\x01\x00\x00" +"\x48\x00\x05\x00\x2D\x00\x00\x00\x0F\x00\x00\x00\x23\x00\x00\x00\x5C\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x10\x00\x00\x00" +"\x23\x00\x00\x00\x60\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x11\x00\x00\x00\x23\x00\x00\x00\x6C\x01\x00\x00\x48\x00\x05\x00" +"\x2D\x00\x00\x00\x12\x00\x00\x00\x23\x00\x00\x00\x70\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x13\x00\x00\x00\x23\x00\x00\x00" +"\x80\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x14\x00\x00\x00\x23\x00\x00\x00\x90\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00" +"\x15\x00\x00\x00\x23\x00\x00\x00\x94\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x16\x00\x00\x00\x23\x00\x00\x00\x98\x01\x00\x00" +"\x47\x00\x03\x00\x2D\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x2F\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00" +"\x2F\x00\x00\x00\x21\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x35\x00\x00\x00\x0B\x00\x00\x00\x0F\x00\x00\x00\x47\x00\x04\x00" +"\x46\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x47\x00\x04\x00\x08\x01\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00" "\x2D\x01\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x2D\x01\x00\x00\x21\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00" "\x3E\x01\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x3E\x01\x00\x00\x21\x00\x00\x00\x03\x00\x00\x00\x47\x00\x04\x00" "\x43\x01\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x48\x00\x04\x00\x55\x01\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00" @@ -4513,7 +4517,7 @@ 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" -"\x7C\x0F\x00\x00\xBC\x0F\x00\x00\x30\x1F\x00\x00\x01\x00\x62\x31\x72\x5F\x66\x6F\x67\x5F\x65\x78\x70\x32\x00\x00\x00\x00\x00\x43" +"\x8C\x0F\x00\x00\xCC\x0F\x00\x00\x40\x1F\x00\x00\x01\x00\x62\x31\x72\x5F\x66\x6F\x67\x5F\x65\x78\x70\x32\x00\x00\x00\x00\x00\x23" "\x03\x02\x23\x07\x00\x00\x01\x00\x01\x00\x08\x00\x58\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" @@ -4574,139 +4578,140 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "\x13\x00\x00\x00\x15\x00\x00\x00\x23\x00\x00\x00\x94\x01\x00\x00\x48\x00\x05\x00\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" -"\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\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\x15\x00\x04\x00\x0F\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00\x10\x00\x00\x00" -"\x04\x00\x00\x00\x1C\x00\x04\x00\x11\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x17\x00\x04\x00\x12\x00\x00\x00\x06\x00\x00\x00" -"\x02\x00\x00\x00\x1E\x00\x19\x00\x13\x00\x00\x00\x0D\x00\x00\x00\x0D\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\x0E\x00\x00\x00\x06\x00\x00\x00\x11\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\x07\x00\x00\x00\x06\x00\x00\x00" -"\x06\x00\x00\x00\x12\x00\x00\x00\x20\x00\x04\x00\x14\x00\x00\x00\x02\x00\x00\x00\x13\x00\x00\x00\x3B\x00\x04\x00\x14\x00\x00\x00" -"\x15\x00\x00\x00\x02\x00\x00\x00\x15\x00\x04\x00\x16\x00\x00\x00\x20\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00\x16\x00\x00\x00" -"\x17\x00\x00\x00\x00\x00\x00\x00\x20\x00\x04\x00\x18\x00\x00\x00\x02\x00\x00\x00\x0D\x00\x00\x00\x20\x00\x04\x00\x1B\x00\x00\x00" -"\x01\x00\x00\x00\x0E\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x1C\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00\x06\x00\x00\x00" -"\x1E\x00\x00\x00\x00\x00\x80\x3F\x2B\x00\x04\x00\x06\x00\x00\x00\x24\x00\x00\x00\x00\x00\x80\xBF\x2B\x00\x04\x00\x0F\x00\x00\x00" -"\x25\x00\x00\x00\x01\x00\x00\x00\x20\x00\x04\x00\x26\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00" -"\x2B\x00\x00\x00\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\x01\x00\x08\x00\x1D\x01\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\x35\x00\x00\x00\x0D\x01\x00\x00\x11\x01\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\x07\x00\x0E\x00\x00\x00\x66\x6F\x67\x33\x61\x64\x64\x69" -"\x74\x69\x76\x65\x28\x76\x66\x33\x3B\x00\x00\x00\x05\x00\x06\x00\x0D\x00\x00\x00\x72\x65\x67\x75\x6C\x61\x72\x63\x6F\x6C\x6F\x75" -"\x72\x00\x00\x00\x05\x00\x05\x00\x14\x00\x00\x00\x66\x6F\x67\x34\x28\x76\x66\x34\x3B\x00\x00\x00\x05\x00\x06\x00\x13\x00\x00\x00" -"\x72\x65\x67\x75\x6C\x61\x72\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x07\x00\x17\x00\x00\x00\x66\x6F\x67\x34\x61\x64\x64\x69" -"\x74\x69\x76\x65\x28\x76\x66\x34\x3B\x00\x00\x00\x05\x00\x06\x00\x16\x00\x00\x00\x72\x65\x67\x75\x6C\x61\x72\x63\x6F\x6C\x6F\x75" -"\x72\x00\x00\x00\x05\x00\x06\x00\x1A\x00\x00\x00\x66\x6F\x67\x34\x62\x6C\x65\x6E\x64\x28\x76\x66\x34\x3B\x00\x00\x05\x00\x06\x00" -"\x19\x00\x00\x00\x72\x65\x67\x75\x6C\x61\x72\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x03\x00\x27\x00\x00\x00\x7A\x00\x00\x00" -"\x05\x00\x05\x00\x2D\x00\x00\x00\x65\x6E\x74\x69\x74\x79\x62\x6C\x6F\x63\x6B\x00\x06\x00\x07\x00\x2D\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\x2D\x00\x00\x00\x01\x00\x00\x00\x6D\x5F\x6D\x6F" -"\x64\x65\x6C\x00\x06\x00\x06\x00\x2D\x00\x00\x00\x02\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x69\x6E\x76\x00\x00\x06\x00\x06\x00" -"\x2D\x00\x00\x00\x03\x00\x00\x00\x65\x5F\x65\x79\x65\x70\x6F\x73\x00\x00\x00\x00\x06\x00\x05\x00\x2D\x00\x00\x00\x04\x00\x00\x00" -"\x65\x5F\x74\x69\x6D\x65\x00\x00\x06\x00\x07\x00\x2D\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\x2D\x00\x00\x00\x06\x00\x00\x00\x65\x70\x61\x64\x31\x00\x00\x00\x06\x00\x06\x00\x2D\x00\x00\x00" -"\x07\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x64\x69\x72\x00\x06\x00\x05\x00\x2D\x00\x00\x00\x08\x00\x00\x00\x65\x70\x61\x64" -"\x32\x00\x00\x00\x06\x00\x06\x00\x2D\x00\x00\x00\x09\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x6D\x75\x6C\x00\x06\x00\x05\x00" -"\x2D\x00\x00\x00\x0A\x00\x00\x00\x65\x70\x61\x64\x33\x00\x00\x00\x06\x00\x06\x00\x2D\x00\x00\x00\x0B\x00\x00\x00\x65\x5F\x6C\x6D" -"\x73\x63\x61\x6C\x65\x73\x00\x00\x06\x00\x07\x00\x2D\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\x2D\x00\x00\x00\x0D\x00\x00\x00\x65\x70\x61\x64\x34\x00\x00\x00\x06\x00\x07\x00\x2D\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\x2D\x00\x00\x00\x0F\x00\x00\x00" -"\x65\x70\x61\x64\x35\x00\x00\x00\x06\x00\x06\x00\x2D\x00\x00\x00\x10\x00\x00\x00\x65\x5F\x67\x6C\x6F\x77\x6D\x6F\x64\x00\x00\x00" -"\x06\x00\x05\x00\x2D\x00\x00\x00\x11\x00\x00\x00\x65\x70\x61\x64\x36\x00\x00\x00\x06\x00\x07\x00\x2D\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\x2D\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\x2D\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\x2D\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\x2D\x00\x00\x00\x16\x00\x00\x00\x65\x70\x61\x64\x37\x00\x00\x00\x05\x00\x03\x00\x2F\x00\x00\x00" -"\x00\x00\x00\x00\x05\x00\x06\x00\x35\x00\x00\x00\x67\x6C\x5F\x46\x72\x61\x67\x43\x6F\x6F\x72\x64\x00\x00\x00\x00\x05\x00\x03\x00" -"\x4D\x00\x00\x00\x66\x61\x63\x00\x05\x00\x03\x00\x6E\x00\x00\x00\x7A\x00\x00\x00\x05\x00\x03\x00\x82\x00\x00\x00\x66\x61\x63\x00" -"\x05\x00\x04\x00\x9B\x00\x00\x00\x70\x61\x72\x61\x6D\x00\x00\x00\x05\x00\x03\x00\xAE\x00\x00\x00\x7A\x00\x00\x00\x05\x00\x03\x00" -"\xC2\x00\x00\x00\x66\x61\x63\x00\x05\x00\x03\x00\xDE\x00\x00\x00\x7A\x00\x00\x00\x05\x00\x03\x00\xF2\x00\x00\x00\x66\x61\x63\x00" -"\x05\x00\x04\x00\x06\x01\x00\x00\x73\x6B\x79\x62\x6F\x78\x00\x00\x05\x00\x06\x00\x0A\x01\x00\x00\x73\x5F\x72\x65\x66\x6C\x65\x63" -"\x74\x63\x75\x62\x65\x00\x00\x00\x05\x00\x03\x00\x0D\x01\x00\x00\x70\x6F\x73\x00\x05\x00\x05\x00\x11\x01\x00\x00\x6F\x75\x74\x63" -"\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x04\x00\x12\x01\x00\x00\x70\x61\x72\x61\x6D\x00\x00\x00\x05\x00\x05\x00\x1A\x01\x00\x00" -"\x6C\x69\x67\x68\x74\x62\x6C\x6F\x63\x6B\x00\x00\x06\x00\x07\x00\x1A\x01\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\x1A\x01\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\x1A\x01\x00\x00\x02\x00\x00\x00\x6C\x70\x61\x64\x31\x00\x00\x00\x06\x00\x07\x00\x1A\x01\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\x1A\x01\x00\x00\x04\x00\x00\x00" -"\x6C\x70\x61\x64\x32\x00\x00\x00\x06\x00\x08\x00\x1A\x01\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\x1A\x01\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\x1A\x01\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\x1A\x01\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\x1A\x01\x00\x00\x09\x00\x00\x00\x6C\x70\x61\x64\x33\x00\x00\x00\x05\x00\x03\x00\x1C\x01\x00\x00\x00\x00\x00\x00" -"\x47\x00\x04\x00\x1D\x00\x00\x00\x01\x00\x00\x00\x15\x00\x00\x00\x47\x00\x04\x00\x2B\x00\x00\x00\x06\x00\x00\x00\x10\x00\x00\x00" -"\x48\x00\x04\x00\x2D\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00" -"\x00\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00\x2D\x00\x00\x00" -"\x01\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x01\x00\x00\x00\x23\x00\x00\x00\x40\x00\x00\x00\x48\x00\x05\x00" -"\x2D\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00\x2D\x00\x00\x00\x02\x00\x00\x00\x05\x00\x00\x00" -"\x48\x00\x05\x00\x2D\x00\x00\x00\x02\x00\x00\x00\x23\x00\x00\x00\x80\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x02\x00\x00\x00" -"\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x03\x00\x00\x00\x23\x00\x00\x00\xC0\x00\x00\x00\x48\x00\x05\x00" -"\x2D\x00\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00\xCC\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x05\x00\x00\x00\x23\x00\x00\x00" -"\xD0\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x06\x00\x00\x00\x23\x00\x00\x00\xDC\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00" -"\x07\x00\x00\x00\x23\x00\x00\x00\xE0\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x08\x00\x00\x00\x23\x00\x00\x00\xEC\x00\x00\x00" -"\x48\x00\x05\x00\x2D\x00\x00\x00\x09\x00\x00\x00\x23\x00\x00\x00\xF0\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x0A\x00\x00\x00" -"\x23\x00\x00\x00\xFC\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x0B\x00\x00\x00\x23\x00\x00\x00\x00\x01\x00\x00\x48\x00\x05\x00" -"\x2D\x00\x00\x00\x0C\x00\x00\x00\x23\x00\x00\x00\x40\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x0D\x00\x00\x00\x23\x00\x00\x00" -"\x4C\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x0E\x00\x00\x00\x23\x00\x00\x00\x50\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00" -"\x0F\x00\x00\x00\x23\x00\x00\x00\x5C\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x10\x00\x00\x00\x23\x00\x00\x00\x60\x01\x00\x00" -"\x48\x00\x05\x00\x2D\x00\x00\x00\x11\x00\x00\x00\x23\x00\x00\x00\x6C\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x12\x00\x00\x00" -"\x23\x00\x00\x00\x70\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x13\x00\x00\x00\x23\x00\x00\x00\x80\x01\x00\x00\x48\x00\x05\x00" -"\x2D\x00\x00\x00\x14\x00\x00\x00\x23\x00\x00\x00\x90\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x15\x00\x00\x00\x23\x00\x00\x00" -"\x94\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x16\x00\x00\x00\x23\x00\x00\x00\x98\x01\x00\x00\x47\x00\x03\x00\x2D\x00\x00\x00" -"\x02\x00\x00\x00\x47\x00\x04\x00\x2F\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x2F\x00\x00\x00\x21\x00\x00\x00" -"\x00\x00\x00\x00\x47\x00\x04\x00\x35\x00\x00\x00\x0B\x00\x00\x00\x0F\x00\x00\x00\x47\x00\x04\x00\x46\x00\x00\x00\x01\x00\x00\x00" -"\x00\x01\x00\x00\x47\x00\x04\x00\x0A\x01\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x0A\x01\x00\x00\x21\x00\x00\x00" -"\x02\x00\x00\x00\x47\x00\x04\x00\x11\x01\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x48\x00\x04\x00\x1A\x01\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\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\x15\x00\x04\x00\x0F\x00\x00\x00\x20\x00\x00\x00" +"\x00\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00\x10\x00\x00\x00\x04\x00\x00\x00\x1C\x00\x04\x00\x11\x00\x00\x00\x07\x00\x00\x00" +"\x10\x00\x00\x00\x17\x00\x04\x00\x12\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x1E\x00\x19\x00\x13\x00\x00\x00\x0D\x00\x00\x00" +"\x0D\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" +"\x0E\x00\x00\x00\x06\x00\x00\x00\x11\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\x07\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x12\x00\x00\x00\x20\x00\x04\x00\x14\x00\x00\x00" +"\x02\x00\x00\x00\x13\x00\x00\x00\x3B\x00\x04\x00\x14\x00\x00\x00\x15\x00\x00\x00\x02\x00\x00\x00\x15\x00\x04\x00\x16\x00\x00\x00" +"\x20\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00\x16\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x20\x00\x04\x00\x18\x00\x00\x00" +"\x02\x00\x00\x00\x0D\x00\x00\x00\x20\x00\x04\x00\x1B\x00\x00\x00\x01\x00\x00\x00\x0E\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00" +"\x1C\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00\x06\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x80\x3F\x2B\x00\x04\x00\x06\x00\x00\x00" +"\x24\x00\x00\x00\x00\x00\x80\xBF\x2B\x00\x04\x00\x0F\x00\x00\x00\x25\x00\x00\x00\x01\x00\x00\x00\x20\x00\x04\x00\x26\x00\x00\x00" +"\x07\x00\x00\x00\x06\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00\x2B\x00\x00\x00\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\x01\x00\x08\x00\x1D\x01\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" +"\x35\x00\x00\x00\x0D\x01\x00\x00\x11\x01\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\x07\x00\x0E\x00\x00\x00\x66\x6F\x67\x33\x61\x64\x64\x69\x74\x69\x76\x65\x28\x76\x66\x33\x3B\x00\x00\x00\x05\x00\x06\x00" +"\x0D\x00\x00\x00\x72\x65\x67\x75\x6C\x61\x72\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x05\x00\x14\x00\x00\x00\x66\x6F\x67\x34" +"\x28\x76\x66\x34\x3B\x00\x00\x00\x05\x00\x06\x00\x13\x00\x00\x00\x72\x65\x67\x75\x6C\x61\x72\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00" +"\x05\x00\x07\x00\x17\x00\x00\x00\x66\x6F\x67\x34\x61\x64\x64\x69\x74\x69\x76\x65\x28\x76\x66\x34\x3B\x00\x00\x00\x05\x00\x06\x00" +"\x16\x00\x00\x00\x72\x65\x67\x75\x6C\x61\x72\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x06\x00\x1A\x00\x00\x00\x66\x6F\x67\x34" +"\x62\x6C\x65\x6E\x64\x28\x76\x66\x34\x3B\x00\x00\x05\x00\x06\x00\x19\x00\x00\x00\x72\x65\x67\x75\x6C\x61\x72\x63\x6F\x6C\x6F\x75" +"\x72\x00\x00\x00\x05\x00\x03\x00\x27\x00\x00\x00\x7A\x00\x00\x00\x05\x00\x05\x00\x2D\x00\x00\x00\x65\x6E\x74\x69\x74\x79\x62\x6C" +"\x6F\x63\x6B\x00\x06\x00\x07\x00\x2D\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\x2D\x00\x00\x00\x01\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x00\x06\x00\x06\x00\x2D\x00\x00\x00\x02\x00\x00\x00" +"\x6D\x5F\x6D\x6F\x64\x65\x6C\x69\x6E\x76\x00\x00\x06\x00\x06\x00\x2D\x00\x00\x00\x03\x00\x00\x00\x65\x5F\x65\x79\x65\x70\x6F\x73" +"\x00\x00\x00\x00\x06\x00\x05\x00\x2D\x00\x00\x00\x04\x00\x00\x00\x65\x5F\x74\x69\x6D\x65\x00\x00\x06\x00\x07\x00\x2D\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\x2D\x00\x00\x00\x06\x00\x00\x00" +"\x65\x70\x61\x64\x31\x00\x00\x00\x06\x00\x06\x00\x2D\x00\x00\x00\x07\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x64\x69\x72\x00" +"\x06\x00\x05\x00\x2D\x00\x00\x00\x08\x00\x00\x00\x65\x70\x61\x64\x32\x00\x00\x00\x06\x00\x06\x00\x2D\x00\x00\x00\x09\x00\x00\x00" +"\x65\x5F\x6C\x69\x67\x68\x74\x5F\x6D\x75\x6C\x00\x06\x00\x05\x00\x2D\x00\x00\x00\x0A\x00\x00\x00\x65\x70\x61\x64\x33\x00\x00\x00" +"\x06\x00\x06\x00\x2D\x00\x00\x00\x0B\x00\x00\x00\x65\x5F\x6C\x6D\x73\x63\x61\x6C\x65\x73\x00\x00\x06\x00\x07\x00\x2D\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\x2D\x00\x00\x00\x0D\x00\x00\x00" +"\x65\x70\x61\x64\x34\x00\x00\x00\x06\x00\x07\x00\x2D\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\x2D\x00\x00\x00\x0F\x00\x00\x00\x65\x70\x61\x64\x35\x00\x00\x00\x06\x00\x06\x00\x2D\x00\x00\x00" +"\x10\x00\x00\x00\x65\x5F\x67\x6C\x6F\x77\x6D\x6F\x64\x00\x00\x00\x06\x00\x05\x00\x2D\x00\x00\x00\x11\x00\x00\x00\x65\x70\x61\x64" +"\x36\x00\x00\x00\x06\x00\x07\x00\x2D\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\x2D\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" +"\x2D\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\x2D\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\x2D\x00\x00\x00\x16\x00\x00\x00" +"\x65\x70\x61\x64\x37\x00\x00\x00\x05\x00\x03\x00\x2F\x00\x00\x00\x00\x00\x00\x00\x05\x00\x06\x00\x35\x00\x00\x00\x67\x6C\x5F\x46" +"\x72\x61\x67\x43\x6F\x6F\x72\x64\x00\x00\x00\x00\x05\x00\x03\x00\x4D\x00\x00\x00\x66\x61\x63\x00\x05\x00\x03\x00\x6E\x00\x00\x00" +"\x7A\x00\x00\x00\x05\x00\x03\x00\x82\x00\x00\x00\x66\x61\x63\x00\x05\x00\x04\x00\x9B\x00\x00\x00\x70\x61\x72\x61\x6D\x00\x00\x00" +"\x05\x00\x03\x00\xAE\x00\x00\x00\x7A\x00\x00\x00\x05\x00\x03\x00\xC2\x00\x00\x00\x66\x61\x63\x00\x05\x00\x03\x00\xDE\x00\x00\x00" +"\x7A\x00\x00\x00\x05\x00\x03\x00\xF2\x00\x00\x00\x66\x61\x63\x00\x05\x00\x04\x00\x06\x01\x00\x00\x73\x6B\x79\x62\x6F\x78\x00\x00" +"\x05\x00\x06\x00\x0A\x01\x00\x00\x73\x5F\x72\x65\x66\x6C\x65\x63\x74\x63\x75\x62\x65\x00\x00\x00\x05\x00\x03\x00\x0D\x01\x00\x00" +"\x70\x6F\x73\x00\x05\x00\x05\x00\x11\x01\x00\x00\x6F\x75\x74\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x04\x00\x12\x01\x00\x00" +"\x70\x61\x72\x61\x6D\x00\x00\x00\x05\x00\x05\x00\x1A\x01\x00\x00\x6C\x69\x67\x68\x74\x62\x6C\x6F\x63\x6B\x00\x00\x06\x00\x07\x00" +"\x1A\x01\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\x1A\x01\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\x1A\x01\x00\x00\x02\x00\x00\x00" +"\x6C\x70\x61\x64\x31\x00\x00\x00\x06\x00\x07\x00\x1A\x01\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\x1A\x01\x00\x00\x04\x00\x00\x00\x6C\x70\x61\x64\x32\x00\x00\x00\x06\x00\x08\x00\x1A\x01\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\x1A\x01\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\x1A\x01\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\x1A\x01\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\x1A\x01\x00\x00\x09\x00\x00\x00\x6C\x70\x61\x64" +"\x33\x00\x00\x00\x05\x00\x03\x00\x1C\x01\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x1D\x00\x00\x00\x01\x00\x00\x00\x15\x00\x00\x00" +"\x47\x00\x04\x00\x2B\x00\x00\x00\x06\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00\x2D\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00" +"\x48\x00\x05\x00\x2D\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x00\x00\x00\x00" +"\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00\x2D\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00" +"\x01\x00\x00\x00\x23\x00\x00\x00\x40\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00" +"\x48\x00\x04\x00\x2D\x00\x00\x00\x02\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x02\x00\x00\x00\x23\x00\x00\x00" +"\x80\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00" +"\x03\x00\x00\x00\x23\x00\x00\x00\xC0\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00\xCC\x00\x00\x00" +"\x48\x00\x05\x00\x2D\x00\x00\x00\x05\x00\x00\x00\x23\x00\x00\x00\xD0\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x06\x00\x00\x00" +"\x23\x00\x00\x00\xDC\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x07\x00\x00\x00\x23\x00\x00\x00\xE0\x00\x00\x00\x48\x00\x05\x00" +"\x2D\x00\x00\x00\x08\x00\x00\x00\x23\x00\x00\x00\xEC\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x09\x00\x00\x00\x23\x00\x00\x00" +"\xF0\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x0A\x00\x00\x00\x23\x00\x00\x00\xFC\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00" +"\x0B\x00\x00\x00\x23\x00\x00\x00\x00\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x0C\x00\x00\x00\x23\x00\x00\x00\x40\x01\x00\x00" +"\x48\x00\x05\x00\x2D\x00\x00\x00\x0D\x00\x00\x00\x23\x00\x00\x00\x4C\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x0E\x00\x00\x00" +"\x23\x00\x00\x00\x50\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x0F\x00\x00\x00\x23\x00\x00\x00\x5C\x01\x00\x00\x48\x00\x05\x00" +"\x2D\x00\x00\x00\x10\x00\x00\x00\x23\x00\x00\x00\x60\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x11\x00\x00\x00\x23\x00\x00\x00" +"\x6C\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x12\x00\x00\x00\x23\x00\x00\x00\x70\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00" +"\x13\x00\x00\x00\x23\x00\x00\x00\x80\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x14\x00\x00\x00\x23\x00\x00\x00\x90\x01\x00\x00" +"\x48\x00\x05\x00\x2D\x00\x00\x00\x15\x00\x00\x00\x23\x00\x00\x00\x94\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x16\x00\x00\x00" +"\x23\x00\x00\x00\x98\x01\x00\x00\x47\x00\x03\x00\x2D\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x2F\x00\x00\x00\x22\x00\x00\x00" +"\x00\x00\x00\x00\x47\x00\x04\x00\x2F\x00\x00\x00\x21\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x35\x00\x00\x00\x0B\x00\x00\x00" +"\x0F\x00\x00\x00\x47\x00\x04\x00\x46\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x47\x00\x04\x00\x0A\x01\x00\x00\x22\x00\x00\x00" +"\x00\x00\x00\x00\x47\x00\x04\x00\x0A\x01\x00\x00\x21\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x0D\x01\x00\x00\x1E\x00\x00\x00" +"\x00\x00\x00\x00\x47\x00\x04\x00\x11\x01\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x48\x00\x04\x00\x1A\x01\x00\x00\x00\x00\x00\x00" "\x05\x00\x00\x00\x48\x00\x05\x00\x1A\x01\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00\x1A\x01\x00\x00" "\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x05\x00\x1A\x01\x00\x00\x01\x00\x00\x00\x23\x00\x00\x00\x40\x00\x00\x00" "\x48\x00\x05\x00\x1A\x01\x00\x00\x02\x00\x00\x00\x23\x00\x00\x00\x4C\x00\x00\x00\x48\x00\x05\x00\x1A\x01\x00\x00\x03\x00\x00\x00" @@ -4996,7 +5001,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND #ifdef VKQUAKE {QR_VULKAN, -1, "defaultfill", "\xFF\x53\x50\x56\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2C\x00\x00\x00\x00\x00\x00\x00\x2C\x00\x00\x00" -"\x70\x0E\x00\x00\x9C\x0E\x00\x00\x90\x09\x00\x00\x03\x02\x23\x07\x00\x00\x01\x00\x01\x00\x08\x00\x4B\x00\x00\x00\x00\x00\x00\x00" +"\x80\x0E\x00\x00\xAC\x0E\x00\x00\xA0\x09\x00\x00\x03\x02\x23\x07\x00\x00\x01\x00\x01\x00\x08\x00\x4B\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\x3B\x00\x00\x00\x3F\x00\x00\x00\x46\x00\x00\x00\x47\x00\x00\x00\x48\x00\x00\x00\x49\x00\x00\x00" @@ -5056,95 +5061,96 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "\x23\x00\x00\x00\x90\x01\x00\x00\x48\x00\x05\x00\x13\x00\x00\x00\x15\x00\x00\x00\x23\x00\x00\x00\x94\x01\x00\x00\x48\x00\x05\x00" "\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\x3B\x00\x00\x00\x1E\x00\x00\x00\x02\x00\x00\x00\x48\x00\x05\x00" -"\x3D\x00\x00\x00\x00\x00\x00\x00\x0B\x00\x00\x00\x00\x00\x00\x00\x47\x00\x03\x00\x3D\x00\x00\x00\x02\x00\x00\x00\x48\x00\x04\x00" -"\x42\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x42\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00" -"\x48\x00\x05\x00\x42\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x05\x00\x42\x00\x00\x00\x01\x00\x00\x00" -"\x23\x00\x00\x00\x40\x00\x00\x00\x48\x00\x05\x00\x42\x00\x00\x00\x02\x00\x00\x00\x23\x00\x00\x00\x4C\x00\x00\x00\x48\x00\x05\x00" -"\x42\x00\x00\x00\x03\x00\x00\x00\x23\x00\x00\x00\x50\x00\x00\x00\x48\x00\x05\x00\x42\x00\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00" -"\x5C\x00\x00\x00\x48\x00\x05\x00\x42\x00\x00\x00\x05\x00\x00\x00\x23\x00\x00\x00\x60\x00\x00\x00\x48\x00\x05\x00\x42\x00\x00\x00" -"\x06\x00\x00\x00\x23\x00\x00\x00\x6C\x00\x00\x00\x48\x00\x05\x00\x42\x00\x00\x00\x07\x00\x00\x00\x23\x00\x00\x00\x70\x00\x00\x00" -"\x48\x00\x05\x00\x42\x00\x00\x00\x08\x00\x00\x00\x23\x00\x00\x00\x80\x00\x00\x00\x48\x00\x05\x00\x42\x00\x00\x00\x09\x00\x00\x00" -"\x23\x00\x00\x00\x88\x00\x00\x00\x47\x00\x03\x00\x42\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x44\x00\x00\x00\x22\x00\x00\x00" -"\x00\x00\x00\x00\x47\x00\x04\x00\x44\x00\x00\x00\x21\x00\x00\x00\x01\x00\x00\x00\x47\x00\x04\x00\x46\x00\x00\x00\x1E\x00\x00\x00" -"\x01\x00\x00\x00\x47\x00\x04\x00\x47\x00\x00\x00\x1E\x00\x00\x00\x03\x00\x00\x00\x47\x00\x04\x00\x48\x00\x00\x00\x1E\x00\x00\x00" -"\x04\x00\x00\x00\x47\x00\x04\x00\x49\x00\x00\x00\x1E\x00\x00\x00\x05\x00\x00\x00\x47\x00\x04\x00\x4A\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\x15\x00\x04\x00\x0F\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00" -"\x2B\x00\x04\x00\x0F\x00\x00\x00\x10\x00\x00\x00\x04\x00\x00\x00\x1C\x00\x04\x00\x11\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00" -"\x17\x00\x04\x00\x12\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x1E\x00\x19\x00\x13\x00\x00\x00\x0D\x00\x00\x00\x0D\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\x0E\x00\x00\x00" -"\x06\x00\x00\x00\x11\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\x07\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x12\x00\x00\x00\x20\x00\x04\x00\x14\x00\x00\x00\x02\x00\x00\x00" -"\x13\x00\x00\x00\x3B\x00\x04\x00\x14\x00\x00\x00\x15\x00\x00\x00\x02\x00\x00\x00\x15\x00\x04\x00\x16\x00\x00\x00\x20\x00\x00\x00" -"\x01\x00\x00\x00\x2B\x00\x04\x00\x16\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x20\x00\x04\x00\x18\x00\x00\x00\x02\x00\x00\x00" -"\x0D\x00\x00\x00\x20\x00\x04\x00\x1B\x00\x00\x00\x01\x00\x00\x00\x0E\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x1C\x00\x00\x00" -"\x01\x00\x00\x00\x2B\x00\x04\x00\x06\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x80\x3F\x2B\x00\x04\x00\x06\x00\x00\x00\x24\x00\x00\x00" -"\x00\x00\x80\xBF\x2B\x00\x04\x00\x0F\x00\x00\x00\x25\x00\x00\x00\x01\x00\x00\x00\x20\x00\x04\x00\x26\x00\x00\x00\x07\x00\x00\x00" -"\x06\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00\x2B\x00\x00\x00\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" -"\x07\x00\x00\x00\x3B\x00\x04\x00\x38\x00\x00\x00\x39\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00\x3A\x00\x00\x00\x01\x00\x00\x00" -"\x07\x00\x00\x00\x3B\x00\x04\x00\x3A\x00\x00\x00\x3B\x00\x00\x00\x01\x00\x00\x00\x1E\x00\x03\x00\x3D\x00\x00\x00\x07\x00\x00\x00" -"\x20\x00\x04\x00\x3E\x00\x00\x00\x03\x00\x00\x00\x3D\x00\x00\x00\x3B\x00\x04\x00\x3E\x00\x00\x00\x3F\x00\x00\x00\x03\x00\x00\x00" -"\x1E\x00\x0C\x00\x42\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\x43\x00\x00\x00\x02\x00\x00\x00\x42\x00\x00\x00" -"\x3B\x00\x04\x00\x43\x00\x00\x00\x44\x00\x00\x00\x02\x00\x00\x00\x20\x00\x04\x00\x45\x00\x00\x00\x01\x00\x00\x00\x12\x00\x00\x00" -"\x3B\x00\x04\x00\x45\x00\x00\x00\x46\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x45\x00\x00\x00\x47\x00\x00\x00\x01\x00\x00\x00" -"\x3B\x00\x04\x00\x1B\x00\x00\x00\x48\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x49\x00\x00\x00\x01\x00\x00\x00" -"\x3B\x00\x04\x00\x1B\x00\x00\x00\x4A\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\x07\x00\x00\x00\x3C\x00\x00\x00\x3B\x00\x00\x00\x3E\x00\x03\x00" -"\x39\x00\x00\x00\x3C\x00\x00\x00\x39\x00\x04\x00\x07\x00\x00\x00\x40\x00\x00\x00\x09\x00\x00\x00\x41\x00\x05\x00\x38\x00\x00\x00" -"\x41\x00\x00\x00\x3F\x00\x00\x00\x17\x00\x00\x00\x3E\x00\x03\x00\x41\x00\x00\x00\x40\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\x01\x00\x08\x00\x19\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\x07\x00" -"\x04\x00\x00\x00\x04\x00\x00\x00\x6D\x61\x69\x6E\x00\x00\x00\x00\x09\x00\x00\x00\x0B\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\x09\x00\x00\x00\x6F\x75\x74\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x03\x00\x0B\x00\x00\x00\x76\x63\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\x64\x65\x6C\x76\x69\x65\x77\x70\x72\x6F\x6A\x00\x06\x00\x05\x00\x13\x00\x00\x00\x01\x00\x00\x00\x6D\x5F\x6D\x6F" -"\x64\x65\x6C\x00\x06\x00\x06\x00\x13\x00\x00\x00\x02\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x69\x6E\x76\x00\x00\x06\x00\x06\x00" -"\x13\x00\x00\x00\x03\x00\x00\x00\x65\x5F\x65\x79\x65\x70\x6F\x73\x00\x00\x00\x00\x06\x00\x05\x00\x13\x00\x00\x00\x04\x00\x00\x00" -"\x65\x5F\x74\x69\x6D\x65\x00\x00\x06\x00\x07\x00\x13\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\x13\x00\x00\x00\x06\x00\x00\x00\x65\x70\x61\x64\x31\x00\x00\x00\x06\x00\x06\x00\x13\x00\x00\x00" -"\x07\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x64\x69\x72\x00\x06\x00\x05\x00\x13\x00\x00\x00\x08\x00\x00\x00\x65\x70\x61\x64" -"\x32\x00\x00\x00\x06\x00\x06\x00\x13\x00\x00\x00\x09\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x6D\x75\x6C\x00\x06\x00\x05\x00" -"\x13\x00\x00\x00\x0A\x00\x00\x00\x65\x70\x61\x64\x33\x00\x00\x00\x06\x00\x06\x00\x13\x00\x00\x00\x0B\x00\x00\x00\x65\x5F\x6C\x6D" -"\x73\x63\x61\x6C\x65\x73\x00\x00\x06\x00\x07\x00\x13\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\x13\x00\x00\x00\x0D\x00\x00\x00\x65\x70\x61\x64\x34\x00\x00\x00\x06\x00\x07\x00\x13\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\x13\x00\x00\x00\x0F\x00\x00\x00" -"\x65\x70\x61\x64\x35\x00\x00\x00\x06\x00\x06\x00\x13\x00\x00\x00\x10\x00\x00\x00\x65\x5F\x67\x6C\x6F\x77\x6D\x6F\x64\x00\x00\x00" -"\x06\x00\x05\x00\x13\x00\x00\x00\x11\x00\x00\x00\x65\x70\x61\x64\x36\x00\x00\x00\x06\x00\x07\x00\x13\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\x13\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\x13\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\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\x16\x00\x00\x00\x6C\x69\x67\x68\x74\x62\x6C\x6F\x63\x6B\x00\x00\x06\x00\x07\x00\x16\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\x16\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\x16\x00\x00\x00\x02\x00\x00\x00\x6C\x70\x61\x64" -"\x31\x00\x00\x00\x06\x00\x07\x00\x16\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\x16\x00\x00\x00\x04\x00\x00\x00\x6C\x70\x61\x64\x32\x00\x00\x00\x06\x00\x08\x00\x16\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\x16\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\x16\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\x16\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\x16\x00\x00\x00\x09\x00\x00\x00\x6C\x70\x61\x64\x33\x00\x00\x00" -"\x05\x00\x03\x00\x18\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x09\x00\x00\x00\x1E\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\x47\x00\x04\x00" +"\x3B\x00\x00\x00\x1E\x00\x00\x00\x02\x00\x00\x00\x48\x00\x05\x00\x3D\x00\x00\x00\x00\x00\x00\x00\x0B\x00\x00\x00\x00\x00\x00\x00" +"\x47\x00\x03\x00\x3D\x00\x00\x00\x02\x00\x00\x00\x48\x00\x04\x00\x42\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00" +"\x42\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00\x42\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00" +"\x10\x00\x00\x00\x48\x00\x05\x00\x42\x00\x00\x00\x01\x00\x00\x00\x23\x00\x00\x00\x40\x00\x00\x00\x48\x00\x05\x00\x42\x00\x00\x00" +"\x02\x00\x00\x00\x23\x00\x00\x00\x4C\x00\x00\x00\x48\x00\x05\x00\x42\x00\x00\x00\x03\x00\x00\x00\x23\x00\x00\x00\x50\x00\x00\x00" +"\x48\x00\x05\x00\x42\x00\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00\x5C\x00\x00\x00\x48\x00\x05\x00\x42\x00\x00\x00\x05\x00\x00\x00" +"\x23\x00\x00\x00\x60\x00\x00\x00\x48\x00\x05\x00\x42\x00\x00\x00\x06\x00\x00\x00\x23\x00\x00\x00\x6C\x00\x00\x00\x48\x00\x05\x00" +"\x42\x00\x00\x00\x07\x00\x00\x00\x23\x00\x00\x00\x70\x00\x00\x00\x48\x00\x05\x00\x42\x00\x00\x00\x08\x00\x00\x00\x23\x00\x00\x00" +"\x80\x00\x00\x00\x48\x00\x05\x00\x42\x00\x00\x00\x09\x00\x00\x00\x23\x00\x00\x00\x88\x00\x00\x00\x47\x00\x03\x00\x42\x00\x00\x00" +"\x02\x00\x00\x00\x47\x00\x04\x00\x44\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x44\x00\x00\x00\x21\x00\x00\x00" +"\x01\x00\x00\x00\x47\x00\x04\x00\x46\x00\x00\x00\x1E\x00\x00\x00\x01\x00\x00\x00\x47\x00\x04\x00\x47\x00\x00\x00\x1E\x00\x00\x00" +"\x03\x00\x00\x00\x47\x00\x04\x00\x48\x00\x00\x00\x1E\x00\x00\x00\x04\x00\x00\x00\x47\x00\x04\x00\x49\x00\x00\x00\x1E\x00\x00\x00" +"\x05\x00\x00\x00\x47\x00\x04\x00\x4A\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" +"\x15\x00\x04\x00\x0F\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00\x10\x00\x00\x00\x04\x00\x00\x00" +"\x1C\x00\x04\x00\x11\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x17\x00\x04\x00\x12\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00" +"\x1E\x00\x19\x00\x13\x00\x00\x00\x0D\x00\x00\x00\x0D\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\x0E\x00\x00\x00\x06\x00\x00\x00\x11\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\x07\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00" +"\x12\x00\x00\x00\x20\x00\x04\x00\x14\x00\x00\x00\x02\x00\x00\x00\x13\x00\x00\x00\x3B\x00\x04\x00\x14\x00\x00\x00\x15\x00\x00\x00" +"\x02\x00\x00\x00\x15\x00\x04\x00\x16\x00\x00\x00\x20\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00\x16\x00\x00\x00\x17\x00\x00\x00" +"\x00\x00\x00\x00\x20\x00\x04\x00\x18\x00\x00\x00\x02\x00\x00\x00\x0D\x00\x00\x00\x20\x00\x04\x00\x1B\x00\x00\x00\x01\x00\x00\x00" +"\x0E\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x1C\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00\x06\x00\x00\x00\x1E\x00\x00\x00" +"\x00\x00\x80\x3F\x2B\x00\x04\x00\x06\x00\x00\x00\x24\x00\x00\x00\x00\x00\x80\xBF\x2B\x00\x04\x00\x0F\x00\x00\x00\x25\x00\x00\x00" +"\x01\x00\x00\x00\x20\x00\x04\x00\x26\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00\x2B\x00\x00\x00" +"\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\x07\x00\x00\x00\x3B\x00\x04\x00\x38\x00\x00\x00\x39\x00\x00\x00" +"\x03\x00\x00\x00\x20\x00\x04\x00\x3A\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00\x3A\x00\x00\x00\x3B\x00\x00\x00" +"\x01\x00\x00\x00\x1E\x00\x03\x00\x3D\x00\x00\x00\x07\x00\x00\x00\x20\x00\x04\x00\x3E\x00\x00\x00\x03\x00\x00\x00\x3D\x00\x00\x00" +"\x3B\x00\x04\x00\x3E\x00\x00\x00\x3F\x00\x00\x00\x03\x00\x00\x00\x1E\x00\x0C\x00\x42\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\x43\x00\x00\x00\x02\x00\x00\x00\x42\x00\x00\x00\x3B\x00\x04\x00\x43\x00\x00\x00\x44\x00\x00\x00\x02\x00\x00\x00" +"\x20\x00\x04\x00\x45\x00\x00\x00\x01\x00\x00\x00\x12\x00\x00\x00\x3B\x00\x04\x00\x45\x00\x00\x00\x46\x00\x00\x00\x01\x00\x00\x00" +"\x3B\x00\x04\x00\x45\x00\x00\x00\x47\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x48\x00\x00\x00\x01\x00\x00\x00" +"\x3B\x00\x04\x00\x1B\x00\x00\x00\x49\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x4A\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" +"\x07\x00\x00\x00\x3C\x00\x00\x00\x3B\x00\x00\x00\x3E\x00\x03\x00\x39\x00\x00\x00\x3C\x00\x00\x00\x39\x00\x04\x00\x07\x00\x00\x00" +"\x40\x00\x00\x00\x09\x00\x00\x00\x41\x00\x05\x00\x38\x00\x00\x00\x41\x00\x00\x00\x3F\x00\x00\x00\x17\x00\x00\x00\x3E\x00\x03\x00" +"\x41\x00\x00\x00\x40\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\x01\x00\x08\x00\x19\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\x07\x00\x04\x00\x00\x00\x04\x00\x00\x00\x6D\x61\x69\x6E\x00\x00\x00\x00" +"\x09\x00\x00\x00\x0B\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\x09\x00\x00\x00\x6F\x75\x74\x63\x6F\x6C\x6F\x75" +"\x72\x00\x00\x00\x05\x00\x03\x00\x0B\x00\x00\x00\x76\x63\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\x64\x65\x6C\x76\x69\x65\x77\x70\x72\x6F\x6A\x00" +"\x06\x00\x05\x00\x13\x00\x00\x00\x01\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x00\x06\x00\x06\x00\x13\x00\x00\x00\x02\x00\x00\x00" +"\x6D\x5F\x6D\x6F\x64\x65\x6C\x69\x6E\x76\x00\x00\x06\x00\x06\x00\x13\x00\x00\x00\x03\x00\x00\x00\x65\x5F\x65\x79\x65\x70\x6F\x73" +"\x00\x00\x00\x00\x06\x00\x05\x00\x13\x00\x00\x00\x04\x00\x00\x00\x65\x5F\x74\x69\x6D\x65\x00\x00\x06\x00\x07\x00\x13\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\x13\x00\x00\x00\x06\x00\x00\x00" +"\x65\x70\x61\x64\x31\x00\x00\x00\x06\x00\x06\x00\x13\x00\x00\x00\x07\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x64\x69\x72\x00" +"\x06\x00\x05\x00\x13\x00\x00\x00\x08\x00\x00\x00\x65\x70\x61\x64\x32\x00\x00\x00\x06\x00\x06\x00\x13\x00\x00\x00\x09\x00\x00\x00" +"\x65\x5F\x6C\x69\x67\x68\x74\x5F\x6D\x75\x6C\x00\x06\x00\x05\x00\x13\x00\x00\x00\x0A\x00\x00\x00\x65\x70\x61\x64\x33\x00\x00\x00" +"\x06\x00\x06\x00\x13\x00\x00\x00\x0B\x00\x00\x00\x65\x5F\x6C\x6D\x73\x63\x61\x6C\x65\x73\x00\x00\x06\x00\x07\x00\x13\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\x13\x00\x00\x00\x0D\x00\x00\x00" +"\x65\x70\x61\x64\x34\x00\x00\x00\x06\x00\x07\x00\x13\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\x13\x00\x00\x00\x0F\x00\x00\x00\x65\x70\x61\x64\x35\x00\x00\x00\x06\x00\x06\x00\x13\x00\x00\x00" +"\x10\x00\x00\x00\x65\x5F\x67\x6C\x6F\x77\x6D\x6F\x64\x00\x00\x00\x06\x00\x05\x00\x13\x00\x00\x00\x11\x00\x00\x00\x65\x70\x61\x64" +"\x36\x00\x00\x00\x06\x00\x07\x00\x13\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\x13\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" +"\x13\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\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\x16\x00\x00\x00\x6C\x69\x67\x68" +"\x74\x62\x6C\x6F\x63\x6B\x00\x00\x06\x00\x07\x00\x16\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\x16\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\x16\x00\x00\x00\x02\x00\x00\x00\x6C\x70\x61\x64\x31\x00\x00\x00\x06\x00\x07\x00\x16\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\x16\x00\x00\x00\x04\x00\x00\x00\x6C\x70\x61\x64" +"\x32\x00\x00\x00\x06\x00\x08\x00\x16\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\x16\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\x16\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" +"\x16\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" +"\x16\x00\x00\x00\x09\x00\x00\x00\x6C\x70\x61\x64\x33\x00\x00\x00\x05\x00\x03\x00\x18\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00" +"\x09\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x0B\x00\x00\x00\x1E\x00\x00\x00\x00\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\x48\x00\x05\x00\x13\x00\x00\x00\x01\x00\x00\x00" @@ -5263,7 +5269,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND #ifdef VKQUAKE {QR_VULKAN, -1, "defaultsprite", "\xFF\x53\x50\x56\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x20\x00\x00\x00\x2C\x00\x00\x00\x20\x00\x00\x00\x4C\x00\x00\x00" -"\x1C\x0F\x00\x00\x68\x0F\x00\x00\x24\x20\x00\x00\x01\x00\x46\x31\x4D\x41\x53\x4B\x00\x00\x00\x00\x00\x01\x01\x62\x31\x72\x5F\x66" +"\x3C\x0F\x00\x00\x88\x0F\x00\x00\x44\x20\x00\x00\x01\x00\x46\x31\x4D\x41\x53\x4B\x00\x00\x00\x00\x00\x01\x01\x62\x31\x72\x5F\x66" "\x6F\x67\x5F\x65\x78\x70\x32\x00\x00\x00\x00\x00\x03\x02\x23\x07\x00\x00\x01\x00\x01\x00\x08\x00\x51\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\x0F\x00\x00\x00\x00\x00\x04\x00\x00\x00\x6D\x61\x69\x6E\x00\x00\x00\x00" @@ -5325,7 +5331,8 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "\x15\x00\x00\x00\x23\x00\x00\x00\x94\x01\x00\x00\x48\x00\x05\x00\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" -"\x3B\x00\x00\x00\x1E\x00\x00\x00\x01\x00\x00\x00\x47\x00\x04\x00\x40\x00\x00\x00\x1E\x00\x00\x00\x02\x00\x00\x00\x48\x00\x05\x00" +"\x39\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x3B\x00\x00\x00\x1E\x00\x00\x00\x01\x00\x00\x00\x47\x00\x04\x00" +"\x3E\x00\x00\x00\x1E\x00\x00\x00\x01\x00\x00\x00\x47\x00\x04\x00\x40\x00\x00\x00\x1E\x00\x00\x00\x02\x00\x00\x00\x48\x00\x05\x00" "\x42\x00\x00\x00\x00\x00\x00\x00\x0B\x00\x00\x00\x00\x00\x00\x00\x47\x00\x03\x00\x42\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00" "\x47\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x47\x00\x04\x00\x48\x00\x00\x00\x01\x00\x00\x00\x01\x01\x00\x00\x47\x00\x04\x00" "\x49\x00\x00\x00\x01\x00\x00\x00\x15\x00\x00\x00\x48\x00\x04\x00\x4A\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00" @@ -5453,8 +5460,9 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "\x23\x00\x00\x00\x98\x01\x00\x00\x47\x00\x03\x00\x2D\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x2F\x00\x00\x00\x22\x00\x00\x00" "\x00\x00\x00\x00\x47\x00\x04\x00\x2F\x00\x00\x00\x21\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x35\x00\x00\x00\x0B\x00\x00\x00" "\x0F\x00\x00\x00\x47\x00\x04\x00\x46\x00\x00\x00\x01\x00\x00\x00\x01\x01\x00\x00\x47\x00\x04\x00\x0A\x01\x00\x00\x22\x00\x00\x00" -"\x00\x00\x00\x00\x47\x00\x04\x00\x0A\x01\x00\x00\x21\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x10\x01\x00\x00\x01\x00\x00\x00" -"\x00\x01\x00\x00\x47\x00\x04\x00\x1C\x01\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x48\x00\x04\x00\x27\x01\x00\x00\x00\x00\x00\x00" +"\x00\x00\x00\x00\x47\x00\x04\x00\x0A\x01\x00\x00\x21\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x0D\x01\x00\x00\x1E\x00\x00\x00" +"\x00\x00\x00\x00\x47\x00\x04\x00\x10\x01\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x47\x00\x04\x00\x1C\x01\x00\x00\x1E\x00\x00\x00" +"\x00\x00\x00\x00\x47\x00\x04\x00\x1E\x01\x00\x00\x1E\x00\x00\x00\x01\x00\x00\x00\x48\x00\x04\x00\x27\x01\x00\x00\x00\x00\x00\x00" "\x05\x00\x00\x00\x48\x00\x05\x00\x27\x01\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00\x27\x01\x00\x00" "\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x05\x00\x27\x01\x00\x00\x01\x00\x00\x00\x23\x00\x00\x00\x40\x00\x00\x00" "\x48\x00\x05\x00\x27\x01\x00\x00\x02\x00\x00\x00\x23\x00\x00\x00\x4C\x00\x00\x00\x48\x00\x05\x00\x27\x01\x00\x00\x03\x00\x00\x00" @@ -5705,7 +5713,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "!!permu REFLECTCUBEMASK\n" "!!cvarf r_glsl_offsetmapping_scale\n" "!!cvardf r_tessellation_level=5\n" -"!!samps diffuse lightmap specular normalmap fullbright reflectmask reflectcube paletted lightmap1 lightmap2 lightmap3\n" +"!!samps diffuse lightmap specular normalmap fullbright reflectmask reflectcube paletted lightmap1 lightmap2 lightmap3 deluxemap deluxemap1 deluxemap2 deluxemap3\n" "#include \"sys/defs.h\"\n" @@ -5967,16 +5975,16 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "#else\n" "vec3 lightmaps = vc.rgb;\n" "#endif\n" -"#define delux vec3(0.0,0.0,1.0)\n" +"#define deluxe vec3(0.0,0.0,1.0)\n" "#else\n" "#ifdef LIGHTSTYLED\n" -"#define delux vec3(0.0,0.0,1.0)\n" +"#define deluxe vec3(0.0,0.0,1.0)\n" "vec3 lightmaps;\n" "#ifdef DELUXE\n" -"lightmaps = texture2D(s_lightmap0, lm0).rgb * e_lmscale[0].rgb * dot(norm, 2.0*texture2D(s_deluxmap0, lm0).rgb-0.5);\n" -"lightmaps += texture2D(s_lightmap1, lm1).rgb * e_lmscale[1].rgb * dot(norm, 2.0*texture2D(s_deluxmap1, lm1).rgb-0.5);\n" -"lightmaps += texture2D(s_lightmap2, lm2).rgb * e_lmscale[2].rgb * dot(norm, 2.0*texture2D(s_deluxmap2, lm2).rgb-0.5);\n" -"lightmaps += texture2D(s_lightmap3, lm3).rgb * e_lmscale[3].rgb * dot(norm, 2.0*texture2D(s_deluxmap3, lm3).rgb-0.5);\n" +"lightmaps = texture2D(s_lightmap0, lm0).rgb * e_lmscale[0].rgb * dot(norm, 2.0*texture2D(s_deluxemap0, lm0).rgb-0.5);\n" +"lightmaps += texture2D(s_lightmap1, lm1).rgb * e_lmscale[1].rgb * dot(norm, 2.0*texture2D(s_deluxemap1, lm1).rgb-0.5);\n" +"lightmaps += texture2D(s_lightmap2, lm2).rgb * e_lmscale[2].rgb * dot(norm, 2.0*texture2D(s_deluxemap2, lm2).rgb-0.5);\n" +"lightmaps += texture2D(s_lightmap3, lm3).rgb * e_lmscale[3].rgb * dot(norm, 2.0*texture2D(s_deluxemap3, lm3).rgb-0.5);\n" "#else\n" "lightmaps = texture2D(s_lightmap0, lm0).rgb * e_lmscale[0].rgb;\n" "lightmaps += texture2D(s_lightmap1, lm1).rgb * e_lmscale[1].rgb;\n" @@ -5987,15 +5995,15 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "vec3 lightmaps = (texture2D(s_lightmap, lm0) * e_lmscale).rgb;\n" //modulate by the bumpmap dot light "#ifdef DELUXE\n" -"vec3 delux = (texture2D(s_deluxmap, lm0).rgb-0.5);\n" +"vec3 deluxe = (texture2D(s_deluxemap, lm0).rgb-0.5);\n" "#ifdef BUMPMODELSPACE\n" -"delux = normalize(delux*invsurface);\n" +"deluxe = normalize(deluxe*invsurface);\n" "#else\n" -"lightmaps *= 2.0 / max(0.25, delux.z); //counter the darkening from deluxmaps\n" +"lightmaps *= 2.0 / max(0.25, deluxe.z); //counter the darkening from deluxemaps\n" "#endif\n" -"lightmaps *= dot(norm, delux);\n" +"lightmaps *= dot(norm, deluxe);\n" "#else\n" -"#define delux vec3(0.0,0.0,1.0)\n" +"#define deluxe vec3(0.0,0.0,1.0)\n" "#endif\n" "#endif\n" "#endif\n" @@ -6003,7 +6011,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND //add in specular, if applicable. "#ifdef SPECULAR\n" "vec4 specs = texture2D(s_specular, tc);\n" -"vec3 halfdir = normalize(normalize(eyevector) + delux); //this norm should be the deluxemap info instead\n" +"vec3 halfdir = normalize(normalize(eyevector) + deluxe); //this norm should be the deluxemap info instead\n" "float spec = pow(max(dot(halfdir, norm), 0.0), FTE_SPECULAR_EXPONENT * specs.a);\n" "spec *= FTE_SPECULAR_MULTIPLIER;\n" //NOTE: rtlights tend to have a *4 scaler here to over-emphasise the effect because it looks cool. @@ -6068,7 +6076,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "\x67\x5F\x73\x63\x61\x6C\x65\x00\x3D\x23\xD7\x0A\x01\x02\x66\x31\x67\x6C\x5F\x73\x70\x65\x63\x75\x6C\x61\x72\x00\x3E\x99\x99\x9A" "\x01\x03\x62\x31\x72\x5F\x66\x6F\x67\x5F\x65\x78\x70\x32\x00\x00\x00\x00\x00\x01\x04\x42\x31\x76\x65\x72\x74\x65\x78\x6C\x69\x74" "\x00\x00\x00\x00\x00\x01\x05\x42\x31\x65\x69\x67\x68\x74\x62\x69\x74\x00\x00\x00\x00\x00\x01\x06\x46\x31\x6D\x61\x73\x6B\x00\x3F" -"\x80\x00\x00\x01\x07\x42\x31\x6D\x61\x73\x6B\x6C\x74\x00\x00\x00\x00\x00\x20\x2A\x03\x02\x23\x07\x00\x00\x01\x00\x01\x00\x08\x00" +"\x80\x00\x00\x01\x07\x42\x31\x6D\x61\x73\x6B\x6C\x74\x00\x00\x00\x00\x00\x00\x00\x03\x02\x23\x07\x00\x00\x01\x00\x01\x00\x08\x00" "\x8F\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\x12\x00\x00\x00\x00\x00\x04\x00\x00\x00" "\x6D\x61\x69\x6E\x00\x00\x00\x00\x1C\x00\x00\x00\x4D\x00\x00\x00\x4F\x00\x00\x00\x56\x00\x00\x00\x5B\x00\x00\x00\x64\x00\x00\x00" @@ -7211,9 +7219,9 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND #ifdef VKQUAKE {QR_VULKAN, -1, "defaultwarp", "\xFF\x53\x50\x56\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x2C\x00\x00\x00\x36\x00\x00\x00\x64\x00\x00\x00" -"\x00\x0F\x00\x00\x64\x0F\x00\x00\xD4\x22\x00\x00\x01\x00\x66\x31\x72\x5F\x77\x61\x74\x65\x72\x61\x6C\x70\x68\x61\x00\x00\x00\x00" +"\x10\x0F\x00\x00\x74\x0F\x00\x00\xE4\x22\x00\x00\x01\x00\x66\x31\x72\x5F\x77\x61\x74\x65\x72\x61\x6C\x70\x68\x61\x00\x00\x00\x00" "\x00\x01\x01\x62\x31\x72\x5F\x66\x6F\x67\x5F\x65\x78\x70\x32\x00\x00\x00\x00\x00\x01\x02\x46\x31\x61\x6C\x70\x68\x61\x00\x00\x00" -"\x00\x00\x52\x41\x03\x02\x23\x07\x00\x00\x01\x00\x01\x00\x08\x00\x50\x00\x00\x00\x00\x00\x00\x00\x11\x00\x02\x00\x01\x00\x00\x00" +"\x00\x00\x3D\x00\x03\x02\x23\x07\x00\x00\x01\x00\x01\x00\x08\x00\x50\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" "\x3B\x00\x00\x00\x3F\x00\x00\x00\x4B\x00\x00\x00\x4C\x00\x00\x00\x4D\x00\x00\x00\x4E\x00\x00\x00\x4F\x00\x00\x00\x03\x00\x03\x00" @@ -7273,134 +7281,135 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "\x48\x00\x05\x00\x13\x00\x00\x00\x15\x00\x00\x00\x23\x00\x00\x00\x94\x01\x00\x00\x48\x00\x05\x00\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\x3B\x00\x00\x00\x1E\x00\x00\x00\x01\x00\x00\x00\x48\x00\x05\x00\x3D\x00\x00\x00\x00\x00\x00\x00" -"\x0B\x00\x00\x00\x00\x00\x00\x00\x47\x00\x03\x00\x3D\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x43\x00\x00\x00\x01\x00\x00\x00" -"\x00\x01\x00\x00\x47\x00\x04\x00\x44\x00\x00\x00\x01\x00\x00\x00\x01\x01\x00\x00\x47\x00\x04\x00\x45\x00\x00\x00\x01\x00\x00\x00" -"\x02\x01\x00\x00\x47\x00\x04\x00\x46\x00\x00\x00\x01\x00\x00\x00\x15\x00\x00\x00\x48\x00\x04\x00\x47\x00\x00\x00\x00\x00\x00\x00" -"\x05\x00\x00\x00\x48\x00\x05\x00\x47\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00\x47\x00\x00\x00" -"\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x05\x00\x47\x00\x00\x00\x01\x00\x00\x00\x23\x00\x00\x00\x40\x00\x00\x00" -"\x48\x00\x05\x00\x47\x00\x00\x00\x02\x00\x00\x00\x23\x00\x00\x00\x4C\x00\x00\x00\x48\x00\x05\x00\x47\x00\x00\x00\x03\x00\x00\x00" -"\x23\x00\x00\x00\x50\x00\x00\x00\x48\x00\x05\x00\x47\x00\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00\x5C\x00\x00\x00\x48\x00\x05\x00" -"\x47\x00\x00\x00\x05\x00\x00\x00\x23\x00\x00\x00\x60\x00\x00\x00\x48\x00\x05\x00\x47\x00\x00\x00\x06\x00\x00\x00\x23\x00\x00\x00" -"\x6C\x00\x00\x00\x48\x00\x05\x00\x47\x00\x00\x00\x07\x00\x00\x00\x23\x00\x00\x00\x70\x00\x00\x00\x48\x00\x05\x00\x47\x00\x00\x00" -"\x08\x00\x00\x00\x23\x00\x00\x00\x80\x00\x00\x00\x48\x00\x05\x00\x47\x00\x00\x00\x09\x00\x00\x00\x23\x00\x00\x00\x88\x00\x00\x00" -"\x47\x00\x03\x00\x47\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x49\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00" -"\x49\x00\x00\x00\x21\x00\x00\x00\x01\x00\x00\x00\x47\x00\x04\x00\x4B\x00\x00\x00\x1E\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00" -"\x4C\x00\x00\x00\x1E\x00\x00\x00\x03\x00\x00\x00\x47\x00\x04\x00\x4D\x00\x00\x00\x1E\x00\x00\x00\x04\x00\x00\x00\x47\x00\x04\x00" -"\x4E\x00\x00\x00\x1E\x00\x00\x00\x05\x00\x00\x00\x47\x00\x04\x00\x4F\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\x15\x00\x04\x00\x0F\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00" -"\x10\x00\x00\x00\x04\x00\x00\x00\x1C\x00\x04\x00\x11\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x17\x00\x04\x00\x12\x00\x00\x00" -"\x06\x00\x00\x00\x02\x00\x00\x00\x1E\x00\x19\x00\x13\x00\x00\x00\x0D\x00\x00\x00\x0D\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\x0E\x00\x00\x00\x06\x00\x00\x00\x11\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\x07\x00\x00\x00" -"\x06\x00\x00\x00\x06\x00\x00\x00\x12\x00\x00\x00\x20\x00\x04\x00\x14\x00\x00\x00\x02\x00\x00\x00\x13\x00\x00\x00\x3B\x00\x04\x00" -"\x14\x00\x00\x00\x15\x00\x00\x00\x02\x00\x00\x00\x15\x00\x04\x00\x16\x00\x00\x00\x20\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00" -"\x16\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x20\x00\x04\x00\x18\x00\x00\x00\x02\x00\x00\x00\x0D\x00\x00\x00\x20\x00\x04\x00" -"\x1B\x00\x00\x00\x01\x00\x00\x00\x0E\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x1C\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00" -"\x06\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x80\x3F\x2B\x00\x04\x00\x06\x00\x00\x00\x24\x00\x00\x00\x00\x00\x80\xBF\x2B\x00\x04\x00" -"\x0F\x00\x00\x00\x25\x00\x00\x00\x01\x00\x00\x00\x20\x00\x04\x00\x26\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x2B\x00\x04\x00" -"\x0F\x00\x00\x00\x2B\x00\x00\x00\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\x12\x00\x00\x00\x3B\x00\x04\x00" -"\x38\x00\x00\x00\x39\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00\x3A\x00\x00\x00\x01\x00\x00\x00\x12\x00\x00\x00\x3B\x00\x04\x00" -"\x3A\x00\x00\x00\x3B\x00\x00\x00\x01\x00\x00\x00\x1E\x00\x03\x00\x3D\x00\x00\x00\x07\x00\x00\x00\x20\x00\x04\x00\x3E\x00\x00\x00" -"\x03\x00\x00\x00\x3D\x00\x00\x00\x3B\x00\x04\x00\x3E\x00\x00\x00\x3F\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00\x41\x00\x00\x00" -"\x03\x00\x00\x00\x07\x00\x00\x00\x32\x00\x04\x00\x06\x00\x00\x00\x43\x00\x00\x00\x00\x00\x80\x43\x32\x00\x04\x00\x16\x00\x00\x00" -"\x44\x00\x00\x00\x01\x01\x00\x00\x32\x00\x04\x00\x06\x00\x00\x00\x45\x00\x00\x00\x00\x00\x81\x43\x32\x00\x04\x00\x16\x00\x00\x00" -"\x46\x00\x00\x00\x15\x00\x00\x00\x1E\x00\x0C\x00\x47\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\x48\x00\x00\x00" -"\x02\x00\x00\x00\x47\x00\x00\x00\x3B\x00\x04\x00\x48\x00\x00\x00\x49\x00\x00\x00\x02\x00\x00\x00\x20\x00\x04\x00\x4A\x00\x00\x00" -"\x01\x00\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00\x4A\x00\x00\x00\x4B\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x3A\x00\x00\x00" -"\x4C\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x4D\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00" -"\x4E\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x4F\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\x12\x00\x00\x00\x3C\x00\x00\x00" -"\x3B\x00\x00\x00\x3E\x00\x03\x00\x39\x00\x00\x00\x3C\x00\x00\x00\x39\x00\x04\x00\x07\x00\x00\x00\x40\x00\x00\x00\x09\x00\x00\x00" -"\x41\x00\x05\x00\x41\x00\x00\x00\x42\x00\x00\x00\x3F\x00\x00\x00\x17\x00\x00\x00\x3E\x00\x03\x00\x42\x00\x00\x00\x40\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\x01\x00\x08\x00\x49\x01\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\x35\x00\x00\x00\x09\x01\x00\x00" -"\x35\x01\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\x07\x00\x0E\x00\x00\x00" -"\x66\x6F\x67\x33\x61\x64\x64\x69\x74\x69\x76\x65\x28\x76\x66\x33\x3B\x00\x00\x00\x05\x00\x06\x00\x0D\x00\x00\x00\x72\x65\x67\x75" -"\x6C\x61\x72\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x05\x00\x14\x00\x00\x00\x66\x6F\x67\x34\x28\x76\x66\x34\x3B\x00\x00\x00" -"\x05\x00\x06\x00\x13\x00\x00\x00\x72\x65\x67\x75\x6C\x61\x72\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x07\x00\x17\x00\x00\x00" -"\x66\x6F\x67\x34\x61\x64\x64\x69\x74\x69\x76\x65\x28\x76\x66\x34\x3B\x00\x00\x00\x05\x00\x06\x00\x16\x00\x00\x00\x72\x65\x67\x75" -"\x6C\x61\x72\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x06\x00\x1A\x00\x00\x00\x66\x6F\x67\x34\x62\x6C\x65\x6E\x64\x28\x76\x66" -"\x34\x3B\x00\x00\x05\x00\x06\x00\x19\x00\x00\x00\x72\x65\x67\x75\x6C\x61\x72\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x03\x00" -"\x27\x00\x00\x00\x7A\x00\x00\x00\x05\x00\x05\x00\x2D\x00\x00\x00\x65\x6E\x74\x69\x74\x79\x62\x6C\x6F\x63\x6B\x00\x06\x00\x07\x00" -"\x2D\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\x2D\x00\x00\x00" -"\x01\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x00\x06\x00\x06\x00\x2D\x00\x00\x00\x02\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x69" -"\x6E\x76\x00\x00\x06\x00\x06\x00\x2D\x00\x00\x00\x03\x00\x00\x00\x65\x5F\x65\x79\x65\x70\x6F\x73\x00\x00\x00\x00\x06\x00\x05\x00" -"\x2D\x00\x00\x00\x04\x00\x00\x00\x65\x5F\x74\x69\x6D\x65\x00\x00\x06\x00\x07\x00\x2D\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\x2D\x00\x00\x00\x06\x00\x00\x00\x65\x70\x61\x64\x31\x00\x00\x00" -"\x06\x00\x06\x00\x2D\x00\x00\x00\x07\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x64\x69\x72\x00\x06\x00\x05\x00\x2D\x00\x00\x00" -"\x08\x00\x00\x00\x65\x70\x61\x64\x32\x00\x00\x00\x06\x00\x06\x00\x2D\x00\x00\x00\x09\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F" -"\x6D\x75\x6C\x00\x06\x00\x05\x00\x2D\x00\x00\x00\x0A\x00\x00\x00\x65\x70\x61\x64\x33\x00\x00\x00\x06\x00\x06\x00\x2D\x00\x00\x00" -"\x0B\x00\x00\x00\x65\x5F\x6C\x6D\x73\x63\x61\x6C\x65\x73\x00\x00\x06\x00\x07\x00\x2D\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\x2D\x00\x00\x00\x0D\x00\x00\x00\x65\x70\x61\x64\x34\x00\x00\x00" -"\x06\x00\x07\x00\x2D\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" -"\x2D\x00\x00\x00\x0F\x00\x00\x00\x65\x70\x61\x64\x35\x00\x00\x00\x06\x00\x06\x00\x2D\x00\x00\x00\x10\x00\x00\x00\x65\x5F\x67\x6C" -"\x6F\x77\x6D\x6F\x64\x00\x00\x00\x06\x00\x05\x00\x2D\x00\x00\x00\x11\x00\x00\x00\x65\x70\x61\x64\x36\x00\x00\x00\x06\x00\x07\x00" -"\x2D\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\x2D\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\x2D\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\x2D\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\x2D\x00\x00\x00\x16\x00\x00\x00\x65\x70\x61\x64\x37\x00\x00\x00" -"\x05\x00\x03\x00\x2F\x00\x00\x00\x00\x00\x00\x00\x05\x00\x06\x00\x35\x00\x00\x00\x67\x6C\x5F\x46\x72\x61\x67\x43\x6F\x6F\x72\x64" -"\x00\x00\x00\x00\x05\x00\x03\x00\x4D\x00\x00\x00\x66\x61\x63\x00\x05\x00\x03\x00\x6E\x00\x00\x00\x7A\x00\x00\x00\x05\x00\x03\x00" -"\x82\x00\x00\x00\x66\x61\x63\x00\x05\x00\x04\x00\x9B\x00\x00\x00\x70\x61\x72\x61\x6D\x00\x00\x00\x05\x00\x03\x00\xAE\x00\x00\x00" -"\x7A\x00\x00\x00\x05\x00\x03\x00\xC2\x00\x00\x00\x66\x61\x63\x00\x05\x00\x03\x00\xDE\x00\x00\x00\x7A\x00\x00\x00\x05\x00\x03\x00" -"\xF2\x00\x00\x00\x66\x61\x63\x00\x05\x00\x03\x00\x07\x01\x00\x00\x6E\x74\x63\x00\x05\x00\x03\x00\x09\x01\x00\x00\x74\x63\x00\x00" -"\x05\x00\x03\x00\x24\x01\x00\x00\x74\x73\x00\x00\x05\x00\x05\x00\x28\x01\x00\x00\x73\x5F\x64\x69\x66\x66\x75\x73\x65\x00\x00\x00" -"\x05\x00\x05\x00\x35\x01\x00\x00\x6F\x75\x74\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x04\x00\x3B\x01\x00\x00\x70\x61\x72\x61" -"\x6D\x00\x00\x00\x05\x00\x04\x00\x44\x01\x00\x00\x70\x61\x72\x61\x6D\x00\x00\x00\x05\x00\x05\x00\x46\x01\x00\x00\x6C\x69\x67\x68" -"\x74\x62\x6C\x6F\x63\x6B\x00\x00\x06\x00\x07\x00\x46\x01\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\x46\x01\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\x46\x01\x00\x00\x02\x00\x00\x00\x6C\x70\x61\x64\x31\x00\x00\x00\x06\x00\x07\x00\x46\x01\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\x46\x01\x00\x00\x04\x00\x00\x00\x6C\x70\x61\x64" -"\x32\x00\x00\x00\x06\x00\x08\x00\x46\x01\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\x46\x01\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\x46\x01\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" -"\x46\x01\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" -"\x46\x01\x00\x00\x09\x00\x00\x00\x6C\x70\x61\x64\x33\x00\x00\x00\x05\x00\x03\x00\x48\x01\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00" -"\x1D\x00\x00\x00\x01\x00\x00\x00\x15\x00\x00\x00\x47\x00\x04\x00\x2B\x00\x00\x00\x06\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00" -"\x2D\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00" -"\x48\x00\x05\x00\x2D\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00\x2D\x00\x00\x00\x01\x00\x00\x00" -"\x05\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x01\x00\x00\x00\x23\x00\x00\x00\x40\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00" -"\x01\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00\x2D\x00\x00\x00\x02\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00" -"\x2D\x00\x00\x00\x02\x00\x00\x00\x23\x00\x00\x00\x80\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00" -"\x10\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x03\x00\x00\x00\x23\x00\x00\x00\xC0\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00" -"\x04\x00\x00\x00\x23\x00\x00\x00\xCC\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x05\x00\x00\x00\x23\x00\x00\x00\xD0\x00\x00\x00" -"\x48\x00\x05\x00\x2D\x00\x00\x00\x06\x00\x00\x00\x23\x00\x00\x00\xDC\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x07\x00\x00\x00" -"\x23\x00\x00\x00\xE0\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x08\x00\x00\x00\x23\x00\x00\x00\xEC\x00\x00\x00\x48\x00\x05\x00" -"\x2D\x00\x00\x00\x09\x00\x00\x00\x23\x00\x00\x00\xF0\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x0A\x00\x00\x00\x23\x00\x00\x00" -"\xFC\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x0B\x00\x00\x00\x23\x00\x00\x00\x00\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00" -"\x0C\x00\x00\x00\x23\x00\x00\x00\x40\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x0D\x00\x00\x00\x23\x00\x00\x00\x4C\x01\x00\x00" -"\x48\x00\x05\x00\x2D\x00\x00\x00\x0E\x00\x00\x00\x23\x00\x00\x00\x50\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x0F\x00\x00\x00" -"\x23\x00\x00\x00\x5C\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x10\x00\x00\x00\x23\x00\x00\x00\x60\x01\x00\x00\x48\x00\x05\x00" -"\x2D\x00\x00\x00\x11\x00\x00\x00\x23\x00\x00\x00\x6C\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x12\x00\x00\x00\x23\x00\x00\x00" -"\x70\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x13\x00\x00\x00\x23\x00\x00\x00\x80\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00" -"\x14\x00\x00\x00\x23\x00\x00\x00\x90\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x15\x00\x00\x00\x23\x00\x00\x00\x94\x01\x00\x00" -"\x48\x00\x05\x00\x2D\x00\x00\x00\x16\x00\x00\x00\x23\x00\x00\x00\x98\x01\x00\x00\x47\x00\x03\x00\x2D\x00\x00\x00\x02\x00\x00\x00" -"\x47\x00\x04\x00\x2F\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x2F\x00\x00\x00\x21\x00\x00\x00\x00\x00\x00\x00" -"\x47\x00\x04\x00\x35\x00\x00\x00\x0B\x00\x00\x00\x0F\x00\x00\x00\x47\x00\x04\x00\x46\x00\x00\x00\x01\x00\x00\x00\x01\x01\x00\x00" +"\x00\x00\x00\x00\x47\x00\x04\x00\x39\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x3B\x00\x00\x00\x1E\x00\x00\x00" +"\x01\x00\x00\x00\x48\x00\x05\x00\x3D\x00\x00\x00\x00\x00\x00\x00\x0B\x00\x00\x00\x00\x00\x00\x00\x47\x00\x03\x00\x3D\x00\x00\x00" +"\x02\x00\x00\x00\x47\x00\x04\x00\x43\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x47\x00\x04\x00\x44\x00\x00\x00\x01\x00\x00\x00" +"\x01\x01\x00\x00\x47\x00\x04\x00\x45\x00\x00\x00\x01\x00\x00\x00\x02\x01\x00\x00\x47\x00\x04\x00\x46\x00\x00\x00\x01\x00\x00\x00" +"\x15\x00\x00\x00\x48\x00\x04\x00\x47\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x47\x00\x00\x00\x00\x00\x00\x00" +"\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00\x47\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x05\x00" +"\x47\x00\x00\x00\x01\x00\x00\x00\x23\x00\x00\x00\x40\x00\x00\x00\x48\x00\x05\x00\x47\x00\x00\x00\x02\x00\x00\x00\x23\x00\x00\x00" +"\x4C\x00\x00\x00\x48\x00\x05\x00\x47\x00\x00\x00\x03\x00\x00\x00\x23\x00\x00\x00\x50\x00\x00\x00\x48\x00\x05\x00\x47\x00\x00\x00" +"\x04\x00\x00\x00\x23\x00\x00\x00\x5C\x00\x00\x00\x48\x00\x05\x00\x47\x00\x00\x00\x05\x00\x00\x00\x23\x00\x00\x00\x60\x00\x00\x00" +"\x48\x00\x05\x00\x47\x00\x00\x00\x06\x00\x00\x00\x23\x00\x00\x00\x6C\x00\x00\x00\x48\x00\x05\x00\x47\x00\x00\x00\x07\x00\x00\x00" +"\x23\x00\x00\x00\x70\x00\x00\x00\x48\x00\x05\x00\x47\x00\x00\x00\x08\x00\x00\x00\x23\x00\x00\x00\x80\x00\x00\x00\x48\x00\x05\x00" +"\x47\x00\x00\x00\x09\x00\x00\x00\x23\x00\x00\x00\x88\x00\x00\x00\x47\x00\x03\x00\x47\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00" +"\x49\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x49\x00\x00\x00\x21\x00\x00\x00\x01\x00\x00\x00\x47\x00\x04\x00" +"\x4B\x00\x00\x00\x1E\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x4C\x00\x00\x00\x1E\x00\x00\x00\x03\x00\x00\x00\x47\x00\x04\x00" +"\x4D\x00\x00\x00\x1E\x00\x00\x00\x04\x00\x00\x00\x47\x00\x04\x00\x4E\x00\x00\x00\x1E\x00\x00\x00\x05\x00\x00\x00\x47\x00\x04\x00" +"\x4F\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\x15\x00\x04\x00\x0F\x00\x00\x00" +"\x20\x00\x00\x00\x00\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00\x10\x00\x00\x00\x04\x00\x00\x00\x1C\x00\x04\x00\x11\x00\x00\x00" +"\x07\x00\x00\x00\x10\x00\x00\x00\x17\x00\x04\x00\x12\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x1E\x00\x19\x00\x13\x00\x00\x00" +"\x0D\x00\x00\x00\x0D\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\x0E\x00\x00\x00\x06\x00\x00\x00\x11\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\x07\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x12\x00\x00\x00\x20\x00\x04\x00" +"\x14\x00\x00\x00\x02\x00\x00\x00\x13\x00\x00\x00\x3B\x00\x04\x00\x14\x00\x00\x00\x15\x00\x00\x00\x02\x00\x00\x00\x15\x00\x04\x00" +"\x16\x00\x00\x00\x20\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00\x16\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x20\x00\x04\x00" +"\x18\x00\x00\x00\x02\x00\x00\x00\x0D\x00\x00\x00\x20\x00\x04\x00\x1B\x00\x00\x00\x01\x00\x00\x00\x0E\x00\x00\x00\x3B\x00\x04\x00" +"\x1B\x00\x00\x00\x1C\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00\x06\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x80\x3F\x2B\x00\x04\x00" +"\x06\x00\x00\x00\x24\x00\x00\x00\x00\x00\x80\xBF\x2B\x00\x04\x00\x0F\x00\x00\x00\x25\x00\x00\x00\x01\x00\x00\x00\x20\x00\x04\x00" +"\x26\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00\x2B\x00\x00\x00\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\x12\x00\x00\x00\x3B\x00\x04\x00\x38\x00\x00\x00\x39\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00" +"\x3A\x00\x00\x00\x01\x00\x00\x00\x12\x00\x00\x00\x3B\x00\x04\x00\x3A\x00\x00\x00\x3B\x00\x00\x00\x01\x00\x00\x00\x1E\x00\x03\x00" +"\x3D\x00\x00\x00\x07\x00\x00\x00\x20\x00\x04\x00\x3E\x00\x00\x00\x03\x00\x00\x00\x3D\x00\x00\x00\x3B\x00\x04\x00\x3E\x00\x00\x00" +"\x3F\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00\x41\x00\x00\x00\x03\x00\x00\x00\x07\x00\x00\x00\x32\x00\x04\x00\x06\x00\x00\x00" +"\x43\x00\x00\x00\x00\x00\x80\x43\x32\x00\x04\x00\x16\x00\x00\x00\x44\x00\x00\x00\x01\x01\x00\x00\x32\x00\x04\x00\x06\x00\x00\x00" +"\x45\x00\x00\x00\x00\x00\x81\x43\x32\x00\x04\x00\x16\x00\x00\x00\x46\x00\x00\x00\x15\x00\x00\x00\x1E\x00\x0C\x00\x47\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\x48\x00\x00\x00\x02\x00\x00\x00\x47\x00\x00\x00\x3B\x00\x04\x00\x48\x00\x00\x00" +"\x49\x00\x00\x00\x02\x00\x00\x00\x20\x00\x04\x00\x4A\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00\x4A\x00\x00\x00" +"\x4B\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x3A\x00\x00\x00\x4C\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00" +"\x4D\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x4E\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00" +"\x4F\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\x12\x00\x00\x00\x3C\x00\x00\x00\x3B\x00\x00\x00\x3E\x00\x03\x00\x39\x00\x00\x00\x3C\x00\x00\x00" +"\x39\x00\x04\x00\x07\x00\x00\x00\x40\x00\x00\x00\x09\x00\x00\x00\x41\x00\x05\x00\x41\x00\x00\x00\x42\x00\x00\x00\x3F\x00\x00\x00" +"\x17\x00\x00\x00\x3E\x00\x03\x00\x42\x00\x00\x00\x40\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\x01\x00\x08\x00" +"\x49\x01\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\x35\x00\x00\x00\x09\x01\x00\x00\x35\x01\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\x07\x00\x0E\x00\x00\x00\x66\x6F\x67\x33\x61\x64\x64\x69\x74\x69\x76\x65\x28\x76\x66\x33" +"\x3B\x00\x00\x00\x05\x00\x06\x00\x0D\x00\x00\x00\x72\x65\x67\x75\x6C\x61\x72\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x05\x00" +"\x14\x00\x00\x00\x66\x6F\x67\x34\x28\x76\x66\x34\x3B\x00\x00\x00\x05\x00\x06\x00\x13\x00\x00\x00\x72\x65\x67\x75\x6C\x61\x72\x63" +"\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x07\x00\x17\x00\x00\x00\x66\x6F\x67\x34\x61\x64\x64\x69\x74\x69\x76\x65\x28\x76\x66\x34" +"\x3B\x00\x00\x00\x05\x00\x06\x00\x16\x00\x00\x00\x72\x65\x67\x75\x6C\x61\x72\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x06\x00" +"\x1A\x00\x00\x00\x66\x6F\x67\x34\x62\x6C\x65\x6E\x64\x28\x76\x66\x34\x3B\x00\x00\x05\x00\x06\x00\x19\x00\x00\x00\x72\x65\x67\x75" +"\x6C\x61\x72\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x03\x00\x27\x00\x00\x00\x7A\x00\x00\x00\x05\x00\x05\x00\x2D\x00\x00\x00" +"\x65\x6E\x74\x69\x74\x79\x62\x6C\x6F\x63\x6B\x00\x06\x00\x07\x00\x2D\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\x2D\x00\x00\x00\x01\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x00\x06\x00\x06\x00" +"\x2D\x00\x00\x00\x02\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x69\x6E\x76\x00\x00\x06\x00\x06\x00\x2D\x00\x00\x00\x03\x00\x00\x00" +"\x65\x5F\x65\x79\x65\x70\x6F\x73\x00\x00\x00\x00\x06\x00\x05\x00\x2D\x00\x00\x00\x04\x00\x00\x00\x65\x5F\x74\x69\x6D\x65\x00\x00" +"\x06\x00\x07\x00\x2D\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" +"\x2D\x00\x00\x00\x06\x00\x00\x00\x65\x70\x61\x64\x31\x00\x00\x00\x06\x00\x06\x00\x2D\x00\x00\x00\x07\x00\x00\x00\x65\x5F\x6C\x69" +"\x67\x68\x74\x5F\x64\x69\x72\x00\x06\x00\x05\x00\x2D\x00\x00\x00\x08\x00\x00\x00\x65\x70\x61\x64\x32\x00\x00\x00\x06\x00\x06\x00" +"\x2D\x00\x00\x00\x09\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x6D\x75\x6C\x00\x06\x00\x05\x00\x2D\x00\x00\x00\x0A\x00\x00\x00" +"\x65\x70\x61\x64\x33\x00\x00\x00\x06\x00\x06\x00\x2D\x00\x00\x00\x0B\x00\x00\x00\x65\x5F\x6C\x6D\x73\x63\x61\x6C\x65\x73\x00\x00" +"\x06\x00\x07\x00\x2D\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" +"\x2D\x00\x00\x00\x0D\x00\x00\x00\x65\x70\x61\x64\x34\x00\x00\x00\x06\x00\x07\x00\x2D\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\x2D\x00\x00\x00\x0F\x00\x00\x00\x65\x70\x61\x64\x35\x00\x00\x00" +"\x06\x00\x06\x00\x2D\x00\x00\x00\x10\x00\x00\x00\x65\x5F\x67\x6C\x6F\x77\x6D\x6F\x64\x00\x00\x00\x06\x00\x05\x00\x2D\x00\x00\x00" +"\x11\x00\x00\x00\x65\x70\x61\x64\x36\x00\x00\x00\x06\x00\x07\x00\x2D\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\x2D\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\x2D\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\x2D\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" +"\x2D\x00\x00\x00\x16\x00\x00\x00\x65\x70\x61\x64\x37\x00\x00\x00\x05\x00\x03\x00\x2F\x00\x00\x00\x00\x00\x00\x00\x05\x00\x06\x00" +"\x35\x00\x00\x00\x67\x6C\x5F\x46\x72\x61\x67\x43\x6F\x6F\x72\x64\x00\x00\x00\x00\x05\x00\x03\x00\x4D\x00\x00\x00\x66\x61\x63\x00" +"\x05\x00\x03\x00\x6E\x00\x00\x00\x7A\x00\x00\x00\x05\x00\x03\x00\x82\x00\x00\x00\x66\x61\x63\x00\x05\x00\x04\x00\x9B\x00\x00\x00" +"\x70\x61\x72\x61\x6D\x00\x00\x00\x05\x00\x03\x00\xAE\x00\x00\x00\x7A\x00\x00\x00\x05\x00\x03\x00\xC2\x00\x00\x00\x66\x61\x63\x00" +"\x05\x00\x03\x00\xDE\x00\x00\x00\x7A\x00\x00\x00\x05\x00\x03\x00\xF2\x00\x00\x00\x66\x61\x63\x00\x05\x00\x03\x00\x07\x01\x00\x00" +"\x6E\x74\x63\x00\x05\x00\x03\x00\x09\x01\x00\x00\x74\x63\x00\x00\x05\x00\x03\x00\x24\x01\x00\x00\x74\x73\x00\x00\x05\x00\x05\x00" +"\x28\x01\x00\x00\x73\x5F\x64\x69\x66\x66\x75\x73\x65\x00\x00\x00\x05\x00\x05\x00\x35\x01\x00\x00\x6F\x75\x74\x63\x6F\x6C\x6F\x75" +"\x72\x00\x00\x00\x05\x00\x04\x00\x3B\x01\x00\x00\x70\x61\x72\x61\x6D\x00\x00\x00\x05\x00\x04\x00\x44\x01\x00\x00\x70\x61\x72\x61" +"\x6D\x00\x00\x00\x05\x00\x05\x00\x46\x01\x00\x00\x6C\x69\x67\x68\x74\x62\x6C\x6F\x63\x6B\x00\x00\x06\x00\x07\x00\x46\x01\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\x46\x01\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\x46\x01\x00\x00\x02\x00\x00\x00\x6C\x70\x61\x64" +"\x31\x00\x00\x00\x06\x00\x07\x00\x46\x01\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\x46\x01\x00\x00\x04\x00\x00\x00\x6C\x70\x61\x64\x32\x00\x00\x00\x06\x00\x08\x00\x46\x01\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\x46\x01\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\x46\x01\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\x46\x01\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\x46\x01\x00\x00\x09\x00\x00\x00\x6C\x70\x61\x64\x33\x00\x00\x00" +"\x05\x00\x03\x00\x48\x01\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x1D\x00\x00\x00\x01\x00\x00\x00\x15\x00\x00\x00\x47\x00\x04\x00" +"\x2B\x00\x00\x00\x06\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00\x2D\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00" +"\x2D\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00" +"\x10\x00\x00\x00\x48\x00\x04\x00\x2D\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x01\x00\x00\x00" +"\x23\x00\x00\x00\x40\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00" +"\x2D\x00\x00\x00\x02\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x02\x00\x00\x00\x23\x00\x00\x00\x80\x00\x00\x00" +"\x48\x00\x05\x00\x2D\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x03\x00\x00\x00" +"\x23\x00\x00\x00\xC0\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00\xCC\x00\x00\x00\x48\x00\x05\x00" +"\x2D\x00\x00\x00\x05\x00\x00\x00\x23\x00\x00\x00\xD0\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x06\x00\x00\x00\x23\x00\x00\x00" +"\xDC\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x07\x00\x00\x00\x23\x00\x00\x00\xE0\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00" +"\x08\x00\x00\x00\x23\x00\x00\x00\xEC\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x09\x00\x00\x00\x23\x00\x00\x00\xF0\x00\x00\x00" +"\x48\x00\x05\x00\x2D\x00\x00\x00\x0A\x00\x00\x00\x23\x00\x00\x00\xFC\x00\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x0B\x00\x00\x00" +"\x23\x00\x00\x00\x00\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x0C\x00\x00\x00\x23\x00\x00\x00\x40\x01\x00\x00\x48\x00\x05\x00" +"\x2D\x00\x00\x00\x0D\x00\x00\x00\x23\x00\x00\x00\x4C\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x0E\x00\x00\x00\x23\x00\x00\x00" +"\x50\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x0F\x00\x00\x00\x23\x00\x00\x00\x5C\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00" +"\x10\x00\x00\x00\x23\x00\x00\x00\x60\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x11\x00\x00\x00\x23\x00\x00\x00\x6C\x01\x00\x00" +"\x48\x00\x05\x00\x2D\x00\x00\x00\x12\x00\x00\x00\x23\x00\x00\x00\x70\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x13\x00\x00\x00" +"\x23\x00\x00\x00\x80\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x14\x00\x00\x00\x23\x00\x00\x00\x90\x01\x00\x00\x48\x00\x05\x00" +"\x2D\x00\x00\x00\x15\x00\x00\x00\x23\x00\x00\x00\x94\x01\x00\x00\x48\x00\x05\x00\x2D\x00\x00\x00\x16\x00\x00\x00\x23\x00\x00\x00" +"\x98\x01\x00\x00\x47\x00\x03\x00\x2D\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x2F\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00" +"\x47\x00\x04\x00\x2F\x00\x00\x00\x21\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x35\x00\x00\x00\x0B\x00\x00\x00\x0F\x00\x00\x00" +"\x47\x00\x04\x00\x46\x00\x00\x00\x01\x00\x00\x00\x01\x01\x00\x00\x47\x00\x04\x00\x09\x01\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00" "\x47\x00\x04\x00\x28\x01\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x28\x01\x00\x00\x21\x00\x00\x00\x02\x00\x00\x00" "\x47\x00\x04\x00\x30\x01\x00\x00\x01\x00\x00\x00\x02\x01\x00\x00\x47\x00\x04\x00\x35\x01\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00" "\x47\x00\x04\x00\x3F\x01\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x48\x00\x04\x00\x46\x01\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00" @@ -7988,9 +7997,9 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND #ifdef VKQUAKE {QR_VULKAN, -1, "drawflat_wall", "\xFF\x53\x50\x56\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x20\x00\x00\x00\x2C\x00\x00\x00\x4C\x00\x00\x00\x78\x00\x00\x00" -"\xB4\x12\x00\x00\x2C\x13\x00\x00\x28\x20\x00\x00\x01\x00\x66\x33\x72\x5F\x66\x6C\x6F\x6F\x72\x63\x6F\x6C\x6F\x72\x00\x00\x00\x00" -"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x03\x66\x33\x72\x5F\x77\x61\x6C\x6C\x63\x6F\x6C\x6F\x72\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x00\x00\x01\x06\x62\x31\x72\x5F\x66\x6F\x67\x5F\x65\x78\x70\x32\x00\x00\x00\x00\x00\x03\x02\x23\x07\x00\x00\x01\x00" +"\xD4\x12\x00\x00\x4C\x13\x00\x00\x48\x20\x00\x00\x01\x00\x66\x33\x72\x5F\x66\x6C\x6F\x6F\x72\x63\x6F\x6C\x6F\x72\x00\x3F\x00\x00" +"\x00\x3F\x00\x00\x00\x3F\x00\x00\x00\x01\x03\x66\x33\x72\x5F\x77\x61\x6C\x6C\x63\x6F\x6C\x6F\x72\x00\x3E\x80\x00\x00\x3E\x80\x00" +"\x00\x3F\x00\x00\x00\x01\x06\x62\x31\x72\x5F\x66\x6F\x67\x5F\x65\x78\x70\x32\x00\x00\x00\x00\x00\x03\x02\x23\x07\x00\x00\x01\x00" "\x01\x00\x08\x00\x78\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\x0F\x00\x00\x00\x00\x00" "\x04\x00\x00\x00\x6D\x61\x69\x6E\x00\x00\x00\x00\x27\x00\x00\x00\x44\x00\x00\x00\x4F\x00\x00\x00\x65\x00\x00\x00\x67\x00\x00\x00" @@ -8056,7 +8065,8 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "\x1E\x00\x00\x00\x15\x00\x00\x00\x23\x00\x00\x00\x94\x01\x00\x00\x48\x00\x05\x00\x1E\x00\x00\x00\x16\x00\x00\x00\x23\x00\x00\x00" "\x98\x01\x00\x00\x47\x00\x03\x00\x1E\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x20\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00" "\x47\x00\x04\x00\x20\x00\x00\x00\x21\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x27\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00" -"\x47\x00\x04\x00\x4F\x00\x00\x00\x1E\x00\x00\x00\x04\x00\x00\x00\x47\x00\x04\x00\x67\x00\x00\x00\x1E\x00\x00\x00\x03\x00\x00\x00" +"\x47\x00\x04\x00\x44\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x4F\x00\x00\x00\x1E\x00\x00\x00\x04\x00\x00\x00" +"\x47\x00\x04\x00\x65\x00\x00\x00\x1E\x00\x00\x00\x01\x00\x00\x00\x47\x00\x04\x00\x67\x00\x00\x00\x1E\x00\x00\x00\x03\x00\x00\x00" "\x48\x00\x05\x00\x69\x00\x00\x00\x00\x00\x00\x00\x0B\x00\x00\x00\x00\x00\x00\x00\x47\x00\x03\x00\x69\x00\x00\x00\x02\x00\x00\x00" "\x47\x00\x04\x00\x6E\x00\x00\x00\x01\x00\x00\x00\x06\x01\x00\x00\x47\x00\x04\x00\x6F\x00\x00\x00\x01\x00\x00\x00\x15\x00\x00\x00" "\x48\x00\x04\x00\x70\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x70\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00" @@ -8212,8 +8222,9 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "\x94\x01\x00\x00\x48\x00\x05\x00\x38\x00\x00\x00\x16\x00\x00\x00\x23\x00\x00\x00\x98\x01\x00\x00\x47\x00\x03\x00\x38\x00\x00\x00" "\x02\x00\x00\x00\x47\x00\x04\x00\x3A\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x3A\x00\x00\x00\x21\x00\x00\x00" "\x00\x00\x00\x00\x47\x00\x04\x00\x40\x00\x00\x00\x0B\x00\x00\x00\x0F\x00\x00\x00\x47\x00\x04\x00\x51\x00\x00\x00\x01\x00\x00\x00" -"\x06\x01\x00\x00\x47\x00\x04\x00\x12\x01\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x18\x01\x00\x00\x22\x00\x00\x00" -"\x00\x00\x00\x00\x47\x00\x04\x00\x18\x01\x00\x00\x21\x00\x00\x00\x02\x00\x00\x00\x48\x00\x04\x00\x21\x01\x00\x00\x00\x00\x00\x00" +"\x06\x01\x00\x00\x47\x00\x04\x00\x12\x01\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x13\x01\x00\x00\x1E\x00\x00\x00" +"\x00\x00\x00\x00\x47\x00\x04\x00\x18\x01\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x18\x01\x00\x00\x21\x00\x00\x00" +"\x02\x00\x00\x00\x47\x00\x04\x00\x1B\x01\x00\x00\x1E\x00\x00\x00\x01\x00\x00\x00\x48\x00\x04\x00\x21\x01\x00\x00\x00\x00\x00\x00" "\x05\x00\x00\x00\x48\x00\x05\x00\x21\x01\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00\x21\x01\x00\x00" "\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x05\x00\x21\x01\x00\x00\x01\x00\x00\x00\x23\x00\x00\x00\x40\x00\x00\x00" "\x48\x00\x05\x00\x21\x01\x00\x00\x02\x00\x00\x00\x23\x00\x00\x00\x4C\x00\x00\x00\x48\x00\x05\x00\x21\x01\x00\x00\x03\x00\x00\x00" @@ -8919,7 +8930,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND #ifdef VKQUAKE {QR_VULKAN, -1, "postproc_fisheye", "\xFF\x53\x50\x56\x01\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2C\x00\x00\x00\x0D\x00\x00\x00\x3C\x00\x00\x00" -"\xA8\x0E\x00\x00\xE4\x0E\x00\x00\xAC\x0E\x00\x00\x01\x00\x66\x31\x66\x66\x6F\x76\x00\x00\x00\x00\x00\x6E\x65\x20\x03\x02\x23\x07" +"\xB8\x0E\x00\x00\xF4\x0E\x00\x00\xBC\x0E\x00\x00\x01\x00\x66\x31\x66\x66\x6F\x76\x00\x00\x00\x00\x00\x00\x4D\x00\x03\x02\x23\x07" "\x00\x00\x01\x00\x01\x00\x08\x00\x4D\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\x3B\x00\x00\x00\x3F\x00\x00\x00" @@ -8980,98 +8991,99 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "\x48\x00\x05\x00\x13\x00\x00\x00\x15\x00\x00\x00\x23\x00\x00\x00\x94\x01\x00\x00\x48\x00\x05\x00\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\x3B\x00\x00\x00\x1E\x00\x00\x00\x01\x00\x00\x00\x48\x00\x05\x00\x3D\x00\x00\x00\x00\x00\x00\x00" -"\x0B\x00\x00\x00\x00\x00\x00\x00\x47\x00\x03\x00\x3D\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x43\x00\x00\x00\x01\x00\x00\x00" -"\x00\x01\x00\x00\x48\x00\x04\x00\x44\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00\x00\x00\x00\x00" -"\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x05\x00" -"\x44\x00\x00\x00\x01\x00\x00\x00\x23\x00\x00\x00\x40\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00\x02\x00\x00\x00\x23\x00\x00\x00" -"\x4C\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00\x03\x00\x00\x00\x23\x00\x00\x00\x50\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00" -"\x04\x00\x00\x00\x23\x00\x00\x00\x5C\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00\x05\x00\x00\x00\x23\x00\x00\x00\x60\x00\x00\x00" -"\x48\x00\x05\x00\x44\x00\x00\x00\x06\x00\x00\x00\x23\x00\x00\x00\x6C\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00\x07\x00\x00\x00" -"\x23\x00\x00\x00\x70\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00\x08\x00\x00\x00\x23\x00\x00\x00\x80\x00\x00\x00\x48\x00\x05\x00" -"\x44\x00\x00\x00\x09\x00\x00\x00\x23\x00\x00\x00\x88\x00\x00\x00\x47\x00\x03\x00\x44\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00" -"\x46\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x46\x00\x00\x00\x21\x00\x00\x00\x01\x00\x00\x00\x47\x00\x04\x00" -"\x48\x00\x00\x00\x1E\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x49\x00\x00\x00\x1E\x00\x00\x00\x03\x00\x00\x00\x47\x00\x04\x00" -"\x4A\x00\x00\x00\x1E\x00\x00\x00\x04\x00\x00\x00\x47\x00\x04\x00\x4B\x00\x00\x00\x1E\x00\x00\x00\x05\x00\x00\x00\x47\x00\x04\x00" -"\x4C\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\x15\x00\x04\x00\x0F\x00\x00\x00" -"\x20\x00\x00\x00\x00\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00\x10\x00\x00\x00\x04\x00\x00\x00\x1C\x00\x04\x00\x11\x00\x00\x00" -"\x07\x00\x00\x00\x10\x00\x00\x00\x17\x00\x04\x00\x12\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x1E\x00\x19\x00\x13\x00\x00\x00" -"\x0D\x00\x00\x00\x0D\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\x0E\x00\x00\x00\x06\x00\x00\x00\x11\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\x07\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x12\x00\x00\x00\x20\x00\x04\x00" -"\x14\x00\x00\x00\x02\x00\x00\x00\x13\x00\x00\x00\x3B\x00\x04\x00\x14\x00\x00\x00\x15\x00\x00\x00\x02\x00\x00\x00\x15\x00\x04\x00" -"\x16\x00\x00\x00\x20\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00\x16\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x20\x00\x04\x00" -"\x18\x00\x00\x00\x02\x00\x00\x00\x0D\x00\x00\x00\x20\x00\x04\x00\x1B\x00\x00\x00\x01\x00\x00\x00\x0E\x00\x00\x00\x3B\x00\x04\x00" -"\x1B\x00\x00\x00\x1C\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00\x06\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x80\x3F\x2B\x00\x04\x00" -"\x06\x00\x00\x00\x24\x00\x00\x00\x00\x00\x80\xBF\x2B\x00\x04\x00\x0F\x00\x00\x00\x25\x00\x00\x00\x01\x00\x00\x00\x20\x00\x04\x00" -"\x26\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00\x2B\x00\x00\x00\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\x12\x00\x00\x00\x3B\x00\x04\x00\x38\x00\x00\x00\x39\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00" -"\x3A\x00\x00\x00\x01\x00\x00\x00\x12\x00\x00\x00\x3B\x00\x04\x00\x3A\x00\x00\x00\x3B\x00\x00\x00\x01\x00\x00\x00\x1E\x00\x03\x00" -"\x3D\x00\x00\x00\x07\x00\x00\x00\x20\x00\x04\x00\x3E\x00\x00\x00\x03\x00\x00\x00\x3D\x00\x00\x00\x3B\x00\x04\x00\x3E\x00\x00\x00" -"\x3F\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00\x41\x00\x00\x00\x03\x00\x00\x00\x07\x00\x00\x00\x32\x00\x04\x00\x06\x00\x00\x00" -"\x43\x00\x00\x00\x00\x00\x80\x43\x1E\x00\x0C\x00\x44\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\x45\x00\x00\x00" -"\x02\x00\x00\x00\x44\x00\x00\x00\x3B\x00\x04\x00\x45\x00\x00\x00\x46\x00\x00\x00\x02\x00\x00\x00\x20\x00\x04\x00\x47\x00\x00\x00" -"\x01\x00\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00\x47\x00\x00\x00\x48\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x3A\x00\x00\x00" -"\x49\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x4A\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00" -"\x4B\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x4C\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\x12\x00\x00\x00\x3C\x00\x00\x00" -"\x3B\x00\x00\x00\x3E\x00\x03\x00\x39\x00\x00\x00\x3C\x00\x00\x00\x39\x00\x04\x00\x07\x00\x00\x00\x40\x00\x00\x00\x09\x00\x00\x00" -"\x41\x00\x05\x00\x41\x00\x00\x00\x42\x00\x00\x00\x3F\x00\x00\x00\x17\x00\x00\x00\x3E\x00\x03\x00\x42\x00\x00\x00\x40\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\x01\x00\x08\x00\x54\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\x07\x00\x04\x00\x00\x00\x04\x00\x00\x00\x6D\x61\x69\x6E\x00\x00\x00\x00\x0B\x00\x00\x00\x43\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\x03\x00\x09\x00\x00\x00\x64\x00\x00\x00\x05\x00\x05\x00\x0B\x00\x00\x00\x74\x65\x78\x63" -"\x6F\x6F\x72\x64\x00\x00\x00\x00\x05\x00\x03\x00\x0D\x00\x00\x00\x61\x6E\x67\x00\x05\x00\x03\x00\x2B\x00\x00\x00\x74\x63\x00\x00" -"\x05\x00\x05\x00\x43\x00\x00\x00\x6F\x75\x74\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x06\x00\x47\x00\x00\x00\x73\x5F\x72\x65" -"\x66\x6C\x65\x63\x74\x63\x75\x62\x65\x00\x00\x00\x05\x00\x05\x00\x4E\x00\x00\x00\x65\x6E\x74\x69\x74\x79\x62\x6C\x6F\x63\x6B\x00" -"\x06\x00\x07\x00\x4E\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" -"\x4E\x00\x00\x00\x01\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x00\x06\x00\x06\x00\x4E\x00\x00\x00\x02\x00\x00\x00\x6D\x5F\x6D\x6F" -"\x64\x65\x6C\x69\x6E\x76\x00\x00\x06\x00\x06\x00\x4E\x00\x00\x00\x03\x00\x00\x00\x65\x5F\x65\x79\x65\x70\x6F\x73\x00\x00\x00\x00" -"\x06\x00\x05\x00\x4E\x00\x00\x00\x04\x00\x00\x00\x65\x5F\x74\x69\x6D\x65\x00\x00\x06\x00\x07\x00\x4E\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\x4E\x00\x00\x00\x06\x00\x00\x00\x65\x70\x61\x64" -"\x31\x00\x00\x00\x06\x00\x06\x00\x4E\x00\x00\x00\x07\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x64\x69\x72\x00\x06\x00\x05\x00" -"\x4E\x00\x00\x00\x08\x00\x00\x00\x65\x70\x61\x64\x32\x00\x00\x00\x06\x00\x06\x00\x4E\x00\x00\x00\x09\x00\x00\x00\x65\x5F\x6C\x69" -"\x67\x68\x74\x5F\x6D\x75\x6C\x00\x06\x00\x05\x00\x4E\x00\x00\x00\x0A\x00\x00\x00\x65\x70\x61\x64\x33\x00\x00\x00\x06\x00\x06\x00" -"\x4E\x00\x00\x00\x0B\x00\x00\x00\x65\x5F\x6C\x6D\x73\x63\x61\x6C\x65\x73\x00\x00\x06\x00\x07\x00\x4E\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\x4E\x00\x00\x00\x0D\x00\x00\x00\x65\x70\x61\x64" -"\x34\x00\x00\x00\x06\x00\x07\x00\x4E\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\x4E\x00\x00\x00\x0F\x00\x00\x00\x65\x70\x61\x64\x35\x00\x00\x00\x06\x00\x06\x00\x4E\x00\x00\x00\x10\x00\x00\x00" -"\x65\x5F\x67\x6C\x6F\x77\x6D\x6F\x64\x00\x00\x00\x06\x00\x05\x00\x4E\x00\x00\x00\x11\x00\x00\x00\x65\x70\x61\x64\x36\x00\x00\x00" -"\x06\x00\x07\x00\x4E\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" -"\x4E\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\x4E\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\x4E\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\x4E\x00\x00\x00\x16\x00\x00\x00\x65\x70\x61\x64" -"\x37\x00\x00\x00\x05\x00\x03\x00\x50\x00\x00\x00\x00\x00\x00\x00\x05\x00\x05\x00\x51\x00\x00\x00\x6C\x69\x67\x68\x74\x62\x6C\x6F" -"\x63\x6B\x00\x00\x06\x00\x07\x00\x51\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\x51\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" -"\x51\x00\x00\x00\x02\x00\x00\x00\x6C\x70\x61\x64\x31\x00\x00\x00\x06\x00\x07\x00\x51\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\x51\x00\x00\x00\x04\x00\x00\x00\x6C\x70\x61\x64\x32\x00\x00\x00" -"\x06\x00\x08\x00\x51\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\x51\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" -"\x51\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\x51\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\x51\x00\x00\x00" -"\x09\x00\x00\x00\x6C\x70\x61\x64\x33\x00\x00\x00\x05\x00\x03\x00\x53\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\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\x47\x00\x04\x00\x3B\x00\x00\x00\x1E\x00\x00\x00" +"\x01\x00\x00\x00\x48\x00\x05\x00\x3D\x00\x00\x00\x00\x00\x00\x00\x0B\x00\x00\x00\x00\x00\x00\x00\x47\x00\x03\x00\x3D\x00\x00\x00" +"\x02\x00\x00\x00\x47\x00\x04\x00\x43\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x48\x00\x04\x00\x44\x00\x00\x00\x00\x00\x00\x00" +"\x05\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00" +"\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00\x01\x00\x00\x00\x23\x00\x00\x00\x40\x00\x00\x00" +"\x48\x00\x05\x00\x44\x00\x00\x00\x02\x00\x00\x00\x23\x00\x00\x00\x4C\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00\x03\x00\x00\x00" +"\x23\x00\x00\x00\x50\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00\x5C\x00\x00\x00\x48\x00\x05\x00" +"\x44\x00\x00\x00\x05\x00\x00\x00\x23\x00\x00\x00\x60\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00\x06\x00\x00\x00\x23\x00\x00\x00" +"\x6C\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00\x07\x00\x00\x00\x23\x00\x00\x00\x70\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00" +"\x08\x00\x00\x00\x23\x00\x00\x00\x80\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00\x09\x00\x00\x00\x23\x00\x00\x00\x88\x00\x00\x00" +"\x47\x00\x03\x00\x44\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x46\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00" +"\x46\x00\x00\x00\x21\x00\x00\x00\x01\x00\x00\x00\x47\x00\x04\x00\x48\x00\x00\x00\x1E\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00" +"\x49\x00\x00\x00\x1E\x00\x00\x00\x03\x00\x00\x00\x47\x00\x04\x00\x4A\x00\x00\x00\x1E\x00\x00\x00\x04\x00\x00\x00\x47\x00\x04\x00" +"\x4B\x00\x00\x00\x1E\x00\x00\x00\x05\x00\x00\x00\x47\x00\x04\x00\x4C\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\x15\x00\x04\x00\x0F\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00" +"\x10\x00\x00\x00\x04\x00\x00\x00\x1C\x00\x04\x00\x11\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x17\x00\x04\x00\x12\x00\x00\x00" +"\x06\x00\x00\x00\x02\x00\x00\x00\x1E\x00\x19\x00\x13\x00\x00\x00\x0D\x00\x00\x00\x0D\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\x0E\x00\x00\x00\x06\x00\x00\x00\x11\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\x07\x00\x00\x00" +"\x06\x00\x00\x00\x06\x00\x00\x00\x12\x00\x00\x00\x20\x00\x04\x00\x14\x00\x00\x00\x02\x00\x00\x00\x13\x00\x00\x00\x3B\x00\x04\x00" +"\x14\x00\x00\x00\x15\x00\x00\x00\x02\x00\x00\x00\x15\x00\x04\x00\x16\x00\x00\x00\x20\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00" +"\x16\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x20\x00\x04\x00\x18\x00\x00\x00\x02\x00\x00\x00\x0D\x00\x00\x00\x20\x00\x04\x00" +"\x1B\x00\x00\x00\x01\x00\x00\x00\x0E\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x1C\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00" +"\x06\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x80\x3F\x2B\x00\x04\x00\x06\x00\x00\x00\x24\x00\x00\x00\x00\x00\x80\xBF\x2B\x00\x04\x00" +"\x0F\x00\x00\x00\x25\x00\x00\x00\x01\x00\x00\x00\x20\x00\x04\x00\x26\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x2B\x00\x04\x00" +"\x0F\x00\x00\x00\x2B\x00\x00\x00\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\x12\x00\x00\x00\x3B\x00\x04\x00" +"\x38\x00\x00\x00\x39\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00\x3A\x00\x00\x00\x01\x00\x00\x00\x12\x00\x00\x00\x3B\x00\x04\x00" +"\x3A\x00\x00\x00\x3B\x00\x00\x00\x01\x00\x00\x00\x1E\x00\x03\x00\x3D\x00\x00\x00\x07\x00\x00\x00\x20\x00\x04\x00\x3E\x00\x00\x00" +"\x03\x00\x00\x00\x3D\x00\x00\x00\x3B\x00\x04\x00\x3E\x00\x00\x00\x3F\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00\x41\x00\x00\x00" +"\x03\x00\x00\x00\x07\x00\x00\x00\x32\x00\x04\x00\x06\x00\x00\x00\x43\x00\x00\x00\x00\x00\x80\x43\x1E\x00\x0C\x00\x44\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\x45\x00\x00\x00\x02\x00\x00\x00\x44\x00\x00\x00\x3B\x00\x04\x00\x45\x00\x00\x00" +"\x46\x00\x00\x00\x02\x00\x00\x00\x20\x00\x04\x00\x47\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00\x47\x00\x00\x00" +"\x48\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x3A\x00\x00\x00\x49\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00" +"\x4A\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x4B\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00" +"\x4C\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\x12\x00\x00\x00\x3C\x00\x00\x00\x3B\x00\x00\x00\x3E\x00\x03\x00\x39\x00\x00\x00\x3C\x00\x00\x00" +"\x39\x00\x04\x00\x07\x00\x00\x00\x40\x00\x00\x00\x09\x00\x00\x00\x41\x00\x05\x00\x41\x00\x00\x00\x42\x00\x00\x00\x3F\x00\x00\x00" +"\x17\x00\x00\x00\x3E\x00\x03\x00\x42\x00\x00\x00\x40\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\x01\x00\x08\x00" +"\x54\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\x07\x00\x04\x00\x00\x00\x04\x00\x00\x00" +"\x6D\x61\x69\x6E\x00\x00\x00\x00\x0B\x00\x00\x00\x43\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\x03\x00\x09\x00\x00\x00" +"\x64\x00\x00\x00\x05\x00\x05\x00\x0B\x00\x00\x00\x74\x65\x78\x63\x6F\x6F\x72\x64\x00\x00\x00\x00\x05\x00\x03\x00\x0D\x00\x00\x00" +"\x61\x6E\x67\x00\x05\x00\x03\x00\x2B\x00\x00\x00\x74\x63\x00\x00\x05\x00\x05\x00\x43\x00\x00\x00\x6F\x75\x74\x63\x6F\x6C\x6F\x75" +"\x72\x00\x00\x00\x05\x00\x06\x00\x47\x00\x00\x00\x73\x5F\x72\x65\x66\x6C\x65\x63\x74\x63\x75\x62\x65\x00\x00\x00\x05\x00\x05\x00" +"\x4E\x00\x00\x00\x65\x6E\x74\x69\x74\x79\x62\x6C\x6F\x63\x6B\x00\x06\x00\x07\x00\x4E\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\x4E\x00\x00\x00\x01\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x00" +"\x06\x00\x06\x00\x4E\x00\x00\x00\x02\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x69\x6E\x76\x00\x00\x06\x00\x06\x00\x4E\x00\x00\x00" +"\x03\x00\x00\x00\x65\x5F\x65\x79\x65\x70\x6F\x73\x00\x00\x00\x00\x06\x00\x05\x00\x4E\x00\x00\x00\x04\x00\x00\x00\x65\x5F\x74\x69" +"\x6D\x65\x00\x00\x06\x00\x07\x00\x4E\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\x4E\x00\x00\x00\x06\x00\x00\x00\x65\x70\x61\x64\x31\x00\x00\x00\x06\x00\x06\x00\x4E\x00\x00\x00\x07\x00\x00\x00" +"\x65\x5F\x6C\x69\x67\x68\x74\x5F\x64\x69\x72\x00\x06\x00\x05\x00\x4E\x00\x00\x00\x08\x00\x00\x00\x65\x70\x61\x64\x32\x00\x00\x00" +"\x06\x00\x06\x00\x4E\x00\x00\x00\x09\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x6D\x75\x6C\x00\x06\x00\x05\x00\x4E\x00\x00\x00" +"\x0A\x00\x00\x00\x65\x70\x61\x64\x33\x00\x00\x00\x06\x00\x06\x00\x4E\x00\x00\x00\x0B\x00\x00\x00\x65\x5F\x6C\x6D\x73\x63\x61\x6C" +"\x65\x73\x00\x00\x06\x00\x07\x00\x4E\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\x4E\x00\x00\x00\x0D\x00\x00\x00\x65\x70\x61\x64\x34\x00\x00\x00\x06\x00\x07\x00\x4E\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\x4E\x00\x00\x00\x0F\x00\x00\x00\x65\x70\x61\x64" +"\x35\x00\x00\x00\x06\x00\x06\x00\x4E\x00\x00\x00\x10\x00\x00\x00\x65\x5F\x67\x6C\x6F\x77\x6D\x6F\x64\x00\x00\x00\x06\x00\x05\x00" +"\x4E\x00\x00\x00\x11\x00\x00\x00\x65\x70\x61\x64\x36\x00\x00\x00\x06\x00\x07\x00\x4E\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\x4E\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\x4E\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\x4E\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\x4E\x00\x00\x00\x16\x00\x00\x00\x65\x70\x61\x64\x37\x00\x00\x00\x05\x00\x03\x00\x50\x00\x00\x00\x00\x00\x00\x00" +"\x05\x00\x05\x00\x51\x00\x00\x00\x6C\x69\x67\x68\x74\x62\x6C\x6F\x63\x6B\x00\x00\x06\x00\x07\x00\x51\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\x51\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\x51\x00\x00\x00\x02\x00\x00\x00\x6C\x70\x61\x64\x31\x00\x00\x00" +"\x06\x00\x07\x00\x51\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" +"\x51\x00\x00\x00\x04\x00\x00\x00\x6C\x70\x61\x64\x32\x00\x00\x00\x06\x00\x08\x00\x51\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\x51\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\x51\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\x51\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\x51\x00\x00\x00\x09\x00\x00\x00\x6C\x70\x61\x64\x33\x00\x00\x00\x05\x00\x03\x00" +"\x53\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x0B\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x1E\x00\x00\x00" "\x01\x00\x00\x00\x00\x01\x00\x00\x47\x00\x04\x00\x43\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x47\x00\x00\x00" "\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x47\x00\x00\x00\x21\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x4D\x00\x00\x00" "\x06\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00\x4E\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x4E\x00\x00\x00" @@ -9191,7 +9203,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND #ifdef VKQUAKE {QR_VULKAN, -1, "postproc_panorama", "\xFF\x53\x50\x56\x01\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2C\x00\x00\x00\x0D\x00\x00\x00\x3C\x00\x00\x00" -"\xA8\x0E\x00\x00\xE4\x0E\x00\x00\x3C\x0C\x00\x00\x01\x00\x66\x31\x66\x66\x6F\x76\x00\x00\x00\x00\x00\x6E\x65\x20\x03\x02\x23\x07" +"\xB8\x0E\x00\x00\xF4\x0E\x00\x00\x4C\x0C\x00\x00\x01\x00\x66\x31\x66\x66\x6F\x76\x00\x00\x00\x00\x00\x00\x4D\x00\x03\x02\x23\x07" "\x00\x00\x01\x00\x01\x00\x08\x00\x4D\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\x3B\x00\x00\x00\x3F\x00\x00\x00" @@ -9252,98 +9264,99 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "\x48\x00\x05\x00\x13\x00\x00\x00\x15\x00\x00\x00\x23\x00\x00\x00\x94\x01\x00\x00\x48\x00\x05\x00\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\x3B\x00\x00\x00\x1E\x00\x00\x00\x01\x00\x00\x00\x48\x00\x05\x00\x3D\x00\x00\x00\x00\x00\x00\x00" -"\x0B\x00\x00\x00\x00\x00\x00\x00\x47\x00\x03\x00\x3D\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x43\x00\x00\x00\x01\x00\x00\x00" -"\x00\x01\x00\x00\x48\x00\x04\x00\x44\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00\x00\x00\x00\x00" -"\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x05\x00" -"\x44\x00\x00\x00\x01\x00\x00\x00\x23\x00\x00\x00\x40\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00\x02\x00\x00\x00\x23\x00\x00\x00" -"\x4C\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00\x03\x00\x00\x00\x23\x00\x00\x00\x50\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00" -"\x04\x00\x00\x00\x23\x00\x00\x00\x5C\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00\x05\x00\x00\x00\x23\x00\x00\x00\x60\x00\x00\x00" -"\x48\x00\x05\x00\x44\x00\x00\x00\x06\x00\x00\x00\x23\x00\x00\x00\x6C\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00\x07\x00\x00\x00" -"\x23\x00\x00\x00\x70\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00\x08\x00\x00\x00\x23\x00\x00\x00\x80\x00\x00\x00\x48\x00\x05\x00" -"\x44\x00\x00\x00\x09\x00\x00\x00\x23\x00\x00\x00\x88\x00\x00\x00\x47\x00\x03\x00\x44\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00" -"\x46\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x46\x00\x00\x00\x21\x00\x00\x00\x01\x00\x00\x00\x47\x00\x04\x00" -"\x48\x00\x00\x00\x1E\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x49\x00\x00\x00\x1E\x00\x00\x00\x03\x00\x00\x00\x47\x00\x04\x00" -"\x4A\x00\x00\x00\x1E\x00\x00\x00\x04\x00\x00\x00\x47\x00\x04\x00\x4B\x00\x00\x00\x1E\x00\x00\x00\x05\x00\x00\x00\x47\x00\x04\x00" -"\x4C\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\x15\x00\x04\x00\x0F\x00\x00\x00" -"\x20\x00\x00\x00\x00\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00\x10\x00\x00\x00\x04\x00\x00\x00\x1C\x00\x04\x00\x11\x00\x00\x00" -"\x07\x00\x00\x00\x10\x00\x00\x00\x17\x00\x04\x00\x12\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x1E\x00\x19\x00\x13\x00\x00\x00" -"\x0D\x00\x00\x00\x0D\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\x0E\x00\x00\x00\x06\x00\x00\x00\x11\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\x07\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x12\x00\x00\x00\x20\x00\x04\x00" -"\x14\x00\x00\x00\x02\x00\x00\x00\x13\x00\x00\x00\x3B\x00\x04\x00\x14\x00\x00\x00\x15\x00\x00\x00\x02\x00\x00\x00\x15\x00\x04\x00" -"\x16\x00\x00\x00\x20\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00\x16\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x20\x00\x04\x00" -"\x18\x00\x00\x00\x02\x00\x00\x00\x0D\x00\x00\x00\x20\x00\x04\x00\x1B\x00\x00\x00\x01\x00\x00\x00\x0E\x00\x00\x00\x3B\x00\x04\x00" -"\x1B\x00\x00\x00\x1C\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00\x06\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x80\x3F\x2B\x00\x04\x00" -"\x06\x00\x00\x00\x24\x00\x00\x00\x00\x00\x80\xBF\x2B\x00\x04\x00\x0F\x00\x00\x00\x25\x00\x00\x00\x01\x00\x00\x00\x20\x00\x04\x00" -"\x26\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00\x2B\x00\x00\x00\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\x12\x00\x00\x00\x3B\x00\x04\x00\x38\x00\x00\x00\x39\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00" -"\x3A\x00\x00\x00\x01\x00\x00\x00\x12\x00\x00\x00\x3B\x00\x04\x00\x3A\x00\x00\x00\x3B\x00\x00\x00\x01\x00\x00\x00\x1E\x00\x03\x00" -"\x3D\x00\x00\x00\x07\x00\x00\x00\x20\x00\x04\x00\x3E\x00\x00\x00\x03\x00\x00\x00\x3D\x00\x00\x00\x3B\x00\x04\x00\x3E\x00\x00\x00" -"\x3F\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00\x41\x00\x00\x00\x03\x00\x00\x00\x07\x00\x00\x00\x32\x00\x04\x00\x06\x00\x00\x00" -"\x43\x00\x00\x00\x00\x00\x80\x43\x1E\x00\x0C\x00\x44\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\x45\x00\x00\x00" -"\x02\x00\x00\x00\x44\x00\x00\x00\x3B\x00\x04\x00\x45\x00\x00\x00\x46\x00\x00\x00\x02\x00\x00\x00\x20\x00\x04\x00\x47\x00\x00\x00" -"\x01\x00\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00\x47\x00\x00\x00\x48\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x3A\x00\x00\x00" -"\x49\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x4A\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00" -"\x4B\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x4C\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\x12\x00\x00\x00\x3C\x00\x00\x00" -"\x3B\x00\x00\x00\x3E\x00\x03\x00\x39\x00\x00\x00\x3C\x00\x00\x00\x39\x00\x04\x00\x07\x00\x00\x00\x40\x00\x00\x00\x09\x00\x00\x00" -"\x41\x00\x05\x00\x41\x00\x00\x00\x42\x00\x00\x00\x3F\x00\x00\x00\x17\x00\x00\x00\x3E\x00\x03\x00\x42\x00\x00\x00\x40\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\x01\x00\x08\x00\x36\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\x07\x00\x04\x00\x00\x00\x04\x00\x00\x00\x6D\x61\x69\x6E\x00\x00\x00\x00\x0B\x00\x00\x00\x25\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\x03\x00\x08\x00\x00\x00\x61\x6E\x67\x00\x05\x00\x05\x00\x0B\x00\x00\x00\x74\x65\x78\x63" -"\x6F\x6F\x72\x64\x00\x00\x00\x00\x05\x00\x03\x00\x16\x00\x00\x00\x74\x63\x00\x00\x05\x00\x05\x00\x25\x00\x00\x00\x6F\x75\x74\x63" -"\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x06\x00\x29\x00\x00\x00\x73\x5F\x72\x65\x66\x6C\x65\x63\x74\x63\x75\x62\x65\x00\x00\x00" -"\x05\x00\x05\x00\x30\x00\x00\x00\x65\x6E\x74\x69\x74\x79\x62\x6C\x6F\x63\x6B\x00\x06\x00\x07\x00\x30\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\x30\x00\x00\x00\x01\x00\x00\x00\x6D\x5F\x6D\x6F" -"\x64\x65\x6C\x00\x06\x00\x06\x00\x30\x00\x00\x00\x02\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x69\x6E\x76\x00\x00\x06\x00\x06\x00" -"\x30\x00\x00\x00\x03\x00\x00\x00\x65\x5F\x65\x79\x65\x70\x6F\x73\x00\x00\x00\x00\x06\x00\x05\x00\x30\x00\x00\x00\x04\x00\x00\x00" -"\x65\x5F\x74\x69\x6D\x65\x00\x00\x06\x00\x07\x00\x30\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\x30\x00\x00\x00\x06\x00\x00\x00\x65\x70\x61\x64\x31\x00\x00\x00\x06\x00\x06\x00\x30\x00\x00\x00" -"\x07\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x64\x69\x72\x00\x06\x00\x05\x00\x30\x00\x00\x00\x08\x00\x00\x00\x65\x70\x61\x64" -"\x32\x00\x00\x00\x06\x00\x06\x00\x30\x00\x00\x00\x09\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x6D\x75\x6C\x00\x06\x00\x05\x00" -"\x30\x00\x00\x00\x0A\x00\x00\x00\x65\x70\x61\x64\x33\x00\x00\x00\x06\x00\x06\x00\x30\x00\x00\x00\x0B\x00\x00\x00\x65\x5F\x6C\x6D" -"\x73\x63\x61\x6C\x65\x73\x00\x00\x06\x00\x07\x00\x30\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\x30\x00\x00\x00\x0D\x00\x00\x00\x65\x70\x61\x64\x34\x00\x00\x00\x06\x00\x07\x00\x30\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\x30\x00\x00\x00\x0F\x00\x00\x00" -"\x65\x70\x61\x64\x35\x00\x00\x00\x06\x00\x06\x00\x30\x00\x00\x00\x10\x00\x00\x00\x65\x5F\x67\x6C\x6F\x77\x6D\x6F\x64\x00\x00\x00" -"\x06\x00\x05\x00\x30\x00\x00\x00\x11\x00\x00\x00\x65\x70\x61\x64\x36\x00\x00\x00\x06\x00\x07\x00\x30\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\x30\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\x30\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\x30\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\x30\x00\x00\x00\x16\x00\x00\x00\x65\x70\x61\x64\x37\x00\x00\x00\x05\x00\x03\x00\x32\x00\x00\x00" -"\x00\x00\x00\x00\x05\x00\x05\x00\x33\x00\x00\x00\x6C\x69\x67\x68\x74\x62\x6C\x6F\x63\x6B\x00\x00\x06\x00\x07\x00\x33\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\x33\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\x33\x00\x00\x00\x02\x00\x00\x00\x6C\x70\x61\x64" -"\x31\x00\x00\x00\x06\x00\x07\x00\x33\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\x33\x00\x00\x00\x04\x00\x00\x00\x6C\x70\x61\x64\x32\x00\x00\x00\x06\x00\x08\x00\x33\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\x33\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\x33\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\x33\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\x33\x00\x00\x00\x09\x00\x00\x00\x6C\x70\x61\x64\x33\x00\x00\x00" -"\x05\x00\x03\x00\x35\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x11\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x47\x00\x04\x00" +"\x00\x00\x00\x00\x47\x00\x04\x00\x39\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x3B\x00\x00\x00\x1E\x00\x00\x00" +"\x01\x00\x00\x00\x48\x00\x05\x00\x3D\x00\x00\x00\x00\x00\x00\x00\x0B\x00\x00\x00\x00\x00\x00\x00\x47\x00\x03\x00\x3D\x00\x00\x00" +"\x02\x00\x00\x00\x47\x00\x04\x00\x43\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x48\x00\x04\x00\x44\x00\x00\x00\x00\x00\x00\x00" +"\x05\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00" +"\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00\x01\x00\x00\x00\x23\x00\x00\x00\x40\x00\x00\x00" +"\x48\x00\x05\x00\x44\x00\x00\x00\x02\x00\x00\x00\x23\x00\x00\x00\x4C\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00\x03\x00\x00\x00" +"\x23\x00\x00\x00\x50\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00\x5C\x00\x00\x00\x48\x00\x05\x00" +"\x44\x00\x00\x00\x05\x00\x00\x00\x23\x00\x00\x00\x60\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00\x06\x00\x00\x00\x23\x00\x00\x00" +"\x6C\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00\x07\x00\x00\x00\x23\x00\x00\x00\x70\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00" +"\x08\x00\x00\x00\x23\x00\x00\x00\x80\x00\x00\x00\x48\x00\x05\x00\x44\x00\x00\x00\x09\x00\x00\x00\x23\x00\x00\x00\x88\x00\x00\x00" +"\x47\x00\x03\x00\x44\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x46\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00" +"\x46\x00\x00\x00\x21\x00\x00\x00\x01\x00\x00\x00\x47\x00\x04\x00\x48\x00\x00\x00\x1E\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00" +"\x49\x00\x00\x00\x1E\x00\x00\x00\x03\x00\x00\x00\x47\x00\x04\x00\x4A\x00\x00\x00\x1E\x00\x00\x00\x04\x00\x00\x00\x47\x00\x04\x00" +"\x4B\x00\x00\x00\x1E\x00\x00\x00\x05\x00\x00\x00\x47\x00\x04\x00\x4C\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\x15\x00\x04\x00\x0F\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00" +"\x10\x00\x00\x00\x04\x00\x00\x00\x1C\x00\x04\x00\x11\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x17\x00\x04\x00\x12\x00\x00\x00" +"\x06\x00\x00\x00\x02\x00\x00\x00\x1E\x00\x19\x00\x13\x00\x00\x00\x0D\x00\x00\x00\x0D\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\x0E\x00\x00\x00\x06\x00\x00\x00\x11\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\x07\x00\x00\x00" +"\x06\x00\x00\x00\x06\x00\x00\x00\x12\x00\x00\x00\x20\x00\x04\x00\x14\x00\x00\x00\x02\x00\x00\x00\x13\x00\x00\x00\x3B\x00\x04\x00" +"\x14\x00\x00\x00\x15\x00\x00\x00\x02\x00\x00\x00\x15\x00\x04\x00\x16\x00\x00\x00\x20\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00" +"\x16\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x20\x00\x04\x00\x18\x00\x00\x00\x02\x00\x00\x00\x0D\x00\x00\x00\x20\x00\x04\x00" +"\x1B\x00\x00\x00\x01\x00\x00\x00\x0E\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x1C\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00" +"\x06\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x80\x3F\x2B\x00\x04\x00\x06\x00\x00\x00\x24\x00\x00\x00\x00\x00\x80\xBF\x2B\x00\x04\x00" +"\x0F\x00\x00\x00\x25\x00\x00\x00\x01\x00\x00\x00\x20\x00\x04\x00\x26\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x2B\x00\x04\x00" +"\x0F\x00\x00\x00\x2B\x00\x00\x00\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\x12\x00\x00\x00\x3B\x00\x04\x00" +"\x38\x00\x00\x00\x39\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00\x3A\x00\x00\x00\x01\x00\x00\x00\x12\x00\x00\x00\x3B\x00\x04\x00" +"\x3A\x00\x00\x00\x3B\x00\x00\x00\x01\x00\x00\x00\x1E\x00\x03\x00\x3D\x00\x00\x00\x07\x00\x00\x00\x20\x00\x04\x00\x3E\x00\x00\x00" +"\x03\x00\x00\x00\x3D\x00\x00\x00\x3B\x00\x04\x00\x3E\x00\x00\x00\x3F\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00\x41\x00\x00\x00" +"\x03\x00\x00\x00\x07\x00\x00\x00\x32\x00\x04\x00\x06\x00\x00\x00\x43\x00\x00\x00\x00\x00\x80\x43\x1E\x00\x0C\x00\x44\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\x45\x00\x00\x00\x02\x00\x00\x00\x44\x00\x00\x00\x3B\x00\x04\x00\x45\x00\x00\x00" +"\x46\x00\x00\x00\x02\x00\x00\x00\x20\x00\x04\x00\x47\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00\x47\x00\x00\x00" +"\x48\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x3A\x00\x00\x00\x49\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00" +"\x4A\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x4B\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00" +"\x4C\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\x12\x00\x00\x00\x3C\x00\x00\x00\x3B\x00\x00\x00\x3E\x00\x03\x00\x39\x00\x00\x00\x3C\x00\x00\x00" +"\x39\x00\x04\x00\x07\x00\x00\x00\x40\x00\x00\x00\x09\x00\x00\x00\x41\x00\x05\x00\x41\x00\x00\x00\x42\x00\x00\x00\x3F\x00\x00\x00" +"\x17\x00\x00\x00\x3E\x00\x03\x00\x42\x00\x00\x00\x40\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\x01\x00\x08\x00" +"\x36\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\x07\x00\x04\x00\x00\x00\x04\x00\x00\x00" +"\x6D\x61\x69\x6E\x00\x00\x00\x00\x0B\x00\x00\x00\x25\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\x03\x00\x08\x00\x00\x00" +"\x61\x6E\x67\x00\x05\x00\x05\x00\x0B\x00\x00\x00\x74\x65\x78\x63\x6F\x6F\x72\x64\x00\x00\x00\x00\x05\x00\x03\x00\x16\x00\x00\x00" +"\x74\x63\x00\x00\x05\x00\x05\x00\x25\x00\x00\x00\x6F\x75\x74\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x06\x00\x29\x00\x00\x00" +"\x73\x5F\x72\x65\x66\x6C\x65\x63\x74\x63\x75\x62\x65\x00\x00\x00\x05\x00\x05\x00\x30\x00\x00\x00\x65\x6E\x74\x69\x74\x79\x62\x6C" +"\x6F\x63\x6B\x00\x06\x00\x07\x00\x30\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\x30\x00\x00\x00\x01\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x00\x06\x00\x06\x00\x30\x00\x00\x00\x02\x00\x00\x00" +"\x6D\x5F\x6D\x6F\x64\x65\x6C\x69\x6E\x76\x00\x00\x06\x00\x06\x00\x30\x00\x00\x00\x03\x00\x00\x00\x65\x5F\x65\x79\x65\x70\x6F\x73" +"\x00\x00\x00\x00\x06\x00\x05\x00\x30\x00\x00\x00\x04\x00\x00\x00\x65\x5F\x74\x69\x6D\x65\x00\x00\x06\x00\x07\x00\x30\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\x30\x00\x00\x00\x06\x00\x00\x00" +"\x65\x70\x61\x64\x31\x00\x00\x00\x06\x00\x06\x00\x30\x00\x00\x00\x07\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x64\x69\x72\x00" +"\x06\x00\x05\x00\x30\x00\x00\x00\x08\x00\x00\x00\x65\x70\x61\x64\x32\x00\x00\x00\x06\x00\x06\x00\x30\x00\x00\x00\x09\x00\x00\x00" +"\x65\x5F\x6C\x69\x67\x68\x74\x5F\x6D\x75\x6C\x00\x06\x00\x05\x00\x30\x00\x00\x00\x0A\x00\x00\x00\x65\x70\x61\x64\x33\x00\x00\x00" +"\x06\x00\x06\x00\x30\x00\x00\x00\x0B\x00\x00\x00\x65\x5F\x6C\x6D\x73\x63\x61\x6C\x65\x73\x00\x00\x06\x00\x07\x00\x30\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\x30\x00\x00\x00\x0D\x00\x00\x00" +"\x65\x70\x61\x64\x34\x00\x00\x00\x06\x00\x07\x00\x30\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\x30\x00\x00\x00\x0F\x00\x00\x00\x65\x70\x61\x64\x35\x00\x00\x00\x06\x00\x06\x00\x30\x00\x00\x00" +"\x10\x00\x00\x00\x65\x5F\x67\x6C\x6F\x77\x6D\x6F\x64\x00\x00\x00\x06\x00\x05\x00\x30\x00\x00\x00\x11\x00\x00\x00\x65\x70\x61\x64" +"\x36\x00\x00\x00\x06\x00\x07\x00\x30\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\x30\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" +"\x30\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\x30\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\x30\x00\x00\x00\x16\x00\x00\x00" +"\x65\x70\x61\x64\x37\x00\x00\x00\x05\x00\x03\x00\x32\x00\x00\x00\x00\x00\x00\x00\x05\x00\x05\x00\x33\x00\x00\x00\x6C\x69\x67\x68" +"\x74\x62\x6C\x6F\x63\x6B\x00\x00\x06\x00\x07\x00\x33\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\x33\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\x33\x00\x00\x00\x02\x00\x00\x00\x6C\x70\x61\x64\x31\x00\x00\x00\x06\x00\x07\x00\x33\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\x33\x00\x00\x00\x04\x00\x00\x00\x6C\x70\x61\x64" +"\x32\x00\x00\x00\x06\x00\x08\x00\x33\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\x33\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\x33\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" +"\x33\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" +"\x33\x00\x00\x00\x09\x00\x00\x00\x6C\x70\x61\x64\x33\x00\x00\x00\x05\x00\x03\x00\x35\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00" +"\x0B\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x11\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x47\x00\x04\x00" "\x25\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x29\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00" "\x29\x00\x00\x00\x21\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x2F\x00\x00\x00\x06\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00" "\x30\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x30\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00" @@ -9502,7 +9515,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND #ifdef VKQUAKE {QR_VULKAN, -1, "postproc_stereographic", "\xFF\x53\x50\x56\x01\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2C\x00\x00\x00\x0D\x00\x00\x00\x3C\x00\x00\x00" -"\xFC\x0E\x00\x00\x38\x0F\x00\x00\x8C\x0E\x00\x00\x01\x00\x66\x31\x66\x66\x6F\x76\x00\x00\x00\x00\x00\x6E\x65\x20\x03\x02\x23\x07" +"\x0C\x0F\x00\x00\x48\x0F\x00\x00\x9C\x0E\x00\x00\x01\x00\x66\x31\x66\x66\x6F\x76\x00\x00\x00\x00\x00\x00\x4D\x00\x03\x02\x23\x07" "\x00\x00\x01\x00\x01\x00\x08\x00\x51\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\x3B\x00\x00\x00\x44\x00\x00\x00" @@ -9563,101 +9576,102 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "\x48\x00\x05\x00\x13\x00\x00\x00\x15\x00\x00\x00\x23\x00\x00\x00\x94\x01\x00\x00\x48\x00\x05\x00\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\x3B\x00\x00\x00\x1E\x00\x00\x00\x01\x00\x00\x00\x47\x00\x04\x00\x3D\x00\x00\x00\x01\x00\x00\x00" -"\x00\x01\x00\x00\x48\x00\x05\x00\x42\x00\x00\x00\x00\x00\x00\x00\x0B\x00\x00\x00\x00\x00\x00\x00\x47\x00\x03\x00\x42\x00\x00\x00" -"\x02\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\x02\x00\x00\x00\x47\x00\x04\x00\x4D\x00\x00\x00\x1E\x00\x00\x00\x03\x00\x00\x00\x47\x00\x04\x00" -"\x4E\x00\x00\x00\x1E\x00\x00\x00\x04\x00\x00\x00\x47\x00\x04\x00\x4F\x00\x00\x00\x1E\x00\x00\x00\x05\x00\x00\x00\x47\x00\x04\x00" -"\x50\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\x15\x00\x04\x00\x0F\x00\x00\x00" -"\x20\x00\x00\x00\x00\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00\x10\x00\x00\x00\x04\x00\x00\x00\x1C\x00\x04\x00\x11\x00\x00\x00" -"\x07\x00\x00\x00\x10\x00\x00\x00\x17\x00\x04\x00\x12\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x1E\x00\x19\x00\x13\x00\x00\x00" -"\x0D\x00\x00\x00\x0D\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\x0E\x00\x00\x00\x06\x00\x00\x00\x11\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\x07\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x12\x00\x00\x00\x20\x00\x04\x00" -"\x14\x00\x00\x00\x02\x00\x00\x00\x13\x00\x00\x00\x3B\x00\x04\x00\x14\x00\x00\x00\x15\x00\x00\x00\x02\x00\x00\x00\x15\x00\x04\x00" -"\x16\x00\x00\x00\x20\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00\x16\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x20\x00\x04\x00" -"\x18\x00\x00\x00\x02\x00\x00\x00\x0D\x00\x00\x00\x20\x00\x04\x00\x1B\x00\x00\x00\x01\x00\x00\x00\x0E\x00\x00\x00\x3B\x00\x04\x00" -"\x1B\x00\x00\x00\x1C\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00\x06\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x80\x3F\x2B\x00\x04\x00" -"\x06\x00\x00\x00\x24\x00\x00\x00\x00\x00\x80\xBF\x2B\x00\x04\x00\x0F\x00\x00\x00\x25\x00\x00\x00\x01\x00\x00\x00\x20\x00\x04\x00" -"\x26\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00\x2B\x00\x00\x00\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\x12\x00\x00\x00\x3B\x00\x04\x00\x38\x00\x00\x00\x39\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00" -"\x3A\x00\x00\x00\x01\x00\x00\x00\x12\x00\x00\x00\x3B\x00\x04\x00\x3A\x00\x00\x00\x3B\x00\x00\x00\x01\x00\x00\x00\x32\x00\x04\x00" -"\x06\x00\x00\x00\x3D\x00\x00\x00\x00\x00\x80\x43\x2B\x00\x04\x00\x06\x00\x00\x00\x3E\x00\x00\x00\x00\x00\xB4\x42\x1E\x00\x03\x00" -"\x42\x00\x00\x00\x07\x00\x00\x00\x20\x00\x04\x00\x43\x00\x00\x00\x03\x00\x00\x00\x42\x00\x00\x00\x3B\x00\x04\x00\x43\x00\x00\x00" -"\x44\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00\x46\x00\x00\x00\x03\x00\x00\x00\x07\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\x07\x00\x00\x00\x3B\x00\x04\x00\x4B\x00\x00\x00" -"\x4C\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x3A\x00\x00\x00\x4D\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00" -"\x4E\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\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\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\x12\x00\x00\x00\x3C\x00\x00\x00\x3B\x00\x00\x00\x3E\x00\x03\x00\x39\x00\x00\x00\x3C\x00\x00\x00" -"\x88\x00\x05\x00\x06\x00\x00\x00\x3F\x00\x00\x00\x3D\x00\x00\x00\x3E\x00\x00\x00\x3D\x00\x04\x00\x12\x00\x00\x00\x40\x00\x00\x00" -"\x39\x00\x00\x00\x8E\x00\x05\x00\x12\x00\x00\x00\x41\x00\x00\x00\x40\x00\x00\x00\x3F\x00\x00\x00\x3E\x00\x03\x00\x39\x00\x00\x00" -"\x41\x00\x00\x00\x39\x00\x04\x00\x07\x00\x00\x00\x45\x00\x00\x00\x09\x00\x00\x00\x41\x00\x05\x00\x46\x00\x00\x00\x47\x00\x00\x00" -"\x44\x00\x00\x00\x17\x00\x00\x00\x3E\x00\x03\x00\x47\x00\x00\x00\x45\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" -"\x01\x00\x08\x00\x56\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\x07\x00\x04\x00\x00\x00" -"\x04\x00\x00\x00\x6D\x61\x69\x6E\x00\x00\x00\x00\x0B\x00\x00\x00\x44\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\x03\x00" -"\x09\x00\x00\x00\x64\x00\x00\x00\x05\x00\x05\x00\x0B\x00\x00\x00\x74\x65\x78\x63\x6F\x6F\x72\x64\x00\x00\x00\x00\x05\x00\x03\x00" -"\x0E\x00\x00\x00\x64\x69\x76\x00\x05\x00\x03\x00\x21\x00\x00\x00\x74\x63\x00\x00\x05\x00\x05\x00\x44\x00\x00\x00\x6F\x75\x74\x63" -"\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x06\x00\x48\x00\x00\x00\x73\x5F\x72\x65\x66\x6C\x65\x63\x74\x63\x75\x62\x65\x00\x00\x00" -"\x05\x00\x05\x00\x50\x00\x00\x00\x65\x6E\x74\x69\x74\x79\x62\x6C\x6F\x63\x6B\x00\x06\x00\x07\x00\x50\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\x50\x00\x00\x00\x01\x00\x00\x00\x6D\x5F\x6D\x6F" -"\x64\x65\x6C\x00\x06\x00\x06\x00\x50\x00\x00\x00\x02\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x69\x6E\x76\x00\x00\x06\x00\x06\x00" -"\x50\x00\x00\x00\x03\x00\x00\x00\x65\x5F\x65\x79\x65\x70\x6F\x73\x00\x00\x00\x00\x06\x00\x05\x00\x50\x00\x00\x00\x04\x00\x00\x00" -"\x65\x5F\x74\x69\x6D\x65\x00\x00\x06\x00\x07\x00\x50\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\x50\x00\x00\x00\x06\x00\x00\x00\x65\x70\x61\x64\x31\x00\x00\x00\x06\x00\x06\x00\x50\x00\x00\x00" -"\x07\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x64\x69\x72\x00\x06\x00\x05\x00\x50\x00\x00\x00\x08\x00\x00\x00\x65\x70\x61\x64" -"\x32\x00\x00\x00\x06\x00\x06\x00\x50\x00\x00\x00\x09\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x6D\x75\x6C\x00\x06\x00\x05\x00" -"\x50\x00\x00\x00\x0A\x00\x00\x00\x65\x70\x61\x64\x33\x00\x00\x00\x06\x00\x06\x00\x50\x00\x00\x00\x0B\x00\x00\x00\x65\x5F\x6C\x6D" -"\x73\x63\x61\x6C\x65\x73\x00\x00\x06\x00\x07\x00\x50\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\x50\x00\x00\x00\x0D\x00\x00\x00\x65\x70\x61\x64\x34\x00\x00\x00\x06\x00\x07\x00\x50\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\x50\x00\x00\x00\x0F\x00\x00\x00" -"\x65\x70\x61\x64\x35\x00\x00\x00\x06\x00\x06\x00\x50\x00\x00\x00\x10\x00\x00\x00\x65\x5F\x67\x6C\x6F\x77\x6D\x6F\x64\x00\x00\x00" -"\x06\x00\x05\x00\x50\x00\x00\x00\x11\x00\x00\x00\x65\x70\x61\x64\x36\x00\x00\x00\x06\x00\x07\x00\x50\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\x50\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\x50\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\x50\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\x50\x00\x00\x00\x16\x00\x00\x00\x65\x70\x61\x64\x37\x00\x00\x00\x05\x00\x03\x00\x52\x00\x00\x00" -"\x00\x00\x00\x00\x05\x00\x05\x00\x53\x00\x00\x00\x6C\x69\x67\x68\x74\x62\x6C\x6F\x63\x6B\x00\x00\x06\x00\x07\x00\x53\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\x53\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\x53\x00\x00\x00\x02\x00\x00\x00\x6C\x70\x61\x64" -"\x31\x00\x00\x00\x06\x00\x07\x00\x53\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\x53\x00\x00\x00\x04\x00\x00\x00\x6C\x70\x61\x64\x32\x00\x00\x00\x06\x00\x08\x00\x53\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\x53\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\x53\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\x53\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\x53\x00\x00\x00\x09\x00\x00\x00\x6C\x70\x61\x64\x33\x00\x00\x00" -"\x05\x00\x03\x00\x55\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x44\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00" +"\x00\x00\x00\x00\x47\x00\x04\x00\x39\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x3B\x00\x00\x00\x1E\x00\x00\x00" +"\x01\x00\x00\x00\x47\x00\x04\x00\x3D\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x48\x00\x05\x00\x42\x00\x00\x00\x00\x00\x00\x00" +"\x0B\x00\x00\x00\x00\x00\x00\x00\x47\x00\x03\x00\x42\x00\x00\x00\x02\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\x02\x00\x00\x00\x47\x00\x04\x00" +"\x4D\x00\x00\x00\x1E\x00\x00\x00\x03\x00\x00\x00\x47\x00\x04\x00\x4E\x00\x00\x00\x1E\x00\x00\x00\x04\x00\x00\x00\x47\x00\x04\x00" +"\x4F\x00\x00\x00\x1E\x00\x00\x00\x05\x00\x00\x00\x47\x00\x04\x00\x50\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\x15\x00\x04\x00\x0F\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00" +"\x10\x00\x00\x00\x04\x00\x00\x00\x1C\x00\x04\x00\x11\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x17\x00\x04\x00\x12\x00\x00\x00" +"\x06\x00\x00\x00\x02\x00\x00\x00\x1E\x00\x19\x00\x13\x00\x00\x00\x0D\x00\x00\x00\x0D\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\x0E\x00\x00\x00\x06\x00\x00\x00\x11\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\x07\x00\x00\x00" +"\x06\x00\x00\x00\x06\x00\x00\x00\x12\x00\x00\x00\x20\x00\x04\x00\x14\x00\x00\x00\x02\x00\x00\x00\x13\x00\x00\x00\x3B\x00\x04\x00" +"\x14\x00\x00\x00\x15\x00\x00\x00\x02\x00\x00\x00\x15\x00\x04\x00\x16\x00\x00\x00\x20\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00" +"\x16\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x20\x00\x04\x00\x18\x00\x00\x00\x02\x00\x00\x00\x0D\x00\x00\x00\x20\x00\x04\x00" +"\x1B\x00\x00\x00\x01\x00\x00\x00\x0E\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x1C\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00" +"\x06\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x80\x3F\x2B\x00\x04\x00\x06\x00\x00\x00\x24\x00\x00\x00\x00\x00\x80\xBF\x2B\x00\x04\x00" +"\x0F\x00\x00\x00\x25\x00\x00\x00\x01\x00\x00\x00\x20\x00\x04\x00\x26\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x2B\x00\x04\x00" +"\x0F\x00\x00\x00\x2B\x00\x00\x00\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\x12\x00\x00\x00\x3B\x00\x04\x00" +"\x38\x00\x00\x00\x39\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00\x3A\x00\x00\x00\x01\x00\x00\x00\x12\x00\x00\x00\x3B\x00\x04\x00" +"\x3A\x00\x00\x00\x3B\x00\x00\x00\x01\x00\x00\x00\x32\x00\x04\x00\x06\x00\x00\x00\x3D\x00\x00\x00\x00\x00\x80\x43\x2B\x00\x04\x00" +"\x06\x00\x00\x00\x3E\x00\x00\x00\x00\x00\xB4\x42\x1E\x00\x03\x00\x42\x00\x00\x00\x07\x00\x00\x00\x20\x00\x04\x00\x43\x00\x00\x00" +"\x03\x00\x00\x00\x42\x00\x00\x00\x3B\x00\x04\x00\x43\x00\x00\x00\x44\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00\x46\x00\x00\x00" +"\x03\x00\x00\x00\x07\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\x07\x00\x00\x00\x3B\x00\x04\x00\x4B\x00\x00\x00\x4C\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x3A\x00\x00\x00" +"\x4D\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x4E\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\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\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\x12\x00\x00\x00\x3C\x00\x00\x00" +"\x3B\x00\x00\x00\x3E\x00\x03\x00\x39\x00\x00\x00\x3C\x00\x00\x00\x88\x00\x05\x00\x06\x00\x00\x00\x3F\x00\x00\x00\x3D\x00\x00\x00" +"\x3E\x00\x00\x00\x3D\x00\x04\x00\x12\x00\x00\x00\x40\x00\x00\x00\x39\x00\x00\x00\x8E\x00\x05\x00\x12\x00\x00\x00\x41\x00\x00\x00" +"\x40\x00\x00\x00\x3F\x00\x00\x00\x3E\x00\x03\x00\x39\x00\x00\x00\x41\x00\x00\x00\x39\x00\x04\x00\x07\x00\x00\x00\x45\x00\x00\x00" +"\x09\x00\x00\x00\x41\x00\x05\x00\x46\x00\x00\x00\x47\x00\x00\x00\x44\x00\x00\x00\x17\x00\x00\x00\x3E\x00\x03\x00\x47\x00\x00\x00" +"\x45\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\x01\x00\x08\x00\x56\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\x07\x00\x04\x00\x00\x00\x04\x00\x00\x00\x6D\x61\x69\x6E\x00\x00\x00\x00\x0B\x00\x00\x00" +"\x44\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\x03\x00\x09\x00\x00\x00\x64\x00\x00\x00\x05\x00\x05\x00\x0B\x00\x00\x00" +"\x74\x65\x78\x63\x6F\x6F\x72\x64\x00\x00\x00\x00\x05\x00\x03\x00\x0E\x00\x00\x00\x64\x69\x76\x00\x05\x00\x03\x00\x21\x00\x00\x00" +"\x74\x63\x00\x00\x05\x00\x05\x00\x44\x00\x00\x00\x6F\x75\x74\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x06\x00\x48\x00\x00\x00" +"\x73\x5F\x72\x65\x66\x6C\x65\x63\x74\x63\x75\x62\x65\x00\x00\x00\x05\x00\x05\x00\x50\x00\x00\x00\x65\x6E\x74\x69\x74\x79\x62\x6C" +"\x6F\x63\x6B\x00\x06\x00\x07\x00\x50\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\x50\x00\x00\x00\x01\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x00\x06\x00\x06\x00\x50\x00\x00\x00\x02\x00\x00\x00" +"\x6D\x5F\x6D\x6F\x64\x65\x6C\x69\x6E\x76\x00\x00\x06\x00\x06\x00\x50\x00\x00\x00\x03\x00\x00\x00\x65\x5F\x65\x79\x65\x70\x6F\x73" +"\x00\x00\x00\x00\x06\x00\x05\x00\x50\x00\x00\x00\x04\x00\x00\x00\x65\x5F\x74\x69\x6D\x65\x00\x00\x06\x00\x07\x00\x50\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\x50\x00\x00\x00\x06\x00\x00\x00" +"\x65\x70\x61\x64\x31\x00\x00\x00\x06\x00\x06\x00\x50\x00\x00\x00\x07\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x64\x69\x72\x00" +"\x06\x00\x05\x00\x50\x00\x00\x00\x08\x00\x00\x00\x65\x70\x61\x64\x32\x00\x00\x00\x06\x00\x06\x00\x50\x00\x00\x00\x09\x00\x00\x00" +"\x65\x5F\x6C\x69\x67\x68\x74\x5F\x6D\x75\x6C\x00\x06\x00\x05\x00\x50\x00\x00\x00\x0A\x00\x00\x00\x65\x70\x61\x64\x33\x00\x00\x00" +"\x06\x00\x06\x00\x50\x00\x00\x00\x0B\x00\x00\x00\x65\x5F\x6C\x6D\x73\x63\x61\x6C\x65\x73\x00\x00\x06\x00\x07\x00\x50\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\x50\x00\x00\x00\x0D\x00\x00\x00" +"\x65\x70\x61\x64\x34\x00\x00\x00\x06\x00\x07\x00\x50\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\x50\x00\x00\x00\x0F\x00\x00\x00\x65\x70\x61\x64\x35\x00\x00\x00\x06\x00\x06\x00\x50\x00\x00\x00" +"\x10\x00\x00\x00\x65\x5F\x67\x6C\x6F\x77\x6D\x6F\x64\x00\x00\x00\x06\x00\x05\x00\x50\x00\x00\x00\x11\x00\x00\x00\x65\x70\x61\x64" +"\x36\x00\x00\x00\x06\x00\x07\x00\x50\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\x50\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" +"\x50\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\x50\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\x50\x00\x00\x00\x16\x00\x00\x00" +"\x65\x70\x61\x64\x37\x00\x00\x00\x05\x00\x03\x00\x52\x00\x00\x00\x00\x00\x00\x00\x05\x00\x05\x00\x53\x00\x00\x00\x6C\x69\x67\x68" +"\x74\x62\x6C\x6F\x63\x6B\x00\x00\x06\x00\x07\x00\x53\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\x53\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\x53\x00\x00\x00\x02\x00\x00\x00\x6C\x70\x61\x64\x31\x00\x00\x00\x06\x00\x07\x00\x53\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\x53\x00\x00\x00\x04\x00\x00\x00\x6C\x70\x61\x64" +"\x32\x00\x00\x00\x06\x00\x08\x00\x53\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\x53\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\x53\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" +"\x53\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" +"\x53\x00\x00\x00\x09\x00\x00\x00\x6C\x70\x61\x64\x33\x00\x00\x00\x05\x00\x03\x00\x55\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00" +"\x0B\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x44\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00" "\x48\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x48\x00\x00\x00\x21\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00" "\x4C\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x47\x00\x04\x00\x4F\x00\x00\x00\x06\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00" "\x50\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x50\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00" @@ -9847,7 +9861,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND #ifdef VKQUAKE {QR_VULKAN, -1, "fxaa", "\xFF\x53\x50\x56\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x2C\x00\x00\x00\x00\x00\x00\x00\x2C\x00\x00\x00" -"\x54\x0F\x00\x00\x80\x0F\x00\x00\x3C\x1D\x00\x00\x03\x02\x23\x07\x00\x00\x01\x00\x01\x00\x08\x00\x54\x00\x00\x00\x00\x00\x00\x00" +"\x74\x0F\x00\x00\xA0\x0F\x00\x00\x5C\x1D\x00\x00\x03\x02\x23\x07\x00\x00\x01\x00\x01\x00\x08\x00\x54\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\x0F\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\x3B\x00\x00\x00\x42\x00\x00\x00\x44\x00\x00\x00\x49\x00\x00\x00\x50\x00\x00\x00\x51\x00\x00\x00" @@ -9908,7 +9922,8 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "\x14\x00\x00\x00\x23\x00\x00\x00\x90\x01\x00\x00\x48\x00\x05\x00\x13\x00\x00\x00\x15\x00\x00\x00\x23\x00\x00\x00\x94\x01\x00\x00" "\x48\x00\x05\x00\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\x3B\x00\x00\x00\x1E\x00\x00\x00\x01\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" +"\x47\x00\x04\x00\x3B\x00\x00\x00\x1E\x00\x00\x00\x01\x00\x00\x00\x47\x00\x04\x00\x42\x00\x00\x00\x1E\x00\x00\x00\x01\x00\x00\x00" "\x47\x00\x04\x00\x44\x00\x00\x00\x1E\x00\x00\x00\x02\x00\x00\x00\x48\x00\x05\x00\x47\x00\x00\x00\x00\x00\x00\x00\x0B\x00\x00\x00" "\x00\x00\x00\x00\x47\x00\x03\x00\x47\x00\x00\x00\x02\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" @@ -10017,6 +10032,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "\x06\x00\x08\x00\xF8\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\xF8\x00\x00\x00\x09\x00\x00\x00\x6C\x70\x61\x64\x33\x00\x00\x00\x05\x00\x03\x00\xFA\x00\x00\x00\x00\x00\x00\x00" "\x47\x00\x04\x00\x14\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x14\x00\x00\x00\x21\x00\x00\x00\x02\x00\x00\x00" +"\x47\x00\x04\x00\x18\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x1C\x00\x00\x00\x1E\x00\x00\x00\x01\x00\x00\x00" "\x47\x00\x04\x00\xE7\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\xF4\x00\x00\x00\x06\x00\x00\x00\x10\x00\x00\x00" "\x48\x00\x04\x00\xF5\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\xF5\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00" "\x00\x00\x00\x00\x48\x00\x05\x00\xF5\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00\xF5\x00\x00\x00" @@ -10249,7 +10265,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND #ifdef VKQUAKE {QR_VULKAN, -1, "underwaterwarp", "\xFF\x53\x50\x56\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x2C\x00\x00\x00\x14\x00\x00\x00\x40\x00\x00\x00" -"\xE8\x10\x00\x00\x28\x11\x00\x00\xA8\x0D\x00\x00\x01\x00\x66\x31\x72\x5F\x77\x61\x74\x65\x72\x77\x61\x72\x70\x00\x00\x00\x00\x00" +"\x18\x11\x00\x00\x58\x11\x00\x00\xD8\x0D\x00\x00\x01\x00\x66\x31\x72\x5F\x77\x61\x74\x65\x72\x77\x61\x72\x70\x00\x00\x00\x00\x00" "\x03\x02\x23\x07\x00\x00\x01\x00\x01\x00\x08\x00\x69\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\x10\x00\x00\x00\x00\x00\x04\x00\x00\x00\x6D\x61\x69\x6E\x00\x00\x00\x00\x1C\x00\x00\x00\x3A\x00\x00\x00\x3F\x00\x00\x00" @@ -10312,119 +10328,122 @@ 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\x48\x00\x05\x00\x38\x00\x00\x00\x00\x00\x00\x00\x0B\x00\x00\x00\x00\x00\x00\x00" -"\x47\x00\x03\x00\x38\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x41\x00\x00\x00\x1E\x00\x00\x00\x01\x00\x00\x00\x47\x00\x04\x00" -"\x5F\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x48\x00\x04\x00\x60\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00" -"\x60\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00\x60\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00" -"\x10\x00\x00\x00\x48\x00\x05\x00\x60\x00\x00\x00\x01\x00\x00\x00\x23\x00\x00\x00\x40\x00\x00\x00\x48\x00\x05\x00\x60\x00\x00\x00" -"\x02\x00\x00\x00\x23\x00\x00\x00\x4C\x00\x00\x00\x48\x00\x05\x00\x60\x00\x00\x00\x03\x00\x00\x00\x23\x00\x00\x00\x50\x00\x00\x00" -"\x48\x00\x05\x00\x60\x00\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00\x5C\x00\x00\x00\x48\x00\x05\x00\x60\x00\x00\x00\x05\x00\x00\x00" -"\x23\x00\x00\x00\x60\x00\x00\x00\x48\x00\x05\x00\x60\x00\x00\x00\x06\x00\x00\x00\x23\x00\x00\x00\x6C\x00\x00\x00\x48\x00\x05\x00" -"\x60\x00\x00\x00\x07\x00\x00\x00\x23\x00\x00\x00\x70\x00\x00\x00\x48\x00\x05\x00\x60\x00\x00\x00\x08\x00\x00\x00\x23\x00\x00\x00" -"\x80\x00\x00\x00\x48\x00\x05\x00\x60\x00\x00\x00\x09\x00\x00\x00\x23\x00\x00\x00\x88\x00\x00\x00\x47\x00\x03\x00\x60\x00\x00\x00" -"\x02\x00\x00\x00\x47\x00\x04\x00\x62\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x62\x00\x00\x00\x21\x00\x00\x00" -"\x01\x00\x00\x00\x47\x00\x04\x00\x64\x00\x00\x00\x1E\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x65\x00\x00\x00\x1E\x00\x00\x00" -"\x03\x00\x00\x00\x47\x00\x04\x00\x66\x00\x00\x00\x1E\x00\x00\x00\x04\x00\x00\x00\x47\x00\x04\x00\x67\x00\x00\x00\x1E\x00\x00\x00" -"\x05\x00\x00\x00\x47\x00\x04\x00\x68\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" -"\x15\x00\x04\x00\x0F\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00\x10\x00\x00\x00\x04\x00\x00\x00" -"\x1C\x00\x04\x00\x11\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x17\x00\x04\x00\x12\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00" -"\x1E\x00\x19\x00\x13\x00\x00\x00\x0D\x00\x00\x00\x0D\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\x0E\x00\x00\x00\x06\x00\x00\x00\x11\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\x07\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00" -"\x12\x00\x00\x00\x20\x00\x04\x00\x14\x00\x00\x00\x02\x00\x00\x00\x13\x00\x00\x00\x3B\x00\x04\x00\x14\x00\x00\x00\x15\x00\x00\x00" -"\x02\x00\x00\x00\x15\x00\x04\x00\x16\x00\x00\x00\x20\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00\x16\x00\x00\x00\x17\x00\x00\x00" -"\x00\x00\x00\x00\x20\x00\x04\x00\x18\x00\x00\x00\x02\x00\x00\x00\x0D\x00\x00\x00\x20\x00\x04\x00\x1B\x00\x00\x00\x01\x00\x00\x00" -"\x0E\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x1C\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00\x06\x00\x00\x00\x1E\x00\x00\x00" -"\x00\x00\x80\x3F\x2B\x00\x04\x00\x06\x00\x00\x00\x24\x00\x00\x00\x00\x00\x80\xBF\x2B\x00\x04\x00\x0F\x00\x00\x00\x25\x00\x00\x00" -"\x01\x00\x00\x00\x20\x00\x04\x00\x26\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00\x2B\x00\x00\x00" -"\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\x1E\x00\x03\x00\x38\x00\x00\x00\x07\x00\x00\x00\x20\x00\x04\x00\x39\x00\x00\x00\x03\x00\x00\x00\x38\x00\x00\x00" -"\x3B\x00\x04\x00\x39\x00\x00\x00\x3A\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00\x3C\x00\x00\x00\x03\x00\x00\x00\x07\x00\x00\x00" -"\x20\x00\x04\x00\x3E\x00\x00\x00\x03\x00\x00\x00\x12\x00\x00\x00\x3B\x00\x04\x00\x3E\x00\x00\x00\x3F\x00\x00\x00\x03\x00\x00\x00" -"\x20\x00\x04\x00\x40\x00\x00\x00\x01\x00\x00\x00\x12\x00\x00\x00\x3B\x00\x04\x00\x40\x00\x00\x00\x41\x00\x00\x00\x01\x00\x00\x00" -"\x2B\x00\x04\x00\x0F\x00\x00\x00\x42\x00\x00\x00\x00\x00\x00\x00\x20\x00\x04\x00\x43\x00\x00\x00\x01\x00\x00\x00\x06\x00\x00\x00" -"\x3B\x00\x04\x00\x3E\x00\x00\x00\x4A\x00\x00\x00\x03\x00\x00\x00\x2B\x00\x04\x00\x16\x00\x00\x00\x4B\x00\x00\x00\x04\x00\x00\x00" -"\x20\x00\x04\x00\x4C\x00\x00\x00\x02\x00\x00\x00\x06\x00\x00\x00\x2B\x00\x04\x00\x06\x00\x00\x00\x4F\x00\x00\x00\x00\x00\x80\x3E" -"\x20\x00\x04\x00\x54\x00\x00\x00\x03\x00\x00\x00\x06\x00\x00\x00\x3B\x00\x04\x00\x3E\x00\x00\x00\x5D\x00\x00\x00\x03\x00\x00\x00" -"\x32\x00\x04\x00\x06\x00\x00\x00\x5F\x00\x00\x00\x00\x00\x80\x43\x1E\x00\x0C\x00\x60\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\x61\x00\x00\x00\x02\x00\x00\x00\x60\x00\x00\x00\x3B\x00\x04\x00\x61\x00\x00\x00\x62\x00\x00\x00\x02\x00\x00\x00" -"\x20\x00\x04\x00\x63\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00\x63\x00\x00\x00\x64\x00\x00\x00\x01\x00\x00\x00" -"\x3B\x00\x04\x00\x40\x00\x00\x00\x65\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x66\x00\x00\x00\x01\x00\x00\x00" -"\x3B\x00\x04\x00\x1B\x00\x00\x00\x67\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x68\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\x39\x00\x04\x00" -"\x07\x00\x00\x00\x3B\x00\x00\x00\x09\x00\x00\x00\x41\x00\x05\x00\x3C\x00\x00\x00\x3D\x00\x00\x00\x3A\x00\x00\x00\x17\x00\x00\x00" -"\x3E\x00\x03\x00\x3D\x00\x00\x00\x3B\x00\x00\x00\x41\x00\x05\x00\x43\x00\x00\x00\x44\x00\x00\x00\x41\x00\x00\x00\x42\x00\x00\x00" -"\x3D\x00\x04\x00\x06\x00\x00\x00\x45\x00\x00\x00\x44\x00\x00\x00\x41\x00\x05\x00\x43\x00\x00\x00\x46\x00\x00\x00\x41\x00\x00\x00" -"\x25\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x47\x00\x00\x00\x46\x00\x00\x00\x83\x00\x05\x00\x06\x00\x00\x00\x48\x00\x00\x00" -"\x1E\x00\x00\x00\x47\x00\x00\x00\x50\x00\x05\x00\x12\x00\x00\x00\x49\x00\x00\x00\x45\x00\x00\x00\x48\x00\x00\x00\x3E\x00\x03\x00" -"\x3F\x00\x00\x00\x49\x00\x00\x00\x41\x00\x05\x00\x4C\x00\x00\x00\x4D\x00\x00\x00\x15\x00\x00\x00\x4B\x00\x00\x00\x3D\x00\x04\x00" -"\x06\x00\x00\x00\x4E\x00\x00\x00\x4D\x00\x00\x00\x85\x00\x05\x00\x06\x00\x00\x00\x50\x00\x00\x00\x4E\x00\x00\x00\x4F\x00\x00\x00" -"\x41\x00\x05\x00\x43\x00\x00\x00\x51\x00\x00\x00\x41\x00\x00\x00\x42\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x52\x00\x00\x00" -"\x51\x00\x00\x00\x81\x00\x05\x00\x06\x00\x00\x00\x53\x00\x00\x00\x50\x00\x00\x00\x52\x00\x00\x00\x41\x00\x05\x00\x54\x00\x00\x00" -"\x55\x00\x00\x00\x4A\x00\x00\x00\x42\x00\x00\x00\x3E\x00\x03\x00\x55\x00\x00\x00\x53\x00\x00\x00\x41\x00\x05\x00\x4C\x00\x00\x00" -"\x56\x00\x00\x00\x15\x00\x00\x00\x4B\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x57\x00\x00\x00\x56\x00\x00\x00\x85\x00\x05\x00" -"\x06\x00\x00\x00\x58\x00\x00\x00\x57\x00\x00\x00\x4F\x00\x00\x00\x41\x00\x05\x00\x43\x00\x00\x00\x59\x00\x00\x00\x41\x00\x00\x00" -"\x25\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x5A\x00\x00\x00\x59\x00\x00\x00\x81\x00\x05\x00\x06\x00\x00\x00\x5B\x00\x00\x00" -"\x58\x00\x00\x00\x5A\x00\x00\x00\x41\x00\x05\x00\x54\x00\x00\x00\x5C\x00\x00\x00\x4A\x00\x00\x00\x25\x00\x00\x00\x3E\x00\x03\x00" -"\x5C\x00\x00\x00\x5B\x00\x00\x00\x3D\x00\x04\x00\x12\x00\x00\x00\x5E\x00\x00\x00\x41\x00\x00\x00\x3E\x00\x03\x00\x5D\x00\x00\x00" -"\x5E\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\x01\x00\x08\x00\x42\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\x09\x00\x04\x00\x00\x00\x04\x00\x00\x00\x6D\x61\x69\x6E\x00\x00\x00\x00\x13\x00\x00\x00" -"\x1E\x00\x00\x00\x28\x00\x00\x00\x30\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\x03\x00\x09\x00\x00\x00\x61\x6D\x70\x00" -"\x05\x00\x04\x00\x10\x00\x00\x00\x73\x5F\x74\x32\x00\x00\x00\x00\x05\x00\x04\x00\x13\x00\x00\x00\x76\x5F\x65\x64\x67\x65\x00\x00" -"\x05\x00\x04\x00\x1B\x00\x00\x00\x6F\x66\x66\x73\x65\x74\x00\x00\x05\x00\x04\x00\x1C\x00\x00\x00\x73\x5F\x74\x31\x00\x00\x00\x00" -"\x05\x00\x04\x00\x1E\x00\x00\x00\x76\x5F\x77\x61\x72\x70\x00\x00\x05\x00\x04\x00\x27\x00\x00\x00\x74\x65\x6D\x70\x00\x00\x00\x00" -"\x05\x00\x04\x00\x28\x00\x00\x00\x76\x5F\x73\x74\x63\x00\x00\x00\x05\x00\x05\x00\x30\x00\x00\x00\x6F\x75\x74\x63\x6F\x6C\x6F\x75" -"\x72\x00\x00\x00\x05\x00\x04\x00\x31\x00\x00\x00\x73\x5F\x74\x30\x00\x00\x00\x00\x05\x00\x05\x00\x3C\x00\x00\x00\x65\x6E\x74\x69" -"\x74\x79\x62\x6C\x6F\x63\x6B\x00\x06\x00\x07\x00\x3C\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\x3C\x00\x00\x00\x01\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x00\x06\x00\x06\x00\x3C\x00\x00\x00" -"\x02\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x69\x6E\x76\x00\x00\x06\x00\x06\x00\x3C\x00\x00\x00\x03\x00\x00\x00\x65\x5F\x65\x79" -"\x65\x70\x6F\x73\x00\x00\x00\x00\x06\x00\x05\x00\x3C\x00\x00\x00\x04\x00\x00\x00\x65\x5F\x74\x69\x6D\x65\x00\x00\x06\x00\x07\x00" -"\x3C\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\x3C\x00\x00\x00" -"\x06\x00\x00\x00\x65\x70\x61\x64\x31\x00\x00\x00\x06\x00\x06\x00\x3C\x00\x00\x00\x07\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F" -"\x64\x69\x72\x00\x06\x00\x05\x00\x3C\x00\x00\x00\x08\x00\x00\x00\x65\x70\x61\x64\x32\x00\x00\x00\x06\x00\x06\x00\x3C\x00\x00\x00" -"\x09\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x6D\x75\x6C\x00\x06\x00\x05\x00\x3C\x00\x00\x00\x0A\x00\x00\x00\x65\x70\x61\x64" -"\x33\x00\x00\x00\x06\x00\x06\x00\x3C\x00\x00\x00\x0B\x00\x00\x00\x65\x5F\x6C\x6D\x73\x63\x61\x6C\x65\x73\x00\x00\x06\x00\x07\x00" -"\x3C\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\x3C\x00\x00\x00" -"\x0D\x00\x00\x00\x65\x70\x61\x64\x34\x00\x00\x00\x06\x00\x07\x00\x3C\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\x3C\x00\x00\x00\x0F\x00\x00\x00\x65\x70\x61\x64\x35\x00\x00\x00\x06\x00\x06\x00" -"\x3C\x00\x00\x00\x10\x00\x00\x00\x65\x5F\x67\x6C\x6F\x77\x6D\x6F\x64\x00\x00\x00\x06\x00\x05\x00\x3C\x00\x00\x00\x11\x00\x00\x00" -"\x65\x70\x61\x64\x36\x00\x00\x00\x06\x00\x07\x00\x3C\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\x3C\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\x3C\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" -"\x3C\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\x3C\x00\x00\x00" -"\x16\x00\x00\x00\x65\x70\x61\x64\x37\x00\x00\x00\x05\x00\x03\x00\x3E\x00\x00\x00\x00\x00\x00\x00\x05\x00\x05\x00\x3F\x00\x00\x00" -"\x6C\x69\x67\x68\x74\x62\x6C\x6F\x63\x6B\x00\x00\x06\x00\x07\x00\x3F\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\x3F\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\x3F\x00\x00\x00\x02\x00\x00\x00\x6C\x70\x61\x64\x31\x00\x00\x00\x06\x00\x07\x00\x3F\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\x3F\x00\x00\x00\x04\x00\x00\x00" -"\x6C\x70\x61\x64\x32\x00\x00\x00\x06\x00\x08\x00\x3F\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\x3F\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\x3F\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\x3F\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\x3F\x00\x00\x00\x09\x00\x00\x00\x6C\x70\x61\x64\x33\x00\x00\x00\x05\x00\x03\x00\x41\x00\x00\x00\x00\x00\x00\x00" -"\x47\x00\x04\x00\x0B\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x47\x00\x04\x00\x10\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00" -"\x47\x00\x04\x00\x10\x00\x00\x00\x21\x00\x00\x00\x04\x00\x00\x00\x47\x00\x04\x00\x1C\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00" -"\x47\x00\x04\x00\x1C\x00\x00\x00\x21\x00\x00\x00\x03\x00\x00\x00\x47\x00\x04\x00\x30\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00" +"\x47\x00\x03\x00\x38\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x3F\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00" +"\x41\x00\x00\x00\x1E\x00\x00\x00\x01\x00\x00\x00\x47\x00\x04\x00\x4A\x00\x00\x00\x1E\x00\x00\x00\x01\x00\x00\x00\x47\x00\x04\x00" +"\x5D\x00\x00\x00\x1E\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x5F\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x48\x00\x04\x00" +"\x60\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x60\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00" +"\x48\x00\x05\x00\x60\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x05\x00\x60\x00\x00\x00\x01\x00\x00\x00" +"\x23\x00\x00\x00\x40\x00\x00\x00\x48\x00\x05\x00\x60\x00\x00\x00\x02\x00\x00\x00\x23\x00\x00\x00\x4C\x00\x00\x00\x48\x00\x05\x00" +"\x60\x00\x00\x00\x03\x00\x00\x00\x23\x00\x00\x00\x50\x00\x00\x00\x48\x00\x05\x00\x60\x00\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00" +"\x5C\x00\x00\x00\x48\x00\x05\x00\x60\x00\x00\x00\x05\x00\x00\x00\x23\x00\x00\x00\x60\x00\x00\x00\x48\x00\x05\x00\x60\x00\x00\x00" +"\x06\x00\x00\x00\x23\x00\x00\x00\x6C\x00\x00\x00\x48\x00\x05\x00\x60\x00\x00\x00\x07\x00\x00\x00\x23\x00\x00\x00\x70\x00\x00\x00" +"\x48\x00\x05\x00\x60\x00\x00\x00\x08\x00\x00\x00\x23\x00\x00\x00\x80\x00\x00\x00\x48\x00\x05\x00\x60\x00\x00\x00\x09\x00\x00\x00" +"\x23\x00\x00\x00\x88\x00\x00\x00\x47\x00\x03\x00\x60\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x62\x00\x00\x00\x22\x00\x00\x00" +"\x00\x00\x00\x00\x47\x00\x04\x00\x62\x00\x00\x00\x21\x00\x00\x00\x01\x00\x00\x00\x47\x00\x04\x00\x64\x00\x00\x00\x1E\x00\x00\x00" +"\x02\x00\x00\x00\x47\x00\x04\x00\x65\x00\x00\x00\x1E\x00\x00\x00\x03\x00\x00\x00\x47\x00\x04\x00\x66\x00\x00\x00\x1E\x00\x00\x00" +"\x04\x00\x00\x00\x47\x00\x04\x00\x67\x00\x00\x00\x1E\x00\x00\x00\x05\x00\x00\x00\x47\x00\x04\x00\x68\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\x15\x00\x04\x00\x0F\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00" +"\x2B\x00\x04\x00\x0F\x00\x00\x00\x10\x00\x00\x00\x04\x00\x00\x00\x1C\x00\x04\x00\x11\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00" +"\x17\x00\x04\x00\x12\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x1E\x00\x19\x00\x13\x00\x00\x00\x0D\x00\x00\x00\x0D\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\x0E\x00\x00\x00" +"\x06\x00\x00\x00\x11\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\x07\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x12\x00\x00\x00\x20\x00\x04\x00\x14\x00\x00\x00\x02\x00\x00\x00" +"\x13\x00\x00\x00\x3B\x00\x04\x00\x14\x00\x00\x00\x15\x00\x00\x00\x02\x00\x00\x00\x15\x00\x04\x00\x16\x00\x00\x00\x20\x00\x00\x00" +"\x01\x00\x00\x00\x2B\x00\x04\x00\x16\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x20\x00\x04\x00\x18\x00\x00\x00\x02\x00\x00\x00" +"\x0D\x00\x00\x00\x20\x00\x04\x00\x1B\x00\x00\x00\x01\x00\x00\x00\x0E\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x1C\x00\x00\x00" +"\x01\x00\x00\x00\x2B\x00\x04\x00\x06\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x80\x3F\x2B\x00\x04\x00\x06\x00\x00\x00\x24\x00\x00\x00" +"\x00\x00\x80\xBF\x2B\x00\x04\x00\x0F\x00\x00\x00\x25\x00\x00\x00\x01\x00\x00\x00\x20\x00\x04\x00\x26\x00\x00\x00\x07\x00\x00\x00" +"\x06\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00\x2B\x00\x00\x00\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\x1E\x00\x03\x00\x38\x00\x00\x00\x07\x00\x00\x00" +"\x20\x00\x04\x00\x39\x00\x00\x00\x03\x00\x00\x00\x38\x00\x00\x00\x3B\x00\x04\x00\x39\x00\x00\x00\x3A\x00\x00\x00\x03\x00\x00\x00" +"\x20\x00\x04\x00\x3C\x00\x00\x00\x03\x00\x00\x00\x07\x00\x00\x00\x20\x00\x04\x00\x3E\x00\x00\x00\x03\x00\x00\x00\x12\x00\x00\x00" +"\x3B\x00\x04\x00\x3E\x00\x00\x00\x3F\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00\x40\x00\x00\x00\x01\x00\x00\x00\x12\x00\x00\x00" +"\x3B\x00\x04\x00\x40\x00\x00\x00\x41\x00\x00\x00\x01\x00\x00\x00\x2B\x00\x04\x00\x0F\x00\x00\x00\x42\x00\x00\x00\x00\x00\x00\x00" +"\x20\x00\x04\x00\x43\x00\x00\x00\x01\x00\x00\x00\x06\x00\x00\x00\x3B\x00\x04\x00\x3E\x00\x00\x00\x4A\x00\x00\x00\x03\x00\x00\x00" +"\x2B\x00\x04\x00\x16\x00\x00\x00\x4B\x00\x00\x00\x04\x00\x00\x00\x20\x00\x04\x00\x4C\x00\x00\x00\x02\x00\x00\x00\x06\x00\x00\x00" +"\x2B\x00\x04\x00\x06\x00\x00\x00\x4F\x00\x00\x00\x00\x00\x80\x3E\x20\x00\x04\x00\x54\x00\x00\x00\x03\x00\x00\x00\x06\x00\x00\x00" +"\x3B\x00\x04\x00\x3E\x00\x00\x00\x5D\x00\x00\x00\x03\x00\x00\x00\x32\x00\x04\x00\x06\x00\x00\x00\x5F\x00\x00\x00\x00\x00\x80\x43" +"\x1E\x00\x0C\x00\x60\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\x61\x00\x00\x00\x02\x00\x00\x00\x60\x00\x00\x00" +"\x3B\x00\x04\x00\x61\x00\x00\x00\x62\x00\x00\x00\x02\x00\x00\x00\x20\x00\x04\x00\x63\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00" +"\x3B\x00\x04\x00\x63\x00\x00\x00\x64\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x40\x00\x00\x00\x65\x00\x00\x00\x01\x00\x00\x00" +"\x3B\x00\x04\x00\x1B\x00\x00\x00\x66\x00\x00\x00\x01\x00\x00\x00\x3B\x00\x04\x00\x1B\x00\x00\x00\x67\x00\x00\x00\x01\x00\x00\x00" +"\x3B\x00\x04\x00\x1B\x00\x00\x00\x68\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\x39\x00\x04\x00\x07\x00\x00\x00\x3B\x00\x00\x00\x09\x00\x00\x00\x41\x00\x05\x00" +"\x3C\x00\x00\x00\x3D\x00\x00\x00\x3A\x00\x00\x00\x17\x00\x00\x00\x3E\x00\x03\x00\x3D\x00\x00\x00\x3B\x00\x00\x00\x41\x00\x05\x00" +"\x43\x00\x00\x00\x44\x00\x00\x00\x41\x00\x00\x00\x42\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x45\x00\x00\x00\x44\x00\x00\x00" +"\x41\x00\x05\x00\x43\x00\x00\x00\x46\x00\x00\x00\x41\x00\x00\x00\x25\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x47\x00\x00\x00" +"\x46\x00\x00\x00\x83\x00\x05\x00\x06\x00\x00\x00\x48\x00\x00\x00\x1E\x00\x00\x00\x47\x00\x00\x00\x50\x00\x05\x00\x12\x00\x00\x00" +"\x49\x00\x00\x00\x45\x00\x00\x00\x48\x00\x00\x00\x3E\x00\x03\x00\x3F\x00\x00\x00\x49\x00\x00\x00\x41\x00\x05\x00\x4C\x00\x00\x00" +"\x4D\x00\x00\x00\x15\x00\x00\x00\x4B\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x4E\x00\x00\x00\x4D\x00\x00\x00\x85\x00\x05\x00" +"\x06\x00\x00\x00\x50\x00\x00\x00\x4E\x00\x00\x00\x4F\x00\x00\x00\x41\x00\x05\x00\x43\x00\x00\x00\x51\x00\x00\x00\x41\x00\x00\x00" +"\x42\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x52\x00\x00\x00\x51\x00\x00\x00\x81\x00\x05\x00\x06\x00\x00\x00\x53\x00\x00\x00" +"\x50\x00\x00\x00\x52\x00\x00\x00\x41\x00\x05\x00\x54\x00\x00\x00\x55\x00\x00\x00\x4A\x00\x00\x00\x42\x00\x00\x00\x3E\x00\x03\x00" +"\x55\x00\x00\x00\x53\x00\x00\x00\x41\x00\x05\x00\x4C\x00\x00\x00\x56\x00\x00\x00\x15\x00\x00\x00\x4B\x00\x00\x00\x3D\x00\x04\x00" +"\x06\x00\x00\x00\x57\x00\x00\x00\x56\x00\x00\x00\x85\x00\x05\x00\x06\x00\x00\x00\x58\x00\x00\x00\x57\x00\x00\x00\x4F\x00\x00\x00" +"\x41\x00\x05\x00\x43\x00\x00\x00\x59\x00\x00\x00\x41\x00\x00\x00\x25\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\x5A\x00\x00\x00" +"\x59\x00\x00\x00\x81\x00\x05\x00\x06\x00\x00\x00\x5B\x00\x00\x00\x58\x00\x00\x00\x5A\x00\x00\x00\x41\x00\x05\x00\x54\x00\x00\x00" +"\x5C\x00\x00\x00\x4A\x00\x00\x00\x25\x00\x00\x00\x3E\x00\x03\x00\x5C\x00\x00\x00\x5B\x00\x00\x00\x3D\x00\x04\x00\x12\x00\x00\x00" +"\x5E\x00\x00\x00\x41\x00\x00\x00\x3E\x00\x03\x00\x5D\x00\x00\x00\x5E\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" +"\x01\x00\x08\x00\x42\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\x09\x00\x04\x00\x00\x00" +"\x04\x00\x00\x00\x6D\x61\x69\x6E\x00\x00\x00\x00\x13\x00\x00\x00\x1E\x00\x00\x00\x28\x00\x00\x00\x30\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\x03\x00\x09\x00\x00\x00\x61\x6D\x70\x00\x05\x00\x04\x00\x10\x00\x00\x00\x73\x5F\x74\x32\x00\x00\x00\x00" +"\x05\x00\x04\x00\x13\x00\x00\x00\x76\x5F\x65\x64\x67\x65\x00\x00\x05\x00\x04\x00\x1B\x00\x00\x00\x6F\x66\x66\x73\x65\x74\x00\x00" +"\x05\x00\x04\x00\x1C\x00\x00\x00\x73\x5F\x74\x31\x00\x00\x00\x00\x05\x00\x04\x00\x1E\x00\x00\x00\x76\x5F\x77\x61\x72\x70\x00\x00" +"\x05\x00\x04\x00\x27\x00\x00\x00\x74\x65\x6D\x70\x00\x00\x00\x00\x05\x00\x04\x00\x28\x00\x00\x00\x76\x5F\x73\x74\x63\x00\x00\x00" +"\x05\x00\x05\x00\x30\x00\x00\x00\x6F\x75\x74\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x05\x00\x04\x00\x31\x00\x00\x00\x73\x5F\x74\x30" +"\x00\x00\x00\x00\x05\x00\x05\x00\x3C\x00\x00\x00\x65\x6E\x74\x69\x74\x79\x62\x6C\x6F\x63\x6B\x00\x06\x00\x07\x00\x3C\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\x3C\x00\x00\x00\x01\x00\x00\x00" +"\x6D\x5F\x6D\x6F\x64\x65\x6C\x00\x06\x00\x06\x00\x3C\x00\x00\x00\x02\x00\x00\x00\x6D\x5F\x6D\x6F\x64\x65\x6C\x69\x6E\x76\x00\x00" +"\x06\x00\x06\x00\x3C\x00\x00\x00\x03\x00\x00\x00\x65\x5F\x65\x79\x65\x70\x6F\x73\x00\x00\x00\x00\x06\x00\x05\x00\x3C\x00\x00\x00" +"\x04\x00\x00\x00\x65\x5F\x74\x69\x6D\x65\x00\x00\x06\x00\x07\x00\x3C\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\x3C\x00\x00\x00\x06\x00\x00\x00\x65\x70\x61\x64\x31\x00\x00\x00\x06\x00\x06\x00" +"\x3C\x00\x00\x00\x07\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x64\x69\x72\x00\x06\x00\x05\x00\x3C\x00\x00\x00\x08\x00\x00\x00" +"\x65\x70\x61\x64\x32\x00\x00\x00\x06\x00\x06\x00\x3C\x00\x00\x00\x09\x00\x00\x00\x65\x5F\x6C\x69\x67\x68\x74\x5F\x6D\x75\x6C\x00" +"\x06\x00\x05\x00\x3C\x00\x00\x00\x0A\x00\x00\x00\x65\x70\x61\x64\x33\x00\x00\x00\x06\x00\x06\x00\x3C\x00\x00\x00\x0B\x00\x00\x00" +"\x65\x5F\x6C\x6D\x73\x63\x61\x6C\x65\x73\x00\x00\x06\x00\x07\x00\x3C\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\x3C\x00\x00\x00\x0D\x00\x00\x00\x65\x70\x61\x64\x34\x00\x00\x00\x06\x00\x07\x00" +"\x3C\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\x3C\x00\x00\x00" +"\x0F\x00\x00\x00\x65\x70\x61\x64\x35\x00\x00\x00\x06\x00\x06\x00\x3C\x00\x00\x00\x10\x00\x00\x00\x65\x5F\x67\x6C\x6F\x77\x6D\x6F" +"\x64\x00\x00\x00\x06\x00\x05\x00\x3C\x00\x00\x00\x11\x00\x00\x00\x65\x70\x61\x64\x36\x00\x00\x00\x06\x00\x07\x00\x3C\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\x3C\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\x3C\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\x3C\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\x3C\x00\x00\x00\x16\x00\x00\x00\x65\x70\x61\x64\x37\x00\x00\x00\x05\x00\x03\x00" +"\x3E\x00\x00\x00\x00\x00\x00\x00\x05\x00\x05\x00\x3F\x00\x00\x00\x6C\x69\x67\x68\x74\x62\x6C\x6F\x63\x6B\x00\x00\x06\x00\x07\x00" +"\x3F\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\x3F\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\x3F\x00\x00\x00\x02\x00\x00\x00" +"\x6C\x70\x61\x64\x31\x00\x00\x00\x06\x00\x07\x00\x3F\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\x3F\x00\x00\x00\x04\x00\x00\x00\x6C\x70\x61\x64\x32\x00\x00\x00\x06\x00\x08\x00\x3F\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\x3F\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\x3F\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\x3F\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\x3F\x00\x00\x00\x09\x00\x00\x00\x6C\x70\x61\x64" +"\x33\x00\x00\x00\x05\x00\x03\x00\x41\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x0B\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00" +"\x47\x00\x04\x00\x10\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x10\x00\x00\x00\x21\x00\x00\x00\x04\x00\x00\x00" +"\x47\x00\x04\x00\x13\x00\x00\x00\x1E\x00\x00\x00\x02\x00\x00\x00\x47\x00\x04\x00\x1C\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00" +"\x47\x00\x04\x00\x1C\x00\x00\x00\x21\x00\x00\x00\x03\x00\x00\x00\x47\x00\x04\x00\x1E\x00\x00\x00\x1E\x00\x00\x00\x01\x00\x00\x00" +"\x47\x00\x04\x00\x28\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x30\x00\x00\x00\x1E\x00\x00\x00\x00\x00\x00\x00" "\x47\x00\x04\x00\x31\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x31\x00\x00\x00\x21\x00\x00\x00\x02\x00\x00\x00" "\x47\x00\x04\x00\x3B\x00\x00\x00\x06\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00\x3C\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00" "\x48\x00\x05\x00\x3C\x00\x00\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00\x3C\x00\x00\x00\x00\x00\x00\x00" @@ -10536,7 +10555,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "\xFF\x53\x50\x56\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x2C\x00\x00\x00\x36\x00\x00\x00\x64\x00\x00\x00" "\xB8\x0F\x00\x00\x1C\x10\x00\x00\x6C\x0E\x00\x00\x01\x00\x69\x31\x72\x5F\x6D\x65\x6E\x75\x74\x69\x6E\x74\x5F\x69\x6E\x76\x65\x72" "\x73\x65\x00\x00\x00\x00\x00\x01\x01\x66\x33\x72\x5F\x6D\x65\x6E\x75\x74\x69\x6E\x74\x00\x3F\x2E\x14\x7B\x3E\xCC\xCC\xCD\x3E\x05" -"\x1E\xB8\x52\x41\x03\x02\x23\x07\x00\x00\x01\x00\x01\x00\x08\x00\x56\x00\x00\x00\x00\x00\x00\x00\x11\x00\x02\x00\x01\x00\x00\x00" +"\x1E\xB8\x00\x05\x03\x02\x23\x07\x00\x00\x01\x00\x01\x00\x08\x00\x56\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\x22\x00\x00\x00\x3F\x00\x00\x00" "\x41\x00\x00\x00\x47\x00\x00\x00\x50\x00\x00\x00\x51\x00\x00\x00\x52\x00\x00\x00\x53\x00\x00\x00\x54\x00\x00\x00\x03\x00\x03\x00" diff --git a/engine/gl/shader.h b/engine/gl/shader.h index 043af6720..eaf820fba 100644 --- a/engine/gl/shader.h +++ b/engine/gl/shader.h @@ -592,6 +592,7 @@ struct shader_s byte_vec4_t fog_color; float fog_dist; float portaldist; + float portalfboscale; //if we're using texturemaps for portal recursion, this is the scale of the texture relative to the screen. int numdeforms; deformv_t deforms[SHADER_DEFORM_MAX]; @@ -714,6 +715,7 @@ void Shader_RemapShader_f(void); void Shader_ShowShader_f(void); program_t *Shader_FindGeneric(char *name, int qrtype); +const char *Shader_NameForGeneric(program_t *prog); void Shader_ReleaseGeneric(program_t *prog); mfog_t *Mod_FogForOrigin(model_t *wmodel, vec3_t org); @@ -838,7 +840,11 @@ qboolean GLBE_BeginShadowMap(int id, int w, int h, int *restorefbo); void GLBE_EndShadowMap(int restorefbo); void GLBE_SetupForShadowMap(dlight_t *dl, int texwidth, int texheight, float shadowscale); - +qboolean GLVID_ApplyGammaRamps (unsigned int size, unsigned short *ramps); //called when gamma ramps need to be reapplied +qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette); //the platform-specific function to init gl state +void GLVID_SwapBuffers(void); +char *GLVID_GetRGBInfo(int *bytestride, int *truewidth, int *trueheight, enum uploadfmt *fmt); +void GLVID_SetCaption(const char *caption); #endif #ifdef D3D8QUAKE void D3D8BE_Init(void); diff --git a/engine/qclib/decomp.c b/engine/qclib/decomp.c index 4d2e89885..0e8825098 100644 --- a/engine/qclib/decomp.c +++ b/engine/qclib/decomp.c @@ -525,7 +525,12 @@ int DecompileReadData(char *srcfilename, char *buf, size_t bufsize) memcpy(&progs, buf, sizeof(progs)); - if (progs.version == PROG_VERSION) + if (progs.version == PROG_QTESTVERSION) + { + defsz = -32; //ddefs_t is 32bit + stsz = -16; //statements is mostly 16bit. there's some line numbers in there too. + } + else if (progs.version == PROG_VERSION) stsz = defsz = 16; else if (progs.version == 7) { @@ -559,8 +564,10 @@ int DecompileReadData(char *srcfilename, char *buf, size_t bufsize) // if (numstatements > MAX_STATEMENTS) // Sys_Error("Too many statements"); - if (stsz == 16) - { + if (stsz == 32) + statements = (dstatement32_t*)(buf+progs.ofs_statements); + else if (stsz == 16) + { //need to expand the statements to 32bit. const dstatement16_t *statements6 = (const dstatement16_t*)(buf+progs.ofs_statements); statements = malloc(numstatements * sizeof(*statements)); for (i = 0; i < numstatements; i++) @@ -582,8 +589,29 @@ int DecompileReadData(char *srcfilename, char *buf, size_t bufsize) statements[i].c = (unsigned short)statements6[i].c; } } - else if (stsz == 32) - statements = (dstatement32_t*)(buf+progs.ofs_statements); + else if (stsz == -16) + { + const qtest_statement_t *statements3 = (const qtest_statement_t*)(buf+progs.ofs_statements); + statements = malloc(numstatements * sizeof(*statements)); + for (i = 0; i < numstatements; i++) + { + statements[i].op = statements3[i].op; + + if (statements[i].op == OP_GOTO) + statements[i].a = (signed short)statements3[i].a; + else + statements[i].a = (unsigned short)statements3[i].a; + + if (statements[i].op == OP_IF_I || statements[i].op == OP_IFNOT_I || + statements[i].op == OP_IF_F || statements[i].op == OP_IFNOT_F || + statements[i].op == OP_IF_S || statements[i].op == OP_IFNOT_S) + statements[i].b = (signed short)statements3[i].b; + else + statements[i].b = (unsigned short)statements3[i].b; + + statements[i].c = (unsigned short)statements3[i].c; + } + } else Sys_Error("Unrecognised progs version"); @@ -615,6 +643,45 @@ int DecompileReadData(char *srcfilename, char *buf, size_t bufsize) fields[i].type = gd16[i].type; } } + else if (defsz == -32) + { + const qtest_function_t *funcin = (const qtest_function_t*)(buf+progs.ofs_functions); + const qtest_def_t *gdqt = (const qtest_def_t*)(buf+progs.ofs_globaldefs); + globals = malloc(numglobaldefs * sizeof(*globals)); + for (i = 0; i < numglobaldefs; i++) + { + globals[i].ofs = gdqt[i].ofs; + globals[i].s_name = gdqt[i].s_name; + globals[i].type = gdqt[i].type; + } + + + gdqt = (const qtest_def_t*)(buf+progs.ofs_fielddefs); + fields = malloc(numfielddefs * sizeof(*fields)); + for (i = 0; i < numfielddefs; i++) + { + fields[i].ofs = gdqt[i].ofs; + fields[i].s_name = gdqt[i].s_name; + fields[i].type = gdqt[i].type; + } + + functions = malloc(numfunctions * sizeof(*functions)); + for (i = 0; i < numfunctions; i++) + { + functions[i].first_statement = funcin[i].first_statement; // negative numbers are builtins + functions[i].parm_start = funcin[i].parm_start; + functions[i].locals = funcin[i].locals; // total ints of parms + locals + + functions[i].profile = funcin[i].profile; // runtime + + functions[i].s_name = funcin[i].s_name; + functions[i].s_file = funcin[i].s_file; // source file defined in + + functions[i].numparms = funcin[i].numparms; + for (j = 0; j < MAX_PARMS; j++) + functions[i].parm_size[j] = funcin[i].parm_size[j]; + } + } else { globals = (QCC_ddef32_t*)(buf+progs.ofs_globaldefs); @@ -2775,7 +2842,7 @@ void DecompileFunction(const char *name, int *lastglobal) } QCC_CatVFile(Decompileofile, "\n{\n"); - startpos = Decompileofile->fsize; + startpos = Decompileofile->size; /* fprintf(Decompileprofile, "%s", DecompileProfiles[findex]); @@ -3014,7 +3081,7 @@ void DecompileProgsDat(char *name, void *buf, size_t bufsize) DecompileReadData(name, buf, bufsize); DecompileDecompileFunctions(c); - printf("Done."); + printf("Done.\n"); } char *DecompileGlobalStringNoContents(gofs_t ofs) diff --git a/engine/qclib/qcc.h b/engine/qclib/qcc.h index bce8fb12e..b1142e08b 100644 --- a/engine/qclib/qcc.h +++ b/engine/qclib/qcc.h @@ -1100,13 +1100,14 @@ int QCC_CopyStringLength (const char *str, size_t length); typedef struct qcc_cachedsourcefile_s { - char filename[128]; size_t size; + size_t bufsize; size_t zhdrofs; int zcrc; char *file; enum{FT_CODE, FT_DATA} type; //quakec source file or not. struct qcc_cachedsourcefile_s *next; + char filename[1]; } qcc_cachedsourcefile_t; extern qcc_cachedsourcefile_t *qcc_sourcefile; int WriteSourceFiles(qcc_cachedsourcefile_t *filelist, int h, pbool sourceaswell, pbool legacyembed); @@ -1164,18 +1165,26 @@ extern void *(*pHash_GetNext)(hashtable_t *table, const char *name, void *old); extern void *(*pHash_Add)(hashtable_t *table, const char *name, void *data, bucket_t *); extern void (*pHash_RemoveData)(hashtable_t *table, const char *name, void *data); -typedef struct vfile_s -{ //when originally running from a .dat, we load up all the functions and work from those rather than actual files. - //(these get re-written into the resulting .dat) - struct vfile_s *next; - void *fdata; - size_t fsize; - size_t msize; - char name[1]; -} vfile_t; +//when originally running from a .dat, we load up all the functions and work from those rather than actual files. +//(these get re-written into the resulting .dat) +typedef struct qcc_cachedsourcefile_s vfile_t; vfile_t *QCC_FindVFile(const char *name); vfile_t *QCC_AddVFile(const char *name, void *data, size_t size); void QCC_CatVFile(vfile_t *, const char *fmt, ...); void QCC_InsertVFile(vfile_t *, size_t pos, const char *fmt, ...); //void *QCC_ReadFile(const char *fname, unsigned char *(*buf_get)(void *ctx, size_t len), void *buf_ctx, size_t *out_size, pbool issourcefile); + + +typedef struct +{ + char name[56]; + int filepos, filelen; +} packfile_t; + +typedef struct +{ + char id[4]; + int dirofs; + int dirlen; +} packheader_t; diff --git a/engine/qclib/qcc_cmdlib.c b/engine/qclib/qcc_cmdlib.c index 3f350ae22..4395e4ef4 100644 --- a/engine/qclib/qcc_cmdlib.c +++ b/engine/qclib/qcc_cmdlib.c @@ -889,10 +889,17 @@ void ResizeBuf(int hand, int newsize) } void SafeWrite(int hand, const void *buf, long count) { - if (qccfile[hand].ofs +count >= qccfile[hand].buffsize) - ResizeBuf(hand, qccfile[hand].ofs + count+(64*1024)); + if (qccfile[hand].stdio) + { + fwrite(buf, 1, count, qccfile[hand].stdio); + } + else + { + if (qccfile[hand].ofs +count >= qccfile[hand].buffsize) + ResizeBuf(hand, qccfile[hand].ofs + count+(64*1024)); - memcpy(&qccfile[hand].buff[qccfile[hand].ofs], buf, count); + memcpy(&qccfile[hand].buff[qccfile[hand].ofs], buf, count); + } qccfile[hand].ofs+=count; if (qccfile[hand].ofs > qccfile[hand].maxofs) qccfile[hand].maxofs = qccfile[hand].ofs; @@ -903,7 +910,10 @@ int SafeSeek(int hand, int ofs, int mode) return qccfile[hand].ofs; else { - ResizeBuf(hand, ofs+1024); + if (qccfile[hand].stdio) + fseek(qccfile[hand].stdio, ofs, SEEK_SET); + else + ResizeBuf(hand, ofs+1024); qccfile[hand].ofs = ofs; if (qccfile[hand].ofs > qccfile[hand].maxofs) qccfile[hand].maxofs = qccfile[hand].ofs; @@ -1220,7 +1230,7 @@ char *QCC_SanitizeCharSet(char *mem, size_t *len, pbool *freeresult, int *origfm static unsigned char *PDECL QCC_LoadFileHunk(void *ctx, size_t size) { //2 ensures we can always put a \n in there. - return (unsigned char*)qccHunkAlloc(sizeof(qcc_cachedsourcefile_t)+size+2) + sizeof(qcc_cachedsourcefile_t); + return (unsigned char*)qccHunkAlloc(sizeof(qcc_cachedsourcefile_t)+strlen(ctx)+size+2) + sizeof(qcc_cachedsourcefile_t) + strlen(ctx); } long QCC_LoadFile (char *filename, void **bufferptr) @@ -1234,13 +1244,13 @@ long QCC_LoadFile (char *filename, void **bufferptr) int orig; pbool warned = false; - mem = externs->ReadFile(filename, QCC_LoadFileHunk, NULL, &len, true); + mem = externs->ReadFile(filename, QCC_LoadFileHunk, filename, &len, true); if (!mem) { QCC_Error(ERR_COULDNTOPENFILE, "Couldn't open file %s", filename); return -1; } - sfile = (qcc_cachedsourcefile_t*)(mem-sizeof(qcc_cachedsourcefile_t)); + sfile = (qcc_cachedsourcefile_t*)(mem-sizeof(qcc_cachedsourcefile_t)-strlen(filename)); mem[len] = 0; mem = QCC_SanitizeCharSet(mem, &len, NULL, &orig); @@ -1284,10 +1294,10 @@ void QCC_AddFile (char *filename) char *mem; size_t len; - mem = externs->ReadFile(filename, QCC_LoadFileHunk, NULL, &len, false); + mem = externs->ReadFile(filename, QCC_LoadFileHunk, filename, &len, false); if (!mem) externs->Abort("failed to find file %s", filename); - sfile = (qcc_cachedsourcefile_t*)(mem-sizeof(qcc_cachedsourcefile_t)); + sfile = (qcc_cachedsourcefile_t*)(mem-sizeof(qcc_cachedsourcefile_t)-strlen(filename)); mem[len] = '\0'; sfile->size = len; diff --git a/engine/qclib/qcc_pr_lex.c b/engine/qclib/qcc_pr_lex.c index a6dca4995..a37a2a887 100644 --- a/engine/qclib/qcc_pr_lex.c +++ b/engine/qclib/qcc_pr_lex.c @@ -3657,11 +3657,10 @@ void QCC_PR_Lex (void) QCC_PR_LexWhitespace (false); - if (currentchunk) - pr_token_line_last = currentchunk->currentlinenumber-1 + pr_token_line; - else - pr_token_line_last = pr_token_line; + pr_token_line_last = pr_token_line; pr_token_line = pr_source_line; + if (currentchunk) + pr_token_line += currentchunk->currentlinenumber-1; if (!pr_file_p) { diff --git a/engine/qclib/qccgui.c b/engine/qclib/qccgui.c index 43dd47bf4..bbccf933e 100644 --- a/engine/qclib/qccgui.c +++ b/engine/qclib/qccgui.c @@ -350,31 +350,132 @@ static pbool QCC_RegSetValue(HKEY base, char *keyname, char *valuename, int type } */ +#undef printf +#undef Sys_Error +void Sys_Error(const char *text, ...); + +pbool qcc_vfiles_changed; static vfile_t *qcc_vfiles; +HWND mainwindow; +HINSTANCE ghInstance; +static INT CALLBACK StupidBrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lp, LPARAM pData) ; +void QCC_SaveVFiles(void) +{ + vfile_t *f; + if (qcc_vfiles_changed) + { + switch (MessageBox(mainwindow, "Save files as archive?", "FTEQCCGUI", MB_YESNOCANCEL)) + { + case IDYES: + { + char filename[MAX_PATH]; + char oldpath[MAX_PATH+10]; + OPENFILENAME ofn; + memset(&ofn, 0, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hInstance = ghInstance; + ofn.lpstrFile = filename; + ofn.lpstrTitle = "Output archive"; + ofn.nMaxFile = sizeof(filename)-1; + ofn.lpstrFilter = "QuakeC Projects\0*.zip\0All files\0*.*\0"; + memset(filename, 0, sizeof(filename)); + GetCurrentDirectory(sizeof(oldpath)-1, oldpath); + ofn.lpstrInitialDir = oldpath; + if (GetSaveFileName(&ofn)) + { + int h = SafeOpenWrite(ofn.lpstrFile, -1); + + progfuncs_t funcs; + progexterns_t ext; + memset(&funcs, 0, sizeof(funcs)); + funcs.funcs.parms = &ext; + memset(&ext, 0, sizeof(ext)); + ext.ReadFile = GUIReadFile; + ext.FileSize = GUIFileSize; + ext.WriteFile = QCC_WriteFile; + ext.Sys_Error = Sys_Error; + ext.Printf = GUIprintf; + + qccprogfuncs = &funcs; + WriteSourceFiles(qcc_vfiles, h, true, false); + qccprogfuncs = NULL; + + SafeClose(h); + + qcc_vfiles_changed = false; + return; + } + } + break; + case IDNO: + { + char oldworkingdir[MAX_PATH], newdir[MAX_PATH+10], workingdir[MAX_PATH]; + BROWSEINFO bi; + LPITEMIDLIST il; + memset(&bi, 0, sizeof(bi)); + bi.hwndOwner = mainwindow; + bi.pidlRoot = NULL; + GetCurrentDirectory(sizeof(oldworkingdir)-1, oldworkingdir); + GetCurrentDirectory(sizeof(workingdir)-1, workingdir); + bi.pszDisplayName = workingdir; + bi.lpszTitle = "Where do you want the source?"; + bi.ulFlags = BIF_RETURNONLYFSDIRS|BIF_STATUSTEXT; + bi.lpfn = StupidBrowseCallbackProc; + bi.lParam = 0; + bi.iImage = 0; + il = SHBrowseForFolder(&bi); + if (il) + { + SHGetPathFromIDList(il, newdir); + CoTaskMemFree(il); + + for (f = qcc_vfiles; f; f = f->next) + { + char nname[MAX_PATH]; + int h; + QC_snprintfz(nname, sizeof(nname), "%s\\%s", newdir, f->filename); + h = SafeOpenWrite(f->filename, -1); + if (h >= 0) + { + SafeWrite(h, f->file, f->size); + SafeClose(h); + } + } + } + SetCurrentDirectory(oldworkingdir); //revert microsoft stupidity. + } + break; + default: + return; + } + } +} void QCC_CloseAllVFiles(void) { vfile_t *f; + while(qcc_vfiles) { f = qcc_vfiles; qcc_vfiles = f->next; - free(f->fdata); + free(f->file); free(f); } + qcc_vfiles_changed = false; } vfile_t *QCC_FindVFile(const char *name) { vfile_t *f; for (f = qcc_vfiles; f; f = f->next) { - if (!strcmp(f->name, name)) + if (!strcmp(f->filename, name)) return f; } //give it another go, for case for (f = qcc_vfiles; f; f = f->next) { - if (!QC_strcasecmp(f->name, name)) + if (!QC_strcasecmp(f->filename, name)) return f; } return NULL; @@ -386,14 +487,17 @@ vfile_t *QCC_AddVFile(const char *name, void *data, size_t size) { f = malloc(sizeof(vfile_t) + strlen(name)); f->next = qcc_vfiles; - strcpy(f->name, name); + strcpy(f->filename, name); qcc_vfiles = f; } else - free(f->fdata); - f->fdata = malloc(size); - memcpy(f->fdata, data, size); - f->fsize = f->msize = size; + free(f->file); + f->file = malloc(size); + f->type = FT_CODE; + memcpy(f->file, data, size); + f->size = f->bufsize = size; + + qcc_vfiles_changed = true; return f; } void QCC_CatVFile(vfile_t *f, const char *fmt, ...) @@ -407,14 +511,14 @@ void QCC_CatVFile(vfile_t *f, const char *fmt, ...) va_end (argptr); n = strlen(msg); - if (f->fsize+n > f->msize) + if (f->size+n > f->bufsize) { - size_t msize = f->msize + n + 8192; - f->fdata = realloc(f->fdata, msize); - f->msize = msize; + size_t msize = f->bufsize + n + 8192; + f->file = realloc(f->file, msize); + f->bufsize = msize; } - memcpy((char*)f->fdata+f->fsize, msg, n); - f->fsize += n; + memcpy((char*)f->file+f->size, msg, n); + f->size += n; } void QCC_InsertVFile(vfile_t *f, size_t pos, const char *fmt, ...) { @@ -426,15 +530,15 @@ void QCC_InsertVFile(vfile_t *f, size_t pos, const char *fmt, ...) va_end (argptr); n = strlen(msg); - if (f->fsize+n > f->msize) + if (f->size+n > f->bufsize) { - size_t msize = f->msize + n + 8192; - f->fdata = realloc(f->fdata, msize); - f->msize = msize; + size_t msize = f->bufsize + n + 8192; + f->file = realloc(f->file, msize); + f->bufsize = msize; } - memmove((char*)f->fdata+pos+n, (char*)f->fdata+pos, f->fsize-pos); - f->fsize += n; - memcpy((char*)f->fdata+pos, msg, n); + memmove((char*)f->file+pos+n, (char*)f->file+pos, f->size-pos); + f->size += n; + memcpy((char*)f->file+pos, msg, n); } void QCC_EnumerateFilesResult(const char *name, const void *compdata, size_t compsize, int method, size_t plainsize) @@ -442,6 +546,7 @@ void QCC_EnumerateFilesResult(const char *name, const void *compdata, size_t com void *buffer = malloc(plainsize); if (QC_decode(NULL, compsize, plainsize, method, compdata, buffer)) QCC_AddVFile(name, buffer, plainsize); + free(buffer); } @@ -459,7 +564,7 @@ static void *QCC_ReadFile(const char *fname, unsigned char *(*buf_get)(void *ctx vfile_t *v = QCC_FindVFile(fname); if (v) { - len = v->fsize; + len = v->size; if (buf_get) buffer = buf_get(buf_ctx, len+1); else @@ -467,9 +572,9 @@ static void *QCC_ReadFile(const char *fname, unsigned char *(*buf_get)(void *ctx if (!buffer) return NULL; ((char*)buffer)[len] = 0; - if (len > v->fsize) - len = v->fsize; - memcpy(buffer, v->fdata, len); + if (len > v->size) + len = v->size; + memcpy(buffer, v->file, len); if (out_size) *out_size = len; return buffer; @@ -510,7 +615,7 @@ int PDECL QCC_RawFileSize (const char *fname) vfile_t *v = QCC_FindVFile(fname); if (v) - return v->fsize; + return v->size; f = fopen(fname, "rb"); if (!f) @@ -3029,6 +3134,7 @@ static void EditorReload(editor_t *editor) //2: draw extra focus to it void EditFile(const char *name, int line, pbool setcontrol) { + const char *ext; char title[1024]; editor_t *neweditor; WNDCLASS wndclass; @@ -3081,6 +3187,33 @@ void EditFile(const char *name, int line, pbool setcontrol) return; } + ext = strrchr(name, '.'); + if (ext) + { + if (!QC_strcasecmp(ext, ".wav")) + { + size_t flensz; + char *rawfile = QCC_ReadFile(name, NULL, NULL, &flensz); + //fixme: thread this... + BOOL (WINAPI *pPlaySound)(LPCSTR pszSound, HMODULE hmod, DWORD fdwSound); + HMODULE winmm = LoadLibrary("winmm.dll"); + pPlaySound = (void*)GetProcAddress(winmm, "PlaySoundA"); + if (pPlaySound) + pPlaySound(rawfile, NULL, SND_MEMORY|SND_SYNC|SND_NODEFAULT); + free(rawfile); + return; + } + else if (!QC_strcasecmp(ext, ".ogg") || !QC_strcasecmp(ext, ".mp3") || !QC_strcasecmp(ext, ".opus") || + !QC_strcasecmp(ext, ".bsp") || !QC_strcasecmp(ext, ".mdl") || !QC_strcasecmp(ext, ".md2") || !QC_strcasecmp(ext, ".md3") || !QC_strcasecmp(ext, ".iqm") || + !QC_strcasecmp(ext, ".wad") || !QC_strcasecmp(ext, ".lmp") || !QC_strcasecmp(ext, ".png") || !QC_strcasecmp(ext, ".tga") || !QC_strcasecmp(ext, ".jpeg") || + !QC_strcasecmp(ext, ".jpg") || !QC_strcasecmp(ext, ".dds") || !QC_strcasecmp(ext, ".ktx") || !QC_strcasecmp(ext, ".bmp") || !QC_strcasecmp(ext, ".pcx") || + !QC_strcasecmp(ext, ".bin") || !QC_strcasecmp(ext, ".dat") || !QC_strcasecmp(ext, ".pak") || !QC_strcasecmp(ext, ".pk3") || !QC_strcasecmp(ext, ".dem") || !QC_strcasecmp(ext, ".spr")) + { + if (IDOK != MessageBox(NULL, "The file extension implies that it is a binary file. Open as text anyway?", "FTEQCCGUI", MB_OKCANCEL)) + return; + } + } + neweditor = malloc(sizeof(editor_t)); if (!neweditor) { @@ -6985,6 +7118,26 @@ static void Packager_MessageCallback(void *ctx, const char *fmt, ...) outlen = GUIEmitOutputText(outputbox, outlen, message, strlen(message), RGB(0, 0, 0)); } +void GUI_DoDecompile(void *buf, size_t size) +{ + char *c = ReadProgsCopyright(buf, size); + if (!c || !*c) + c = "COPYRIGHT OWNER NOT KNOWN"; //all work is AUTOMATICALLY copyrighted under the terms of the Berne Convention in all major nations. It _IS_ copyrighted, even if there's no license etc included. Good luck guessing what rights you have. + if (MessageBox(mainwindow, qcva("The copyright message from this progs is\n%s\n\nPlease respect the wishes and legal rights of the person who created this.", c), "Copyright", MB_OKCANCEL|MB_DEFBUTTON2|MB_ICONSTOP) == IDOK) + { + CreateOutputWindow(true); + compilecb(); + DecompileProgsDat(progssrcname, buf, size); + if (SplitterGet(outputbox)) + { + SendMessage(outputbox, WM_SETREDRAW, TRUE, 0); + RedrawWindow(outputbox, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN); + } + + QCC_SaveVFiles(); + } +} + int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { pbool fl_acc; @@ -7176,7 +7329,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin //if the project is a .dat or .zip then decompile it now (so we can access the 'source') { char *ext = strrchr(progssrcname, '.'); - if (ext && (!QC_strcasecmp(ext, ".dat") || !QC_strcasecmp(ext, ".zip") || !QC_strcasecmp(ext, ".pk3"))) + if (ext && (!QC_strcasecmp(ext, ".dat") || !QC_strcasecmp(ext, ".pak") || !QC_strcasecmp(ext, ".zip") || !QC_strcasecmp(ext, ".pk3"))) { FILE *f = fopen(progssrcname, "rb"); if (f) @@ -7192,21 +7345,24 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin fclose(f); QCC_CloseAllVFiles(); if (!QC_EnumerateFilesFromBlob(buf, size, QCC_EnumerateFilesResult) && !QC_strcasecmp(ext, ".dat")) + { //its a .dat and contains no .src files + GUI_DoDecompile(buf, size); + } + else if (!QCC_FindVFile("progs.src")) { - char *c = ReadProgsCopyright(buf, size); - if (!c || !*c) - c = "COPYRIGHT OWNER NOT KNOWN"; //all work is AUTOMATICALLY copyrighted under the terms of the Berne Convention in all major nations. It _IS_ copyrighted, even if there's no license etc included. Good luck guessing what rights you have. - if (MessageBox(mainwindow, qcva("The copyright message from this progs is\n%s\n\nPlease respect the wishes and legal rights of the person who created this.", c), "Copyright", MB_OKCANCEL|MB_DEFBUTTON2|MB_ICONSTOP) == IDOK) - { - CreateOutputWindow(true); - compilecb(); - DecompileProgsDat(progssrcname, buf, size); - if (SplitterGet(outputbox)) - { - SendMessage(outputbox, WM_SETREDRAW, TRUE, 0); - RedrawWindow(outputbox, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN); - } - } + vfile_t *f; + char *archivename = progssrcname; + while(strchr(archivename, '\\')) + archivename = strchr(archivename, '\\')+1; + AddSourceFile(NULL, archivename); + for (f = qcc_vfiles; f; f = f->next) + AddSourceFile(archivename, f->filename); + + f = QCC_FindVFile("progs.dat"); + if (f) + GUI_DoDecompile(f->file, f->size); + else + resetprogssrc = false; } free(buf); strcpy(progssrcname, "progs.src"); @@ -7227,8 +7383,11 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin if (fl_compileonstart) { - CreateOutputWindow(false); - RunCompiler(lpCmdLine, false); + if (resetprogssrc) + { + CreateOutputWindow(false); + RunCompiler(lpCmdLine, false); + } } else { @@ -7242,8 +7401,9 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin RunCompiler("-?", false); } } + if (resetprogssrc) + UpdateFileList(); resetprogssrc = false; - UpdateFileList(); } EditorsRun(); diff --git a/engine/qclib/qccmain.c b/engine/qclib/qccmain.c index e1732d2d8..6cdf1b47d 100644 --- a/engine/qclib/qccmain.c +++ b/engine/qclib/qccmain.c @@ -769,7 +769,7 @@ int WriteSourceFiles(qcc_cachedsourcefile_t *filelist, int h, pbool sourceaswell if (zipembed) { size_t end; - char header[32+sizeof(f->filename)]; + char header[32]; size_t fnamelen = strlen(f->filename); f->zcrc = QC_encodecrc(f->size, f->file); misint (header, 0, 0x04034b50); @@ -783,10 +783,10 @@ int WriteSourceFiles(qcc_cachedsourcefile_t *filelist, int h, pbool sourceaswell misint (header, 22, f->size);//uncompressed size misshort(header, 26, fnamelen);//filename length misshort(header, 28, 0);//extradata length - strcpy(header+30, f->filename); f->zhdrofs = SafeSeek(h, 0, SEEK_CUR); - SafeWrite(h, header, 30+fnamelen); + SafeWrite(h, header, 30); + SafeWrite(h, f->filename, fnamelen); strcpy(idf[num].filename, f->filename); idf[num].size = f->size; @@ -803,13 +803,13 @@ int WriteSourceFiles(qcc_cachedsourcefile_t *filelist, int h, pbool sourceaswell end = SafeSeek(h, 0, SEEK_CUR); SafeSeek(h, f->zhdrofs, SEEK_SET); - SafeWrite(h, header, 30+strlen(f->filename)); + SafeWrite(h, header, 30); SafeSeek(h, end, SEEK_SET); } } else { - if (f->type == FT_CODE && !sourceaswell) + if (strlen(f->filename) >= sizeof(idf[num].filename)) continue; strcpy(idf[num].filename, f->filename); @@ -827,7 +827,7 @@ int WriteSourceFiles(qcc_cachedsourcefile_t *filelist, int h, pbool sourceaswell if (zipembed) { - char centralheader[46+sizeof(f->filename)]; + char centralheader[46]; int centraldirsize; ofs = SafeSeek(h, 0, SEEK_CUR); for (f = filelist,num=0; f ; f=f->next) @@ -853,8 +853,8 @@ int WriteSourceFiles(qcc_cachedsourcefile_t *filelist, int h, pbool sourceaswell misshort(centralheader, 36, 0);//internal file attribs misint (centralheader, 38, 0);//external file attribs misint (centralheader, 42, f->zhdrofs);//local header offset - strcpy(centralheader+46, f->filename); - SafeWrite(h, centralheader, 46 + fnamelen); + SafeWrite(h, centralheader, 46); + SafeWrite(h, f->filename, fnamelen); num++; } @@ -3614,19 +3614,6 @@ DIRECTORY COPYING / PACKFILE CREATION ============================================================================== */ -typedef struct -{ - char name[56]; - int filepos, filelen; -} packfile_t; - -typedef struct -{ - char id[4]; - int dirofs; - int dirlen; -} packheader_t; - packfile_t pfiles[4096], *pf; int packhandle; int packbytes; diff --git a/engine/qclib/qcd_main.c b/engine/qclib/qcd_main.c index 126f44e8a..9f18cc39b 100644 --- a/engine/qclib/qcd_main.c +++ b/engine/qclib/qcd_main.c @@ -191,6 +191,18 @@ int QC_EnumerateFilesFromBlob(const void *blob, size_t blobsize, void (*cb)(cons int ret = 0; if (blobsize < 22) return ret; + if (!strncmp(blob, "PACK", 4)) + { + const packheader_t *head = blob; + const packfile_t *f = (packfile_t*)((char*)blob + head->dirofs); + for (ret = 0; ret < head->dirlen/sizeof(*f); ret++, f++) + { + cb(f->name, (const char*)blob+f->filepos, f->filelen, 0, f->filelen); + } + return ret; + } + + //treat it as a zip eocd = blob; eocd += blobsize-22; if (QC_ReadRawInt(eocd+0) != 0x06054b50) diff --git a/engine/server/net_preparse.c b/engine/server/net_preparse.c index dde0f3ed0..b97463a4b 100644 --- a/engine/server/net_preparse.c +++ b/engine/server/net_preparse.c @@ -647,11 +647,11 @@ void NPP_SetInfo(client_t *cl, char *key, char *value) if (!strcmp(key, "colours")) { i = atoi(value); - Info_SetValueForKey (cl->userinfo, "bottomcolor", va("%i", i&15), sizeof(cl->userinfo)); - Info_SetValueForKey (cl->userinfo, "topcolor", va("%i", i>>4), sizeof(cl->userinfo)); + InfoBuf_SetKey (&cl->userinfo, "bottomcolor", va("%i", i&15)); + InfoBuf_SetKey (&cl->userinfo, "topcolor", va("%i", i>>4)); } - Info_SetValueForKey (cl->userinfo, key, value, sizeof(cl->userinfo)); - if (!*Info_ValueForKey (cl->userinfo, "name")) + InfoBuf_SetKey (&cl->userinfo, key, value); + if (!*InfoBuf_ValueForKey (&cl->userinfo, "name")) cl->name[0] = '\0'; else // process any changed values SV_ExtractFromUserinfo (cl, false); @@ -662,19 +662,19 @@ void NPP_SetInfo(client_t *cl, char *key, char *value) MSG_WriteByte (&sv.reliable_datagram, svc_setinfo); MSG_WriteByte (&sv.reliable_datagram, i); MSG_WriteString (&sv.reliable_datagram, "bottomcolor"); - MSG_WriteString (&sv.reliable_datagram, Info_ValueForKey(cl->userinfo, "bottomcolor")); + MSG_WriteString (&sv.reliable_datagram, InfoBuf_ValueForKey(&cl->userinfo, "bottomcolor")); MSG_WriteByte (&sv.reliable_datagram, svc_setinfo); MSG_WriteByte (&sv.reliable_datagram, i); MSG_WriteString (&sv.reliable_datagram, "topcolor"); - MSG_WriteString (&sv.reliable_datagram, Info_ValueForKey(cl->userinfo, "topcolor")); + MSG_WriteString (&sv.reliable_datagram, InfoBuf_ValueForKey(&cl->userinfo, "topcolor")); } else { MSG_WriteByte (&sv.reliable_datagram, svc_setinfo); MSG_WriteByte (&sv.reliable_datagram, i); MSG_WriteString (&sv.reliable_datagram, key); - MSG_WriteString (&sv.reliable_datagram, Info_ValueForKey(cl->userinfo, key)); + MSG_WriteString (&sv.reliable_datagram, InfoBuf_ValueForKey(&cl->userinfo, key)); } } @@ -1851,8 +1851,8 @@ void NPP_QWFlush(void) unsigned int j = buffer[1]; if (j < sv.allocated_client_slots) { - Q_strncpyz(svs.clients[j].userinfo, (buffer+6), sizeof(svs.clients[j].userinfo)); - if (*Info_ValueForKey(svs.clients[j].userinfo, "name")) + InfoBuf_FromString(&svs.clients[j].userinfo, buffer+6, false); + if (*InfoBuf_ValueForKey(&svs.clients[j].userinfo, "name")) SV_ExtractFromUserinfo(&svs.clients[j], false); else *svs.clients[j].name = '\0'; @@ -1864,7 +1864,7 @@ void NPP_QWFlush(void) if (j < sv.allocated_client_slots) { *svs.clients[j].name = '\0'; - *svs.clients[j].userinfo = '\0'; + InfoBuf_Clear(&svs.clients[j].userinfo, true); } } diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index d538c1c13..b36bd7238 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -206,6 +206,47 @@ static qcstate_t *PR_CreateThread(pubprogfuncs_t *prinst, float retval, float re return state; } +void *PR_GetWriteQCPtr(pubprogfuncs_t *prinst, int qcptr, int qcsize) +{ +// void *r; + if (qcsize < 0) + return NULL; + if (!qcptr) + return NULL; + if (qcptr >= 0 && qcptr <= prinst->stringtablemaxsize) + { + if (qcptr + qcsize <= prinst->stringtablemaxsize) + return prinst->stringtable+qcptr; //its in bounds + } + /*else + { + r = PR_GetString(prinst, qcptr); + if (qcsize < strlen(r)) + return r; + }*/ + return NULL; +} +const void *PR_GetReadQCPtr(pubprogfuncs_t *prinst, int qcptr, int qcsize) +{ + const char *r; + if (qcsize < 0) + return NULL; + if (!qcptr) + return NULL; + if (qcptr >= 0 && qcptr <= prinst->stringtablemaxsize) + { + if (qcptr + qcsize <= prinst->stringtablemaxsize) + return prinst->stringtable+qcptr; //its in bounds + } + else + { + r = PR_GetString(prinst, qcptr); + if (qcsize < strlen(r)) + return r; + } + return NULL; +} + void PDECL ED_Spawned (struct edict_s *ent, int loading) { #ifdef VM_Q1 @@ -1778,7 +1819,7 @@ void Q_InitProgs(void) int j, maps; char *f; - f = COM_LoadTempFile("maplist.txt", NULL); + f = COM_LoadTempFile("maplist.txt", 0, NULL); f = COM_Parse(f); maps = atoi(com_token); for (j = 0; j < maps; j++) @@ -3853,7 +3894,7 @@ void PF_stuffcmd_Internal(int entnum, const char *str, unsigned int flags) case 13: tname = "blue"; break; default: tname = va("t%i", team); break; //good job our va has multiple buffers } - PF_ForceInfoKey_Internal(entnum, "team", tname); + PF_ForceInfoKey_Internal(entnum, "team", tname, strlen(tname)); ClientReliableWrite_Begin (cl, svc_stufftext, 2+strlen("color ")); ClientReliableWrite_String (cl, "color "); @@ -4721,14 +4762,14 @@ void QCBUILTIN PF_aim (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) i = NUM_FOR_EDICT(prinst, ent); if (i>0 && i 0) { VectorCopy (P_VEC(v_forward), G_VECTOR(OFS_RETURN)); return; } - noaim = Info_ValueForKey (svs.clients[i-1].userinfo, "aim"); + noaim = InfoBuf_ValueForKey (&svs.clients[i-1].userinfo, "aim"); if (noaim) { dist = atof(noaim); @@ -5842,8 +5883,8 @@ char *PF_infokey_Internal (int entnum, const char *key) value = "2.40"; else { - if ((value = Info_ValueForKey (svs.info, key)) == NULL || !*value) - value = Info_ValueForKey(localinfo, key); + if ((value = InfoBuf_ValueForKey(&svs.info, key)) == NULL || !*value) + value = InfoBuf_ValueForKey(&svs.localinfo, key); } } else if (entnum <= sv.allocated_client_slots) @@ -5950,7 +5991,7 @@ char *PF_infokey_Internal (int entnum, const char *key) else if (!strcmp(key, "*islagged")) value = (svs.clients[entnum-1].penalties & BAN_LAGGED)?"1":""; else - value = Info_ValueForKey (svs.clients[entnum-1].userinfo, key); + value = InfoBuf_ValueForKey (&svs.clients[entnum-1].userinfo, key); } else value = ""; @@ -5985,18 +6026,96 @@ static void QCBUILTIN PF_infokey_f (pubprogfuncs_t *prinst, struct globalvars_s static void QCBUILTIN PF_sv_serverkeystring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { const char *key = PR_GetStringOfs(prinst, OFS_PARM0); - const char *value = Info_ValueForKey (svs.info, key); + const char *value = InfoBuf_ValueForKey (&svs.info, key); G_INT(OFS_RETURN) = *value?PR_TempString(prinst, value):0; } static void QCBUILTIN PF_sv_serverkeyfloat (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { const char *key = PR_GetStringOfs(prinst, OFS_PARM0); - const char *value = Info_ValueForKey (svs.info, key); + const char *value = InfoBuf_ValueForKey (&svs.info, key); if (*value) G_FLOAT(OFS_RETURN) = strtod(value, NULL); else G_FLOAT(OFS_RETURN) = (prinst->callargc>=2)?G_FLOAT(OFS_PARM1):0; } +static void QCBUILTIN PF_sv_serverkeyblob (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) +{ + size_t blobsize = 0; + const char *key = PR_GetStringOfs(prinst, OFS_PARM0); + const char *blobvalue = InfoBuf_BlobForKey(&svs.info, key, &blobsize); + + if ((prinst->callargc<2) || G_INT(OFS_PARM1) == 0) + G_INT(OFS_RETURN) = blobsize; //no pointer to write to, just return the length. + else + { + size_t size = min(blobsize, G_INT(OFS_PARM2)); + void *ptr = PR_GetWriteQCPtr(prinst, G_INT(OFS_PARM1), size); + if (!ptr) + PR_BIError(prinst, "PF_sv_serverkeyblob: invalid pointer/size\n"); + G_INT(OFS_RETURN) = size; + memcpy(ptr, blobvalue, size); + } +} +static void QCBUILTIN PF_setserverkey (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) +{ + const char *key = PR_GetStringOfs(prinst, OFS_PARM0); + const char *value; + size_t size; + if (prinst->callargc > 2) + { + size = G_INT(OFS_PARM2); + value = PR_GetReadQCPtr(prinst, G_INT(OFS_PARM1), size); + } + else + { + value = PR_GetStringOfs(prinst, OFS_PARM1); + size = strlen(value); + } + if (!value) + PR_BIError(prinst, "PF_setserverkey: invalid pointer/size\n"); + + InfoBuf_SetStarBlobKey(&svs.info, key, value, size); +} + + +static void QCBUILTIN PF_getlocalinfo (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) +{ + size_t blobsize = 0; + const char *key = PR_GetStringOfs(prinst, OFS_PARM0); + const char *blobvalue = InfoBuf_BlobForKey(&svs.localinfo, key, &blobsize); + + if ((prinst->callargc<2) || G_INT(OFS_PARM1) == 0) + G_INT(OFS_RETURN) = blobsize; //no pointer to write to, just return the length. + else + { + size_t size = min(blobsize, G_INT(OFS_PARM2)); + void *ptr = PR_GetWriteQCPtr(prinst, G_INT(OFS_PARM1), size); + if (!ptr) + PR_BIError(prinst, "PF_getlocalinfo: invalid pointer/size\n"); + G_INT(OFS_RETURN) = size; + memcpy(ptr, blobvalue, size); + } +} +static void QCBUILTIN PF_setlocalinfo (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) +{ + const char *key = PR_GetStringOfs(prinst, OFS_PARM0); + const char *value; + size_t size; + if (prinst->callargc > 2) + { + size = G_INT(OFS_PARM2); + value = PR_GetReadQCPtr(prinst, G_INT(OFS_PARM1), size); + } + else + { + value = PR_GetStringOfs(prinst, OFS_PARM1); + size = strlen(value); + } + if (!value) + PR_BIError(prinst, "PF_setlocalinfo: invalid pointer/size\n"); + + InfoBuf_SetStarBlobKey(&svs.localinfo, key, value, size); +} /* ============== @@ -7384,7 +7503,7 @@ void PRH2_SetPlayerClass(client_t *cl, int classnum, qboolean fromqc) sprintf(temp,"%i",(int)classnum); else *temp = 0; - Info_SetValueForKey (cl->userinfo, "cl_playerclass", temp, sizeof(cl->userinfo)); + InfoBuf_SetKey (&cl->userinfo, "cl_playerclass", temp); if (cl->playerclass != classnum) { cl->edict->xv->playerclass = classnum; @@ -7427,7 +7546,7 @@ static void QCBUILTIN PF_h2setclass (pubprogfuncs_t *prinst, struct globalvars_s client->playerclass = NewClass; sprintf(temp,"%d",(int)NewClass); - Info_SetValueForKey (client->userinfo, "cl_playerclass", temp, sizeof(client->userinfo)); + InfoBuf_SetValueForKey (&client->userinfo, "cl_playerclass", temp); client->sendinfo = true; } @@ -9091,29 +9210,25 @@ static void QCBUILTIN PF_te_plasmaburn(pubprogfuncs_t *prinst, struct globalvars } -int PF_ForceInfoKey_Internal(unsigned int entnum, const char *key, const char *value) +int PF_ForceInfoKey_Internal(unsigned int entnum, const char *key, const char *value, size_t valsize) { if (entnum == 0) - { //localinfo - Info_SetValueForKey (localinfo, key, value, MAX_LOCALINFO_STRING); + { //serverinfo + InfoBuf_SetStarBlobKey(&svs.info, key, value, valsize); return 2; } else if (entnum <= sv.allocated_client_slots) { //woo. we found a client. - char *oldvalue; if (svs.clients[entnum-1].state == cs_free) { Con_DPrintf("PF_ForceInfoKey: inactive client\n"); return 0; } - oldvalue = Info_ValueForKey(svs.clients[entnum-1].userinfo, key); - if (strcmp(oldvalue, value)) + if (InfoBuf_SetStarBlobKey(&svs.clients[entnum-1].userinfo, key, value, valsize)) { - Info_SetValueForStarKey(svs.clients[entnum-1].userinfo, key, value, sizeof(svs.clients[entnum-1].userinfo)); - SV_ExtractFromUserinfo (&svs.clients[entnum-1], false); - value = Info_ValueForKey(svs.clients[entnum-1].userinfo, key); + value = InfoBuf_ValueForKey(&svs.clients[entnum-1].userinfo, key); if (!strcmp(key, "*spectator")) { @@ -9155,7 +9270,33 @@ static void QCBUILTIN PF_ForceInfoKey(pubprogfuncs_t *prinst, struct globalvars_ key = PR_GetStringOfs(prinst, OFS_PARM1); value = PR_GetStringOfs(prinst, OFS_PARM2); - G_FLOAT(OFS_RETURN) = PF_ForceInfoKey_Internal(e->entnum, key, value); + G_FLOAT(OFS_RETURN) = PF_ForceInfoKey_Internal(e->entnum, key, value, strlen(value)); +} +static void QCBUILTIN PF_ForceInfoKeyBlob(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) +{ + edict_t *e; + const char *value; + const char *key; + int size; + + e = G_EDICT(prinst, OFS_PARM0); + key = PR_GetStringOfs(prinst, OFS_PARM1); + value = PR_GetStringOfs(prinst, OFS_PARM2); + size = G_INT(OFS_PARM3); + if (size < 0) + size = 0; + if (G_INT(OFS_PARM2) >= 0 && G_INT(OFS_PARM2) < prinst->stringtablesize) + { + if (value+size > prinst->stringtable+prinst->stringtablesize) + return; + } + else + { + if (size > strlen(value)+1) + return; + } + + G_FLOAT(OFS_RETURN) = PF_ForceInfoKey_Internal(e->entnum, key, value, size); } /* @@ -9189,16 +9330,16 @@ static void QCBUILTIN PF_setcolors (pubprogfuncs_t *prinst, struct globalvars_s client->edict->v->team = (i & 15) + 1; Q_snprintfz(number, sizeof(number), "%i", i>>4); - if (strcmp(number, Info_ValueForKey(client->userinfo, "topcolor"))) + if (strcmp(number, InfoBuf_ValueForKey(&client->userinfo, "topcolor"))) { - Info_SetValueForKey(client->userinfo, "topcolor", number, sizeof(client->userinfo)); + InfoBuf_SetValueForKey(&client->userinfo, "topcolor", number); key = "topcolor"; } Q_snprintfz(number, sizeof(number), "%i", i&15); - if (strcmp(number, Info_ValueForKey(client->userinfo, "bottomcolor"))) + if (strcmp(number, InfoBuf_ValueForKey(&client->userinfo, "bottomcolor"))) { - Info_SetValueForKey(client->userinfo, "bottomcolor", number, sizeof(client->userinfo)); + InfoBuf_SetValueForKey(&client->userinfo, "bottomcolor", number); key = key?"*bothcolours":"bottomcolor"; } @@ -10282,6 +10423,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs {"abort", PF_Abort, 0, 0, 0, 211, D("void(optional __variant ret)", "QC execution is aborted. Parent QC functions on the stack will be skipped, effectively this forces all QC functions to 'return ret' until execution returns to the engine. If ret is ommited, it is assumed to be 0.")}, {"sleep", PF_Sleep, 0, 0, 0, 212, D("void(float sleeptime)", "Suspends the current QC execution thread for 'sleeptime' seconds.\nOther QC functions can and will be executed in the interim, including changing globals and field state (but not simultaneously).\nThe self and other globals will be restored when the thread wakes up (or set to world if they were removed since the thread started sleeping). Locals will be preserved, but will not be protected from remove calls.\nIf the engine is expecting the QC to return a value (even in the parent/root function), the value 0 shall be used instead of waiting for the qc to resume.")}, {"forceinfokey", PF_ForceInfoKey, 0, 0, 0, 213, D("void(entity player, string key, string value)", "Directly changes a user's info without pinging off the client. Also allows explicitly setting * keys, including *spectator. Does not affect the user's config or other servers.")}, + {"forceinfokeyblob",PF_ForceInfoKeyBlob,0, 0, 0, 0, D("void(entity player, string key, void *data, int size)", "Directly changes a user's info without pinging off the client. Also allows explicitly setting * keys, including *spectator. Does not affect the user's config or other servers.")}, #ifdef SVCHAT {"chat", PF_chat, 0, 0, 0, 214, "void(string filename, float starttag, entity edict)"}, //(FTE_NPCCHAT) #endif @@ -10486,8 +10628,8 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs {"drawline", PF_Fixme, 0, 0, 0, 315, D("void(float width, vector pos1, vector pos2, vector rgb, float alpha, optional float drawflag)", "Draws a 2d line between the two 2d points.")},// (EXT_CSQC) {"iscachedpic", PF_Fixme, 0, 0, 0, 316, D("float(string name)", "Checks to see if the image is currently loaded. Engines might lie, or cache between maps.")},// (EXT_CSQC) {"precache_pic", PF_Fixme, 0, 0, 0, 317, D("string(string name, optional float trywad)", "Forces the engine to load the named image. If trywad is specified, the specified name must any lack path and extension.")},// (EXT_CSQC) - {"r_uploadimage", PF_Fixme, 0, 0, 0, 0, D("void(string imagename, int width, int height, int *pixeldata)", "Updates a texture with the specified rgba data. Will be created if needed.")}, - {"r_readimage", PF_Fixme, 0, 0, 0, 0, D("int*(string filename, __out int width, __out int height)", "Reads and decodes an image from disk, providing raw pixel data. Returns __NULL__ if the image could not be read for any reason. Use memfree to free the data once you're done with it.")}, + {"r_uploadimage", PF_Fixme, 0, 0, 0, 0, D("void(string imagename, int width, int height, void *pixeldata, optional int datasize, optional int format)", "Updates a texture with the specified rgba data. Will be created if needed. If blobsize is specified then the image is decoded (eg .ktx or .dds data) instead of being raw R8G8B8A data. You'll typically want shaderforname to also generate a shader to use the texture.")}, + {"r_readimage", PF_Fixme, 0, 0, 0, 0, D("int*(string filename, __out int width, __out int height)", "Reads and decodes an image from disk, providing raw R8G8B8A pixel data. Should not be used for dds or ktx etc formats. Returns __NULL__ if the image could not be read for any reason. Use memfree to free the data once you're done with it.")}, {"drawgetimagesize",PF_Fixme, 0, 0, 0, 318, D("#define draw_getimagesize drawgetimagesize\nvector(string picname)", "Returns the dimensions of the named image. Images specified with .lmp should give the original .lmp's dimensions even if texture replacements use a different resolution.")},// (EXT_CSQC) {"freepic", PF_Fixme, 0, 0, 0, 319, D("void(string name)", "Tells the engine that the image is no longer needed. The image will appear to be new the next time its needed.")},// (EXT_CSQC) //320 @@ -10540,6 +10682,10 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs {"runstandardplayerphysics",PF_runclientphys,0,0,0, 347, D("void(entity ent)", "Perform the engine's standard player movement prediction upon the given entity using the input_* globals to describe movement.")}, {"getplayerkeyvalue", PF_Fixme,0, 0, 0, 348, D("string(float playernum, string keyname)", "Look up a player's userinfo, to discover things like their name, topcolor, bottomcolor, skin, team, *ver.\nAlso includes scoreboard info like frags, ping, pl, userid, entertime, as well as voipspeaking and voiploudness.")},// (EXT_CSQC) {"getplayerkeyfloat", PF_Fixme,0, 0, 0, 0, D("float(float playernum, string keyname, optional float assumevalue)", "Cheaper version of getplayerkeyvalue that avoids the need for so many tempstrings.")}, + {"getplayerkeyblob", PF_Fixme,0, 0, 0, 0, D("int(float playernum, string keyname, optional void *outptr, int size)", "Obtains a copy of the full data blob. Will write up to size bytes and return the actual size. Does not null terminate (but memalloc(ret+1) will, if you want to cast the buffer to a string), and the blob may contain embedded nulls. Ignores all special keys, returning only what is actually there.")}, + + {"getlocalinfo", PF_getlocalinfo,0, 0, 0, 0, D("int(string keyname, optional void *outptr, int size)", "Obtains a copy of the full data blob. Will write up to size bytes and return the actual size. Does not null terminate (but memalloc(ret+1) will, if you want to cast the buffer to a string), and the blob may contain embedded nulls. Ignores all special keys, returning only what is actually there.")}, + {"setlocalinfo", PF_setlocalinfo,0, 0, 0, 0, D("void(string keyname, optional void *outptr, int size)", "Changes the server's localinfo. This data will be available for the following map, and will *usually* reload with saved games.")}, {"isdemo", PF_Fixme, 0, 0, 0, 349, D("float()", "Returns if the client is currently playing a demo or not")},// (EXT_CSQC) {"isserver", PF_Fixme, 0, 0, 0, 350, D("float()", "Returns if the client is acting as the server (aka: listen server)")},//(EXT_CSQC) @@ -10549,6 +10695,8 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs {"wasfreed", PF_WasFreed,0, 0, 0, 353, D("float(entity ent)", "Quickly check to see if the entity is currently free. This function is only valid during the two-second non-reuse window, after that it may give bad results. Try one second to make it more robust.")},//(EXT_CSQC) (should be availabe on server too) {"serverkey", PF_sv_serverkeystring,0,0, 0, 354, D("string(string key)", "Look up a key in the server's public serverinfo string")},// {"serverkeyfloat", PF_sv_serverkeyfloat,0,0, 0, 0, D("float(string key, optional float assumevalue)", "Version of serverkey that returns the value as a float (which avoids tempstrings).")},// + {"serverkeyblob", PF_sv_serverkeyblob,0,0, 0, 0, D("int(int buf, string key, optional void *ptr, int size)", "Version of serverkey that can obtain entire serverinfo, localinfo, or (local)userinfo blobs. Returns blob size")},// + {"setserverkey", PF_setserverkey,0, 0, 0, 0, D("void(int buf, string key, void *ptr, optional int size)", "Changes the server's serverinfo.")},// {"getentitytoken", PF_Fixme, 0, 0, 0, 355, D("string(optional string resetstring)", "Grab the next token in the map's entity lump.\nIf resetstring is not specified, the next token will be returned with no other sideeffects.\nIf empty, will reset from the map before returning the first token, probably {.\nIf not empty, will tokenize from that string instead.\nAlways returns tempstrings.")},//; {"findfont", PF_Fixme, 0, 0, 0, 356, D("float(string s)", "Looks up a named font slot. Matches the actual font name as a last resort.")},//; {"loadfont", PF_Fixme, 0, 0, 0, 357, D("float(string fontname, string fontmaps, string sizes, float slot, optional float fix_scale, optional float fix_voffset)", "too convoluted for me to even try to explain correct usage. Try drawfont = loadfont(\"\", \"cour\", \"16\", -1, 0, 0); to switch to the courier font (optimised for 16 virtual pixels high), if you have the freetype2 library in windows..")}, @@ -10869,6 +11017,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs {"crypto_getmyidfp",PF_Fixme, 0, 0, 0, 637, "string(float addr)" STUB}, // {"VM_CL_RotateMoves",PF_Fixme, 0, 0, 0, 638, ""}, {"digest_hex", PF_digest_hex, 0, 0, 0, 639, "string(string digest, string data, ...)"}, + {"digest_ptr", PF_digest_ptr, 0, 0, 0, 0, D("string(string digest, void *data, int length)", "Calculates the digest of a single contiguous block of memory (including nulls) using the specified hash function.")}, // {"V_CalcRefdef", PF_Fixme, 0, 0, 0, 640, "void(entity e)"}, {"crypto_getmyidstatus",PF_Fixme, 0, 0, 0, 641, "float(float i)" STUB}, @@ -11075,7 +11224,7 @@ void PR_ResetBuiltins(progstype_t type) //fix all nulls to PF_FIXME and add any { char *builtinmap; int binum; - builtinmap = COM_LoadTempFile("fte_bimap.txt", NULL); + builtinmap = COM_LoadTempFile("fte_bimap.txt", 0, NULL); while(1) { builtinmap = COM_Parse(builtinmap); diff --git a/engine/server/pr_lua.c b/engine/server/pr_lua.c index 7d78deefb..5f84603bd 100644 --- a/engine/server/pr_lua.c +++ b/engine/server/pr_lua.c @@ -1100,7 +1100,7 @@ static int bi_lua_setinfokey(lua_State *L) key = lua_tolstring(L, 2, NULL); value = lua_tolstring(L, 3, NULL); - result = PF_ForceInfoKey_Internal(entnum, key, value); + result = PF_ForceInfoKey_Internal(entnum, key, value, strlen(value)); lua_pushinteger(L, result); return 1; } diff --git a/engine/server/pr_q1qvm.c b/engine/server/pr_q1qvm.c index b90854bf6..efa90f386 100755 --- a/engine/server/pr_q1qvm.c +++ b/engine/server/pr_q1qvm.c @@ -1532,11 +1532,11 @@ static qintptr_t QVM_Add_Bot (void *offset, quintptr_t mask, const qintptr_t *ar cl->edict = EDICT_NUM_PB(sv.world.progs, i+1); - Info_SetValueForKey(cl->userinfo, "name", name, sizeof(cl->userinfo)); - Info_SetValueForKey(cl->userinfo, "topcolor", va("%i", top), sizeof(cl->userinfo)); - Info_SetValueForKey(cl->userinfo, "bottomcolor", va("%i", bottom), sizeof(cl->userinfo)); - Info_SetValueForKey(cl->userinfo, "skin", skin, sizeof(cl->userinfo)); - Info_SetValueForStarKey(cl->userinfo, "*bot", "1", sizeof(cl->userinfo)); + InfoBuf_SetKey(&cl->userinfo, "name", name); + InfoBuf_SetKey(&cl->userinfo, "topcolor", va("%i", top)); + InfoBuf_SetKey(&cl->userinfo, "bottomcolor", va("%i", bottom)); + InfoBuf_SetKey(&cl->userinfo, "skin", skin); + InfoBuf_SetStarKey(&cl->userinfo, "*bot", "1"); SV_ExtractFromUserinfo(cl, true); SV_SetUpClientEdict (cl, cl->edict); @@ -1598,14 +1598,20 @@ static qintptr_t QVM_SetBotCMD (void *offset, quintptr_t mask, const qintptr_t * } static qintptr_t QVM_SetUserInfo (void *offset, quintptr_t mask, const qintptr_t *arg) { - char *key = VM_POINTER(arg[1]); + int ent = VM_LONG(arg[0]); + const char *key = VM_POINTER(arg[1]); + const char *val = VM_POINTER(arg[2]); if (*key == '*' && (VM_LONG(arg[3])&1)) return -1; //denied! - return PF_ForceInfoKey_Internal(VM_LONG(arg[0]), VM_POINTER(arg[1]), VM_POINTER(arg[2])); + return PF_ForceInfoKey_Internal(ent, key, val, strlen(val)); } static qintptr_t QVM_SetBotUserInfo (void *offset, quintptr_t mask, const qintptr_t *arg) { - return PF_ForceInfoKey_Internal(VM_LONG(arg[0]), VM_POINTER(arg[1]), VM_POINTER(arg[2])); + int ent = VM_LONG(arg[0]); + const char *key = VM_POINTER(arg[1]); + const char *val = VM_POINTER(arg[2]); + + return PF_ForceInfoKey_Internal(ent, key, val, strlen(val)); } static qintptr_t QVM_MoveToGoal (void *offset, quintptr_t mask, const qintptr_t *arg) { @@ -2509,7 +2515,7 @@ qboolean Q1QVM_ClientSay(edict_t *player, qboolean team) } qboolean Q1QVM_UserInfoChanged(edict_t *player) -{ +{ //mod will use G_CMD_ARGV to get argv1+argv2 to read the info that is changing. if (!q1qvm) return false; diff --git a/engine/server/savegame.c b/engine/server/savegame.c index 72eb2f8ca..3cd562b40 100644 --- a/engine/server/savegame.c +++ b/engine/server/savegame.c @@ -1207,7 +1207,6 @@ void SV_Savegame (const char *savename, qboolean mapchange) vfsfile_t *f; int len; levelcache_t *cache; - char str[MAX_LOCALINFO_STRING+1]; char *savefilename; #ifndef QUAKETC @@ -1291,13 +1290,9 @@ void SV_Savegame (const char *savename, qboolean mapchange) //write floats too so you can use it to debug. } - Q_strncpyz(str, svs.info, sizeof(str)); - Info_RemovePrefixedKeys(str, '*'); - VFS_PRINTF (f, "%s\n", str); - - Q_strncpyz(str, localinfo, sizeof(str)); - Info_RemovePrefixedKeys(str, '*'); - VFS_PUTS(f, str); + InfoBuf_WriteToFile(f, &svs.info, NULL, 0); + VFS_PUTS(f, "\n"); + InfoBuf_WriteToFile(f, &svs.localinfo, NULL, 0); VFS_PRINTF (f, "\n{\n"); //all game vars. FIXME: Should save the ones that have been retrieved/set by progs. VFS_PRINTF (f, "skill \"%s\"\n", skill.string); @@ -1703,9 +1698,8 @@ void SV_Loadgame_f (void) for (trim = str; *trim <= ' ' && *trim; trim++) ; Info_RemovePrefixedKeys(str, '*'); //just in case - Info_RemoveNonStarKeys(svs.info); - len = strlen(svs.info); - Q_strncpyz(svs.info+len, str, sizeof(svs.info)-len); + InfoBuf_Clear(&svs.info, false); + InfoBuf_FromString(&svs.info, str, true); VFS_GETS(f, str, sizeof(str)-1); for (trim = str+strlen(str)-1; trim>=str && *trim <= ' '; trim--) @@ -1713,9 +1707,8 @@ void SV_Loadgame_f (void) for (trim = str; *trim <= ' ' && *trim; trim++) ; Info_RemovePrefixedKeys(str, '*'); //just in case - Info_RemoveNonStarKeys(localinfo); - len = strlen(localinfo); - Q_strncpyz(localinfo+len, str, sizeof(localinfo)-len); + InfoBuf_Clear(&svs.localinfo, false); + InfoBuf_FromString(&svs.localinfo, str, true); VFS_GETS(f, str, sizeof(str)-1); for (trim = str+strlen(str)-1; trim>=str && *trim <= ' '; trim--) diff --git a/engine/server/server.h b/engine/server/server.h index b20eb9507..8a7d50909 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -458,9 +458,10 @@ typedef struct client_s qboolean drop; // lose this guy next opportunity int lossage; // loss percentage - int challenge; - int userid; // identifying number - char userinfo[EXTENDED_INFO_STRING]; // infostring + int challenge; + int userid; // identifying number + infobuf_t userinfo; // all of the user's various settings + infosync_t infosync; // information about the infos that the client still doesn't know (server and multiple clients). char *transfer; usercmd_t lastcmd; // for filling in big drops and partial predictions @@ -908,7 +909,8 @@ typedef struct int heartbeat_sequence; svstats_t stats; - char info[MAX_SERVERINFO_STRING]; + infobuf_t info; + infobuf_t localinfo; // log messages are used so that fraglog processes can get stats int logsequence; // the message currently being filled @@ -1069,8 +1071,6 @@ extern edict_t *sv_player; //extern char localmodels[MAX_MODELS][5]; // inline model names for precache -extern char localinfo[MAX_LOCALINFO_STRING+1]; - extern vfsfile_t *sv_fraglogfile; //=========================================================== @@ -1123,7 +1123,6 @@ void SV_ArgumentOverrides(void); int SV_CalcPing (client_t *cl, qboolean forcecalc); void SV_FullClientUpdate (client_t *client, client_t *to); -void SV_GeneratePublicUserInfo(int pext, client_t *cl, char *info, int infolength); char *SV_PlayerPublicAddress(client_t *cl); qboolean SVC_GetChallenge (qboolean respond_dp); @@ -1273,7 +1272,6 @@ void VARGS SV_ClientTPrintf (client_t *cl, int level, translation_t text, ...); void VARGS SV_BroadcastPrintf (int level, const char *fmt, ...) LIKEPRINTF(2); void VARGS SV_BroadcastTPrintf (int level, translation_t fmt, ...); void VARGS SV_BroadcastCommand (const char *fmt, ...) LIKEPRINTF(1); -void SV_SendServerInfoChange(const char *key, const char *value); void SV_SendMessagesToAll (void); void SV_FindModelNumbers (void); diff --git a/engine/server/sv_ccmds.c b/engine/server/sv_ccmds.c index dbe7105e0..369f0a88e 100644 --- a/engine/server/sv_ccmds.c +++ b/engine/server/sv_ccmds.c @@ -579,7 +579,7 @@ void SV_Map_f (void) if (!startspot) { //revert the startspot if its not overridden - Q_strncpyz(spot, Info_ValueForKey(svs.info, "*startspot"), sizeof(spot)); + Q_strncpyz(spot, InfoBuf_ValueForKey(&svs.info, "*startspot"), sizeof(spot)); startspot = spot; } } @@ -664,7 +664,7 @@ void SV_Map_f (void) if (!isDedicated) //otherwise, info used on map loading isn't present { cl.haveserverinfo = true; - Q_strncpyz (cl.serverinfo, svs.info, sizeof(cl.serverinfo)); + InfoBuf_Clone(&cl.serverinfo, &svs.info); CL_CheckServerInfo(); } @@ -1100,9 +1100,9 @@ void SV_EvaluatePenalties(client_t *cl) } if (delta & BAN_VIP) - Info_SetValueForStarKey(cl->userinfo, "*VIP", (cl->penalties & BAN_VIP)?"1":"", sizeof(cl->userinfo)); + InfoBuf_SetStarKey(&cl->userinfo, "*VIP", (cl->penalties & BAN_VIP)?"1":""); if (delta & BAN_MAPPER) - Info_SetValueForStarKey(cl->userinfo, "*mapper", (cl->penalties & BAN_MAPPER)?"1":"", sizeof(cl->userinfo)); + InfoBuf_SetStarKey(&cl->userinfo, "*mapper", (cl->penalties & BAN_MAPPER)?"1":""); } static time_t reevaluatebantime; @@ -1623,7 +1623,7 @@ static void SV_ForceName_f (void) while((cl = SV_GetClientForString(Cmd_Argv(1), &clnum))) { - Info_SetValueForKey(cl->userinfo, "name", Cmd_Argv(2), EXTENDED_INFO_STRING); + InfoBuf_SetKey(&cl->userinfo, "name", Cmd_Argv(2)); SV_LogPlayer(cl, "name forced"); SV_ExtractFromUserinfo(cl, true); Q_strncpyz(cl->name, Cmd_Argv(2), sizeof(cl->namebuf)); @@ -2192,51 +2192,6 @@ static void SV_Heartbeat_f (void) SV_Master_ReResolve(); } -#define FOREACHCLIENT(i,cl) \ -for (i = sv.mvdrecording?-1:0; i < sv.allocated_client_slots; i++) \ -if ((cl = (i==-1?&demo.recorder:&svs.clients[i]))) \ -if ((i == -1) || cl->state >= cs_connected) - -void SV_SendServerInfoChange(const char *key, const char *value) -{ - int i; - client_t *cl; - - if (!sv.state) - return; - -#ifdef Q2SERVER - if (svs.gametype == GT_QUAKE2) - return; //FIXME!!! -#endif -#ifdef Q3SERVER - if (svs.gametype == GT_QUAKE3) - return; //FIXME!!! -#endif - - FOREACHCLIENT(i, cl) - { - if (cl->controller) - continue; - - if (ISQWCLIENT(cl)) - { - ClientReliableWrite_Begin(cl, svc_serverinfo, strlen(key) + strlen(value)+3); - ClientReliableWrite_String(cl, key); - ClientReliableWrite_String(cl, value); - } - else if (ISNQCLIENT(cl) && (cl->fteprotocolextensions2 & PEXT2_PREDINFO)) - { - ClientReliableWrite_Begin(cl, svc_stufftext, 1+6+strlen(key)+2+strlen(value)+3); - ClientReliableWrite_SZ(cl, "//svi ", 6); - ClientReliableWrite_SZ(cl, key, strlen(key)); - ClientReliableWrite_SZ(cl, " \"", 2); - ClientReliableWrite_SZ(cl, value, strlen(value)); - ClientReliableWrite_String(cl, "\"\n"); - } - } -} - /* =========== SV_Serverinfo_f @@ -2253,7 +2208,7 @@ void SV_Serverinfo_f (void) if (Cmd_Argc() == 1) { Con_TPrintf ("Server info settings:\n"); - Info_Print (svs.info, ""); + InfoBuf_Print (&svs.info, ""); return; } @@ -2268,18 +2223,18 @@ void SV_Serverinfo_f (void) if (!strcmp(Cmd_Argv(1), "*")) if (!strcmp(Cmd_Argv(2), "")) { //clear it out - char *k; + const char *k; for(i=0;;) { - k = Info_KeyForNumber(svs.info, i); - if (!*k) + k = InfoBuf_KeyForNumber(&svs.info, i); + if (!k) break; //no more. else if (*k == '*') i++; //can't remove * keys else if ((var = Cvar_FindVar(k)) && var->flags&CVAR_SERVERINFO) i++; //this one is a cvar. else - Info_RemoveKey(svs.info, k); //we can remove this one though, so yay. + InfoBuf_RemoveKey(&svs.info, k); //we can remove this one though, so yay. } return; @@ -2287,15 +2242,34 @@ void SV_Serverinfo_f (void) Con_Printf ("Can't set * keys\n"); return; } - Q_strncpyz(value, Cmd_Argv(2), sizeof(value)); - value[sizeof(value)-1] = '\0'; - for (i = 3; i < Cmd_Argc(); i++) - { - strncat(value, " ", sizeof(value)-1); - strncat(value, Cmd_Argv(i), sizeof(value)-1); - } - Info_SetValueForKey (svs.info, Cmd_Argv(1), value, MAX_SERVERINFO_STRING); + if (!strcmp(Cmd_Argv(0), "serverinfoblob")) + { + qofs_t fsize; + char *data = FS_MallocFile(Cmd_Argv(2), FS_GAME, &fsize); + if (!data) + { + Con_Printf ("Unable to read %s\n", Cmd_Argv(2)); + return; + } + if (fsize > 64*1024*1024) + Con_Printf ("File is over 64mb\n"); + else + InfoBuf_SetStarBlobKey(&svs.info, Cmd_Argv(1), data, fsize); + FS_FreeFile(data); + } + else + { + Q_strncpyz(value, Cmd_Argv(2), sizeof(value)); + value[sizeof(value)-1] = '\0'; + for (i = 3; i < Cmd_Argc(); i++) + { + strncat(value, " ", sizeof(value)-1); + strncat(value, Cmd_Argv(i), sizeof(value)-1); + } + + InfoBuf_SetValueForKey (&svs.info, Cmd_Argv(1), value); + } // if this is a cvar, change it too var = Cvar_FindVar (Cmd_Argv(1)); @@ -2306,8 +2280,6 @@ void SV_Serverinfo_f (void) var->string = Z_StrDup (value); var->value = Q_atof (var->string); */ } - - SV_SendServerInfoChange(Cmd_Argv(1), value); } @@ -2325,7 +2297,7 @@ static void SV_Localinfo_f (void) if (Cmd_Argc() == 1) { Con_TPrintf ("Local info settings:\n"); - Info_Print (localinfo, ""); + InfoBuf_Print (&svs.localinfo, ""); return; } @@ -2340,14 +2312,14 @@ static void SV_Localinfo_f (void) if (!strcmp(Cmd_Argv(1), "*")) if (!strcmp(Cmd_Argv(2), "")) { //clear it out - Info_RemoveNonStarKeys(localinfo); + InfoBuf_Clear(&svs.localinfo, false); return; } Con_Printf ("Can't set * keys\n"); return; } - old = Info_ValueForKey(localinfo, Cmd_Argv(1)); - Info_SetValueForKey (localinfo, Cmd_Argv(1), Cmd_Argv(2), MAX_LOCALINFO_STRING); + old = InfoBuf_ValueForKey(&svs.localinfo, Cmd_Argv(1)); + InfoBuf_SetValueForKey (&svs.localinfo, Cmd_Argv(1), Cmd_Argv(2)); PR_LocalInfoChanged(Cmd_Argv(1), old, Cmd_Argv(2)); @@ -2358,10 +2330,10 @@ void SV_SaveInfos(vfsfile_t *f) { VFS_WRITE(f, "\n", 1); VFS_WRITE(f, "serverinfo * \"\"\n", 16); - Info_WriteToFile(f, svs.info, "serverinfo", CVAR_SERVERINFO); + InfoBuf_WriteToFile(f, &svs.info, "serverinfo", CVAR_SERVERINFO); VFS_WRITE(f, "\n", 1); VFS_WRITE(f, "localinfo * \"\"\n", 15); - Info_WriteToFile(f, localinfo, "localinfo", 0); + InfoBuf_WriteToFile(f, &svs.localinfo, "localinfo", 0); } /* @@ -2390,7 +2362,7 @@ void SV_User_f (void) "fatness", "hlbsp", "bullet", "hullsize", "modeldbl", "entitydbl", "entitydbl2", "floatcoords", "OLD vweap", "q2bsp", "q3bsp", "colormod", "splitscreen", "hexen2", "spawnstatic2", "customtempeffects", "packents", "UNKNOWN", "showpic", "setattachment","UNKNOWN", "chunkeddls", "csqc", "dpflags"}; - static const char *pext2names[32] = { "prydoncursor", "voip", "setangledelta", "rplcdeltas", "maxplayers", "predinfo", "sizeenc", "UNKNOWN", + static const char *pext2names[32] = { "prydoncursor", "voip", "setangledelta", "rplcdeltas", "maxplayers", "predinfo", "sizeenc", "infoblobs", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN"}; @@ -2405,14 +2377,17 @@ void SV_User_f (void) Con_Printf("Userinfo:\n"); while((cl = SV_GetClientForString(Cmd_Argv(1), &clnum))) { - Info_Print (cl->userinfo, " "); + InfoBuf_Print (&cl->userinfo, " "); switch(cl->protocol) { case SCP_BAD: Con_Printf("protocol: bot/invalid\n"); break; - case SCP_QUAKEWORLD: - Con_Printf("protocol: quakeworld\n"); + case SCP_QUAKEWORLD: //branding is everything... + if (cl->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) + Con_Printf("protocol: fteqw-nack\n"); + else + Con_Printf("protocol: quakeworld\n"); break; case SCP_QUAKE2: Con_Printf("protocol: quake2\n"); @@ -2421,13 +2396,19 @@ void SV_User_f (void) Con_Printf("protocol: quake3\n"); break; case SCP_NETQUAKE: - Con_Printf("protocol: (net)quake\n"); + if (cl->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) + Con_Printf("protocol: ftenq-nack\n"); + else + Con_Printf("protocol: (net)quake\n"); break; case SCP_BJP3: Con_Printf("protocol: bjp3\n"); break; case SCP_FITZ666: - Con_Printf("protocol: fitzquake 666\n"); + if (cl->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) + Con_Printf("protocol: fte666-nack\n"); + else + Con_Printf("protocol: fitzquake 666\n"); break; case SCP_DARKPLACES6: Con_Printf("protocol: dpp6\n"); @@ -2442,9 +2423,12 @@ void SV_User_f (void) if (cl->fteprotocolextensions) { + unsigned int effective = cl->fteprotocolextensions; + if (cl->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) //these flags were made obsolete. don't list them. + effective &= ~(PEXT_SCALE|PEXT_TRANS|PEXT_ACCURATETIMINGS|PEXT_FATNESS|PEXT_HULLSIZE|PEXT_MODELDBL|PEXT_ENTITYDBL|PEXT_ENTITYDBL2|PEXT_COLOURMOD|PEXT_SPAWNSTATIC2|PEXT_SETATTACHMENT|PEXT_DPFLAGS); Con_Printf("pext1:"); for (u = 0; u < 32; u++) - if (cl->fteprotocolextensions & (1u<fromgame == fg_doom) - Info_SetValueForStarKey(svs.info, "*bspversion", "1", MAX_SERVERINFO_STRING); + InfoBuf_SetStarKey(&svs.info, "*bspversion", "1"); else if (sv.world.worldmodel->fromgame == fg_halflife) - Info_SetValueForStarKey(svs.info, "*bspversion", "30", MAX_SERVERINFO_STRING); + InfoBuf_SetStarKey(&svs.info, "*bspversion", "30"); else if (sv.world.worldmodel->fromgame == fg_quake2) - Info_SetValueForStarKey(svs.info, "*bspversion", "38", MAX_SERVERINFO_STRING); + InfoBuf_SetStarKey(&svs.info, "*bspversion", "38"); else if (sv.world.worldmodel->fromgame == fg_quake3) - Info_SetValueForStarKey(svs.info, "*bspversion", "46", MAX_SERVERINFO_STRING); + InfoBuf_SetStarKey(&svs.info, "*bspversion", "46"); else - Info_SetValueForStarKey(svs.info, "*bspversion", "", MAX_SERVERINFO_STRING); - Info_SetValueForStarKey(svs.info, "*startspot", (startspot?startspot:""), MAX_SERVERINFO_STRING); + InfoBuf_SetStarKey(&svs.info, "*bspversion", ""); + InfoBuf_SetStarKey(&svs.info, "*startspot", (startspot?startspot:"")); // // init physics interaction links @@ -1049,7 +1057,7 @@ void SV_SpawnServer (const char *server, const char *startspot, qboolean noents, #ifdef PEXT_CSQC fsz = 0; if (*sv_csqc_progname.string) - file = COM_LoadTempFile(sv_csqc_progname.string, &fsz); + file = COM_LoadTempFile(sv_csqc_progname.string, 0, &fsz); else file = NULL; if (file) @@ -1057,27 +1065,27 @@ void SV_SpawnServer (const char *server, const char *startspot, qboolean noents, char text[64]; sv.csqcchecksum = Com_BlockChecksum(file, fsz); sprintf(text, "0x%x", sv.csqcchecksum); - Info_SetValueForStarKey(svs.info, "*csprogs", text, MAX_SERVERINFO_STRING); + InfoBuf_SetValueForStarKey(&svs.info, "*csprogs", text); sprintf(text, "0x%x", (unsigned int)fsz); - Info_SetValueForStarKey(svs.info, "*csprogssize", text, MAX_SERVERINFO_STRING); + InfoBuf_SetValueForStarKey(&svs.info, "*csprogssize", text); if (strcmp(sv_csqc_progname.string, "csprogs.dat")) - Info_SetValueForStarKey(svs.info, "*csprogsname", sv_csqc_progname.string, MAX_SERVERINFO_STRING); + InfoBuf_SetValueForStarKey(&svs.info, "*csprogsname", sv_csqc_progname.string); else - Info_SetValueForStarKey(svs.info, "*csprogsname", "", MAX_SERVERINFO_STRING); + InfoBuf_SetValueForStarKey(&svs.info, "*csprogsname", ""); } else { sv.csqcchecksum = 0; - Info_SetValueForStarKey(svs.info, "*csprogs", "", MAX_SERVERINFO_STRING); - Info_SetValueForStarKey(svs.info, "*csprogssize", "", MAX_SERVERINFO_STRING); - Info_SetValueForStarKey(svs.info, "*csprogsname", "", MAX_SERVERINFO_STRING); + InfoBuf_SetValueForStarKey(&svs.info, "*csprogs", ""); + InfoBuf_SetValueForStarKey(&svs.info, "*csprogssize", ""); + InfoBuf_SetValueForStarKey(&svs.info, "*csprogsname", ""); } sv.csqcdebug = sv_csqcdebug.value; if (sv.csqcdebug) - Info_SetValueForStarKey(svs.info, "*csqcdebug", "1", MAX_SERVERINFO_STRING); + InfoBuf_SetValueForStarKey(&svs.info, "*csqcdebug", "1"); else - Info_RemoveKey(svs.info, "*csqcdebug"); + InfoBuf_RemoveKey(&svs.info, "*csqcdebug"); #endif if (svs.gametype == GT_PROGS) @@ -1272,6 +1280,7 @@ void SV_SpawnServer (const char *server, const char *startspot, qboolean noents, svs.clients[i].edict = NULL; svs.clients[i].name = svs.clients[i].namebuf; svs.clients[i].team = svs.clients[i].teambuf; + InfoSync_Clear(&svs.clients[i].infosync); //we'll mark all the info as dirty at some point while connecting. } switch (svs.gametype) @@ -1368,8 +1377,8 @@ void SV_SpawnServer (const char *server, const char *startspot, qboolean noents, for (i=0 ; ientitiescrc); - Info_SetValueForStarKey(svs.info, "*entfile", crc, MAX_SERVERINFO_STRING); + InfoBuf_SetValueForStarKey(&svs.info, "*entfile", crc); } else - Info_SetValueForStarKey(svs.info, "*entfile", "", MAX_SERVERINFO_STRING); + InfoBuf_SetValueForStarKey(&svs.info, "*entfile", ""); file = Mod_GetEntitiesString(sv.world.worldmodel); if (!file) @@ -1599,7 +1608,7 @@ void SV_SpawnServer (const char *server, const char *startspot, qboolean noents, SV_GibFilterInit(); SV_FilterImpulseInit(); - Info_SetValueForKey (svs.info, "map", svs.name, MAX_SERVERINFO_STRING); + InfoBuf_SetValueForKey (&svs.info, "map", svs.name); if (sv.allocated_client_slots != 1) Con_TPrintf ("Server spawned.\n"); //misc filenotfounds can be misleading. diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index 306f38d94..09afc21ee 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -271,6 +271,10 @@ void SV_Shutdown (void) Cmd_Shutdown(); PM_Shutdown(); + + InfoBuf_Clear(&svs.info, true); + InfoBuf_Clear(&svs.localinfo, true); + #ifdef WEBSERVER IWebShutdown(); #endif @@ -643,7 +647,8 @@ void SV_DropClient (client_t *drop) #endif drop->namebuf[0] = 0; drop->name = drop->namebuf; - memset (drop->userinfo, 0, sizeof(drop->userinfo)); + InfoBuf_Clear(&drop->userinfo, true); + InfoSync_Clear(&drop->infosync); while ((lp = drop->laggedpacket)) { @@ -943,39 +948,6 @@ int SV_CalcPing (client_t *cl, qboolean forcecalc) return 0; } -//generate whatever public userinfo is supported by the client. -//private keys like _ prefixes and the password key are stripped out here. -//password needs to be stripped in case the password key doesn't actually relate to this server. -void SV_GeneratePublicUserInfo(int pext, client_t *cl, char *info, int infolength) -{ - char *key, *s; - int i; - - //FIXME: we should probably use some sort of priority system instead if I'm honest about it - if (pext & PEXT_BIGUSERINFOS) - Q_strncpyz (info, cl->userinfo, infolength); - else - { - if (infolength >= BASIC_INFO_STRING) - infolength = BASIC_INFO_STRING; - *info = 0; - for (i = 0; (key = Info_KeyForNumber(cl->userinfo, i)); i++) - { - if (!*key) - break; - if (!SV_UserInfoIsBasic(key)) - continue; - - s = Info_ValueForKey(cl->userinfo, key); - Info_SetValueForStarKey (info, key, s, infolength); - } - } - - Info_RemovePrefixedKeys (info, '_'); // server passwords, etc - Info_RemoveKey(info, "password"); - Info_RemoveKey(info, "*ip"); -} - /* =================== SV_FullClientUpdate @@ -1011,6 +983,7 @@ void SV_FullClientUpdate (client_t *client, client_t *to) if (ISQWCLIENT(to)) { + unsigned int pext = to->fteprotocolextensions; int ping = SV_CalcPing (client, false); if (ping > 0xffff) ping = 0xffff; @@ -1031,8 +1004,7 @@ void SV_FullClientUpdate (client_t *client, client_t *to) ClientReliableWrite_Byte (to, i); ClientReliableWrite_Float (to, realtime - client->connection_started); - SV_GeneratePublicUserInfo(to->fteprotocolextensions, client, info, sizeof(info)); - + InfoBuf_ToString(&client->userinfo, info, (pext&PEXT_BIGUSERINFOS)?BASIC_INFO_STRING:sizeof(info), basicuserinfos, privateuserinfos, (pext&PEXT_BIGUSERINFOS)?NULL:basicuserinfos, NULL, NULL); ClientReliableWrite_Begin(to, svc_updateuserinfo, 7 + strlen(info)); ClientReliableWrite_Byte (to, i); ClientReliableWrite_Long (to, client->userid); @@ -1041,7 +1013,7 @@ void SV_FullClientUpdate (client_t *client, client_t *to) else if (ISNQCLIENT(to)) { int top, bottom, playercolor; - char *nam = Info_ValueForKey(client->userinfo, "name"); + char *nam = InfoBuf_ValueForKey(&client->userinfo, "name"); ClientReliableWrite_Begin(to, svc_updatefrags, 4); ClientReliableWrite_Byte (to, i); @@ -1051,8 +1023,8 @@ void SV_FullClientUpdate (client_t *client, client_t *to) ClientReliableWrite_Byte (to, i); ClientReliableWrite_String(to, nam); - top = atoi(Info_ValueForKey(client->userinfo, "topcolor")); - bottom = atoi(Info_ValueForKey(client->userinfo, "bottomcolor")); + top = atoi(InfoBuf_ValueForKey(&client->userinfo, "topcolor")); + bottom = atoi(InfoBuf_ValueForKey(&client->userinfo, "bottomcolor")); top &= 15; if (top > 13) top = 13; @@ -1067,8 +1039,9 @@ void SV_FullClientUpdate (client_t *client, client_t *to) if (to->fteprotocolextensions2 & PEXT2_PREDINFO) { - char quotedval[8192]; - char *s = va("//fui %i %s\n", i, COM_QuotedString(client->userinfo, quotedval, sizeof(quotedval), false)); + char *s; + InfoBuf_ToString(&client->userinfo, info, sizeof(info), basicuserinfos, privateuserinfos, NULL, NULL, NULL); + s = va("//fui %i \"%s\"\n", i, info); ClientReliableWrite_Begin(to, svc_stufftext, 2+strlen(s)); ClientReliableWrite_String(to, s); } @@ -1124,21 +1097,27 @@ static void SVC_Status (void) Cmd_TokenizeString ("status", false, false); SV_BeginRedirect (RD_PACKET, TL_FindLanguage("")); if (displayflags&STATUS_SERVERINFO) - Con_Printf ("%s\n", svs.info); + { + char infostr[1024]; //FIXME: vanilla limit is 512. we should probably have a list of known cvars for lower priority sending. + const char *ignorekeys[] = {"mapname", "*z_ext", NULL}; //ignore some pointless stuff + const char *prioritykeys[] = {"hostname", "admin", "*gamedir", "*version", "deathmatch", "timelimit", "fraglimit", "maxclients", "maxspectators", "status", NULL}; //make sure we include these before we start overflowing + InfoBuf_ToString(&svs.info, infostr, sizeof(infostr), prioritykeys, ignorekeys, NULL, NULL, NULL); + Con_Printf ("%s\n", infostr); + } for (i=0 ; istate == cs_connected || cl->state == cs_spawned || cl->name[0]) && ((cl->spectator && displayflags&STATUS_SPECTATORS) || (!cl->spectator && displayflags&STATUS_PLAYERS))) { - top = atoi(Info_ValueForKey (cl->userinfo, "topcolor")); - bottom = atoi(Info_ValueForKey (cl->userinfo, "bottomcolor")); + top = atoi(InfoBuf_ValueForKey (&cl->userinfo, "topcolor")); + bottom = atoi(InfoBuf_ValueForKey (&cl->userinfo, "bottomcolor")); top = (top < 0) ? 0 : ((top > 13) ? 13 : top); bottom = (bottom < 0) ? 0 : ((bottom > 13) ? 13 : bottom); ping = SV_CalcPing (cl, false); name = cl->name; - skin = Info_ValueForKey (cl->userinfo, "skin"); - team = Info_ValueForKey (cl->userinfo, "team"); + skin = InfoBuf_ValueForKey (&cl->userinfo, "skin"); + team = InfoBuf_ValueForKey (&cl->userinfo, "team"); if (!cl->state || cl->protocol == SCP_BAD) //show bots differently. Just to be courteous. botpre = "BOT:"; @@ -1235,26 +1214,31 @@ static void SVC_GetInfo (char *challenge, int fullstatus) resp += strlen(resp); *resp++ = '\n'; - //first line is the serverinfo - Q_strncpyz(resp, svs.info, sizeof(response) - (resp-response)); - //this is a DP protocol query, so some QW fields are not needed - Info_RemoveKey(resp, "maxclients"); //replaced with sv_maxclients - Info_RemoveKey(resp, "map"); //replaced with mapname - Info_RemoveKey(resp, "*gamedir"); //replaced with modname - Info_RemoveKey(resp, "*z_ext"); //uninteresting and spammy. - Info_SetValueForKey(resp, "gamename", protocolname, sizeof(response) - (resp-response)); - Info_SetValueForKey(resp, "modname", FS_GetGamedir(true), sizeof(response) - (resp-response)); -// Info_SetValueForKey(resp, "gamedir", FS_GetGamedir(true), sizeof(response) - (resp-response)); - Info_SetValueForKey(resp, "protocol", va("%d", com_protocolversion.ival), sizeof(response) - (resp-response)); - Info_SetValueForKey(resp, "clients", va("%d", numclients), sizeof(response) - (resp-response)); - Info_SetValueForKey(resp, "sv_maxclients", maxclients.string, sizeof(response) - (resp-response)); - Info_SetValueForKey(resp, "mapname", Info_ValueForKey(svs.info, "map"), sizeof(response) - (resp-response)); - if (*gamestatus) - Info_SetValueForKey(resp, "qcstatus", gamestatus, sizeof(response) - (resp-response)); - Info_SetValueForKey(resp, "challenge", challenge, sizeof(response) - (resp-response)); - resp += strlen(resp); + //first line contains the serverinfo, or some form of it + { + const char *ignorekeys[] = { + "maxclients", "map", "*gamedir", "*z_ext", //this is a DP protocol query, so some QW fields are not needed + "gamename", "modname", "protocol", "clients", "sv_maxclients", "mapname", "qcstatus", "challenge", NULL}; //and we need to add some + const char *prioritykeys[] = {"hostname", NULL}; //make sure we include these before we start overflowing - *resp++ = 0; //there's already a null, but hey + *resp = 0; + Info_SetValueForKey(resp, "challenge", challenge, sizeof(response) - (resp-response)); //the challenge can be important for the master protocol to prevent poisoning + Info_SetValueForKey(resp, "gamename", protocolname, sizeof(response) - (resp-response));//distinguishes it from other types of games + Info_SetValueForKey(resp, "protocol", com_protocolversion.string, sizeof(response) - (resp-response)); //should be an int. + Info_SetValueForKey(resp, "modname", FS_GetGamedir(true), sizeof(response) - (resp-response)); + Info_SetValueForKey(resp, "clients", va("%d", numclients), sizeof(response) - (resp-response)); + Info_SetValueForKey(resp, "sv_maxclients", maxclients.string, sizeof(response) - (resp-response)); + Info_SetValueForKey(resp, "mapname", InfoBuf_ValueForKey(&svs.info, "map"), sizeof(response) - (resp-response)); + resp += strlen(resp); + //now include the full/regular serverinfo + resp += InfoBuf_ToString(&svs.info, resp, sizeof(response) - (resp-response), prioritykeys, ignorekeys, NULL, NULL, NULL); + *resp = 0; + //and any possibly-long qc status string + if (*gamestatus) + Info_SetValueForKey(resp, "qcstatus", gamestatus, sizeof(response) - (resp-response)); + resp += strlen(resp); + } + *resp++ = 0; if (fullstatus) { @@ -2225,21 +2209,18 @@ client_t *SV_AddSplit(client_t *controller, char *info, int id) case GT_QUAKE2: cl->q2edict = Q2EDICT_NUM(i+1); - if (!ge->ClientConnect(cl->q2edict, cl->userinfo)) + if (!ge->ClientConnect(cl->q2edict, info)) { - const char *reject = Info_ValueForKey(cl->userinfo, "rejmsg"); + const char *reject = Info_ValueForKey(info, "rejmsg"); if (*reject) SV_ClientPrintf(controller, PRINT_HIGH, "Splitscreen Refused: %s\n", reject); else SV_ClientPrintf(controller, PRINT_HIGH, "Splitscreen Refused\n"); Con_DPrintf ("Game rejected a connection.\n"); - - *cl->userinfo = 0; - cl->namebuf[0] = 0; return NULL; } - ge->ClientUserinfoChanged(cl->q2edict, cl->userinfo); + ge->ClientUserinfoChanged(cl->q2edict, info); break; #endif default: @@ -2252,13 +2233,11 @@ client_t *SV_AddSplit(client_t *controller, char *info, int id) cl->controller = controller; cl->controlled = NULL; - Q_strncpyS (cl->userinfo, info, sizeof(cl->userinfo)-1); - cl->userinfo[sizeof(cl->userinfo)-1] = '\0'; - - Info_RemoveKey (cl->userinfo, "spectator"); + InfoBuf_FromString(&cl->userinfo, info, false); + InfoBuf_RemoveKey (&cl->userinfo, "spectator"); //this is a hint rather than a game breaker should it fail. if (cl->spectator) - Info_SetValueForStarKey (cl->userinfo, "*spectator", va("%i", cl->spectator), sizeof(cl->userinfo)); + InfoBuf_SetValueForStarKey (&cl->userinfo, "*spectator", va("%i", cl->spectator)); cl->state = controller->state; // host_client = NULL; @@ -2759,20 +2738,6 @@ client_t *SVC_DirectConnect(void) if (sv.msgfromdemo) newcl->wasrecorded = true; - // works properly - if (!sv_highchars.value) - { - qbyte *p, *q; - - for (p = (qbyte *)newcl->userinfo, q = (qbyte *)userinfo; - *q && p < (qbyte *)newcl->userinfo + sizeof(newcl->userinfo)-1; q++) - if (*q > 31 && *q <= 127) - *p++ = *q; - } - else - Q_strncpyS (newcl->userinfo, userinfo[0], sizeof(newcl->userinfo)-1); - newcl->userinfo[sizeof(newcl->userinfo)-1] = '\0'; - // Con_TPrintf("%s:%s:connect\n", sv.name, NET_AdrToString (adrbuf, sizeof(adrbuf), &adr)); // if there is already a slot for this ip, drop it @@ -2814,13 +2779,13 @@ client_t *SVC_DirectConnect(void) } } - name = Info_ValueForKey (temp.userinfo, "name"); + name = Info_ValueForKey (userinfo[0], "name"); - if (sv.world.worldmodel && protocol == SCP_QUAKEWORLD &&!atoi(Info_ValueForKey (temp.userinfo, "iknow"))) + if (sv.world.worldmodel && protocol == SCP_QUAKEWORLD &&!atoi(Info_ValueForKey (userinfo[0], "iknow"))) { if (sv.world.worldmodel->fromgame == fg_halflife && !(newcl->fteprotocolextensions & PEXT_HLBSP)) { - if (atof(Info_ValueForKey (temp.userinfo, "*FuhQuake")) < 0.3) + if (atof(Info_ValueForKey (userinfo[0], "*FuhQuake")) < 0.3) { SV_RejectMessage (protocol, "The server is using a halflife level and we don't think your client supports this\nuse 'setinfo iknow 1' to ignore this check\nYou can go to "ENGINEWEBSITE" to get a compatible client\n\nYou may need to enable an option\n\n"); // Con_Printf("player %s was dropped due to incompatible client\n", name); @@ -3045,9 +3010,9 @@ client_t *SVC_DirectConnect(void) temp.edict = NULL; temp.q2edict = q2ent; - if (!ge->ClientConnect(q2ent, temp.userinfo)) + if (!ge->ClientConnect(q2ent, userinfo[0])) { - const char *reject = Info_ValueForKey(temp.userinfo, "rejmsg"); + const char *reject = Info_ValueForKey(userinfo[0], "rejmsg"); if (*reject) SV_RejectMessage(protocol, "%s\nConnection Refused.", reject); else @@ -3056,7 +3021,7 @@ client_t *SVC_DirectConnect(void) return NULL; } - ge->ClientUserinfoChanged(q2ent, temp.userinfo); + ge->ClientUserinfoChanged(q2ent, userinfo[0]); break; @@ -3074,13 +3039,18 @@ client_t *SVC_DirectConnect(void) temp.name = newcl->name; temp.team = newcl->team; + + InfoSync_Clear(&newcl->infosync); *newcl = temp; + newcl->userinfo.ChangeCB = svs.info.ChangeCB; + newcl->userinfo.ChangeCTX = &svs.clients[i].userinfo; + InfoBuf_FromString(&newcl->userinfo, userinfo[0], false); // NET_AdrToStringResolve(&adr, SV_UserDNSResolved, NULL, newcl-svs.clients, newcl->userid); newcl->challenge = challenge; - newcl->zquake_extensions = atoi(Info_ValueForKey(newcl->userinfo, "*z_ext")); - if (*Info_ValueForKey(newcl->userinfo, "*fuhquake")) //fuhquake doesn't claim to support z_ext but does look at our z_ext serverinfo key. + newcl->zquake_extensions = atoi(InfoBuf_ValueForKey(&newcl->userinfo, "*z_ext")); + if (*InfoBuf_ValueForKey(&newcl->userinfo, "*fuhquake")) //fuhquake doesn't claim to support z_ext but does look at our z_ext serverinfo key. { //so switch on the bits that it should be sending. newcl->zquake_extensions |= Z_EXT_PM_TYPE|Z_EXT_PM_TYPE_NEW; } @@ -3089,7 +3059,7 @@ client_t *SVC_DirectConnect(void) //ezquake's download mechanism is so smegging buggy. //its causing far far far too many connectivity issues. seriously. its beyond a joke. I cannot stress that enough. //as the client needs to listen for the serverinfo to know which extensions will actually be used (yay demos), we can just forget that it supports svc-level extensions, at least for anything that isn't spammed via clc_move etc before the serverinfo. - s = Info_ValueForKey(newcl->userinfo, "*client"); + s = InfoBuf_ValueForKey(&newcl->userinfo, "*client"); if (!strncmp(s, "ezQuake", 7) && (newcl->fteprotocolextensions & PEXT_CHUNKEDDOWNLOADS)) { if (pext_ezquake_nochunks.ival) @@ -3184,7 +3154,7 @@ client_t *SVC_DirectConnect(void) SV_RejectMessage (protocol, "Rankings/Account system failed\n"); Con_TPrintf("banned player %s is trying to connect\n", newcl->name); newcl->name[0] = 0; - memset (newcl->userinfo, 0, sizeof(newcl->userinfo)); + InfoBuf_Clear(&newcl->userinfo, true); newcl->state = cs_free; return NULL; } @@ -3312,7 +3282,7 @@ client_t *SVC_DirectConnect(void) if (spectators >= maxspectators.ival) newcl->drop = true; //oops. newcl->spectator = spectator = true; - Info_SetValueForStarKey (cl->userinfo, "*spectator", "1", sizeof(cl->userinfo)); + InfoBuf_SetValueForStarKey (&cl->userinfo, "*spectator", "1"); } //only advertise PEXT_SPLITSCREEN when splitscreen is allowed, to avoid spam. this might mean people need to reconnect after its enabled. oh well. @@ -4076,18 +4046,18 @@ qboolean SVNQ_ConnectionlessPacket(void) SZ_Clear (&sb); MSG_WriteLong (&sb, 0); { - char *rname, *rval, *kname; + const char *rname, *rval, *kname; rname = MSG_ReadString(); if (!*rname) - rname = Info_KeyForNumber(svs.info, 0); + rname = InfoBuf_KeyForNumber(&svs.info, 0); else { int i = 0; for(;;) { - kname = Info_KeyForNumber(svs.info, i); - if (!*kname) + kname = InfoBuf_KeyForNumber(&svs.info, i); + if (!kname) { rname = NULL; break; @@ -4095,12 +4065,15 @@ qboolean SVNQ_ConnectionlessPacket(void) i++; if (!strcmp(kname, rname)) { - rname = Info_KeyForNumber(svs.info, i); + rname = InfoBuf_KeyForNumber(&svs.info, i); break; } } } - rval = Info_ValueForKey(svs.info, rname); + if (rname) + rval = InfoBuf_ValueForKey(&svs.info, rname); + else + rval = rname = ""; MSG_WriteByte (&sb, CCREP_RULE_INFO); MSG_WriteString (&sb, rname); MSG_WriteString (&sb, rval); @@ -4627,9 +4600,9 @@ void SV_CheckVars (void) Con_DPrintf ("Updated needpass.\n"); if (!v) - Info_SetValueForKey (svs.info, "needpass", "", MAX_SERVERINFO_STRING); + InfoBuf_SetValueForKey (&svs.info, "needpass", ""); else - Info_SetValueForKey (svs.info, "needpass", va("%i",v), MAX_SERVERINFO_STRING); + InfoBuf_SetValueForKey (&svs.info, "needpass", va("%i",v)); } #ifdef Q2SERVER @@ -4815,8 +4788,7 @@ float SV_Frame (void) newspeed = ""; else newspeed = va("%g", sv.gamespeed*100); - Info_SetValueForStarKey(svs.info, "*gamespeed", newspeed, MAX_SERVERINFO_STRING); - SV_SendServerInfoChange("*gamespeed", newspeed); + InfoBuf_SetValueForStarKey(&svs.info, "*gamespeed", newspeed); //correct sv.starttime sv.starttime = Sys_DoubleTime() - (sv.time/sv.gamespeed); @@ -5048,6 +5020,23 @@ float SV_Frame (void) return delay; } +static void SV_InfoChanged(void *context, const char *key) +{ + size_t i; + if (context != &svs.info && *key == '_') + return; //these keys are considered private to originating client/server, and are not broadcast to anyone else + + if (svs.demorecording) + InfoSync_Add(&demo.recorder.infosync, context, key); //make sure it gets written into mvds too. + for (i = 0; i < svs.allocated_client_slots; i++) + { + if (svs.clients[i].state >= cs_connected) + { + InfoSync_Add(&svs.clients[i].infosync, context, key); + } + } +} + /* =============== SV_InitLocal @@ -5232,9 +5221,10 @@ void SV_InitLocal (void) SV_MVDInit(); - Info_SetValueForStarKey (svs.info, "*version", version_string(), MAX_SERVERINFO_STRING); - - Info_SetValueForStarKey (svs.info, "*z_ext", va("%i", SUPPORTED_Z_EXTENSIONS), MAX_SERVERINFO_STRING); + svs.info.ChangeCB = SV_InfoChanged; + svs.info.ChangeCTX = &svs.info; + InfoBuf_SetValueForStarKey (&svs.info, "*version", version_string()); + InfoBuf_SetValueForStarKey (&svs.info, "*z_ext", va("%i", SUPPORTED_Z_EXTENSIONS)); // init fraglog stuff svs.logsequence = 1; @@ -5251,17 +5241,18 @@ void SV_InitLocal (void) } #define iswhite(c) ((c) == ' ' || (unsigned char)(c) == (unsigned char)INVIS_CHAR1 || (unsigned char)(c) == (unsigned char)INVIS_CHAR2 || (unsigned char)(c) == (unsigned char)INVIS_CHAR3) -#define isinvalid(c) ((c) == ':' || (c) == '\r' || (c) == '\n' || (unsigned char)(c) == (unsigned char)0xff || (c) == '\"') +#define isinvalid(c) ((c) == ':' || (c) == '\\' || (c) == '\r' || (c) == '\n' || (unsigned char)(c) == (unsigned char)0xff || (c) == '\"') //colon is so clients can't get confused while parsing chats //255 is so fuhquake/ezquake don't end up with nameless players //" is so mods that use player names in tokenizing/frik_files don't mess up. mods are still expected to be able to cope with space. +//\ is blocked because it messes up our ^[NAME\player\NUM^] links, and because vanilla would hate it. //is allowed to shorten, out must be as long as in and min of "unnamed"+1 void SV_FixupName(const char *in, char *out, unsigned int outlen) { char *s, *p; - unsigned int len; - conchar_t testbuf[1024], *t, *e; + unsigned int len, codepoint, codeflags; + conchar_t testbuf[1024], *t, *n, *e; if (outlen == 0) return; @@ -5274,7 +5265,7 @@ void SV_FixupName(const char *in, char *out, unsigned int outlen) while(*in && len > 1) { if (isinvalid(*in)) - { + { //chars that cause a problem. in++; continue; } @@ -5285,16 +5276,21 @@ void SV_FixupName(const char *in, char *out, unsigned int outlen) /*note: clients are not guarenteed to parse things the same as the server. utf-8 surrogates may be awkward here*/ e = COM_ParseFunString(CON_WHITEMASK, out, testbuf, sizeof(testbuf), false); - for (t = testbuf; t < e; t++) + for (t = testbuf; t < e; t = n) { + n = Font_Decode(t, &codeflags, &codepoint); /*reject anything hidden in names*/ - if (*t & CON_HIDDEN) + if ((codeflags & CON_HIDDEN) || (codeflags&(CON_LINKSPECIAL|CON_RICHFORECOLOUR))==CON_LINKSPECIAL) break; /*reject pictograms*/ - if ((*t & CON_CHARMASK) >= 0xe100 && (*t & CON_CHARMASK) < 0xe200) + if (codepoint >= 0xe100 && codepoint < 0xe200) + break; + if (!sv_highchars.ival && (codeflags & CON_2NDCHARSETTEXT)) break; /*FIXME: should we try to ensure that the chars are in most fonts? that might annoy speakers of more exotic languages I suppose. cvar it?*/ } + //and spit it out again, which makes sure there's no weird markup that might screw up other strings. + COM_DeFunString(testbuf, t, out, outlen, false, false); if (!*out || (t < e) || e == testbuf) { //reached end and it was all whitespace @@ -5316,9 +5312,9 @@ qboolean ReloadRanking(client_t *cl, const char *newname) int newid; int j; rankstats_t rs; - newid = Rank_GetPlayerID(cl->guid, newname, atoi(Info_ValueForKey (cl->userinfo, "_pwd")), true, false); //'_' keys are always stripped. On any server. So try and use that so persistant data won't give out the password when connecting to a different server + newid = Rank_GetPlayerID(cl->guid, newname, atoi(InfoBuf_ValueForKey (&cl->userinfo, "_pwd")), true, false); //'_' keys are always stripped. On any server. So try and use that so persistant data won't give out the password when connecting to a different server if (!newid) - newid = Rank_GetPlayerID(cl->guid, newname, atoi(Info_ValueForKey (cl->userinfo, "password")), true, false); + newid = Rank_GetPlayerID(cl->guid, newname, atoi(InfoBuf_ValueForKey (&cl->userinfo, "password")), true, false); if (newid) { if (cl->rankid && cl->state >= cs_spawned)//apply current stats @@ -5383,23 +5379,23 @@ void SV_ExtractFromUserinfo (client_t *cl, qboolean verbose) extern cvar_t rank_filename; #endif - int bottom = atoi(Info_ValueForKey(cl->userinfo, "bottomcolor")); + int bottom = atoi(InfoBuf_ValueForKey(&cl->userinfo, "bottomcolor")); if (progstype == PROG_NQ) p = va("t%u", bottom); else - p = Info_ValueForKey(localinfo, va("team%u", bottom)); - val = Info_ValueForKey (cl->userinfo, "team"); + p = InfoBuf_ValueForKey(&svs.localinfo, va("team%u", bottom)); + val = InfoBuf_ValueForKey (&cl->userinfo, "team"); if (*p && strcmp(p, val)) { - Info_SetValueForKey(cl->userinfo, "team", p, sizeof(cl->userinfo)); + InfoBuf_SetValueForKey(&cl->userinfo, "team", p); if (verbose) SV_BroadcastUserinfoChange(cl, true, "team", p); } Q_strncpyz (cl->team, val, sizeof(cl->teambuf)); // name for C code - val = Info_ValueForKey (cl->userinfo, "name"); + val = InfoBuf_ValueForKey (&cl->userinfo, "name"); if (cl->protocol != SCP_BAD || *val) { @@ -5473,18 +5469,6 @@ void SV_ExtractFromUserinfo (client_t *cl, qboolean verbose) } } - //try and actually set that new name, if it differs from what they asked for. - if (strcmp(val, newname)) - { - Info_SetValueForKey (cl->userinfo, "name", newname, sizeof(cl->userinfo)); - val = Info_ValueForKey (cl->userinfo, "name"); - if (!*val) - { - SV_BroadcastTPrintf (PRINT_HIGH, "corrupt userinfo for player %s\n", cl->name); - cl->drop = true; - } - } - if (!cl->drop && strncmp(val, cl->name, sizeof(cl->namebuf)-1) && cl->state > cs_zombie) { if (*cl->name && cl->state >= cs_spawned && !cl->spectator && verbose) @@ -5506,30 +5490,41 @@ void SV_ExtractFromUserinfo (client_t *cl, qboolean verbose) } } - val = Info_ValueForKey (cl->userinfo, "lang"); + //make CERTAIN that the name we think they're using is actually the name everyone else sees too. + { + InfoBuf_SetValueForKey (&cl->userinfo, "name", newname); + val = InfoBuf_ValueForKey (&cl->userinfo, "name"); + if (!*val) + { + SV_BroadcastTPrintf (PRINT_HIGH, "corrupt userinfo for player %s\n", cl->name); + cl->drop = true; + } + } + + val = InfoBuf_ValueForKey (&cl->userinfo, "lang"); cl->language = *val?TL_FindLanguage(val):svs.language; - val = Info_ValueForKey (cl->userinfo, "nogib"); + val = InfoBuf_ValueForKey (&cl->userinfo, "nogib"); cl->gibfilter = !!atoi(val); // rate command - val = Info_ValueForKey (cl->userinfo, "rate"); + val = InfoBuf_ValueForKey (&cl->userinfo, "rate"); if (strlen(val)) cl->rate = atoi(val); else cl->rate = 0;//0 means no specific limit, limited only by sv_maxrate. - val = Info_ValueForKey (cl->userinfo, "dupe"); + val = InfoBuf_ValueForKey (&cl->userinfo, "dupe"); cl->netchan.dupe = bound(0, atoi(val), 5); - val = Info_ValueForKey (cl->userinfo, "drate"); + val = InfoBuf_ValueForKey (&cl->userinfo, "drate"); if (strlen(val)) cl->drate = atoi(val); else cl->drate = 0; //0 disables rate limiting while downloading #ifdef HEXEN2 - val = Info_ValueForKey (cl->userinfo, "cl_playerclass"); + val = InfoBuf_ValueForKey (&cl->userinfo, "cl_playerclass"); if (val) { PRH2_SetPlayerClass(cl, atoi(val), false); @@ -5537,13 +5532,13 @@ void SV_ExtractFromUserinfo (client_t *cl, qboolean verbose) #endif // msg command - val = Info_ValueForKey (cl->userinfo, "msg"); + val = InfoBuf_ValueForKey (&cl->userinfo, "msg"); if (strlen(val)) { cl->messagelevel = atoi(val); } - val = Info_ValueForKey (cl->userinfo, "sp"); //naming for compat with mvdsv + val = InfoBuf_ValueForKey (&cl->userinfo, "sp"); //naming for compat with mvdsv if (*val) cl->spec_print = atoi(val); else @@ -5551,7 +5546,7 @@ void SV_ExtractFromUserinfo (client_t *cl, qboolean verbose) #ifdef NQPROT { - int top = atoi(Info_ValueForKey(cl->userinfo, "topcolor")); + int top = atoi(InfoBuf_ValueForKey(&cl->userinfo, "topcolor")); top &= 15; if (top > 13) top = 13; diff --git a/engine/server/sv_mvd.c b/engine/server/sv_mvd.c index 2c744df97..bb9867b3d 100644 --- a/engine/server/sv_mvd.c +++ b/engine/server/sv_mvd.c @@ -823,7 +823,7 @@ void SV_MVD_FullClientUpdate(sizebuf_t *msg, client_t *player) MSG_WriteByte (msg, player - svs.clients); MSG_WriteFloat (msg, realtime - player->connection_started); - SV_GeneratePublicUserInfo(demo.recorder.fteprotocolextensions, player, info, sizeof(info)); + InfoBuf_ToString(&player->userinfo, info, sizeof(info), basicuserinfos, privateuserinfos, NULL, &demo.recorder.infosync, player); if (dosizes) msg = MVDWrite_Begin (dem_all, 0, 7 + strlen(info)); @@ -1205,12 +1205,12 @@ static char *SV_PrintTeams(void) clients[numcl++] = &svs.clients[i]; for (j = 0; j < numt; j++) - if (!strcmp(Info_ValueForKey(svs.clients[i].userinfo, "team"), teams[j])) + if (!strcmp(InfoBuf_ValueForKey(&svs.clients[i].userinfo, "team"), teams[j])) break; if (j != numt) continue; - teams[numt++] = Info_ValueForKey(svs.clients[i].userinfo, "team"); + teams[numt++] = InfoBuf_ValueForKey(&svs.clients[i].userinfo, "team"); } // create output @@ -1231,7 +1231,7 @@ static char *SV_PrintTeams(void) { snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "team %s:\n", teams[j]); for (i = 0; i < numcl; i++) - if (!strcmp(Info_ValueForKey(clients[i]->userinfo, "team"), teams[j])) + if (!strcmp(InfoBuf_ValueForKey(&clients[i]->userinfo, "team"), teams[j])) snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " %s\n", clients[i]->name); } } @@ -1668,7 +1668,7 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest) // send the serverdata - gamedir = Info_ValueForKey (svs.info, "*gamedir"); + gamedir = InfoBuf_ValueForKey (&svs.info, "*gamedir"); if (!gamedir[0]) gamedir = FS_GetGamedir(true); @@ -2088,11 +2088,11 @@ char *Dem_Team(int num) if (!client->name[0] || client->spectator) continue; - if (first || strcmp(lastteam[index], Info_ValueForKey(client->userinfo, "team"))) + if (first || strcmp(lastteam[index], InfoBuf_ValueForKey(&client->userinfo, "team"))) { first = false; num--; - lastteam[index] = Info_ValueForKey(client->userinfo, "team"); + lastteam[index] = InfoBuf_ValueForKey(&client->userinfo, "team"); } } @@ -2136,7 +2136,7 @@ char *Dem_PlayerNameTeam(char *t) if (!client->name[0] || client->spectator) continue; - if (strcmp(t, Info_ValueForKey(client->userinfo, "team"))==0) + if (strcmp(t, InfoBuf_ValueForKey(&client->userinfo, "team"))==0) { if (sep >= 1) Q_strncatz (n, "_", sizeof(n)); @@ -2158,7 +2158,7 @@ int Dem_CountTeamPlayers (char *t) for (i = 0; i < sv.allocated_client_slots ; i++) { if (svs.clients[i].name[0] && !svs.clients[i].spectator) - if (strcmp(Info_ValueForKey(svs.clients[i].userinfo, "team"), t)==0) + if (strcmp(InfoBuf_ValueForKey(&svs.clients[i].userinfo, "team"), t)==0) count++; } diff --git a/engine/server/sv_send.c b/engine/server/sv_send.c index 0d22ee769..78c22954a 100644 --- a/engine/server/sv_send.c +++ b/engine/server/sv_send.c @@ -2683,7 +2683,7 @@ qboolean SV_CanTrack(client_t *client, int entity) return false; if (svs.clients[entity-1].spectator) return false; - if (svs.clients[entity-1].state == cs_spawned || (svs.clients[entity-1].state == cs_free && *svs.clients[entity-1].userinfo)) + if (svs.clients[entity-1].state == cs_spawned || (svs.clients[entity-1].state == cs_free && svs.clients[entity-1].userinfo.numkeys)) return true; return false; } @@ -2924,6 +2924,100 @@ void SV_FlushBroadcasts (void) #endif } +static qboolean SV_SyncInfoBuf(client_t *client) +{ + const char *key = client->infosync.keys[0].name; + infobuf_t *info = client->infosync.keys[0].context; + size_t bloboffset = client->infosync.keys[0].syncpos; + //unsigned int seat = info - cls.userinfo; + size_t blobsize; + const char *blobdata = InfoBuf_BlobForKey(info, key, &blobsize); + size_t sendsize; + size_t bufferspace; + + qboolean final; + char enckey[2048]; + char encval[2048]; + + if (client->protocol == SCP_QUAKE2) + { //q2 gamecode is fully responsible for networking this via configstrings. + InfoSync_Clear(&client->infosync); + return false; + } + + if (host_client->num_backbuf) + return false; + if (client->netchan.message.cursize >= MAX_BACKBUFLEN/2) + return false; //don't bother trying to send anything. + + if (!InfoBuf_EncodeString(key, strlen(key), enckey, sizeof(enckey))) + { + InfoSync_Remove(&client->infosync, 0); + return false; + } + + sendsize = blobsize - bloboffset; + bufferspace = MAX_BACKBUFLEN - client->netchan.message.cursize; + bufferspace -= 7 - strlen(enckey) - 2; //extra overhead + bufferspace = (bufferspace/4)*3; //encoding overhead + sendsize = min(bufferspace, sendsize); + final = (bloboffset+sendsize >= blobsize); + + if (!InfoBuf_EncodeString(blobdata+bloboffset, sendsize, encval, sizeof(encval))) + { + InfoSync_Remove(&client->infosync, 0); + return false; + } + + if (final && !bloboffset && *enckey != '\xff' && *encval != '\xff') + { //vanilla-compatible info. + if (ISNQCLIENT(client)) + { //except that nq never had any userinfo + const char *s = va("//ui %i \"%s\" \"%s\"\n", (client_t*)info-svs.clients, enckey, encval); + ClientReliableWrite_Begin(client, svc_stufftext, strlen(s)+2); + ClientReliableWrite_String(client, s); + } + else + { + if (info == &svs.info) + ClientReliableWrite_Begin(client, svc_serverinfo, 1+strlen(enckey)+1+strlen(encval)+1); + else + { + ClientReliableWrite_Begin(client, svc_setinfo, 2+strlen(enckey)+1+strlen(encval)+1); + ClientReliableWrite_Byte(client, (client_t*)info-svs.clients); + } + ClientReliableWrite_String(client, enckey); + ClientReliableWrite_String(client, encval); + } + } + else if (client->fteprotocolextensions2 & PEXT2_INFOBLOBS) + { + int pl; + if (info == &svs.info) + pl = 255; //colourmaps being 1-based with these being 0-based means that only 0-254 are valid players, and 255 is unused, so lets use it for serverinfo blobs. + else + pl = (client_t*)info-svs.clients; + + ClientReliableWrite_Begin(client, svc_setinfo, 7+strlen(enckey)+1+strlen(encval)+1); + ClientReliableWrite_Byte(client, 255); //special meaning to say that this is a partial update + ClientReliableWrite_Byte(client, pl); + ClientReliableWrite_Long(client, (final?0x80000000:0)|bloboffset); + ClientReliableWrite_String(client, enckey); + ClientReliableWrite_String(client, encval); + } + else + { //client can't receive this info, stop trying to send it. + InfoSync_Remove(&client->infosync, 0); + return true; + } + + if (bloboffset+sendsize == blobsize) + InfoSync_Remove(&client->infosync, 0); + else + client->infosync.keys[0].syncpos += sendsize; + return true; +} + /* ======================= SV_UpdateToReliableMessages @@ -2949,8 +3043,8 @@ void SV_UpdateToReliableMessages (void) //DP_SV_CLIENTCOLORS if (host_client->edict->xv->clientcolors != host_client->playercolor) { - Info_SetValueForKey(host_client->userinfo, "topcolor", va("%i", (int)host_client->edict->xv->clientcolors/16), sizeof(host_client->userinfo)); - Info_SetValueForKey(host_client->userinfo, "bottomcolor", va("%i", (int)host_client->edict->xv->clientcolors&15), sizeof(host_client->userinfo)); + InfoBuf_SetValueForKey(&host_client->userinfo, "topcolor", va("%i", (int)host_client->edict->xv->clientcolors/16)); + InfoBuf_SetValueForKey(&host_client->userinfo, "bottomcolor", va("%i", (int)host_client->edict->xv->clientcolors&15)); { SV_ExtractFromUserinfo (host_client, true); //this will take care of nq for us anyway. SV_BroadcastUserinfoChange(host_client, true, "*bothcolours", NULL); @@ -2974,7 +3068,7 @@ void SV_UpdateToReliableMessages (void) Q_strncpyz(oname, host_client->name, sizeof(oname)); Con_DPrintf("Client %s programatically renamed to %s\n", host_client->name, name); - Info_SetValueForKey(host_client->userinfo, "name", name, sizeof(host_client->userinfo)); + InfoBuf_SetValueForKey(&host_client->userinfo, "name", name); SV_ExtractFromUserinfo (host_client, true); if (strcmp(oname, host_client->name)) @@ -3135,6 +3229,12 @@ void SV_UpdateToReliableMessages (void) } } } + + while (host_client->infosync.numkeys) + { + if (!SV_SyncInfoBuf(host_client)) + break; + } } if (sv.reliable_datagram.overflowed) @@ -3173,7 +3273,7 @@ static void SV_SendUserinfoChange(client_t *to, client_t *about, qboolean isbasi return; if (!newval) - newval = Info_ValueForKey(about->userinfo, key); + newval = InfoBuf_ValueForKey(&about->userinfo, key); if (ISQWCLIENT(to)) { @@ -3181,13 +3281,13 @@ static void SV_SendUserinfoChange(client_t *to, client_t *about, qboolean isbasi { if (ISQWCLIENT(to) && !strcmp(key, "*bothcolours")) { - newval = Info_ValueForKey(about->userinfo, "topcolor"); + newval = InfoBuf_ValueForKey(&about->userinfo, "topcolor"); ClientReliableWrite_Begin(to, svc_setinfo, 4+strlen(key)+strlen(newval)); ClientReliableWrite_Byte(to, playernum); ClientReliableWrite_String(to, "topcolor"); - ClientReliableWrite_String(to, Info_ValueForKey(about->userinfo, "topcolor")); + ClientReliableWrite_String(to, InfoBuf_ValueForKey(&about->userinfo, "topcolor")); - newval = Info_ValueForKey(about->userinfo, "bottomcolor"); + newval = InfoBuf_ValueForKey(&about->userinfo, "bottomcolor"); ClientReliableWrite_Begin(to, svc_setinfo, 4+strlen(key)+strlen(newval)); ClientReliableWrite_Byte(to, playernum); ClientReliableWrite_String(to, "bottomcolor"); @@ -3223,8 +3323,8 @@ static void SV_SendUserinfoChange(client_t *to, client_t *about, qboolean isbasi } else if (!strcmp(key, "topcolor") || !strcmp(key, "bottomcolor") || !strcmp(key, "*bothcolours")) { //due to these being combined, nq players get double colour change notifications... - int tc = atoi(Info_ValueForKey(about->userinfo, "topcolor")); - int bc = atoi(Info_ValueForKey(about->userinfo, "bottomcolor")); + int tc = atoi(InfoBuf_ValueForKey(&about->userinfo, "topcolor")); + int bc = atoi(InfoBuf_ValueForKey(&about->userinfo, "bottomcolor")); if (tc < 0 || tc > 13) tc = 0; if (bc < 0 || bc > 13) @@ -3250,7 +3350,7 @@ void SV_BroadcastUserinfoChange(client_t *about, qboolean isbasic, const char *k client_t *client; int j; if (!newval) - newval = Info_ValueForKey(about->userinfo, key); + newval = InfoBuf_ValueForKey(&about->userinfo, key); for (j = 0; j < svs.allocated_client_slots; j++) { client = svs.clients+j; diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index 16e388336..78532dcab 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -121,6 +121,9 @@ cvar_t sv_realiphostname_ipv4 = CVARD("sv_realiphostname_ipv4", "", "This is the cvar_t sv_realiphostname_ipv6 = CVARD("sv_realiphostname_ipv6", "", "This is the server's public ip:port. This is needed for realip to work when the autodetected/local ip is not globally routable"); cvar_t sv_realip_timeout = CVAR("sv_realip_timeout", "10"); +cvar_t sv_userinfo_keylimit = CVARD("sv_userinfo_keylimit", "128", "This is the maximum number of userinfo keys each user may create."); +cvar_t sv_userinfo_bytelimit = CVARD("sv_userinfo_bytelimit", "8192", "This is the maximum number of bytes that may be stored into each user's userinfo. Note that this includes key names too."); + #ifdef VOICECHAT cvar_t sv_voip = CVARD("sv_voip", "1", "Enable reception of voice packets."); cvar_t sv_voip_record = CVARD("sv_voip_record", "0", "Record voicechat into mvds. Requires player support. 0=noone, 1=everyone, 2=spectators only"); @@ -255,7 +258,7 @@ void SV_New_f (void) } else { - char *srv = Info_ValueForKey(host_client->userinfo, "*redirect"); + const char *srv = InfoBuf_ValueForKey(&host_client->userinfo, "*redirect"); if (*srv) { char *msg = va("connect \"%s\"\n", srv); @@ -284,7 +287,7 @@ void SV_New_f (void) // SV_FullClientUpdate (host_client, &sv.reliable_datagram); // host_client->sendinfo = true; - gamedir = Info_ValueForKey (svs.info, "*gamedir"); + gamedir = InfoBuf_ValueForKey (&svs.info, "*gamedir"); if (!gamedir[0]) { if (ISQWCLIENT(host_client) || ISQ2CLIENT(host_client)) @@ -650,7 +653,7 @@ void SVNQ_New_f (void) Q_snprintfz(build, sizeof(build), "%s", __DATE__); #endif - gamedir = Info_ValueForKey (svs.info, "*gamedir"); + gamedir = InfoBuf_ValueForKey (&svs.info, "*gamedir"); if (!gamedir[0]) { gamedir = FS_GetGamedir(true); @@ -694,7 +697,7 @@ void SVNQ_New_f (void) MSG_WriteByte (&host_client->netchan.message, svc_stufftext); MSG_WriteString (&host_client->netchan.message, "cl_serverextension_download 1\n"); - f = COM_LoadTempFile("csprogs.dat", &sz); + f = COM_LoadTempFile("csprogs.dat", 0, &sz); if (f) { MSG_WriteByte (&host_client->netchan.message, svc_stufftext); @@ -1009,13 +1012,15 @@ void SV_SendClientPrespawnInfo(client_t *client) { if (!ISNQCLIENT(client) || (client->fteprotocolextensions2 & PEXT2_PREDINFO)) { //nq does not normally get serverinfo sent to it. - ClientReliableWrite_Begin(client, svc_stufftext, 20 + strlen(svs.info)); - ClientReliableWrite_String (client, va("fullserverinfo \"%s\"\n", svs.info) ); + i = InfoBuf_ToString(&svs.info, buffer, sizeof(buffer), NULL, NULL, NULL, &client->infosync, &svs.info); + ClientReliableWrite_Begin(client, svc_stufftext, 20 + i); + ClientReliableWrite_String (client, va("fullserverinfo \"%s\"\n", buffer) ); } else if (sv.csqcdebug) { - ClientReliableWrite_Begin(client, svc_stufftext, 22 + strlen(svs.info)); - ClientReliableWrite_String (client, va("//fullserverinfo \"%s\"\n", svs.info) ); + i = InfoBuf_ToString(&svs.info, buffer, sizeof(buffer), NULL, NULL, NULL, &client->infosync, &svs.info); + ClientReliableWrite_Begin(client, svc_stufftext, 22 + i); + ClientReliableWrite_String (client, va("//fullserverinfo \"%s\"\n", buffer) ); } } else if (client->prespawn_idx == 1) @@ -1946,7 +1951,9 @@ void SV_Begin_Core(client_t *split) #ifdef Q2SERVER if (ge) { - ge->ClientUserinfoChanged (split->q2edict, split->userinfo); //tell the gamecode + char userinfo[8192]; + InfoBuf_ToString(&split->userinfo, userinfo, sizeof(userinfo), NULL, NULL, NULL, NULL, NULL); + ge->ClientUserinfoChanged (split->q2edict, userinfo); //tell the gamecode SV_ExtractFromUserinfo(split, true); //let the server routines know ge->ClientBegin(split->q2edict); @@ -1980,11 +1987,11 @@ void SV_Begin_Core(client_t *split) eval = svprogfuncs->GetEdictFieldValue(svprogfuncs, ent, "playermodel", ev_string, NULL); if (eval) - svprogfuncs->SetStringField(svprogfuncs, ent, &eval->string, Info_ValueForKey(split->userinfo, "model"), false); + svprogfuncs->SetStringField(svprogfuncs, ent, &eval->string, InfoBuf_ValueForKey(&split->userinfo, "model"), false); eval = svprogfuncs->GetEdictFieldValue(svprogfuncs, ent, "playerskin", ev_string, NULL); if (eval) - svprogfuncs->SetStringField(svprogfuncs, ent, &eval->string, Info_ValueForKey(split->userinfo, "skin"), false); + svprogfuncs->SetStringField(svprogfuncs, ent, &eval->string, InfoBuf_ValueForKey(&split->userinfo, "skin"), false); eval = svprogfuncs->GetEdictFieldValue(svprogfuncs, ent, "netaddress", ev_string, NULL); if (eval) @@ -2176,8 +2183,8 @@ void SV_Begin_f (void) //check he's not cheating if (progstype == PROG_QW) { - pmodel = atoi(Info_ValueForKey (host_client->userinfo, "pmodel")); - emodel = atoi(Info_ValueForKey (host_client->userinfo, "emodel")); + pmodel = atoi(InfoBuf_ValueForKey (&host_client->userinfo, "pmodel")); + emodel = atoi(InfoBuf_ValueForKey (&host_client->userinfo, "emodel")); if (pmodel != sv.model_player_checksum || emodel != sv.eyes_player_checksum) @@ -3694,7 +3701,7 @@ void SV_Say (qboolean team) if (team) { - Q_strncpyz (t1, Info_ValueForKey (host_client->userinfo, "team"), sizeof(t1)); + Q_strncpyz (t1, InfoBuf_ValueForKey(&host_client->userinfo, "team"), sizeof(t1)); } if (host_client->spectator && (!sv_spectalk.value || team)) @@ -3790,7 +3797,7 @@ void SV_Say (qboolean team) if (!client->spectator) continue; } else { - t2 = Info_ValueForKey (client->userinfo, "team"); + t2 = InfoBuf_ValueForKey (&client->userinfo, "team"); if (strcmp(t1, t2) || client->spectator) continue; // on different teams } @@ -4222,7 +4229,7 @@ void SV_Rate_f (void) return; } - Info_SetValueForKey (host_client->userinfo, "rate", Cmd_Argv(1), sizeof(host_client->userinfo)); + InfoBuf_SetKey (&host_client->userinfo, "rate", Cmd_Argv(1)); SV_ExtractFromUserinfo (host_client, true); if (host_client->state > cs_connected) @@ -4254,20 +4261,9 @@ void SV_Msg_f (void) qboolean SV_UserInfoIsBasic(const char *infoname) { int i; - char *basicinfos[] = { - - "name", - "team", - "skin", - "topcolor", - "bottomcolor", - "chat", //ezquake's afk indicators - - NULL}; - - for (i = 0; basicinfos[i]; i++) + for (i = 1; basicuserinfos[i]; i++) { - if (*infoname == '*' || !strcmp(infoname, basicinfos[i])) + if (*infoname == '*' || !strcmp(infoname, basicuserinfos[i])) return true; } return false; @@ -4277,6 +4273,8 @@ qboolean SV_UserInfoIsBasic(const char *infoname) static void SV_SetInfo_PrintCB (void *ctx, const char *key, const char *value) { client_t *cl = ctx; + if (cl->num_backbuf > MAX_BACK_BUFFERS/2) + return; //stop printing if there's too many... SV_ClientPrintf(cl, PRINT_HIGH, "\t%-20s%s\n", key, value); } @@ -4290,89 +4288,102 @@ Allow clients to change userinfo void SV_SetInfo_f (void) { char oldval[MAX_INFO_KEY]; - char *key, *val; + char *key, *val, *t; + size_t offset, keysize, valsize, k; + qboolean final; if (Cmd_Argc() == 1) { SV_ClientPrintf(host_client, PRINT_HIGH, "User info settings:\n"); - Info_Enumerate(host_client->userinfo, (void*)host_client, SV_SetInfo_PrintCB); + InfoBuf_Enumerate(&host_client->userinfo, (void*)host_client, SV_SetInfo_PrintCB); + SV_ClientPrintf(host_client, PRINT_HIGH, "[%u/%i, %u/%i]\n", (unsigned int)host_client->userinfo.numkeys, sv_userinfo_keylimit.ival, (unsigned int)host_client->userinfo.totalsize, sv_userinfo_bytelimit.ival); return; } - if (Cmd_Argc() != 3) + if (Cmd_Argc() == 4) + { + offset = strtoul(Cmd_Argv(3), &t, 0); + final = (*t != '+'); + } + else if (Cmd_Argc() == 3) + { + offset = 0; + final = true; + } + else { SV_ClientPrintf(host_client, PRINT_HIGH, "usage: setinfo [ ]\n"); return; } - key = Cmd_Argv(1); - - if (key[0] == '*') - return; // don't set priveledged values - - if (strstr(key, "\\") || strstr(Cmd_Argv(2), "\\")) - return; // illegal char - - Q_strncpyz(oldval, Info_ValueForKey(host_client->userinfo, key), sizeof(oldval)); - #ifdef VM_Q1 if (Q1QVM_UserInfoChanged(sv_player)) return; #endif - Info_SetValueForKey (host_client->userinfo, key, Cmd_Argv(2), sizeof(host_client->userinfo)); -// name is extracted below in ExtractFromUserInfo -// strncpy (host_client->name, Info_ValueForKey (host_client->userinfo, "name") -// , sizeof(host_client->name)-1); -// SV_FullClientUpdate (host_client, &sv.reliable_datagram); -// host_client->sendinfo = true; - - if (!strcmp(Info_ValueForKey(host_client->userinfo, key), oldval)) - return; // key hasn't changed + key = Cmd_Argv(1); + val = Cmd_Argv(2); + if (strstr(key, "\\") || strstr(val, "\\")) + return; // illegal char, at least at this point. + key = InfoBuf_DecodeString(key, key+strlen(key), &keysize); + val = InfoBuf_DecodeString(val, val+strlen(val), &valsize); + if (key[0] == '*') + SV_ClientPrintf(host_client, PRINT_HIGH, "setinfo: %s may not be changed mid-game\n", key); + else if (sv_userinfo_keylimit.ival >= 0 && host_client->userinfo.numkeys >= sv_userinfo_keylimit.ival && !offset && *val && !InfoBuf_FindKey(&host_client->userinfo, key, &k)) //when the limit is hit, allow people to freely change existing keys, but not new ones. they can also silently remove any that don't exist yet, too. + SV_ClientPrintf(host_client, PRINT_MEDIUM, "setinfo: userinfo is limited to %i keys. Ignoring setting %s\n", sv_userinfo_keylimit.ival, key); + else if (sv_userinfo_bytelimit.ival >= 0 && host_client->userinfo.totalsize >= sv_userinfo_bytelimit.ival && *val) + { + SV_ClientPrintf(host_client, PRINT_MEDIUM, "setinfo: userinfo is limited to %i bytes. Ignoring setting %s\n", sv_userinfo_bytelimit.ival, key); + if (offset) //kill it if they're part way through sending one, so that they're not penalised by the presence of partials that will never complete. + InfoBuf_RemoveKey(&host_client->userinfo, key); + } + else if (InfoBuf_SyncReceive(&host_client->userinfo, key, keysize, val, valsize, offset, final)) + { #ifdef Q2SERVER - if (svs.gametype == GT_QUAKE2) - { - ge->ClientUserinfoChanged (host_client->q2edict, host_client->userinfo); //tell the gamecode - SV_ExtractFromUserinfo(host_client, true); //let the server routines know - return; - } + if (svs.gametype == GT_QUAKE2) + { + char tempbuffer[32768]; + InfoBuf_ToString(&host_client->userinfo, tempbuffer, sizeof(tempbuffer), NULL, NULL, NULL, NULL, NULL); + ge->ClientUserinfoChanged (host_client->q2edict, tempbuffer); //tell the gamecode + SV_ExtractFromUserinfo(host_client, true); //let the server routines know + } + else #endif + { - if (progstype != PROG_QW && !strcmp(key, "bottomcolor")) - { //team fortress has a nasty habit of booting people without this - sv_player->v->team = atoi(Cmd_Argv(2))+1; - } + if (progstype != PROG_QW && !strcmp(key, "bottomcolor")) + { //team fortress has a nasty habit of booting people without this + sv_player->v->team = atoi(Cmd_Argv(2))+1; + } #ifndef NOLEGACY - if (progstype != PROG_QW && !strcmp(key, "model")) - { - eval_t *eval = svprogfuncs->GetEdictFieldValue(svprogfuncs, sv_player, "playermodel", ev_string, NULL); - if (eval) - svprogfuncs->SetStringField(svprogfuncs, sv_player, &eval->string, Cmd_Argv(2), false); - } - if (progstype != PROG_QW && !strcmp(key, "skin")) - { - eval_t *eval = svprogfuncs->GetEdictFieldValue(svprogfuncs, sv_player, "playerskin", ev_string, NULL); - if (eval) - svprogfuncs->SetStringField(svprogfuncs, sv_player, &eval->string, Cmd_Argv(2), false); - } + if (progstype != PROG_QW && !strcmp(key, "model")) + { + eval_t *eval = svprogfuncs->GetEdictFieldValue(svprogfuncs, sv_player, "playermodel", ev_string, NULL); + if (eval) + svprogfuncs->SetStringField(svprogfuncs, sv_player, &eval->string, Cmd_Argv(2), false); + } + if (progstype != PROG_QW && !strcmp(key, "skin")) + { + eval_t *eval = svprogfuncs->GetEdictFieldValue(svprogfuncs, sv_player, "playerskin", ev_string, NULL); + if (eval) + svprogfuncs->SetStringField(svprogfuncs, sv_player, &eval->string, Cmd_Argv(2), false); + } #endif - // process any changed values - SV_ExtractFromUserinfo (host_client, true); + // process any changed values + // chat happens far too often and makes debugging annoying, as well as making logs spammy + if (strcmp(key, "chat")) + { + SV_ExtractFromUserinfo (host_client, true); + SV_LogPlayer(host_client, "userinfo changed"); + } - if (*key != '_') - { - val = Info_ValueForKey(host_client->userinfo, key); - - SV_BroadcastUserinfoChange(host_client, SV_UserInfoIsBasic(key), key, val); + PR_ClientUserInfoChanged(key, oldval, InfoBuf_ValueForKey(&host_client->userinfo, key)); + } } - - //doh't spam chat changes. they're not interesting, and just spammy. - if (strcmp(key, "chat")) - SV_LogPlayer(host_client, "userinfo changed"); - - PR_ClientUserInfoChanged(key, oldval, Info_ValueForKey(host_client->userinfo, key)); + Z_Free(key); + Z_Free(val); } /* @@ -4385,7 +4396,7 @@ Dumps the serverinfo info string void SV_ShowServerinfo_f (void) { SV_BeginRedirect(RD_CLIENT, host_client->language); - Info_Print (svs.info, ""); + InfoBuf_Print (&svs.info, ""); SV_EndRedirect(); } @@ -4950,8 +4961,8 @@ void SV_SetUpClientEdict (client_t *cl, edict_t *ent) } { - int tc = atoi(Info_ValueForKey(cl->userinfo, "topcolor")); - int bc = atoi(Info_ValueForKey(cl->userinfo, "bottomcolor")); + int tc = atoi(InfoBuf_ValueForKey(&cl->userinfo, "topcolor")); + int bc = atoi(InfoBuf_ValueForKey(&cl->userinfo, "bottomcolor")); if (tc < 0 || tc > 13) tc = 0; if (bc < 0 || bc > 13) @@ -5152,7 +5163,7 @@ void Cmd_Join_f (void) // turn the spectator into a player host_client->spectator = false; - Info_RemoveKey (host_client->userinfo, "*spectator"); + InfoBuf_RemoveKey (&host_client->userinfo, "*spectator"); // FIXME, bump the client's userid? @@ -5287,7 +5298,7 @@ void Cmd_Observe_f (void) // turn the player into a spectator host_client->spectator = true; - Info_SetValueForStarKey (host_client->userinfo, "*spectator", "1", sizeof(host_client->userinfo)); + InfoBuf_SetValueForStarKey (&host_client->userinfo, "*spectator", "1"); // FIXME, bump the client's userid? @@ -5555,8 +5566,8 @@ static void SVNQ_Begin_f (void) if (sv_playermodelchecks.value) { - pmodel = atoi(Info_ValueForKey (host_client->userinfo, "pmodel")); - emodel = atoi(Info_ValueForKey (host_client->userinfo, "emodel")); + pmodel = atoi(InfoBuf_ValueForKey (&host_client->userinfo, "pmodel")); + emodel = atoi(InfoBuf_ValueForKey (&host_client->userinfo, "emodel")); if (pmodel != sv.model_player_checksum || emodel != sv.eyes_player_checksum) @@ -5672,18 +5683,12 @@ static void SVNQ_NQColour_f (void) host_client->edict->v->team = bottom + 1; val = va("%i", top); - if (strcmp(val, Info_ValueForKey(host_client->userinfo, "topcolor"))) - { - Info_SetValueForKey(host_client->userinfo, "topcolor", val, sizeof(host_client->userinfo)); + if (InfoBuf_SetValueForKey(&host_client->userinfo, "topcolor", val)) SV_BroadcastUserinfoChange(host_client, true, "topcolor", NULL); - } val = va("%i", bottom); - if (strcmp(val, Info_ValueForKey(host_client->userinfo, "bottomcolor"))) - { - Info_SetValueForKey(host_client->userinfo, "bottomcolor", val, sizeof(host_client->userinfo)); + if (InfoBuf_SetValueForKey(&host_client->userinfo, "bottomcolor", val)) SV_BroadcastUserinfoChange(host_client, true, "bottomcolor", NULL); - } switch(bottom) { @@ -5697,9 +5702,9 @@ static void SVNQ_NQColour_f (void) val = va("t%i", bottom+1); break; } - if (strcmp(val, Info_ValueForKey(host_client->userinfo, "team"))) + if (strcmp(val, InfoBuf_ValueForKey(&host_client->userinfo, "team"))) { - Info_SetValueForKey(host_client->userinfo, "team", val, sizeof(host_client->userinfo)); + InfoBuf_SetValueForKey(&host_client->userinfo, "team", val); SV_BroadcastUserinfoChange(host_client, true, "team", NULL); } @@ -6066,6 +6071,7 @@ ucmd_t nqucmds[] = {"download", SV_BeginDownload_f}, {"sv_startdownload", SVDP_StartDownload_f}, + {"serverinfo", SV_ShowServerinfo_f}, /*userinfo stuff*/ {"setinfo", SV_SetInfo_f}, {"name", SVNQ_NQInfo_f}, @@ -8067,9 +8073,11 @@ void SVQ2_ExecuteClientMessage (client_t *cl) break; case clcq2_userinfo: - strncpy (cl->userinfo, MSG_ReadString (), sizeof(cl->userinfo)-1); - ge->ClientUserinfoChanged (cl->q2edict, cl->userinfo); //tell the gamecode + //FIXME: allows the client to set * keys mid-game. + s = MSG_ReadString(); + InfoBuf_FromString(&cl->userinfo, s, false); SV_ExtractFromUserinfo(cl, true); //let the server routines know + ge->ClientUserinfoChanged (cl->q2edict, s); //tell the gamecode break; case clcq2_stringcmd: @@ -8459,6 +8467,9 @@ void SV_UserInit (void) Cvar_Register (&sv_realiphostname_ipv6, cvargroup_servercontrol); Cvar_Register (&sv_realip_timeout, cvargroup_servercontrol); + Cvar_Register (&sv_userinfo_keylimit, cvargroup_servercontrol); + Cvar_Register (&sv_userinfo_bytelimit, cvargroup_servercontrol); + Cvar_Register (&sv_pushplayers, cvargroup_servercontrol); Cvar_Register (&sv_protocol_nq, cvargroup_servercontrol); diff --git a/engine/server/svq3_game.c b/engine/server/svq3_game.c index 7e250c610..09b14a1a8 100644 --- a/engine/server/svq3_game.c +++ b/engine/server/svq3_game.c @@ -1013,7 +1013,9 @@ static qintptr_t Q3G_SystemCalls(void *offset, unsigned int mask, qintptr_t fn, { char *dest = VM_POINTER(arg[0]); int length = VM_LONG(arg[1]); - Q_strncpyz(dest, svs.info, length); + if (VM_OOB(arg[1], arg[2])) + return 0; + InfoBuf_ToString(&svs.info, dest, length, NULL, NULL, NULL, NULL, NULL); } return true; case G_GET_USERINFO://int num, char *buffer, int bufferSize 20 @@ -1021,11 +1023,13 @@ static qintptr_t Q3G_SystemCalls(void *offset, unsigned int mask, qintptr_t fn, return 0; if ((unsigned)VM_LONG(arg[0]) >= sv.allocated_client_slots) return 0; - Q_strncpyz(VM_POINTER(arg[1]), svs.clients[VM_LONG(arg[0])].userinfo, VM_LONG(arg[2])); + InfoBuf_ToString(&svs.clients[VM_LONG(arg[0])].userinfo, VM_POINTER(arg[1]), VM_LONG(arg[2]), NULL, NULL, NULL, NULL, NULL); break; case G_SET_USERINFO://int num, char *buffer 20 - Q_strncpyz(svs.clients[VM_LONG(arg[0])].userinfo, VM_POINTER(arg[1]), sizeof(svs.clients[0].userinfo)); + if (VM_OOB(arg[1], 1)) + return 0; + InfoBuf_FromString(&svs.clients[VM_LONG(arg[0])].userinfo, VM_POINTER(arg[1]), false); SV_ExtractFromUserinfo(&svs.clients[VM_LONG(arg[0])], false); break; @@ -1894,13 +1898,13 @@ qboolean SVQ3_InitGame(void) q3_sentities = Z_Malloc(sizeof(q3serverEntity_t)*MAX_GENTITIES); - /*qw serverinfo settings are not normally visible in the q3 serverinfo*/ - strcpy(buffer, svs.info); - Info_SetValueForKey(buffer, "map", "", sizeof(buffer)); - Info_SetValueForKey(buffer, "maxclients", "", sizeof(buffer)); - Info_SetValueForKey(buffer, "mapname", svs.name, sizeof(buffer)); - Info_SetValueForKey(buffer, "sv_maxclients", "32", sizeof(buffer)); - Info_SetValueForKey(buffer, "sv_pure", "", sizeof(buffer)); + { /*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"); @@ -3069,8 +3073,7 @@ void SVQ3_ParseUsercmd(client_t *client, qboolean delta) void SVQ3_UpdateUserinfo_f(client_t *cl) { - Q_strncpyz(cl->userinfo, Cmd_Argv(1), sizeof(cl->userinfo)); - + InfoBuf_FromString(&cl->userinfo, Cmd_Argv(1), false); SV_ExtractFromUserinfo (cl, true); if (svs.gametype == GT_QUAKE3) @@ -3386,9 +3389,9 @@ void SVQ3_DirectConnect(void) //Actually connect the client, use up a slot, and reason = "Invalid challenge"; else { - Q_strncpyz(cl->userinfo, userinfo, sizeof(cl->userinfo)); + InfoBuf_FromString(&cl->userinfo, userinfo, false); reason = NET_AdrToString(adr, sizeof(adr), &net_from); - Info_SetValueForStarKey(cl->userinfo, "ip", reason, sizeof(cl->userinfo)); + InfoBuf_SetKey(&cl->userinfo, "ip", reason); ret = VM_Call(q3gamevm, GAME_CLIENT_CONNECT, (int)(cl-svs.clients), false, false); if (!ret) diff --git a/engine/shaders/generatebuiltinsl.c b/engine/shaders/generatebuiltinsl.c index 4ba1a580a..0ca6c4314 100644 --- a/engine/shaders/generatebuiltinsl.c +++ b/engine/shaders/generatebuiltinsl.c @@ -5,6 +5,7 @@ char shaders[][64] = { "fixedemu", + "q3terrain", "altwater", "bloom_blur", "bloom_filter", @@ -129,7 +130,7 @@ int main(void) if (!c) { printf("unable to open a file\n"); - return; + return 0; } fprintf(c, "/*\nWARNING: THIS FILE IS GENERATED BY '"__FILE__"'.\nYOU SHOULD NOT EDIT THIS FILE BY HAND\n*/\n\n"); @@ -166,4 +167,6 @@ int main(void) } fclose(c); + + return 0; } diff --git a/engine/shaders/glsl/defaultwall.glsl b/engine/shaders/glsl/defaultwall.glsl index 5f5353056..eba9fe51c 100644 --- a/engine/shaders/glsl/defaultwall.glsl +++ b/engine/shaders/glsl/defaultwall.glsl @@ -9,7 +9,7 @@ !!permu REFLECTCUBEMASK !!cvarf r_glsl_offsetmapping_scale !!cvardf r_tessellation_level=5 -!!samps diffuse lightmap specular normalmap fullbright reflectmask reflectcube paletted lightmap1 lightmap2 lightmap3 +!!samps diffuse lightmap specular normalmap fullbright reflectmask reflectcube paletted lightmap1 lightmap2 lightmap3 deluxemap deluxemap1 deluxemap2 deluxemap3 #include "sys/defs.h" @@ -271,16 +271,16 @@ void main () #else vec3 lightmaps = vc.rgb; #endif - #define delux vec3(0.0,0.0,1.0) + #define deluxe vec3(0.0,0.0,1.0) #else #ifdef LIGHTSTYLED - #define delux vec3(0.0,0.0,1.0) + #define deluxe vec3(0.0,0.0,1.0) vec3 lightmaps; #ifdef DELUXE - lightmaps = texture2D(s_lightmap0, lm0).rgb * e_lmscale[0].rgb * dot(norm, 2.0*texture2D(s_deluxmap0, lm0).rgb-0.5); - lightmaps += texture2D(s_lightmap1, lm1).rgb * e_lmscale[1].rgb * dot(norm, 2.0*texture2D(s_deluxmap1, lm1).rgb-0.5); - lightmaps += texture2D(s_lightmap2, lm2).rgb * e_lmscale[2].rgb * dot(norm, 2.0*texture2D(s_deluxmap2, lm2).rgb-0.5); - lightmaps += texture2D(s_lightmap3, lm3).rgb * e_lmscale[3].rgb * dot(norm, 2.0*texture2D(s_deluxmap3, lm3).rgb-0.5); + lightmaps = texture2D(s_lightmap0, lm0).rgb * e_lmscale[0].rgb * dot(norm, 2.0*texture2D(s_deluxemap0, lm0).rgb-0.5); + lightmaps += texture2D(s_lightmap1, lm1).rgb * e_lmscale[1].rgb * dot(norm, 2.0*texture2D(s_deluxemap1, lm1).rgb-0.5); + lightmaps += texture2D(s_lightmap2, lm2).rgb * e_lmscale[2].rgb * dot(norm, 2.0*texture2D(s_deluxemap2, lm2).rgb-0.5); + lightmaps += texture2D(s_lightmap3, lm3).rgb * e_lmscale[3].rgb * dot(norm, 2.0*texture2D(s_deluxemap3, lm3).rgb-0.5); #else lightmaps = texture2D(s_lightmap0, lm0).rgb * e_lmscale[0].rgb; lightmaps += texture2D(s_lightmap1, lm1).rgb * e_lmscale[1].rgb; @@ -291,15 +291,15 @@ void main () vec3 lightmaps = (texture2D(s_lightmap, lm0) * e_lmscale).rgb; //modulate by the bumpmap dot light #ifdef DELUXE - vec3 delux = (texture2D(s_deluxmap, lm0).rgb-0.5); + vec3 deluxe = (texture2D(s_deluxemap, lm0).rgb-0.5); #ifdef BUMPMODELSPACE - delux = normalize(delux*invsurface); + deluxe = normalize(deluxe*invsurface); #else - lightmaps *= 2.0 / max(0.25, delux.z); //counter the darkening from deluxmaps + lightmaps *= 2.0 / max(0.25, deluxe.z); //counter the darkening from deluxemaps #endif - lightmaps *= dot(norm, delux); + lightmaps *= dot(norm, deluxe); #else - #define delux vec3(0.0,0.0,1.0) + #define deluxe vec3(0.0,0.0,1.0) #endif #endif #endif @@ -307,7 +307,7 @@ void main () //add in specular, if applicable. #ifdef SPECULAR vec4 specs = texture2D(s_specular, tc); - vec3 halfdir = normalize(normalize(eyevector) + delux); //this norm should be the deluxemap info instead + vec3 halfdir = normalize(normalize(eyevector) + deluxe); //this norm should be the deluxemap info instead float spec = pow(max(dot(halfdir, norm), 0.0), FTE_SPECULAR_EXPONENT * specs.a); spec *= FTE_SPECULAR_MULTIPLIER; //NOTE: rtlights tend to have a *4 scaler here to over-emphasise the effect because it looks cool. diff --git a/engine/vk/vk_backend.c b/engine/vk/vk_backend.c index 6586d5ec4..557589aef 100644 --- a/engine/vk/vk_backend.c +++ b/engine/vk/vk_backend.c @@ -5069,7 +5069,6 @@ void VKBE_RT_End(struct vk_rendertarg *targ) static qboolean BE_GenerateRefraction(batch_t *batch, shader_t *bs) { - extern cvar_t r_refractreflect_scale; float oldil; int oldbem; // struct vk_rendertarg *targ; @@ -5093,8 +5092,8 @@ static qboolean BE_GenerateRefraction(batch_t *batch, shader_t *bs) r_refdef.vrect.x = 0; r_refdef.vrect.y = 0; - r_refdef.vrect.width = max(1, vid.fbvwidth*r_refractreflect_scale.value); - r_refdef.vrect.height = max(1, vid.fbvheight*r_refractreflect_scale.value); + r_refdef.vrect.width = max(1, vid.fbvwidth*bs->portalfboscale); + r_refdef.vrect.height = max(1, vid.fbvheight*bs->portalfboscale); VKBE_RT_Gen(&shaderstate.rt_reflection, r_refdef.vrect.width, r_refdef.vrect.height, false, RT_IMAGEFLAGS); VKBE_RT_Begin(&shaderstate.rt_reflection); R_DrawPortal(batch, cl.worldmodel->batches, NULL, 1); diff --git a/engine/vk/vk_init.c b/engine/vk/vk_init.c index 68a26f64f..62f7c07d6 100644 --- a/engine/vk/vk_init.c +++ b/engine/vk/vk_init.c @@ -3746,7 +3746,7 @@ qboolean VK_Init(rendererstate_t *info, const char **sysextnames, qboolean (*cre VkResult err; VkApplicationInfo app; VkInstanceCreateInfo inst_info; - int gpuidx; + int gpuidx = 0; const char *extensions[8]; uint32_t extensions_count = 0;