[ioquake3] [PATCH] mumble link support

Ludwig Nussel ludwig.nussel at suse.de
Sun May 25 11:24:37 PDT 2008


Hi,

Ryan's patch finally pointed me at the missing pieces that were
necessary to link mumble and ioquake3. The coordinate calculation is
adopted from Warsow's mumble patch. I don't know the first thing
about q3's coordinate system so no idea whether that's correct. At
least the loudness of a player's voice seems to change with
distance. I could be hallucinating though ;-) Needs a real life
test.

Mumble link support doesn't add external dependencies.
Tested on Linux. Mingw cross compilation also still works.

Mumble packages for SUSE, Fedora and Mandriva are available from the build
service btw if anyone wants to test but is scared by mumble's use of qmake...
http://download.opensuse.org/repositories/home:/lnussel:/mumble/

cu
Ludwig

---
 Makefile                    |   33 +++++++++++
 code/client/cl_cgame.c      |    9 +++
 code/client/cl_main.c       |   61 +++++++++++++++++++
 code/client/client.h        |    5 ++
 code/client/libmumblelink.c |  134 +++++++++++++++++++++++++++++++++++++++++++
 code/client/libmumblelink.h |   26 ++++++++
 6 files changed, 268 insertions(+), 0 deletions(-)
 create mode 100644 code/client/libmumblelink.c
 create mode 100644 code/client/libmumblelink.h

diff --git a/Makefile b/Makefile
index e124f25..fa7928b 100644
--- a/Makefile
+++ b/Makefile
@@ -125,6 +125,10 @@ ifndef USE_CODEC_VORBIS
 USE_CODEC_VORBIS=0
 endif
 
+ifndef USE_MUMBLE
+USE_MUMBLE=1
+endif
+
 ifndef USE_LOCAL_HEADERS
 USE_LOCAL_HEADERS=1
 endif
@@ -232,6 +236,10 @@ ifeq ($(PLATFORM),linux)
     BASE_CFLAGS += -DUSE_CODEC_VORBIS
   endif
 
+  ifeq ($(USE_MUMBLE),1)
+    BASE_CFLAGS += -DUSE_MUMBLE
+  endif
+
   OPTIMIZE = -O3 -ffast-math -funroll-loops -fomit-frame-pointer
 
   ifeq ($(ARCH),x86_64)
@@ -283,6 +291,10 @@ ifeq ($(PLATFORM),linux)
     CLIENT_LDFLAGS += -lvorbisfile -lvorbis -logg
   endif
 
+  ifeq ($(USE_MUMBLE),1)
+    CLIENT_LDFLAGS += -lrt
+  endif
+
   ifeq ($(ARCH),i386)
     # linux32 make ...
     BASE_CFLAGS += -m32
@@ -346,6 +358,10 @@ ifeq ($(PLATFORM),darwin)
     CLIENT_LDFLAGS += -lvorbisfile -lvorbis -logg
   endif
 
+  ifeq ($(USE_MUMBLE),1)
+    BASE_CFLAGS += -DUSE_MUMBLE
+  endif
+
   BASE_CFLAGS += -D_THREAD_SAFE=1
 
   ifeq ($(USE_LOCAL_HEADERS),1)
@@ -412,6 +428,10 @@ ifeq ($(PLATFORM),mingw32)
     BASE_CFLAGS += -DUSE_CODEC_VORBIS
   endif
 
+  ifeq ($(USE_MUMBLE),1)
+    BASE_CFLAGS += -DUSE_MUMBLE
+  endif
+
   OPTIMIZE = -O3 -march=i586 -fno-omit-frame-pointer -ffast-math \
     -falign-loops=2 -funroll-loops -falign-jumps=2 -falign-functions=2 \
     -fstrength-reduce
@@ -497,6 +517,10 @@ ifeq ($(PLATFORM),freebsd)
     BASE_CFLAGS += -DUSE_CODEC_VORBIS
   endif
 
+  ifeq ($(USE_MUMBLE),1)
+    BASE_CFLAGS += -DUSE_MUMBLE
+  endif
+
   ifeq ($(ARCH),axp)
     BASE_CFLAGS += -DNO_VM_COMPILED
     RELEASE_CFLAGS=$(BASE_CFLAGS) -DNDEBUG -O3 -ffast-math -funroll-loops \
@@ -564,6 +588,10 @@ ifeq ($(PLATFORM),openbsd)
     BASE_CFLAGS += -DUSE_CODEC_VORBIS
   endif
 
+  ifeq ($(USE_MUMBLE),1)
+    BASE_CFLAGS += -DUSE_MUMBLE
+  endif
+
   BASE_CFLAGS += -DNO_VM_COMPILED -I/usr/X11R6/include -I/usr/local/include
   RELEASE_CFLAGS=$(BASE_CFLAGS) -DNDEBUG -O3 \
     -march=pentium -fomit-frame-pointer -pipe -ffast-math \
