diff --git a/engine/client/cl_plugin.inc b/engine/client/cl_plugin.inc index 1701458b3..2dd93ec0e 100644 --- a/engine/client/cl_plugin.inc +++ b/engine/client/cl_plugin.inc @@ -413,6 +413,12 @@ qintptr_t VARGS Plug_Con_SubPrint(void *offset, quintptr_t mask, const qintptr_t if (currentplug->conexecutecommand) { + con->notif_x = 0; + con->notif_y = 8*4; + con->notif_w = vid.width; + con->notif_t = 8; + con->notif_l = 4; + con->flags |= CONF_NOTIFY; con->userdata = currentplug; con->linebuffered = Plug_SubConsoleCommand; } diff --git a/engine/client/cl_screen.c b/engine/client/cl_screen.c index 88e0b74bf..a1dfb4905 100644 --- a/engine/client/cl_screen.c +++ b/engine/client/cl_screen.c @@ -882,30 +882,6 @@ void SCR_ShowPic_Script_f(void) //============================================================================= -/* -==================== -CalcFov -==================== -*/ -float CalcFov (float fov_x, float width, float height) -{ - float a; - float x; - - if (fov_x < 1 || fov_x > 179) - Sys_Error ("Bad fov: %f", fov_x); - - x = fov_x/360*M_PI; - x = tan(x); - x = width/x; - - a = atan (height/x); - - a = a*360/M_PI; - - return a; -} - void SCR_Fov_Callback (struct cvar_s *var, char *oldvalue) { if (var->value < 10) diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index 1c442b6e9..d2fcacd76 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -1142,11 +1142,15 @@ void QCBUILTIN PF_R_PolygonEnd(pubprogfuncs_t *prinst, struct globalvars_s *pr_g qboolean csqc_rebuildmatricies; float csqc_proj_matrix[16]; float csqc_proj_matrix_inverse[16]; +void V_ApplyAFov(void); void buildmatricies(void) { float modelview[16]; float proj[16]; + if (r_refdef.dirty & RDFD_FOV) + V_ApplyAFov(); + /*build modelview and projection*/ Matrix4x4_CM_ModelViewMatrix(modelview, r_refdef.viewangles, r_refdef.vieworg); Matrix4x4_CM_Projection2(proj, r_refdef.fov_x, r_refdef.fov_y, 4); diff --git a/engine/client/snd_dma.c b/engine/client/snd_dma.c index 29a288f35..6d8db6f5e 100644 --- a/engine/client/snd_dma.c +++ b/engine/client/snd_dma.c @@ -1064,7 +1064,7 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf) if (outpos && (!buf || buf->maxsize - buf->cursize >= outpos+4)) { - if (buf && (cl_voip_send.ival & ~4)) + if (buf && (cl_voip_send.ival != 4)) { MSG_WriteByte(buf, clc); MSG_WriteByte(buf, (s_voip.enccodec<<4) | (s_voip.generation & 0x0f)); /*gonna leave that nibble clear here... in this version, the client will ignore packets with those bits set. can use them for codec or something*/ diff --git a/engine/client/view.c b/engine/client/view.c index f125a501c..51cd0e614 100644 --- a/engine/client/view.c +++ b/engine/client/view.c @@ -1014,7 +1014,56 @@ void V_CalcIntermissionRefdef (playerview_t *pv) v_idlescale.value = old; } -float CalcFov (float fov_x, float width, float height); +float CalcFov (float fov_x, float width, float height) +{ + float a; + float x; + + if (fov_x < 1 || fov_x > 179) + Sys_Error ("Bad fov: %f", fov_x); + + x = fov_x/360*M_PI; + x = tan(x); + x = width/x; + + a = atan (height/x); + + a = a*360/M_PI; + + return a; +} +void V_ApplyAFov(void) +{ + //explicit fov overrides aproximate fov. + //aproximate fov is our regular fov value. explicit is settable by gamecode for weird aspect ratios + if (!r_refdef.fov_x || !r_refdef.fov_y) + { + extern cvar_t r_stereo_method, r_stereo_separation; + float ws; + + float afov = r_refdef.afov; + if (!afov) //make sure its sensible. + afov = scr_fov.value; + if (r_refdef.playerview->stats[STAT_VIEWZOOM]) + afov *= r_refdef.playerview->stats[STAT_VIEWZOOM]/255.0f; + + ws = 1; + if (r_stereo_method.ival == 5 && r_stereo_separation.value) + ws = 0.5; + + //attempt to retain a classic fov + if (ws*r_refdef.vrect.width < (r_refdef.vrect.height*640)/432) + { + r_refdef.fov_y = CalcFov(afov, (ws*r_refdef.vrect.width*vid.pixelwidth)/vid.width, (r_refdef.vrect.height*vid.pixelheight)/vid.height); + r_refdef.fov_x = afov;//CalcFov(r_refdef.fov_y, 432, 640); + } + else + { + r_refdef.fov_y = CalcFov(afov, 640, 432); + r_refdef.fov_x = CalcFov(r_refdef.fov_y, r_refdef.vrect.height, r_refdef.vrect.width*ws); + } + } +} /* ================= v_ApplyRefdef @@ -1109,37 +1158,7 @@ void V_ApplyRefdef (void) r_refdef.vrect.y += r_refdef.grect.y; if (r_refdef.dirty & RDFD_FOV) - { - //explicit fov overrides aproximate fov. - //aproximate fov is our regular fov value. explicit is settable by gamecode for weird aspect ratios - if (!r_refdef.fov_x || !r_refdef.fov_y) - { - extern cvar_t r_stereo_method, r_stereo_separation; - float ws; - - float afov = r_refdef.afov; - if (!afov) //make sure its sensible. - afov = scr_fov.value; - if (r_refdef.playerview->stats[STAT_VIEWZOOM]) - afov *= r_refdef.playerview->stats[STAT_VIEWZOOM]/255.0f; - - ws = 1; - if (r_stereo_method.ival == 5 && r_stereo_separation.value) - ws = 0.5; - - //attempt to retain a classic fov - if (ws*r_refdef.vrect.width < (r_refdef.vrect.height*640)/432) - { - r_refdef.fov_y = CalcFov(afov, (ws*r_refdef.vrect.width*vid.pixelwidth)/vid.width, (r_refdef.vrect.height*vid.pixelheight)/vid.height); - r_refdef.fov_x = afov;//CalcFov(r_refdef.fov_y, 432, 640); - } - else - { - r_refdef.fov_y = CalcFov(afov, 640, 432); - r_refdef.fov_x = CalcFov(r_refdef.fov_y, r_refdef.vrect.height, r_refdef.vrect.width*ws); - } - } - } + V_ApplyAFov(); r_refdef.dirty = 0; } diff --git a/engine/common/net_wins.c b/engine/common/net_wins.c index e6848ffe4..cc98a7604 100644 --- a/engine/common/net_wins.c +++ b/engine/common/net_wins.c @@ -5631,6 +5631,8 @@ void QDECL ICE_Close(struct icestate_s *con) { struct icestate_s **link; + ICE_Set(con, "state", STRINGIFY(ICE_INACTIVE)); + for (link = &icelist; *link; ) { if (con == *link) diff --git a/engine/gl/gl_heightmap.c b/engine/gl/gl_heightmap.c index 12b8535e1..7d2f48ad5 100644 --- a/engine/gl/gl_heightmap.c +++ b/engine/gl/gl_heightmap.c @@ -688,7 +688,7 @@ static hmsection_t *Terr_LoadSection(heightmap_t *hm, hmsection_t *s, int sx, in #endif diskimage = NULL; - len = -1;//FS_LoadFile(Terr_DiskSectionName(hm, sx, sy), (void**)&diskimage); + len = FS_LoadFile(Terr_DiskSectionName(hm, sx, sy), (void**)&diskimage); /*queue the file for download if we don't have it yet*/ if (len < 0) @@ -2477,7 +2477,7 @@ qboolean Heightmap_Trace(struct model_s *model, int hulloverride, int frame, vec if (hmtrace.frac == -1) { - trace->fraction = 0; + trace->fraction = 1; trace->startsolid = true; trace->allsolid = true; VectorCopy(start, trace->endpos); diff --git a/plugins/jabber/jabberclient.c b/plugins/jabber/jabberclient.c index 31ebd7d7b..dfc3cf0e9 100644 --- a/plugins/jabber/jabberclient.c +++ b/plugins/jabber/jabberclient.c @@ -275,6 +275,7 @@ qintptr_t Plug_Init(qintptr_t *args) #define CAP_QUERIED 1 //a query is pending or something. #define CAP_VOICE 2 //supports voice #define CAP_INVITE 4 //supports game invites. +#define CAP_POKE 8 //can be slapped. typedef struct bresource_s { @@ -673,19 +674,19 @@ void JCL_Join(jclient_t *jcl, char *target, char *sid, qboolean allow, int proto xmltree_t *jingle; struct icestate_s *ice; char autotarget[256]; + buddy_t *b; + bresource_t *br; if (!jcl) return; - if (!strchr(target, '/')) - { - buddy_t *b; - bresource_t *br; - JCL_FindBuddy(jcl, target, &b, &br); - if (!br) - br = b->defaultresource; - if (!br) - br = b->resources; + JCL_FindBuddy(jcl, target, &b, &br); + if (!br) + br = b->defaultresource; + if (!br) + br = b->resources; + if (!strchr(target, '/')) + { if (!br) { Con_Printf("User name not valid\n"); @@ -712,23 +713,23 @@ void JCL_Join(jclient_t *jcl, char *target, char *sid, qboolean allow, int proto c2c = JCL_JingleCreateSession(jcl, target, true, sid, DEFAULTICEMODE, ((protocol == ICEP_INVALID)?ICEP_QWCLIENT:protocol)); JCL_JingleSend(jcl, c2c, "session-initiate"); - Con_Printf("%s ^[[%s]\\xmpp\\%s^] ^[[Hang Up]\\xmppact\\jdeny\\xmpp\\%s\\xmppsid\\%s^].\n", protocol==ICEP_VOICE?"Calling":"Requesting session with", target, target, target, c2c->sid); + Con_SubPrintf(b->name, "%s ^[[%s]\\xmpp\\%s^] ^[[Hang Up]\\xmppact\\jdeny\\xmpp\\%s\\xmppsid\\%s^].\n", protocol==ICEP_VOICE?"Calling":"Requesting session with", target, target, target, c2c->sid); } else - Con_Printf("That session has expired.\n"); + Con_SubPrintf(b->name, "That session has expired.\n"); } else if (c2c->creator) { //resend initiate if they've not acked it... I dunno... JCL_JingleSend(jcl, c2c, "session-initiate"); - Con_Printf("Restarting session with ^[[%s]\\xmpp\\%s^].\n", target, target); + Con_SubPrintf(b->name, "Restarting session with ^[[%s]\\xmpp\\%s^].\n", target, target); } else if (c2c->accepted) - Con_Printf("That session was already accepted.\n"); + Con_SubPrintf(b->name, "That session was already accepted.\n"); else { JCL_JingleSend(jcl, c2c, "session-accept"); - Con_Printf("Accepting session from ^[[%s]\\xmpp\\%s^].\n", target, target); + Con_SubPrintf(b->name, "Accepting session from ^[[%s]\\xmpp\\%s^].\n", target, target); } } else @@ -736,10 +737,10 @@ void JCL_Join(jclient_t *jcl, char *target, char *sid, qboolean allow, int proto if (c2c) { JCL_JingleSend(jcl, c2c, "session-terminate"); - Con_Printf("Terminating session with ^[[%s]\\xmpp\\%s^].\n", target, target); + Con_SubPrintf(b->name, "Terminating session with ^[[%s]\\xmpp\\%s^].\n", target, target); } else - Con_Printf("That session has already expired.\n"); + Con_SubPrintf(b->name, "That session has already expired.\n"); } } @@ -835,6 +836,7 @@ qboolean JCL_JingleHandleInitiate(jclient_t *jcl, xmltree_t *inj, char *from) struct c2c_s *c2c = NULL; int mt = ICEP_INVALID; + buddy_t *b; //FIXME: add support for session forwarding so that we might forward the connection to the real server. for now we just reject it. initiator = XML_GetParameter(inj, "initiator", ""); @@ -876,6 +878,9 @@ qboolean JCL_JingleHandleInitiate(jclient_t *jcl, xmltree_t *inj, char *from) if (!c2c) return false; + + JCL_FindBuddy(jcl, from, &b, NULL); + if (c2c->mediatype == ICEP_VOICE) { qboolean okay = false; @@ -916,7 +921,7 @@ qboolean JCL_JingleHandleInitiate(jclient_t *jcl, xmltree_t *inj, char *from) if (!pCvar_GetFloat(autocvar)) { //show a prompt for it, send the reply when the user decides. - Con_Printf( + Con_SubPrintf(b->name, "^[[%s]\\xmpp\\%s^] wants to %s. " "^[[Authorise]\\xmppact\\jauth\\xmpp\\%s\\xmppsid\\%s^] " "^[[Deny]\\xmppact\\jdeny\\xmpp\\%s\\xmppsid\\%s^]\n", @@ -924,11 +929,12 @@ qboolean JCL_JingleHandleInitiate(jclient_t *jcl, xmltree_t *inj, char *from) offer, from, sid, from, sid); + pCon_SetActive(b->name); return true; } else { - Con_Printf("Auto-accepting session from ^[[%s]\\xmpp\\%s^]\n", from, from); + Con_SubPrintf(b->name, "Auto-accepting session from ^[[%s]\\xmpp\\%s^]\n", from, from); response = "session-accept"; } } @@ -943,6 +949,7 @@ qboolean JCL_ParseJingle(jclient_t *jcl, xmltree_t *tree, char *from, char *id) char *sid = XML_GetParameter(tree, "sid", ""); struct c2c_s *c2c = NULL, **link; + buddy_t *b; for (link = &jcl->c2c; *link; link = &(*link)->next) { @@ -954,6 +961,8 @@ qboolean JCL_ParseJingle(jclient_t *jcl, xmltree_t *tree, char *from, char *id) } } + JCL_FindBuddy(jcl, from, &b, NULL); + //validate sender if (c2c && strcmp(c2c->with, from)) { @@ -972,9 +981,9 @@ qboolean JCL_ParseJingle(jclient_t *jcl, xmltree_t *tree, char *from, char *id) } if (reason && reason->child) - Con_Printf("Session ended: %s\n", reason->child->name); + Con_SubPrintf(b->name, "Session ended: %s\n", reason->child->name); else - Con_Printf("Session ended\n"); + Con_SubPrintf(b->name, "Session ended\n"); //unlink it for (link = &jcl->c2c; *link; link = &(*link)->next) @@ -1052,7 +1061,7 @@ qboolean JCL_ParseJingle(jclient_t *jcl, xmltree_t *tree, char *from, char *id) { return false; } - Con_Printf("Session Accepted!\n"); + Con_SubPrintf(b->name, "Session Accepted!\n"); // XML_ConPrintTree(tree, 0); JCL_JingleParsePeerPorts(jcl, c2c, tree, from); @@ -1754,6 +1763,7 @@ static char *caps[] = "urn:xmpp:time", #endif "urn:xmpp:ping", //FIXME: I'm not keen on this. I only added support to stop errors from pidgin when trying to debug. + "urn:xmpp:attention:0", //poke. #else //for testing, this is the list of features pidgin supports (which is the other client I'm testing against). @@ -2103,6 +2113,15 @@ void JCL_ParseMessage(jclient_t *jcl, xmltree_t *tree) } } + ot = XML_ChildOfTree(tree, "attention", 0); + if (ot) + { + Con_SubPrintf(f, "%s is an attention whore.\n", f); + pCon_SetActive(f); + if (BUILTINISVALID(LocalSound)) + pLocalSound("misc/talk.wav"); + } + ot = XML_ChildOfTree(tree, "body", 0); if (ot) { @@ -2963,7 +2982,89 @@ void JCL_SendMessage(jclient_t *jcl, char *to, char *msg) else Con_SubPrintf(b->name, "^5%s^7: "COLOURYELLOW"%s\n", jcl->localalias, msg); } +void JCL_AttentionMessage(jclient_t *jcl, char *to, char *msg) +{ + char fullto[256]; + buddy_t *b; + bresource_t *br; + xmltree_t *m; + char *s; + JCL_FindBuddy(jcl, to, &b, &br); + if (!br) + br = b->defaultresource; + if (!br) + br = b->resources; + if (!br) + { + Con_SubPrintf(b->name, "User is not online\n"); + return; + } + Q_snprintf(fullto, sizeof(fullto), "%s/%s", b->accountdomain, br->resource); + + m = XML_CreateNode(NULL, "message", "", ""); + XML_AddParameter(m, "to", fullto); +// XML_AddParameter(m, "type", "headline"); + + XML_CreateNode(m, "attention", "urn:xmpp:attention:0", ""); + if (msg) + XML_CreateNode(m, "body", "", msg); + + s = XML_GenerateString(m); + JCL_AddClientMessageString(jcl, s); + free(s); + XML_Destroy(m); + + if (msg) + { + if (!strncmp(msg, "/me ", 4)) + Con_SubPrintf(b->name, "*^5%s^7"COLOURYELLOW"%s\n", ((!strcmp(jcl->localalias, ">>"))?"me":jcl->localalias), msg+3); + else + Con_SubPrintf(b->name, "^5%s^7: "COLOURYELLOW"%s\n", jcl->localalias, msg); + } +} + +void JCL_ToJID(jclient_t *jcl, char *in, char *out, int outsize) +{ + //decompose links first + if (in[0] == '^' && in[1] == '[') + { + char *sl; + char *le; + sl = in+2; + sl = strchr(in, '\\'); + if (sl) + { + le = strstr(sl, "^]"); + if (le) + { + *le = 0; + JCL_Info_ValueForKey(in, "xmpp", out, outsize); + *le = '^'; + return; + } + } + } + + if (!strchr(in, '@')) + { + //no @? probably its an alias, but could also be a server/domain perhaps. not sure we care. you'll just have to rename your friend. + //check to see if we can find a friend going by that name + //fixme: allow resources to make it through here + buddy_t *b; + for (b = jcl->buddies; b; b = b->next) + { + if (!strcasecmp(b->name, in)) + { + Q_strlcpy(out, b->accountdomain, outsize); + return; + } + } + } + + //a regular jabber account name + Q_strlcpy(out, in, outsize); +} void JCL_Command(char *console) { @@ -2971,6 +3072,7 @@ void JCL_Command(char *console) char arg[6][256]; char *msg; int i; + char nname[256]; pCmd_Args(imsg, sizeof(imsg)); @@ -2984,6 +3086,8 @@ void JCL_Command(char *console) if (arg[0][0] == '/' && arg[0][1] != '/' && strcmp(arg[0]+1, "me")) { + JCL_ToJID(jclient, *arg[1]?arg[1]:console, nname, sizeof(nname)); + if (!strcmp(arg[0]+1, "open") || !strcmp(arg[0]+1, "connect") || !strcmp(arg[0]+1, "tlsopen") || !strcmp(arg[0]+1, "tlsconnect")) { //tlsconnect is 'old'. if (!*arg[1]) @@ -3107,19 +3211,41 @@ void JCL_Command(char *console) } else if (!strcmp(arg[0]+1, "join")) { - JCL_Join(jclient, *arg[1]?arg[1]:console, NULL, true, ICEP_QWCLIENT); + JCL_Join(jclient, nname, NULL, true, ICEP_QWCLIENT); } else if (!strcmp(arg[0]+1, "invite")) { - JCL_Join(jclient, *arg[1]?arg[1]:console, NULL, true, ICEP_QWSERVER); + JCL_Join(jclient, nname, NULL, true, ICEP_QWSERVER); } else if (!strcmp(arg[0]+1, "voice") || !strcmp(arg[0]+1, "call")) { - JCL_Join(jclient, *arg[1]?arg[1]:console, NULL, true, ICEP_VOICE); + JCL_Join(jclient, nname, NULL, true, ICEP_VOICE); } else if (!strcmp(arg[0]+1, "kick")) { - JCL_Join(jclient, *arg[1]?arg[1]:console, NULL, false, ICEP_INVALID); + JCL_Join(jclient, nname, NULL, false, ICEP_INVALID); + } + else if (!strcmp(arg[0]+1, "slap")) + { + char *msgtab[] = + { + "/me slaps you around a bit with a large trout", + "/me slaps you around a bit with a large tunafish", + "/me slaps you around a bit with a slimy hagfish", + "/me slaps a large trout around a bit with your face", + "/me gets eaten by a rabid shark while trying to slap you with it", + "/me gets crushed under the weight of a large whale", + "/me searches for a fresh fish, but gets crabs instead", + "/me searches for a fish, but there are no more fish in the sea", + "/me tickles you around a bit with a large fish finger", + "/me goes to order cod and chips. brb", + "/me goes to watch some monty python" + }; + JCL_AttentionMessage(jclient, nname, msgtab[rand()%(sizeof(msgtab)/sizeof(msgtab[0]))]); + } + else if (!strcmp(arg[0]+1, "poke")) + { + JCL_AttentionMessage(jclient, nname, NULL); } else if (!strcmp(arg[0]+1, "raw")) { @@ -3145,7 +3271,8 @@ void JCL_Command(char *console) } else { - JCL_SendMessage(jclient, jclient->defaultdest, msg); + JCL_ToJID(jclient, *console?console:jclient->defaultdest, nname, sizeof(nname)); + JCL_SendMessage(jclient, nname, msg); } } else