Created
November 4, 2014 17:49
-
-
Save iqualfragile/bc0864e1cc9830d40e0a to your computer and use it in GitHub Desktop.
Adds mumble positional audio to minetest
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/game.cpp b/src/game.cpp | |
index b4bce33..06483e4 100644 | |
--- a/src/game.cpp | |
+++ b/src/game.cpp | |
@@ -70,6 +70,12 @@ with this program; if not, write to the Free Software Foundation, Inc., | |
#include "util/pointedthing.h" | |
#include "drawscene.h" | |
#include "content_cao.h" | |
+// shared memory | |
+#include <sys/mman.h> | |
+#include <sys/stat.h> /* For mode constants */ | |
+#include <fcntl.h> /* For O_* constants */ | |
+ | |
+LinkedMem *mumblelm = NULL; | |
#ifdef HAVE_TOUCHSCREENGUI | |
#include "touchscreengui.h" | |
@@ -1389,6 +1395,10 @@ class Game | |
void showOverlayMessage(const char *msg, float dtime, int percent, | |
bool draw_clouds = true); | |
+ // Mumble | |
+ void initMumble(std::string *address, u16 port); | |
+ void updateMumblePositionalAudio(); | |
+ | |
private: | |
InputHandler *input; | |
@@ -1548,6 +1558,8 @@ bool Game::startup(bool *kill, | |
if (!createClient(playername, password, address, port, error_message)) | |
return false; | |
+ initMumble(address, port); | |
+ | |
return true; | |
} | |
@@ -1620,6 +1632,7 @@ void Game::run() | |
flags.show_hud, flags.show_debug); | |
updateFrame(highlight_boxes, &graph, &stats, &runData, dtime, | |
flags, cam_view); | |
+ updateMumblePositionalAudio(); | |
updateProfilerGraphs(&graph); | |
} | |
} | |
@@ -1701,7 +1714,6 @@ bool Game::init( | |
if (!createSingleplayerServer(map_dir, gamespec, port, address)) | |
return false; | |
} | |
- | |
return true; | |
} | |
@@ -1732,6 +1744,53 @@ bool Game::initSound() | |
return true; | |
} | |
+void Game::initMumble(std::string *address, u16 port) | |
+{ | |
+#ifdef WIN32 | |
+ HANDLE hMapObject = OpenFileMappingW(FILE_MAP_ALL_ACCESS, FALSE, L"MumbleLink"); | |
+ if (hMapObject == NULL) | |
+ return; | |
+ | |
+ mumblelm = (LinkedMem *) MapViewOfFile(hMapObject, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(LinkedMem)); | |
+ if (mumblelm == NULL) { | |
+ CloseHandle(hMapObject); | |
+ hMapObject = NULL; | |
+ return; | |
+ } | |
+#else | |
+ char memname[256]; | |
+ snprintf(memname, 256, "/MumbleLink.%d", getuid()); | |
+ | |
+ int shmfd = shm_open(memname, O_RDWR, S_IRUSR | S_IWUSR); | |
+ | |
+ if (shmfd < 0) { | |
+ return; | |
+ } | |
+ | |
+ mumblelm = (LinkedMem *)(mmap(NULL, sizeof(struct LinkedMem), PROT_READ | PROT_WRITE, MAP_SHARED, shmfd,0)); | |
+ | |
+ if (mumblelm == (void *)(-1)) { | |
+ mumblelm = NULL; | |
+ return; | |
+ } | |
+#endif | |
+ | |
+ // Context is equal for players on the same server | |
+ //TODO allow mods to append something to allow for teams | |
+ std::stringstream contextstringstream; | |
+ contextstringstream << (*address) << ":" << port; | |
+ std::string context = contextstringstream.str(); | |
+ memcpy(mumblelm->context, context.c_str(), context.length()); | |
+ mumblelm->context_len = context.length(); | |
+ | |
+ // Identifier which uniquely identifies the player on the server (nicknames are unique per server) | |
+ std::string playername = client->getEnv().getLocalPlayer()->getName(); | |
+ std::wstring wplayername; | |
+ wplayername.assign(playername.begin(), playername.end()); | |
+ wcsncpy(mumblelm->identity, wplayername.c_str(), 256); | |
+ | |
+} | |
+ | |
bool Game::createSingleplayerServer(const std::string map_dir, | |
const SubgameSpec &gamespec, u16 port, std::string *address) | |
{ | |
@@ -3096,6 +3155,64 @@ void Game::updateSound(f32 dtime) | |
soundmaker->m_player_step_sound = nodedef_manager->get(n).sound_footstep; | |
} | |
+void Game::updateMumblePositionalAudio() | |
+{ | |
+ LocalPlayer *avatar = client->getEnv().getLocalPlayer(); | |
+ v3f player_position = avatar->getEyePosition(); | |
+ v3f camera_position = camera->getPosition(); | |
+ v3f camera_direction = camera->getDirection(); | |
+ camera_direction = camera_direction.normalize(); | |
+ // Todo: calculate from yaw and pitch | |
+ v3f player_direction = camera_direction; | |
+ | |
+ if (! mumblelm) | |
+ return; | |
+ | |
+ if(mumblelm->uiVersion != 2) { | |
+ wcsncpy(mumblelm->name, L"MinetestLink", 256); | |
+ wcsncpy(mumblelm->description, L"Link to the Minetest game.", 2048); | |
+ mumblelm->uiVersion = 2; | |
+ } | |
+ mumblelm->uiTick++; | |
+ | |
+ // Left handed coordinate system. | |
+ // X positive towards "right". | |
+ // Y positive towards "up". | |
+ // Z positive towards "front". | |
+ // | |
+ // 1 unit = 1 meter | |
+ | |
+ // Position of the avatar | |
+ mumblelm->fAvatarPosition[0] = player_position.X; | |
+ mumblelm->fAvatarPosition[1] = player_position.Y; | |
+ mumblelm->fAvatarPosition[2] = player_position.Z; | |
+ | |
+ // Unit vector pointing out of the avatars eyes | |
+ mumblelm->fAvatarFront[0] = player_direction.X; | |
+ mumblelm->fAvatarFront[1] = player_direction.Y; | |
+ mumblelm->fAvatarFront[2] = player_direction.Z; | |
+ | |
+ // Unit vector pointing out of the top of the avatars head | |
+ // minetest never lets the player roll or anything so this is always straight up | |
+ mumblelm->fAvatarTop[0] = 0.0f; | |
+ mumblelm->fAvatarTop[1] = 1.0f; | |
+ mumblelm->fAvatarTop[2] = 0.0f; | |
+ | |
+ // Same as avatar but for the camera. | |
+ mumblelm->fCameraPosition[0] = camera_position.X; | |
+ mumblelm->fCameraPosition[1] = camera_position.Y; | |
+ mumblelm->fCameraPosition[2] = camera_position.Z; | |
+ | |
+ mumblelm->fCameraFront[0] = camera_direction.X; | |
+ mumblelm->fCameraFront[1] = camera_direction.Y; | |
+ mumblelm->fCameraFront[2] = camera_direction.Z; | |
+ | |
+ mumblelm->fCameraTop[0] = 0.0f; | |
+ mumblelm->fCameraTop[1] = 1.0f; | |
+ mumblelm->fCameraTop[2] = 0.0f; | |
+ | |
+} | |
+ | |
void Game::processPlayerInteraction(std::vector<aabb3f> &highlight_boxes, | |
GameRunData *runData, f32 dtime, bool show_hud, bool show_debug) | |
diff --git a/src/game.h b/src/game.h | |
index c3a7691..ffd6a54 100644 | |
--- a/src/game.h | |
+++ b/src/game.h | |
@@ -151,5 +151,28 @@ void the_game(bool *kill, | |
const SubgameSpec &gamespec, // Used for local game | |
bool simple_singleplayer_mode); | |
+struct LinkedMem { | |
+#ifdef WIN32 | |
+ UINT32 uiVersion; | |
+ DWORD uiTick; | |
+#else | |
+ u32 uiVersion; | |
+ u32 uiTick; | |
+#endif | |
+ float fAvatarPosition[3]; | |
+ float fAvatarFront[3]; | |
+ float fAvatarTop[3]; | |
+ wchar_t name[256]; | |
+ float fCameraPosition[3]; | |
+ float fCameraFront[3]; | |
+ float fCameraTop[3]; | |
+ wchar_t identity[256]; | |
+#ifdef WIN32 | |
+ UINT32 context_len; | |
+#else | |
+ u32 context_len; | |
+#endif | |
+ unsigned char context[256]; | |
+ wchar_t description[2048]; | |
+}; | |
#endif | |
- |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I think
#include <sys/stat.h>
is not necessary here.I'm not sure what the standard Macro for Windows detection in Minetest is but according to http://nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system
#ifdef _WIN32
is the most portable way to do it.