@@ -1339,6 +1367,11 @@ else
     $(B)/client/sys_unix.o
 endif
 
+ifeq ($(USE_MUMBLE),1)
+  Q3OBJ += \
+    $(B)/client/libmumblelink.o
+endif
+
 Q3POBJ += \
   $(B)/client/sdl_glimp.o
 
diff --git a/code/client/cl_cgame.c b/code/client/cl_cgame.c
index da9ac01..334294e 100644
--- a/code/client/cl_cgame.c
+++ b/code/client/cl_cgame.c
@@ -25,6 +25,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
 #include "../botlib/botlib.h"
 
+#include "libmumblelink.h"
+
 extern	botlib_export_t	*botlib_export;
 
 extern qboolean loadCamera(const char *name);
@@ -907,6 +909,13 @@ void CL_FirstSnapshot( void ) {
 		Cbuf_AddText( cl_activeAction->string );
 		Cvar_Set( "activeAction", "" );
 	}
+
+#ifdef USE_MUMBLE
+	if ((cl_useMumble->integer) && !mumble_islinked()) {
+		int ret = mumble_link(CLIENT_WINDOW_TITLE);
+		Com_Printf("Mumble: Linking to Mumble application %s\n", ret==0?"ok":"failed");
+	}
+#endif
 }
 
 /*
diff --git a/code/client/cl_main.c b/code/client/cl_main.c
index d130620..b9243d5 100644
--- a/code/client/cl_main.c
+++ b/code/client/cl_main.c
@@ -24,6 +24,15 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #include "client.h"
 #include <limits.h>
 
+#ifdef USE_MUMBLE
+#include "libmumblelink.h"
+#endif
+
+#ifdef USE_MUMBLE
+cvar_t	*cl_useMumble;
+cvar_t	*cl_mumbleScale;
+#endif
+
 cvar_t	*cl_nodelta;
 cvar_t	*cl_debugMove;
 
@@ -121,6 +130,43 @@ void CL_CDDialog( void ) {
 	cls.cddialog = qtrue;	// start it next frame
 }
 
+#ifdef USE_MUMBLE
+static
+void CL_UpdateMumble(void)
+{
+	vec3_t pos, forward, up;
+	float scale = cl_mumbleScale->value;
+	float tmp;
+	
+	if(!cl_useMumble->integer)
+		return;
+
+	// !!! FIXME: not sure if this is even close to correct.
+	AngleVectors( cl.snap.ps.viewangles, forward, NULL, up);
+
+	pos[0] = cl.snap.ps.origin[0] * scale;
+	pos[1] = cl.snap.ps.origin[2] * scale;
+	pos[2] = cl.snap.ps.origin[1] * scale;
+
+	tmp = forward[1];
+	forward[1] = forward[2];
+	forward[2] = tmp;
+
+	tmp = up[1];
+	up[1] = up[2];
+	up[2] = tmp;
+
+	if(cl_useMumble->integer > 1) {
+		fprintf(stderr, "%f %f %f, %f %f %f, %f %f %f\n",
+			pos[0], pos[1], pos[2],
+			forward[0], forward[1], forward[2],
+			up[0], up[1], up[2]);
+	}
+
+	mumble_update_coordinates(pos, forward, up);
+}
+#endif
+
 
 /*
 =======================================================================
@@ -852,6 +898,13 @@ void CL_Disconnect( qboolean showMainMenu ) {
 	*clc.downloadTempName = *clc.downloadName = 0;
 	Cvar_Set( "cl_downloadName", "" );
 
+#ifdef USE_MUMBLE
+	if (cl_useMumble->integer && mumble_islinked()) {
+		Com_Printf("Mumble: Unlinking from Mumble application\n");
+		mumble_unlink();
+	}
+#endif
+
 	if ( clc.demofile ) {
 		FS_FCloseFile( clc.demofile );
 		clc.demofile = 0;
@@ -2306,6 +2359,9 @@ void CL_Frame ( int msec ) {
 	// update audio
 	S_Update();
 
+#ifdef USE_MUMBLE
+	CL_UpdateMumble();
+#endif
 	// advance local effects for next frame
 	SCR_RunCinematic();
 
@@ -2720,6 +2776,11 @@ void CL_Init( void ) {
 
 	cl_guidServerUniq = Cvar_Get ("cl_guidServerUniq", "1", CVAR_ARCHIVE);
 
+#ifdef USE_MUMBLE
+	cl_useMumble = Cvar_Get ("cl_useMumble", "0", CVAR_ARCHIVE);
+	cl_mumbleScale = Cvar_Get ("cl_mumbleScale", "0.0254", CVAR_ARCHIVE);
+#endif
+
 	// userinfo
 	Cvar_Get ("name", "UnnamedPlayer", CVAR_USERINFO | CVAR_ARCHIVE );
 	Cvar_Get ("rate", "3000", CVAR_USERINFO | CVAR_ARCHIVE );
diff --git a/code/client/client.h b/code/client/client.h
index 34aacc5..b064404 100644
--- a/code/client/client.h
+++ b/code/client/client.h
@@ -367,6 +367,11 @@ extern	cvar_t	*cl_inGameVideo;
 extern	cvar_t	*cl_lanForcePackets;
 extern	cvar_t	*cl_autoRecordDemo;
 
+#ifdef USE_MUMBLE
+extern	cvar_t	*cl_useMumble;
+extern	cvar_t	*cl_mumbleScale;
+#endif
+
 //=================================================
 
 //
diff --git a/code/client/libmumblelink.c b/code/client/libmumblelink.c
new file mode 100644
index 0000000..c45e6a1
--- /dev/null
+++ b/code/client/libmumblelink.c
@@ -0,0 +1,134 @@
+/* libmumblelink.c -- mumble link interface
+
+  Copyright (C) 2008 Ludwig Nussel <ludwig.nussel at suse.de>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+*/
+
+#ifdef WIN32
+#include <windows.h>
+#define uint32_t UINT32
+#else
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#endif
+
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "libmumblelink.h"
+
+typedef struct
+{
+	uint32_t uiVersion;
+	uint32_t uiTick;
+	float   fPosition[3];
+	float   fFront[3];
+	float   fTop[3];
+	wchar_t name[256];
+} LinkedMem;
+
+static LinkedMem *lm = NULL;
+
+#ifdef WIN32
+static HANDLE hMapObject = NULL;
+#else
+static int32_t GetTickCount(void)
+{
+	struct timeval tv;
+	gettimeofday(&tv,NULL);
+
+	return tv.tv_usec / 1000 + tv.tv_sec * 1000;
+}
+#endif
+
+int mumble_link(const char* name)
+{
+#ifdef WIN32
+	if(lm)
+		return 0;
+
+	hMapObject = OpenFileMappingW(FILE_MAP_ALL_ACCESS, FALSE, L"MumbleLink");
+	if (hMapObject == NULL)
+		return -1;
+
+	lm = (LinkedMem *) MapViewOfFile(hMapObject, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(LinkedMem));
+	if (lm == NULL) {
+		CloseHandle(hMapObject);
+		hMapObject = NULL;
+		return -1;
+	}
+#else
+	char file[256];
+	int shmfd;
+	if(lm)
+		return 0;
+
+	snprintf(file, sizeof (file), "/MumbleLink.%d", getuid());
+	shmfd = shm_open(file, O_RDWR, S_IRUSR | S_IWUSR);
+	if(shmfd < 0) {
+		return -1;
+	}
+
+	lm = (LinkedMem *) (mmap(NULL, sizeof(LinkedMem), PROT_READ | PROT_WRITE, MAP_SHARED, shmfd,0));
+	if (lm == (void *) (-1)) {
+		lm = NULL;
+	}
+	close(shmfd);
+#endif
+	mbstowcs(lm->name, name, sizeof(lm->name));
+
+	return 0;
+}
+
+void mumble_update_coordinates(float fPosition[3], float fFront[3], float fTop[3])
+{
+	if (!lm)
+		return;
+
+	memcpy(lm->fPosition, fPosition, sizeof(fPosition));
+	memcpy(lm->fFront, fFront, sizeof(fFront));
+	memcpy(lm->fTop, fTop, sizeof(fTop));
+	lm->uiVersion = 1;
+	lm->uiTick = GetTickCount();
+}
+
+void mumble_unlink()
+{
+	if(!lm)
+		return;
+#ifdef WIN32
+	UnmapViewOfFile(lm);
+	CloseHandle(hMapObject);
+	hMapObject = NULL;
+#else
+	munmap(lm, sizeof(LinkedMem));
+#endif
+	lm = NULL;
+}
+
+int mumble_islinked(void)
+{
+	return lm != NULL;
+}
diff --git a/code/client/libmumblelink.h b/code/client/libmumblelink.h
new file mode 100644
index 0000000..0623931
--- /dev/null
+++ b/code/client/libmumblelink.h
@@ -0,0 +1,26 @@
+/* libmumblelink.h -- mumble link interface
+
+  Copyright (C) 2008 Ludwig Nussel <ludwig.nussel at suse.de>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+*/
+
+int mumble_link(const char* name);
+int mumble_islinked(void);
+void mumble_update_coordinates(float fPosition[3], float fFront[3], float fTop[3]);
+void mumble_unlink(void);
-- 
1.5.2.4

-- 
 (o_   Ludwig Nussel
 //\   SUSE LINUX Products GmbH, Development
 V_/_  http://www.suse.de/




More information about the ioquake3 mailing list