From 6e6a767ba61d071c544ee54091ad64903019f78e Mon Sep 17 00:00:00 2001 From: Spoike Date: Sat, 22 Aug 2015 02:59:01 +0000 Subject: [PATCH] fix hitmodel. allow providing a videomap shader as a cwindow background. because I can. move all the tenebrae hacks over to only explicitly detected tenebrae progs. small irc plugin update. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4969 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/cl_plugin.inc | 26 ++- engine/client/console.c | 33 +++- engine/client/keys.c | 21 ++- engine/client/pr_menu.c | 21 +++ engine/client/snd_dma.c | 6 +- engine/common/com_mesh.c | 7 +- engine/common/console.h | 2 + engine/common/net_ice.c | 297 ++++++++++++++++++++++++++++------- engine/gl/gl_backend.c | 2 +- engine/gl/gl_vidcommon.c | 10 ++ engine/server/net_preparse.c | 8 +- engine/server/pr_cmds.c | 3 + engine/server/progs.h | 2 +- engine/server/savegame.c | 1 + engine/server/sv_ents.c | 10 +- engine/server/world.c | 2 +- plugins/irc/ircclient.c | 49 +++--- 17 files changed, 405 insertions(+), 95 deletions(-) diff --git a/engine/client/cl_plugin.inc b/engine/client/cl_plugin.inc index 6fefdfee2..75885d815 100644 --- a/engine/client/cl_plugin.inc +++ b/engine/client/cl_plugin.inc @@ -1005,7 +1005,7 @@ static qintptr_t VARGS Plug_Con_GetConsoleString(void *offset, quintptr_t mask, { const char *conname = VM_POINTER(arg[0]); const char *attrib = VM_POINTER(arg[1]); - const char *value = VM_POINTER(arg[2]); + char *value = VM_POINTER(arg[2]); size_t size = VM_LONG(arg[3]); console_t *con = Con_FindConsole(conname); @@ -1016,6 +1016,17 @@ static qintptr_t VARGS Plug_Con_GetConsoleString(void *offset, quintptr_t mask, return 0; else if (!strcmp(attrib, "footer")) ; + else if (!strcmp(attrib, "title")) + { + Q_strncpyz(value, con->title, size); + } + else if (!strcmp(attrib, "backimage")) + { + if (con->backshader) + Q_strncpyz(value, con->backshader->name, size); + else + Q_strncpyz(value, con->backimage, size); + } return 0; } static qintptr_t VARGS Plug_Con_SetConsoleString(void *offset, quintptr_t mask, const qintptr_t *arg) @@ -1039,6 +1050,19 @@ static qintptr_t VARGS Plug_Con_SetConsoleString(void *offset, quintptr_t mask, Con_Footerf(con, false, "%s", value); else if (!strcmp(attrib, "title")) Q_strncpyz(con->title, value, sizeof(con->title)); + else if (!strcmp(attrib, "backimage")) + { + Q_strncpyz(con->backimage, value, sizeof(con->backimage)); + if (con->backshader) + R_UnloadShader(con->backshader); + } + else if (!strcmp(attrib, "backvideomap")) + { + Q_strncpyz(con->backimage, "", sizeof(con->backimage)); + if (con->backshader) + R_UnloadShader(con->backshader); + con->backshader = R_RegisterCustom(va("consolevid_%s", con->name), SUF_NONE, Shader_DefaultCinematic, value); + } else return -1; return 0; diff --git a/engine/client/console.c b/engine/client/console.c index a897fcfea..5c3a0c16c 100644 --- a/engine/client/console.c +++ b/engine/client/console.c @@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // console.c #include "quakedef.h" +#include "shader.h" console_t con_main; console_t *con_curwindow; @@ -103,6 +104,7 @@ int Con_IsActive (console_t *con) /*kills a console_t object. will never destroy the main console (which will only be cleared)*/ void Con_Destroy (console_t *con) { + shader_t *shader; console_t *prev; conline_t *t; /*purge the lines from the console*/ @@ -138,6 +140,8 @@ void Con_Destroy (console_t *con) } } + shader = con->backshader; + BZ_Free(con); if (con_current == con) @@ -154,6 +158,9 @@ void Con_Destroy (console_t *con) Key_Dest_Remove(kdm_cwindows); } con_mouseover = NULL; + + if (shader) + R_UnloadShader(shader); } /*obtains a console_t without creating*/ console_t *Con_FindConsole(const char *name) @@ -1720,7 +1727,7 @@ int Con_DrawAlternateConsoles(int lines) } return y; } -#include "shader.h" + //draws the conline_t list bottom-up within the width of the screen until the top of the screen is reached. //if text is selected, the selstartline globals will be updated, so make sure the lines persist or check them. static int Con_DrawConsoleLines(console_t *con, conline_t *l, int sx, int ex, int y, int top, qboolean selactive, int selsx, int selex, int selsy, int seley) @@ -2044,6 +2051,30 @@ void Con_DrawConsole (int lines, qboolean noback) R2D_ImageColours(0.0, 0.05, 0.1, 0.5); R2D_FillBlock(w->wnd_x, w->wnd_y, w->wnd_w, w->wnd_h); + + + if (w->backshader || *w->backimage) + { + shader_t *shader = w->backshader; + if (!shader) + shader = w->backshader = R_RegisterPic(w->backimage);// R_RegisterCustom(w->backimage, SUF_NONE, Shader_DefaultCinematic, w->backimage); + if (shader) + { + cin_t *cin = R_ShaderGetCinematic(shader); + if (cin) + { + Media_Send_Resize(cin, ((w->wnd_w-16.0)*(int)vid.rotpixelwidth) / (float)vid.width, ((w->wnd_h-16.0)*(int)vid.rotpixelheight) / (float)vid.height); + Media_Send_MouseMove(cin, (w->mousecursor[0]-8.0) / (w->wnd_w-16.0), (w->mousecursor[1]-8.0) / (w->wnd_h-16.0)); + if (con_curwindow==w) + Media_Send_Command(cin, "cmd:focus"); + else + Media_Send_Command(cin, "cmd:unfocus"); + } + R2D_ImageColours(1, 1, 1, 1); + R2D_Image(w->wnd_x+8, w->wnd_y+8, w->wnd_w-16, w->wnd_h-16, 0, 0, 1, 1, shader); + } + } + Draw_FunStringWidth(w->wnd_x, w->wnd_y, w->title, w->wnd_w-16, 2, (con_curwindow==w)?true:false); Draw_FunStringWidth(w->wnd_x+w->wnd_w-8, w->wnd_y, "X", 8, 2, (w->buttonsdown == CB_CLOSE&& w->mousecursor[0] > w->wnd_w-8 && w->mousecursor[1] < 8)?true:false); diff --git a/engine/client/keys.c b/engine/client/keys.c index 863cd889f..8a1c1898d 100644 --- a/engine/client/keys.c +++ b/engine/client/keys.c @@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifdef _WIN32 #include "winquake.h" #endif +#include "shader.h" /* key up events are sent even if in console mode @@ -982,6 +983,13 @@ void Key_ConsoleRelease(console_t *con, int key, int unicode) } // if (con->buttonsdown == CB_MOVE) //window title(move) con->buttonsdown = CB_NONE; + + if (con->backshader) + { + cin_t *cin = R_ShaderGetCinematic(con->backshader); + if (cin) + Media_Send_KeyEvent(cin, key, unicode, 1); + } } //if the referenced (trailing) chevron is doubled up, then it doesn't act as part of any markup and should be ignored for such things. static qboolean utf_specialchevron(unsigned char *start, unsigned char *chev) @@ -1353,12 +1361,23 @@ qboolean Key_Console (console_t *con, unsigned int unicode, int key) con->buttonsdown = CB_SCROLL; } - return true; + if ((con->buttonsdown == CB_COPY || con->buttonsdown == CB_SCROLL) && !con->linecount && !con->linebuffered) + con->buttonsdown = CB_NONE; + else + return true; } //console does not have any way to accept input, so don't try giving it any. if (!con->linebuffered) + { + if (con->backshader) + { + cin_t *cin = R_ShaderGetCinematic(con->backshader); + if (cin) + Media_Send_KeyEvent(cin, key, unicode, 0); + } return false; + } if (key == K_ENTER || key == K_KP_ENTER) { // backslash text are commands, else chat diff --git a/engine/client/pr_menu.c b/engine/client/pr_menu.c index 813a2b231..b1ff0960e 100644 --- a/engine/client/pr_menu.c +++ b/engine/client/pr_menu.c @@ -945,6 +945,27 @@ void QCBUILTIN PF_SubConGetSet (pubprogfuncs_t *prinst, struct globalvars_s *pr_ if (value) con->unseentext = atoi(value); } + else if (!strcmp(field, "backimage")) + { + RETURN_TSTRING(con->backshader?con->backshader->name:con->backimage); + if (value) + { + Q_strncpyz(con->backimage, value, sizeof(con->backimage)); + if (con->backshader) + R_UnloadShader(con->backshader); + } + } + else if (!strcmp(field, "backvideomap")) + { + RETURN_TSTRING(con->backshader?con->backshader->name:con->backimage); + if (value) + { + Q_strncpyz(con->backimage, "", sizeof(con->backimage)); + if (con->backshader) + R_UnloadShader(con->backshader); + con->backshader = R_RegisterCustom(va("consolevid_%s", con->name), SUF_NONE, Shader_DefaultCinematic, value); + } + } } void QCBUILTIN PF_SubConPrintf (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { diff --git a/engine/client/snd_dma.c b/engine/client/snd_dma.c index 2d20e582b..d504de55e 100644 --- a/engine/client/snd_dma.c +++ b/engine/client/snd_dma.c @@ -737,14 +737,14 @@ void S_Voip_Decode(unsigned int sender, unsigned int codec, unsigned int gen, un } #ifdef SUPPORT_ICE -qboolean S_Voip_RTP_CodecOkay(char *codec) +qboolean S_Voip_RTP_CodecOkay(const char *codec) { if (!strcmp(codec, "speex@8000") || !strcmp(codec, "speex@11025") || !strcmp(codec, "speex@16000") || !strcmp(codec, "speex@32000")) { if (S_Speex_Init()) return true; } - else if (!strcmp(codec, "opus")) + else if (!strcmp(codec, "opus") || !strcmp(codec, "opus@48000")) { if (S_Opus_Init()) return true; @@ -761,7 +761,7 @@ void S_Voip_RTP_Parse(unsigned short sequence, char *codec, unsigned char *data, S_Voip_Decode(MAX_CLIENTS-1, VOIP_SPEEX_WIDE, 0, sequence&0xff, datalen, data); if (!strcmp(codec, "speex@32000")) S_Voip_Decode(MAX_CLIENTS-1, VOIP_SPEEX_ULTRAWIDE, 0, sequence, datalen, data); - if (!strcmp(codec, "opus")) + if (!strcmp(codec, "opus") || !strcmp(codec, "opus@48000")) S_Voip_Decode(MAX_CLIENTS-1, VOIP_OPUS, 0, sequence, datalen, data); } qboolean NET_RTP_Transmit(unsigned int sequence, unsigned int timestamp, const char *codec, char *cdata, int clength); diff --git a/engine/common/com_mesh.c b/engine/common/com_mesh.c index c4849cbac..48480d48a 100644 --- a/engine/common/com_mesh.c +++ b/engine/common/com_mesh.c @@ -2221,6 +2221,7 @@ qboolean Mod_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], #endif } + trace->truefraction = 1; if (Mod_Trace_Trisoup(posedata, indexes, mod->numindexes, start_l, end_l, mins, maxs, trace) && axis) { if (axis) @@ -2250,9 +2251,9 @@ qboolean Mod_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], }*/ /*okay, this is where it hits this plane*/ -// trace->endpos[0] = traceinfo.start[0] + frac*(traceinfo.end[0] - traceinfo.start[0]); -// trace->endpos[1] = traceinfo.start[1] + frac*(traceinfo.end[1] - traceinfo.start[1]); -// trace->endpos[2] = traceinfo.start[2] + frac*(traceinfo.end[2] - traceinfo.start[2]); + trace->endpos[0] = start[0] + trace->fraction*(end[0] - start[0]); + trace->endpos[1] = start[1] + trace->fraction*(end[1] - start[1]); + trace->endpos[2] = start[2] + trace->fraction*(end[2] - start[2]); } mod = mod->nextsurf; diff --git a/engine/common/console.h b/engine/common/console.h index 02c744c0a..fb3d5688c 100644 --- a/engine/common/console.h +++ b/engine/common/console.h @@ -130,6 +130,8 @@ typedef struct console_s int nextlineid; //the current line being written to. so we can rewrite links etc. char name[128]; char title[128]; + char backimage[MAX_QPATH]; + shader_t *backshader; float wnd_x; float wnd_y; float wnd_w; diff --git a/engine/common/net_ice.c b/engine/common/net_ice.c index 26a060d33..946537d27 100644 --- a/engine/common/net_ice.c +++ b/engine/common/net_ice.c @@ -108,7 +108,7 @@ struct rtpheader_s unsigned int csrc[1]; //sized according to cc }; void S_Voip_RTP_Parse(unsigned short sequence, const char *codec, const unsigned char *data, unsigned int datalen); -qboolean S_Voip_RTP_CodecOkay(char *codec); +qboolean S_Voip_RTP_CodecOkay(const char *codec); qboolean NET_RTP_Parse(void) { struct rtpheader_s *rtpheader = (void*)net_message.data; @@ -522,7 +522,64 @@ void ICE_ToStunServer(struct icestate_s *con) NET_SendPacket((con->proto==ICEP_QWSERVER)?NS_SERVER:NS_CLIENT, buf.cursize, data, &con->pubstunserver); } -qboolean QDECL ICE_Set(struct icestate_s *con, char *prop, char *value) +void QDECL ICE_AddRCandidateInfo(struct icestate_s *con, struct icecandinfo_s *n) +{ + struct icecandidate_s *o; + qboolean isnew; + netadr_t peer; + //I don't give a damn about rtpc. + if (n->component != 1) + return; + if (n->transport != 0) + return; //only UDP is supported. + + if (!NET_StringToAdr(n->addr, n->port, &peer)) + return; + + if (peer.type == NA_IP) + { + //ignore invalid addresses + if (!peer.address.ip[0] && !peer.address.ip[1] && !peer.address.ip[2] && !peer.address.ip[3]) + return; + } + + for (o = con->rc; o; o = o->next) + { + //not sure that updating candidates is particuarly useful tbh, but hey. + if (!strcmp(o->info.candidateid, n->candidateid)) + break; + } + if (!o) + { + o = Z_Malloc(sizeof(*o)); + o->next = con->rc; + con->rc = o; + Q_strncpyz(o->info.candidateid, n->candidateid, sizeof(o->info.candidateid)); + + isnew = true; + } + else + { + isnew = false; + } + Q_strncpyz(o->info.addr, n->addr, sizeof(o->info.addr)); + o->info.port = n->port; + o->info.type = n->type; + o->info.priority = n->priority; + o->info.network = n->network; + o->info.generation = n->generation; + o->info.foundation = n->foundation; + o->info.component = n->component; + o->info.transport = n->transport; + o->dirty = true; + o->peer = peer; + o->tried = 0; + o->reachable = 0; + + Con_DPrintf("%s remote candidate %s: [%s]:%i\n", isnew?"Added":"Updated", o->info.candidateid, o->info.addr, o->info.port); +} + +qboolean QDECL ICE_Set(struct icestate_s *con, const char *prop, const char *value) { if (!strcmp(prop, "state")) { @@ -619,6 +676,111 @@ qboolean QDECL ICE_Set(struct icestate_s *con, char *prop, char *value) if (con->stunserver) NET_StringToAdr(con->stunserver, con->stunport, &con->pubstunserver); } +/* + else if (!strcmp(prop, "sdp")) + { + const char *eol; + for (; *value; value = eol) + { + eol = strchr(value, '\n'); + if (!eol) + eol = value+strlen(value); + + if (!strncmp(value, "a=ice-pwd:", 10)) + ICE_Set(con, "rpwd", value+10); + else if (!strncmp(value, "a=ice-ufrag:", 12)) + ICE_Set(con, "rufrag", value+12); + else if (!strncmp(value, "a=rtpmap:", 9)) + { + char name[64]; + int codec; + char *sl; + value += 9; + codec = strtoul(value, &value, 0); + if (*value == ' ') value++; + + COM_ParseOut(value, name, sizeof(name)); + sl = strchr(name, '/'); + if (sl) + *sl = '@'; + ICE_Set(con, va("codec%i", codec), name); + } + else if (!strncmp(value, "a=candidate:", 12)) + { + struct icecandinfo_s n; + memset(&n, 0, sizeof(n)); + + value += 12; + n.foundation = strtoul(value, &value, 0); + + if(*value == ' ')value++; + n.component = strtoul(value, &value, 0); + + if(*value == ' ')value++; + if (!strncmp(value, "UDP ", 4)) + { + n.transport = 0; + value += 3; + } + else + break; + + if(*value == ' ')value++; + n.priority = strtoul(value, &value, 0); + + if(*value == ' ')value++; + value = COM_ParseOut(value, n.addr, sizeof(n.addr)); + if (!value) break; + + if(*value == ' ')value++; + n.port = strtoul(value, &value, 0); + + if(*value == ' ')value++; + if (strncmp(value, "typ ", 4)) break; + value += 3; + + if(*value == ' ')value++; + if (!strncmp(value, "host", 4)) + n.type = ICE_HOST; + else if (!strncmp(value, "srflx", 4)) + n.type = ICE_SRFLX; + else if (!strncmp(value, "prflx", 4)) + n.type = ICE_PRFLX; + else if (!strncmp(value, "relay", 4)) + n.type = ICE_RELAY; + else + break; + + while (value < eol) + { + if(*value == ' ')value++; + if (!strncmp(value, "raddr ", 6)) + { + value += 6; + value = COM_ParseOut(value, n.reladdr, sizeof(n.reladdr)); + if (!value) + break; + } + else if (!strncmp(value, "rport ", 6)) + { + value += 6; + n.relport = strtoul(value, &value, 0); + } + else + { + //this is meant to be extensible. + while (*value && value < eol && *value != ' ') + value++; + if(*value == ' ')value++; + while (*value && value < eol && *value != ' ') + value++; + } + } + ICE_AddRCandidateInfo(con, &n); + } + } + } +*/ else return false; return true; @@ -657,6 +819,83 @@ qboolean QDECL ICE_Get(struct icestate_s *con, char *prop, char *value, int valu } } } +/* + else if (!strcmp(prop, "sdp")) + { + struct icecandidate_s *can; + netadr_t sender; + char tmpstr[MAX_QPATH], *at; + int i; + + { + netadr_t addr[1]; + struct ftenet_generic_connection_s *gcon[countof(addr)]; + int flags[countof(addr)]; + + if (!NET_EnumerateAddresses(ICE_PickConnection(con), gcon, flags, addr, countof(addr))) + sender.type = NA_INVALID; + else + sender = *addr; + } + + Q_strncpyz(value, "v=0\n", valuelen); + Q_strncatz(value, va("o=$NAME $? $? IN IP4 $ADR\n"), valuelen); + Q_strncatz(value, "s=\n", valuelen); + Q_strncatz(value, va("c=IN %s %s\n", sender.type==NA_IPV6?"IP6":"IP4", NET_BaseAdrToString(tmpstr, sizeof(tmpstr), &sender)), valuelen); + Q_strncatz(value, "t=0 0\n", valuelen); + Q_strncatz(value, va("a=ice-pwd:%s\n", con->lpwd), valuelen); + Q_strncatz(value, va("a=ice-ufrag:%s\n", con->lufrag), valuelen); + + for (i = 0; i < countof(con->codec); i++) + { + int codec = atoi(prop+5); + if (!con->codec[i]) + continue; + + Q_strncatz(value, va("m=audio %i RTP/AVP %i\n", sender.port, i+96), valuelen); + Q_strncatz(value, va("b=RS:0\n"), valuelen); + Q_strncatz(value, va("b=RR:0\n"), valuelen); + Q_strncpyz(tmpstr, con->codec[i], sizeof(tmpstr)); + at = strchr(tmpstr, '@'); + if (at) + { + *at = '/'; + Q_strncatz(value, va("a=rtpmap:%i %s\n", i+96, tmpstr), valuelen); + } + else + Q_strncatz(value, va("a=rtpmap:%i %s/%i\n", i+96, tmpstr, 8000), valuelen); + + for (can = con->lc; can; can = can->next) + { + char *ctype = NULL; + can->dirty = false; //doesn't matter now. + switch(can->info.type) + { + default: + case ICE_HOST: ctype = "host"; break; + case ICE_SRFLX: ctype = "srflx"; break; + case ICE_PRFLX: ctype = "prflx"; break; + case ICE_RELAY: ctype = "relay"; break; + } + Q_strncatz(value, va("a=candidate:%i %i %s %i %s %i typ %s", + can->info.foundation, + can->info.component, + can->info.transport==0?"UDP":"ERROR", + can->info.priority, + can->info.addr, + can->info.port, + ctype + ), valuelen); + if (can->info.type != ICE_HOST) + { + Q_strncatz(value, va(" raddr %s", can->info.reladdr), valuelen); + Q_strncatz(value, va(" rport %i", can->info.relport), valuelen); + } + Q_strncatz(value, "\n", valuelen); + } + } + } +*/ else return false; return true; @@ -720,60 +959,6 @@ void QDECL ICE_AddLCandidateConn(ftenet_connections_t *col, netadr_t *addr, int } } -void QDECL ICE_AddRCandidateInfo(struct icestate_s *con, struct icecandinfo_s *n) -{ - struct icecandidate_s *o; - qboolean isnew; - netadr_t peer; - //I don't give a damn about rtpc. - if (n->component != 1) - return; - - if (!NET_StringToAdr(n->addr, n->port, &peer)) - return; - - if (peer.type == NA_IP) - { - //ignore invalid addresses - if (!peer.address.ip[0] && !peer.address.ip[1] && !peer.address.ip[2] && !peer.address.ip[3]) - return; - } - - for (o = con->rc; o; o = o->next) - { - //not sure that updating candidates is particuarly useful tbh, but hey. - if (!strcmp(o->info.candidateid, n->candidateid)) - break; - } - if (!o) - { - o = Z_Malloc(sizeof(*o)); - o->next = con->rc; - con->rc = o; - Q_strncpyz(o->info.candidateid, n->candidateid, sizeof(o->info.candidateid)); - - isnew = true; - } - else - { - isnew = false; - } - Q_strncpyz(o->info.addr, n->addr, sizeof(o->info.addr)); - o->info.port = n->port; - o->info.type = n->type; - o->info.priority = n->priority; - o->info.network = n->network; - o->info.generation = n->generation; - o->info.foundation = n->foundation; - o->info.component = n->component; - o->info.transport = n->transport; - o->dirty = true; - o->peer = peer; - o->tried = 0; - o->reachable = 0; - - Con_DPrintf("%s remote candidate %s: [%s]:%i\n", isnew?"Added":"Updated", o->info.candidateid, o->info.addr, o->info.port); -} static void ICE_Destroy(struct icestate_s *con) { if (con->connections) diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index 47eeedb9b..0a504906d 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -629,7 +629,7 @@ static void BE_ApplyAttributes(unsigned int bitstochange, unsigned int bitstoend } } - if (!((bitstochange|bitstoendisable) & ~((1u<= sizeof(qbyte)*2+destprim->coordsize*6+sizeof(int)*2 && !data) @@ -1286,7 +1286,7 @@ void NPP_NQWriteByte(int dest, qbyte data) //replacement write func (nq to qw) break; case svcdp_showlmp: //tenebrae compat: - if (progstype == PROG_UNKNOWN) + if (progstype == PROG_TENEBRAE) { //svc, coord3, byte, effectname if (bufferlen >= sizeof(qbyte)*2+destprim->coordsize*3 && !data) diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index 43f52fa6c..ea3fec0af 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -523,6 +523,7 @@ static qboolean SVPR_Event_ContentsTransition(world_t *w, wedict_t *ent, int old #define QW_PROGHEADER_CRC 54730 #define NQ_PROGHEADER_CRC 5927 #define PREREL_PROGHEADER_CRC 26940 //prerelease +#define TENEBRAE_PROGHEADER_CRC 32401 //tenebrae #define H2_PROGHEADER_CRC 38488 //basic hexen2 #define H2MP_PROGHEADER_CRC 26905 //hexen2 mission pack uses slightly different defs... *sigh*... #define H2DEMO_PROGHEADER_CRC 14046 //I'm guessing this is from the original release or something @@ -540,6 +541,8 @@ pbool PDECL PR_SSQC_CheckHeaderCrc(pubprogfuncs_t *inst, progsnum_t idx, int crc #endif else if (crc == PREREL_PROGHEADER_CRC) modtype = PROG_PREREL; + else if (crc == TENEBRAE_PROGHEADER_CRC) + modtype = PROG_TENEBRAE; else modtype = PROG_UNKNOWN; diff --git a/engine/server/progs.h b/engine/server/progs.h index 4bcec0203..00484e201 100644 --- a/engine/server/progs.h +++ b/engine/server/progs.h @@ -50,7 +50,7 @@ void PRSV_RunThreads(void); extern int compileactive; -typedef enum {PROG_NONE, PROG_QW, PROG_NQ, PROG_H2, PROG_PREREL, PROG_UNKNOWN} progstype_t; //unknown obtains NQ behaviour +typedef enum {PROG_NONE, PROG_QW, PROG_NQ, PROG_H2, PROG_PREREL, PROG_TENEBRAE, PROG_UNKNOWN} progstype_t; //unknown obtains NQ behaviour extern progstype_t progstype; diff --git a/engine/server/savegame.c b/engine/server/savegame.c index 173a20c21..11a62d905 100644 --- a/engine/server/savegame.c +++ b/engine/server/savegame.c @@ -971,6 +971,7 @@ void SV_SaveLevelCache(char *savedir, qboolean dontharmgame) case PROG_NQ: mode = "NQ"; break; case PROG_H2: mode = "H2"; break; case PROG_PREREL: mode = "PREREL"; break; + case PROG_TENEBRAE: mode = "TENEBRAE"; break; case PROG_UNKNOWN: mode = "UNKNOWN"; break; } VFS_PRINTF (f, "vmmode %s\n", COM_QuotedString(mode, buf, sizeof(buf), false)); diff --git a/engine/server/sv_ents.c b/engine/server/sv_ents.c index 244d6bfe8..0aaf3c4e6 100644 --- a/engine/server/sv_ents.c +++ b/engine/server/sv_ents.c @@ -3086,8 +3086,8 @@ void SV_Snapshot_BuildStateQ1(entity_state_t *state, edict_t *ent, client_t *cli if (progstype != PROG_QW) { - if (progstype == PROG_UNKNOWN) - { //unknown progs crc. things here are basically hacks. + if (progstype == PROG_TENEBRAE) + { //tenebrae has some hideous hacks if (!strcmp(sv.strings.model_precache[state->modelindex], "progs/w_light.spr") || !strcmp(sv.strings.model_precache[state->modelindex], "progs/b_light.spr") || @@ -3126,14 +3126,14 @@ void SV_Snapshot_BuildStateQ1(entity_state_t *state, edict_t *ent, client_t *cli state->hexen2flags = 0; } } - else if (progstype == PROG_UNKNOWN) - { //unknown progs crc. things here are basically hacks. + else if (progstype == PROG_TENEBRAE) + { if (state->effects & 16) //tenebrae's EF_FULLDYNAMIC { state->effects &= ~16; state->lightpflags |= PFLAGS_FULLDYNAMIC; } - if (state->effects & 32) + if (state->effects & 32) //tenebrae's EF_GREEN { state->effects &= ~32; state->effects |= EF_GREEN; diff --git a/engine/server/world.c b/engine/server/world.c index 3691e817c..49fc92ba3 100644 --- a/engine/server/world.c +++ b/engine/server/world.c @@ -1119,7 +1119,7 @@ static trace_t World_ClipMoveToEntity (world_t *w, wedict_t *ent, vec3_t eorg, v } // if using hitmodel, we know it hit the bounding box, so try a proper trace now. - if (hitmodel && trace.fraction != 1 && !model) + if (hitmodel && (trace.fraction != 1 || trace.startsolid) && !model) { //okay, we hit the bbox model = w->Get_CModel(w, mdlidx); diff --git a/plugins/irc/ircclient.c b/plugins/irc/ircclient.c index ae89c1efd..bfd59e61e 100644 --- a/plugins/irc/ircclient.c +++ b/plugins/irc/ircclient.c @@ -17,9 +17,10 @@ vmcvar_t irc_debug = {"irc_debug", "0", irccvars, 0}; vmcvar_t irc_motd = {"irc_motd", "1", irccvars, 0}; vmcvar_t irc_nick = {"irc_nick", "anonymous", irccvars, 0}; vmcvar_t irc_altnick = {"irc_altnick", "unnamed", irccvars, 0}; -vmcvar_t irc_realname = {"irc_realname", "FTE IRC-Plugin http://www.fteqw.com", irccvars, 0}; +vmcvar_t irc_realname = {"irc_realname", "FTE IRC-Plugin", irccvars, 0}; vmcvar_t irc_ident = {"irc_ident", "FTE", irccvars, 0}; vmcvar_t irc_timestamp = {"irc_timestamp", "0", irccvars, 0}; +vmcvar_t irc_quitmessage = {"irc_quitmessage", "", irccvars, 0}; #undef irccvars vmcvar_t *cvarlist[] ={ @@ -30,6 +31,7 @@ vmcvar_t *cvarlist[] ={ &irc_realname, &irc_ident, &irc_timestamp, + &irc_quitmessage, NULL }; @@ -37,12 +39,10 @@ vmcvar_t *cvarlist[] ={ char commandname[64]; // belongs to magic tokenizer char subvar[9][1000]; // etghack char casevar[9][1000]; //numbered_command -time_t seconds; // irc_connect -int irc_connecting = 0; char servername[64]; // store server name #define CURRENTCONSOLE "" // need to make this the current console #define DEFAULTCONSOLE "" -#define RELEASE "__DATE__" +#define RELEASE __DATE__ void (*Con_TrySubPrint)(char *subname, char *text); void Con_FakeSubPrint(char *subname, char *text) @@ -55,6 +55,7 @@ void Con_SubPrintf(char *subname, char *format, ...) static char string[1024]; char lwr[128]; int i; + char *channame = subname; va_start (argptr, format); Q_vsnprintf (string, sizeof(string), format,argptr); @@ -76,6 +77,16 @@ void Con_SubPrintf(char *subname, char *format, ...) lwr[i] = *subname; } lwr[i] = '\0'; + + if (BUILTINISVALID(Con_SetConsoleFloat) && pCon_GetConsoleFloat(lwr, "iswindow") < true) + { + pCon_SetConsoleString(lwr, "title", channame); + pCon_SetConsoleFloat(lwr, "iswindow", true); + pCon_SetConsoleFloat(lwr, "forceutf8", true); + pCon_SetConsoleFloat(lwr, "wnd_w", 256); + pCon_SetConsoleFloat(lwr, "wnd_h", 320); + } + Con_TrySubPrint(lwr, string); } @@ -192,6 +203,7 @@ typedef struct { qhandle_t socket; + qboolean connecting; char nick[IRC_MAXNICKLEN]; char pwd[64]; char realname[128]; @@ -270,6 +282,7 @@ qintptr_t Plug_Init(qintptr_t *args) } IRC_InitCvars(); + Q_strlcpy(defaultuser, "FTEUser", sizeof(defaultuser)); return true; } else @@ -325,16 +338,13 @@ void IRC_AddClientMessage(ircclient_t *irc, char *msg) ircclient_t *IRC_Connect(char *server, int defport) { ircclient_t *irc; - unsigned long _true = true; - - seconds = time (NULL); // when we connected - irc_connecting = 1; //we are connecting.. so lets do the nickname stuff irc = IRC_Malloc(sizeof(ircclient_t)); if (!irc) return NULL; memset(irc, 0, sizeof(ircclient_t)); + irc->connecting = true; irc->socket = pNet_TCPConnect(server, defport); //port is only used if the url doesn't contain one. It's a default. @@ -582,17 +592,20 @@ void numbered_command(int comm,char *msg,ircclient_t *irc) // move vars up 1 mor switch (comm) { - case 001: - case 002: - case 003: - case 004: - case 005: + case 1: + case 2: + case 3: + case 4: + case 5: { - irc_connecting = 0; // ok we are connected + irc->connecting = 0; // ok we are connected Con_SubPrintf(DEFAULTCONSOLE, COLOURYELLOW "SERVER STATS: %s\n",casevar[3]); return; } +// case 020: +// Con_SubPrintf(DEFAULTCONSOLE, COLOURYELLOW "SERVER STATS: %s\n",casevar[3]); +// return; case 250: case 251: case 252: @@ -769,11 +782,11 @@ void numbered_command(int comm,char *msg,ircclient_t *irc) // move vars up 1 mor Con_SubPrintf(DEFAULTCONSOLE, COLOURRED "ERROR: <%s> is already in use.\n",nickname); - if ( !strcmp(nickname,irc_nick.string) && (irc_connecting == 1) ) + if ( !strcmp(nickname,irc_nick.string) && (irc->connecting == 1) ) { IRC_SetNick(irc, irc_altnick.string); } - else if ( !strcmp(nickname,irc_altnick.string) && (irc_connecting == 1) ) + else if ( !strcmp(nickname,irc_altnick.string) && (irc->connecting == 1) ) { Con_SubPrintf(DEFAULTCONSOLE, COLOURRED "ERROR: <%s> AND <%s> both in use. Attempting generic nickname.\n",irc_nick.string,irc_altnick.string); seedednick = va("FTE%i",rand()); @@ -783,7 +796,7 @@ void numbered_command(int comm,char *msg,ircclient_t *irc) // move vars up 1 mor } else { - if (irc_connecting == 1) + if (irc->connecting == 1) { seedednick = va("FTE%i",rand()); IRC_SetNick(irc, seedednick); @@ -1443,7 +1456,7 @@ void IRC_Command(char *dest) if (*token) IRC_AddClientMessage(ircclient, va("QUIT :%s", token)); else - IRC_AddClientMessage(ircclient, va("QUIT :FTE QuakeWorld IRC-Plugin Release: %s http://www.fteqw.com/plugins/", RELEASE)); + IRC_AddClientMessage(ircclient, va("QUIT :%s", irc_quitmessage.string)); } else if (!strcmp(token+1, "whois")) {