diff --git a/Makefile b/Makefile index e124f251..fa7928b1 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 da9ac011..334294ec 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 d130620a..b9243d51 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 +#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 34aacc57..b0644041 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 00000000..c45e6a1d --- /dev/null +++ b/code/client/libmumblelink.c @@ -0,0 +1,134 @@ +/* libmumblelink.c -- mumble link interface + + Copyright (C) 2008 Ludwig Nussel + + 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 +#define uint32_t UINT32 +#else +#include +#include +#include +#include +#include +#endif + +#include +#include +#include +#include +#include + +#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 00000000..0623931e --- /dev/null +++ b/code/client/libmumblelink.h @@ -0,0 +1,26 @@ +/* libmumblelink.h -- mumble link interface + + Copyright (C) 2008 Ludwig Nussel + + 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);