Skip to content

Commit 85b242f

Browse files
committed
Added a voice activity indicator to HUD
1 parent 9145f33 commit 85b242f

20 files changed

+1454
-14
lines changed

Code/DllGlobals.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#include "DllGlobals.hpp"
2+
3+
HMODULE DllGlobals::SelfModule = nullptr;

Code/DllGlobals.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#pragma once
2+
3+
#include "win_include.hpp"
4+
5+
class DllGlobals
6+
{
7+
public:
8+
static HMODULE SelfModule;
9+
};

Code/PlayerVoiceManager.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "SmSdk/CharacterManager.hpp"
55
#include "SmSdk/PlayerManager.hpp"
66
#include "SmSdk/AudioManager.hpp"
7+
#include "SmSdk/MyPlayer.hpp"
78

89
#include "Utils/Console.hpp"
910

@@ -53,10 +54,19 @@ void PlayerVoiceManager::Update()
5354
PlayerVoiceManager::RemoveDeadVoices();
5455
}
5556

57+
bool is_player_local(Player* pl)
58+
{
59+
MyPlayer* v_player = MyPlayer::GetInstance();
60+
if (!v_player || !v_player->player) return false;
61+
62+
return v_player->player->steam_id == pl->steam_id;
63+
}
64+
5665
void PlayerVoiceManager::UpdatePlayerSound(Player* player)
5766
{
5867
//Players without the characters should not be processed
59-
if (player->character_id == -1) return;
68+
if (player->character_id == -1 || is_player_local(player))
69+
return;
6070

6171
AudioManager* v_aud_mgr = AudioManager::GetInstance();
6272
if (!v_aud_mgr) return;
@@ -99,7 +109,7 @@ void PlayerVoiceManager::UpdatePlayerSound(Player* player)
99109
v_new_voice->m_pChannel->setMode(FMOD_3D);
100110
v_new_voice->m_pChannel->set3DConeSettings(30.0f, 360.0f, 0.01f);
101111
v_new_voice->m_pChannel->set3DMinMaxDistance(0.01f, 10000.0f);
102-
v_new_voice->m_pChannel->setVolume(200.0f);
112+
v_new_voice->m_pChannel->setVolume(300.0f);
103113
v_new_voice->m_pChannel->setReverbProperties(0, 0.0f);
104114
v_new_voice->m_pChannel->setReverbProperties(1, 0.0f);
105115
v_new_voice->m_pChannel->setReverbProperties(2, 0.0f);

Code/Utils/TextureLoader.cpp

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#include "TextureLoader.hpp"
2+
3+
#include "DllGlobals.hpp"
4+
5+
const char* TexLoader::TexLoadResultToString(TexLoader::TexLoadResult load_res)
6+
{
7+
switch (load_res)
8+
{
9+
case TexLoadResult_ResourceNotFound: return "Couldn't find the resource!";
10+
case TexLoadResult_ResourceDataNotFound: return "Couldn't find the resource data!";
11+
case TexLoadResult_FailedToGetImageMemory: return "Failed to get image memory!";
12+
case TexLoadResult_FailedToOpenImageMemory: return "Failed to open image memory!";
13+
case TexLoadResult_FailedToLoadImgFromMemory: return "Failed to load image from memory!";
14+
case TexLoadResult_Success: return "Success";
15+
default: return "UNKNOWN";
16+
}
17+
}
18+
19+
std::uint32_t TexLoader::GetBitsPerPixels(MyGUI::PixelFormat fmt)
20+
{
21+
switch (fmt.getValue())
22+
{
23+
case MyGUI::PixelFormat::Enum::R8G8B8A8:
24+
return 32;
25+
case MyGUI::PixelFormat::Enum::R8G8B8:
26+
return 24;
27+
default:
28+
return 0;
29+
}
30+
}
31+
32+
TexLoader::TexLoadResult TexLoader::LoadTextureFromResource(
33+
FIBITMAP** out_fibitmap,
34+
LPCWSTR resource_name,
35+
LPCWSTR resource_type,
36+
FREE_IMAGE_FORMAT fmt,
37+
MyGUI::PixelFormat pix_fmt)
38+
{
39+
HRSRC v_imgRes = FindResource(DllGlobals::SelfModule, resource_name, resource_type);
40+
if (!v_imgRes) return TexLoadResult_ResourceNotFound;
41+
42+
HGLOBAL v_imgResData = LoadResource(DllGlobals::SelfModule, v_imgRes);
43+
if (!v_imgResData) return TexLoadResult_ResourceDataNotFound;
44+
45+
void* v_imgMem = LockResource(v_imgResData);
46+
if (!v_imgMem) return TexLoadResult_FailedToGetImageMemory;
47+
48+
const DWORD v_imgSize = SizeofResource(DllGlobals::SelfModule, v_imgRes);
49+
FIMEMORY* v_fmem = FreeImage_OpenMemory((BYTE*)v_imgMem, v_imgSize);
50+
if (!v_fmem) return TexLoadResult_FailedToOpenImageMemory;
51+
52+
FIBITMAP* v_img_data = FreeImage_LoadFromMemory(fmt, v_fmem, 0);
53+
FreeImage_CloseMemory(v_fmem);
54+
if (!v_img_data) return TexLoadResult_FailedToLoadImgFromMemory;
55+
56+
if (FreeImage_GetBPP(v_img_data) != TexLoader::GetBitsPerPixels(pix_fmt))
57+
{
58+
FIBITMAP* v_old_img_data = v_img_data;
59+
switch (pix_fmt.getValue())
60+
{
61+
case MyGUI::PixelFormat::Enum::R8G8B8A8:
62+
v_img_data = FreeImage_ConvertTo32Bits(v_img_data);
63+
break;
64+
case MyGUI::PixelFormat::Enum::R8G8B8:
65+
v_img_data = FreeImage_ConvertTo24Bits(v_img_data);
66+
break;
67+
default:
68+
break;
69+
}
70+
71+
if (v_img_data == nullptr)
72+
v_img_data = v_old_img_data;
73+
else if (v_img_data != v_old_img_data)
74+
FreeImage_Unload(v_old_img_data);
75+
}
76+
77+
*out_fibitmap = v_img_data;
78+
return TexLoadResult_Success;
79+
}

Code/Utils/TextureLoader.hpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#pragma once
2+
3+
#include "win_include.hpp"
4+
5+
#include <freeimage/FreeImage.h>
6+
#include <MyGUI.h>
7+
8+
namespace TexLoader
9+
{
10+
enum TexLoadResult : std::uint8_t
11+
{
12+
TexLoadResult_Success = 0,
13+
TexLoadResult_ResourceNotFound = 1,
14+
TexLoadResult_ResourceDataNotFound = 2,
15+
TexLoadResult_FailedToGetImageMemory = 3,
16+
TexLoadResult_FailedToOpenImageMemory = 4,
17+
TexLoadResult_FailedToLoadImgFromMemory = 5
18+
};
19+
20+
const char* TexLoadResultToString(TexLoadResult load_res);
21+
22+
std::uint32_t GetBitsPerPixels(MyGUI::PixelFormat fmt);
23+
TexLoadResult LoadTextureFromResource(
24+
FIBITMAP** out_fibitmap,
25+
LPCWSTR resource_name,
26+
LPCWSTR resource_type,
27+
FREE_IMAGE_FORMAT fmt,
28+
MyGUI::PixelFormat pix_fmt = MyGUI::PixelFormat::Enum::R8G8B8A8);
29+
}

Code/VoiceManager.cpp

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
11
#include "VoiceManager.hpp"
22

33
#include "SmSdk/Gui/GuiSystemManager.hpp"
4+
#include "SmSdk/Gui/InGameGuiManager.hpp"
45
#include "SmSdk/InputManager.hpp"
56
#include "SmSdk/GameState.hpp"
67
#include "SmSdk/MyPlayer.hpp"
78

9+
#include "Utils/TextureLoader.hpp"
810
#include "Utils/BufferWriter.hpp"
911
#include "Utils/BufferReader.hpp"
1012
#include "Utils/Console.hpp"
13+
#include "DllGlobals.hpp"
1114

1215
#include "PlayerVoiceManager.hpp"
1316

1417
#include <steam/steam_api.h>
1518
#include <lz4/lz4.h>
1619

20+
#include "../resource.h"
21+
22+
1723

1824
VoiceManager::fClientPacketHandler VoiceManager::o_clientPacketHandler = nullptr;
1925
VoiceManager::fServerPacketHandler VoiceManager::o_serverPacketHandler = nullptr;
@@ -135,6 +141,7 @@ void VoiceManager::StartVoiceRecording()
135141
if (!sm_isVoiceRecording)
136142
{
137143
sm_isVoiceRecording = true;
144+
VoiceManager::UpdateSpeakerUiIcon();
138145
SteamUser()->StartVoiceRecording();
139146
}
140147
}
@@ -144,6 +151,7 @@ void VoiceManager::StopVoiceRecording()
144151
if (sm_isVoiceRecording)
145152
{
146153
sm_isVoiceRecording = false;
154+
VoiceManager::UpdateSpeakerUiIcon();
147155
SteamUser()->StopVoiceRecording();
148156
}
149157
}
@@ -220,4 +228,80 @@ void VoiceManager::UpdateVoiceRecording()
220228
DebugErrorL("Couldn't send the packet to server host");
221229
}
222230
}
231+
}
232+
233+
////////////////UI FUNCTIONS/////////////////
234+
235+
void VoiceManager::CreateSpeakerImage()
236+
{
237+
MyGUI::RenderManager* v_rend_mgr = MyGUI::RenderManager::getInstancePtr();
238+
if (v_rend_mgr->getTexture("SpeakerIcon"))
239+
return;
240+
241+
MyGUI::ITexture* v_new_tex = v_rend_mgr->createTexture("SpeakerIcon");
242+
FIBITMAP* v_fibitmap;
243+
244+
TexLoader::TexLoadResult v_res = TexLoader::LoadTextureFromResource(&v_fibitmap, MAKEINTRESOURCE(IDB_PNG1), L"PNG", FIF_PNG);
245+
if (v_res != TexLoader::TexLoadResult_Success)
246+
{
247+
AttachDebugConsole();
248+
DebugErrorL(TexLoader::TexLoadResultToString(v_res));
249+
return;
250+
}
251+
252+
const int v_img_width = int(FreeImage_GetWidth(v_fibitmap));
253+
const int v_img_height = int(FreeImage_GetHeight(v_fibitmap));
254+
BYTE* v_img_bits = FreeImage_GetBits(v_fibitmap);
255+
256+
v_new_tex->createManual(v_img_width, v_img_height,
257+
MyGUI::TextureUsage::Write | MyGUI::TextureUsage::Static, MyGUI::PixelFormat::R8G8B8A8);
258+
void* v_img_mem = v_new_tex->lock(MyGUI::TextureUsage::Write);
259+
std::memcpy(v_img_mem, v_img_bits, v_img_width * v_img_height * 4);
260+
v_new_tex->unlock();
261+
262+
FreeImage_Unload(v_fibitmap);
263+
}
264+
265+
MyGUI::ImageBox* VoiceManager::GetSpeakerImageBox(MyGUI::Widget* main_panel)
266+
{
267+
MyGUI::Widget* v_widget = main_panel->findWidget("SpeakerIcon");
268+
if (v_widget)
269+
{
270+
if (v_widget->isType<MyGUI::ImageBox>())
271+
return v_widget->castType<MyGUI::ImageBox>();
272+
273+
return nullptr;
274+
}
275+
276+
VoiceManager::CreateSpeakerImage();
277+
MyGUI::ImageBox* v_new_img_box = main_panel->createWidgetReal<MyGUI::ImageBox>(
278+
"ImageBox", MyGUI::FloatCoord(0.0f, 0.0f, 0.0f, 0.0f), MyGUI::Align::Default, "SpeakerIcon")->castType<MyGUI::ImageBox>();
279+
280+
v_new_img_box->setVisible(false);
281+
v_new_img_box->setImageTexture("SpeakerIcon");
282+
283+
return v_new_img_box;
284+
}
285+
286+
void VoiceManager::UpdateSpeakerUiIcon()
287+
{
288+
InGameGuiManager* v_gui_mgr = InGameGuiManager::GetInstance();
289+
if (!v_gui_mgr || !v_gui_mgr->m_pHudGui) return;
290+
291+
MyGUI::ImageBox* v_speaker_icon = VoiceManager::GetSpeakerImageBox(v_gui_mgr->m_pHudGui->m_pMainPanel);
292+
if (!v_speaker_icon) return;
293+
294+
MyGUI::Widget* v_main_panel = v_gui_mgr->m_pHudGui->m_pMainPanel;
295+
const float v_aspect_ratio = float(v_main_panel->getWidth()) / float(v_main_panel->getHeight());
296+
const int v_icon_sz = int(50.0f * v_aspect_ratio);
297+
const int v_icon_spacing = int(20.0f * v_aspect_ratio);
298+
299+
v_speaker_icon->setSize(v_icon_sz, v_icon_sz);
300+
301+
v_speaker_icon->setPosition(MyGUI::IntPoint(
302+
v_main_panel->getWidth() - v_speaker_icon->getWidth() - v_icon_spacing,
303+
(v_main_panel->getHeight() - v_speaker_icon->getHeight()) / 2
304+
));
305+
306+
v_speaker_icon->setVisible(VoiceManager::sm_isVoiceRecording);
223307
}

