forked from shadeMe/Fuz-Ro-D-oh-64
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFuzRoDohInternals.cpp
135 lines (107 loc) · 3.2 KB
/
FuzRoDohInternals.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include "FuzrodohInternals.h"
IDebugLog gLog;
namespace interfaces
{
PluginHandle kPluginHandle = kPluginHandle_Invalid;
SKSEMessagingInterface* kMsgInterface = nullptr;
}
FuzRoDohINIManager FuzRoDohINIManager::Instance;
SubtitleHasher SubtitleHasher::Instance;
const double SubtitleHasher::kPurgeInterval = 1000.0 * 60.0f;
SME::INI::INISetting kWordsPerSecondSilence("WordsPerSecondSilence",
"General",
"Number of words a second of silent voice can \"hold\"",
(SInt32)2);
SME::INI::INISetting kSkipEmptyResponses("SkipEmptyResponses",
"General",
"Don't play back silent dialog for empty dialog responses",
(SInt32)1);
std::string MakeSillyName()
{
std::string Out("Fuz Ro ");
for (int i = 0; i < 64; i++)
Out += "D'oh";
#ifdef VR_BUILD
Out += " (for Skyrim VR)";
#endif
return Out;
}
bool CanShowDialogSubtitles()
{
return GetINISetting("bDialogueSubtitles:Interface")->data.u8 != 0;
}
bool CanShowGeneralSubtitles()
{
return GetINISetting("bGeneralSubtitles:Interface")->data.u8 != 0;
}
void FuzRoDohINIManager::Initialize(const char* INIPath, void* Paramenter)
{
this->INIFilePath = INIPath;
_MESSAGE("INI Path: %s", INIPath);
std::fstream INIStream(INIPath, std::fstream::in);
bool CreateINI = false;
if (INIStream.fail())
{
_MESSAGE("INI File not found; Creating one...");
CreateINI = true;
}
INIStream.close();
INIStream.clear();
RegisterSetting(&kWordsPerSecondSilence);
RegisterSetting(&kSkipEmptyResponses);
if (CreateINI)
Save();
}
SubtitleHasher::HashT SubtitleHasher::CalculateHash(const char* String)
{
SME_ASSERT(String);
// Uses the djb2 string hashing algorithm
// http://www.cse.yorku.ca/~oz/hash.html
HashT Hash = 0;
int i;
while (i = *String++)
Hash = ((Hash << 5) + Hash) + i; // Hash * 33 + i
return Hash;
}
void SubtitleHasher::Add(const char* Subtitle)
{
IScopedCriticalSection Guard(&Lock);
if (Subtitle && strlen(Subtitle) > 1 && HasMatch(Subtitle) == false)
Store.insert(CalculateHash(Subtitle));
}
bool SubtitleHasher::HasMatch(const char* Subtitle)
{
IScopedCriticalSection Guard(&Lock);
HashT Current = CalculateHash(Subtitle);
return Store.find(Current) != Store.end();
}
void SubtitleHasher::Purge(void)
{
IScopedCriticalSection Guard(&Lock);
Store.clear();
}
void SubtitleHasher::Tick(void)
{
IScopedCriticalSection Guard(&Lock);
TickCounter.Update();
TickReminder -= TickCounter.GetTimePassed();
if (TickReminder <= 0.0f)
{
TickReminder = kPurgeInterval;
#ifndef NDEBUG
_MESSAGE("SubtitleHasher::Tick - Tock!");
#endif
// we need to periodically purge the hash store as we can't differentiate b'ween topic responses with the same dialog text but different voice assets
// for instance, there may be two responses with the text "Hello there!" but only one with a valid voice file
Purge();
}
}
BSIStream* BSIStream::CreateInstance(const char* FilePath, void* ParentLocation)
{
auto Instance = (BSIStream*)Heap_Allocate(0x20); // standard bucket
return CALL_MEMBER_FN(Instance, Ctor)(FilePath, ParentLocation);
}
override::MenuTopicManager* override::MenuTopicManager::GetSingleton(void)
{
return (override::MenuTopicManager*)::MenuTopicManager::GetSingleton();
}