Code/VoiceManager.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
#include "SmSdk/Network/NetworkServer.hpp"
44

5+
#include <MyGUI.h>
6+
57
#include <cstddef>
68
#include <cstdint>
79

@@ -49,6 +51,12 @@ class VoiceManager
4951
static void StopVoiceRecording();
5052
static void UpdateVoiceRecording();
5153

54+
////UI FUNCTIONS
55+
56+
static void CreateSpeakerImage();
57+
static MyGUI::ImageBox* GetSpeakerImageBox(MyGUI::Widget* main_panel);
58+
static void UpdateSpeakerUiIcon();
59+
5260
private:
5361
static bool sm_isVoiceRecording;
5462
};

Code/main.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "Utils/BufferWriter.hpp"
22
#include "Utils/BufferReader.hpp"
33
#include "Utils/Console.hpp"
4+
#include "DllGlobals.hpp"
45

56
#include "PlayerVoiceManager.hpp"
67
#include "VoiceManager.hpp"
@@ -32,8 +33,10 @@ static void h_perframeUpdate(void* a1, float dt, void* a3, void* a4, void* pFram
3233
o_perframeUpdate(a1, dt, a3, a4, pFrameSettings);
3334
}
3435

35-
static void process_attach()
36+
static void process_attach(HMODULE hMod)
3637
{
38+
DllGlobals::SelfModule = hMod;
39+
3740
AttachDebugConsole();
3841

3942
if (MH_Initialize() != MH_OK)
@@ -74,7 +77,7 @@ BOOL APIENTRY DllMain(
7477
switch (ul_reason_for_call)
7578
{
7679
case DLL_PROCESS_ATTACH:
77-
process_attach();
80+
process_attach(hModule);
7881
break;
7982
case DLL_PROCESS_DETACH:
8083
process_detach(hModule);
6.62 MB
Binary file not shown.
63.8 KB
Binary file not shown.

0 commit comments

Comments
 (0)