mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-14 14:37:41 +00:00
Compare commits
83 Commits
working_su
...
OPENURU_BU
Author | SHA1 | Date | |
---|---|---|---|
4b0ab75a79 | |||
dcb0309a08 | |||
7dde0855dc | |||
44c9b0694d | |||
dedf04ac43 | |||
eeb458817f | |||
68c7187155 | |||
6fa695a2c3 | |||
2a3c1b32ef | |||
d3cbaa94ef | |||
e7758ccc10 | |||
07b92234ad | |||
7dfa2ba56a | |||
1a091b7019 | |||
104a5ef4ee | |||
19cfaaaea9 | |||
dafd190083 | |||
fdee5a921b | |||
b322ee094c | |||
54c768d966 | |||
82159bcb4a | |||
b81eb21145 | |||
e7b4f5c6ba | |||
202e846a56 | |||
deb4858f3e | |||
bff879abfd | |||
fededb574b | |||
126e7a76dd | |||
26807a8d87 | |||
f54f14328e | |||
311671e7a2 | |||
8aaa98b8b7 | |||
3489e04463 | |||
33bbc490be | |||
fd0c2a205e | |||
b2521e0777 | |||
1f7de46bc2 | |||
f9d629cfc5 | |||
b16de9d86f | |||
aba5e2562c | |||
bff8203fbe | |||
23ded3210f | |||
bbeb25d29a | |||
9f9d510958 | |||
f0d2bd3eaa | |||
41627d1c7c | |||
ea4bb43623 | |||
40bcaba9d8 | |||
e93db035ba | |||
94fab5996f | |||
da7d2d0e5c | |||
2e8dc81bf3 | |||
c0e83259f3 | |||
838e3e51ad | |||
40f200e066 | |||
6e4996e1be | |||
2f1bb87056 | |||
df848b48c4 | |||
75c570877a | |||
e512dd0c68 | |||
4c76549fb3 | |||
1a930cb47f | |||
b9af23e458 | |||
9e2e2d02e1 | |||
7a73c2d8e3 | |||
933cbe2fe7 | |||
fe88f2e8a2 | |||
9e308cbebe | |||
126d7511e0 | |||
64323c6073 | |||
8a2534dff6 | |||
9a1b37e7f6 | |||
1012251d9a | |||
1d65c78097 | |||
c50bb08e8d | |||
229883654e | |||
51b6b4750b | |||
69dac251b6 | |||
e81af06584 | |||
5f3a8644a7 | |||
62089be53f | |||
391bbaa4e7 | |||
b00c7729cc |
@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
<ProjectConfiguration Include="Debug_Internal|Win32">
|
<ProjectConfiguration Include="Debug_Internal|Win32">
|
||||||
@ -121,6 +121,8 @@
|
|||||||
<MapFileName>$(OutDir)$(TargetName).map</MapFileName>
|
<MapFileName>$(OutDir)$(TargetName).map</MapFileName>
|
||||||
<MapExports>true</MapExports>
|
<MapExports>true</MapExports>
|
||||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||||
|
<HeapReserveSize>0x140000</HeapReserveSize>
|
||||||
|
<StackReserveSize>0x140000</StackReserveSize>
|
||||||
</Link>
|
</Link>
|
||||||
<Midl>
|
<Midl>
|
||||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
@ -177,6 +179,8 @@
|
|||||||
<MapFileName>$(OutDir)$(TargetName).map</MapFileName>
|
<MapFileName>$(OutDir)$(TargetName).map</MapFileName>
|
||||||
<MapExports>true</MapExports>
|
<MapExports>true</MapExports>
|
||||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||||
|
<HeapReserveSize>0x140000</HeapReserveSize>
|
||||||
|
<StackReserveSize>0x140000</StackReserveSize>
|
||||||
</Link>
|
</Link>
|
||||||
<Midl>
|
<Midl>
|
||||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
@ -237,6 +241,8 @@
|
|||||||
<TargetMachine>MachineX86</TargetMachine>
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
<MapExports>true</MapExports>
|
<MapExports>true</MapExports>
|
||||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||||
|
<HeapReserveSize>0x140000</HeapReserveSize>
|
||||||
|
<StackReserveSize>0x140000</StackReserveSize>
|
||||||
</Link>
|
</Link>
|
||||||
<Midl>
|
<Midl>
|
||||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
@ -298,6 +304,8 @@
|
|||||||
<TargetMachine>MachineX86</TargetMachine>
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
<MapExports>true</MapExports>
|
<MapExports>true</MapExports>
|
||||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||||
|
<HeapReserveSize>0x140000</HeapReserveSize>
|
||||||
|
<StackReserveSize>0x140000</StackReserveSize>
|
||||||
</Link>
|
</Link>
|
||||||
<Midl>
|
<Midl>
|
||||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
@ -802,4 +810,4 @@
|
|||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
</Project>
|
</Project>
|
@ -244,6 +244,7 @@
|
|||||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release_Internal|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release_Internal|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudioCore\plSrtFileReader.cpp" />
|
||||||
<ClCompile Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudio\plOGGCodec.cpp">
|
<ClCompile Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudio\plOGGCodec.cpp">
|
||||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug_Internal|Win32'">Disabled</Optimization>
|
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug_Internal|Win32'">Disabled</Optimization>
|
||||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
|
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
|
||||||
@ -315,6 +316,7 @@
|
|||||||
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudioCore\plAudioFileReader.h" />
|
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudioCore\plAudioFileReader.h" />
|
||||||
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudioCore\plBufferedFileReader.h" />
|
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudioCore\plBufferedFileReader.h" />
|
||||||
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudioCore\plFastWavReader.h" />
|
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudioCore\plFastWavReader.h" />
|
||||||
|
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudioCore\plSrtFileReader.h" />
|
||||||
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudio\plOGGCodec.h" />
|
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudio\plOGGCodec.h" />
|
||||||
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudioCore\plSoundBuffer.h" />
|
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudioCore\plSoundBuffer.h" />
|
||||||
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudioCore\plSoundDeswizzler.h" />
|
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudioCore\plSoundDeswizzler.h" />
|
||||||
|
@ -32,6 +32,9 @@
|
|||||||
<ClCompile Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudio\plWavFile.cpp">
|
<ClCompile Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudio\plWavFile.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudioCore\plSrtFileReader.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudioCore\plAudioCore.h">
|
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudioCore\plAudioCore.h">
|
||||||
@ -61,5 +64,8 @@
|
|||||||
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudio\plWavFile.h">
|
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudio\plWavFile.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudioCore\plSrtFileReader.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -817,6 +817,7 @@
|
|||||||
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plMessage\plSimStateMsg.h" />
|
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plMessage\plSimStateMsg.h" />
|
||||||
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plMessage\plSpawnModMsg.h" />
|
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plMessage\plSpawnModMsg.h" />
|
||||||
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plMessage\plSpawnRequestMsg.h" />
|
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plMessage\plSpawnRequestMsg.h" />
|
||||||
|
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plMessage\plSubtitleMsg.h" />
|
||||||
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plMessage\plSwimMsg.h" />
|
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plMessage\plSwimMsg.h" />
|
||||||
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plMessage\plSynchEnableMsg.h" />
|
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plMessage\plSynchEnableMsg.h" />
|
||||||
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plMessage\plTimerCallbackMsg.h" />
|
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plMessage\plTimerCallbackMsg.h" />
|
||||||
|
@ -361,5 +361,8 @@
|
|||||||
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plMessage\plVaultNotifyMsg.h">
|
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plMessage\plVaultNotifyMsg.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plMessage\plSubtitleMsg.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -2313,6 +2313,7 @@ void plClient::IDetectAudioVideoSettings()
|
|||||||
WriteInt(stream, "Audio.SetChannelVolume Ambience", 1);
|
WriteInt(stream, "Audio.SetChannelVolume Ambience", 1);
|
||||||
WriteInt(stream, "Audio.SetChannelVolume NPCVoice", 1);
|
WriteInt(stream, "Audio.SetChannelVolume NPCVoice", 1);
|
||||||
WriteInt(stream, "Audio.EnableVoiceRecording", 1);
|
WriteInt(stream, "Audio.EnableVoiceRecording", 1);
|
||||||
|
WriteInt(stream, "Audio.EnableSubtitles", true);
|
||||||
WriteString(stream, "Audio.SetDeviceName", deviceName );
|
WriteString(stream, "Audio.SetDeviceName", deviceName );
|
||||||
stream->Close();
|
stream->Close();
|
||||||
delete stream;
|
delete stream;
|
||||||
|
@ -3391,6 +3391,11 @@ PF_CONSOLE_CMD( Audio, MuteAll, "bool on", "Mute or unmute all sounds")
|
|||||||
plgAudioSys::SetMuted( (bool)params[ 0 ] );
|
plgAudioSys::SetMuted( (bool)params[ 0 ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PF_CONSOLE_CMD(Audio, EnableSubtitles, "bool on", "Enable or disable displaying subtitles for audio files containing speech")
|
||||||
|
{
|
||||||
|
plgAudioSys::SetEnableSubtitles((bool)params[0]);
|
||||||
|
}
|
||||||
|
|
||||||
PF_CONSOLE_CMD( Audio, SetDistanceModel, "int type", "Sets the distance model for all 3d sounds")
|
PF_CONSOLE_CMD( Audio, SetDistanceModel, "int type", "Sets the distance model for all 3d sounds")
|
||||||
{
|
{
|
||||||
if(plgAudioSys::Sys())
|
if(plgAudioSys::Sys())
|
||||||
|
@ -165,6 +165,8 @@ class pfKIMsg : public plMessage
|
|||||||
kUNUSED1 = 0x00000008,
|
kUNUSED1 = 0x00000008,
|
||||||
kStatusMsg = 0x00000010,
|
kStatusMsg = 0x00000010,
|
||||||
kNeighborMsg = 0x00000020, // sending to all the neighbors
|
kNeighborMsg = 0x00000020, // sending to all the neighbors
|
||||||
|
kSubtitleMsg = 0x00000040,
|
||||||
|
kLocKeyMsg = 0x00000080,
|
||||||
kChannelMask = 0x0000ff00
|
kChannelMask = 0x0000ff00
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -94,6 +94,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|||||||
#include "../pfGameMgr/pfGameMgr.h"
|
#include "../pfGameMgr/pfGameMgr.h"
|
||||||
#include "../plMessage/plAIMsg.h"
|
#include "../plMessage/plAIMsg.h"
|
||||||
#include "../plAvatar/plAvBrainCritter.h"
|
#include "../plAvatar/plAvBrainCritter.h"
|
||||||
|
#include "../plMessage/plSubtitleMsg.h"
|
||||||
|
|
||||||
#include "plProfile.h"
|
#include "plProfile.h"
|
||||||
|
|
||||||
@ -189,6 +190,7 @@ char* plPythonFileMod::fFunctionNames[] =
|
|||||||
{ "OnGameMgrMsg" }, // kfunc_OnGameMgrMsg
|
{ "OnGameMgrMsg" }, // kfunc_OnGameMgrMsg
|
||||||
{ "OnGameCliMsg" }, // kfunc_OnGameCliMsg
|
{ "OnGameCliMsg" }, // kfunc_OnGameCliMsg
|
||||||
{ "OnAIMsg" }, // kfunc_OnAIMsg
|
{ "OnAIMsg" }, // kfunc_OnAIMsg
|
||||||
|
{ "OnSubtitleMsg" }, // kfunc_OnSubtitleMsg
|
||||||
{ nil }
|
{ nil }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -828,6 +830,8 @@ void plPythonFileMod::AddTarget(plSceneObject* sobj)
|
|||||||
// the message that is spammed to anyone who will listen
|
// the message that is spammed to anyone who will listen
|
||||||
plgDispatch::Dispatch()->RegisterForExactType(plAIBrainCreatedMsg::Index(), GetKey());
|
plgDispatch::Dispatch()->RegisterForExactType(plAIBrainCreatedMsg::Index(), GetKey());
|
||||||
}
|
}
|
||||||
|
if (fPyFunctionInstances[kfunc_OnSubtitleMsg])
|
||||||
|
plgDispatch::Dispatch()->RegisterForExactType(plSubtitleMsg::Index(), GetKey());
|
||||||
|
|
||||||
// As the last thing... call the OnInit function if they have one
|
// As the last thing... call the OnInit function if they have one
|
||||||
if ( fPyFunctionInstances[kfunc_Init] != nil )
|
if ( fPyFunctionInstances[kfunc_Init] != nil )
|
||||||
@ -2780,6 +2784,36 @@ hsBool plPythonFileMod::MsgReceive(plMessage* msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fPyFunctionInstances[kfunc_OnSubtitleMsg])
|
||||||
|
{
|
||||||
|
plSubtitleMsg* pSubMsg = plSubtitleMsg::ConvertNoRef(msg);
|
||||||
|
if (pSubMsg)
|
||||||
|
{
|
||||||
|
plProfile_BeginTiming(PythonUpdate);
|
||||||
|
PyObject* retVal = PyObject_CallMethod(
|
||||||
|
fPyFunctionInstances[kfunc_OnSubtitleMsg], fFunctionNames[kfunc_OnSubtitleMsg],
|
||||||
|
"ss", pSubMsg->GetText().c_str(), pSubMsg->GetSpeaker().c_str());
|
||||||
|
if (retVal == nil)
|
||||||
|
{
|
||||||
|
#ifndef PLASMA_EXTERNAL_RELEASE
|
||||||
|
// for some reason this function didn't, remember that and not call it again
|
||||||
|
fPyFunctionInstances[kfunc_OnSubtitleMsg] = nil;
|
||||||
|
#endif //PLASMA_EXTERNAL_RELEASE
|
||||||
|
// if there was an error make sure that the stderr gets flushed so it can be seen
|
||||||
|
ReportError();
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_XDECREF(retVal);
|
||||||
|
plProfile_EndTiming(PythonUpdate);
|
||||||
|
|
||||||
|
// display any output (NOTE: this would be disabled in production)
|
||||||
|
DisplayPythonOutput();
|
||||||
|
|
||||||
|
// we handled this message (I think)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return plModifier::MsgReceive(msg);
|
return plModifier::MsgReceive(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,6 +202,7 @@ public:
|
|||||||
kfunc_OnGameMgrMsg,
|
kfunc_OnGameMgrMsg,
|
||||||
kfunc_OnGameCliMsg,
|
kfunc_OnGameCliMsg,
|
||||||
kfunc_OnAIMsg,
|
kfunc_OnAIMsg,
|
||||||
|
kfunc_OnSubtitleMsg,
|
||||||
kfunc_lastone
|
kfunc_lastone
|
||||||
};
|
};
|
||||||
// array of matching Python instance where the functions are, if defined
|
// array of matching Python instance where the functions are, if defined
|
||||||
|
@ -474,6 +474,12 @@ void plPythonSDLModifier::IPythonVarToSDL(plStateDataRecord* state, const char*
|
|||||||
int count = PyTuple_Size(pyVar);
|
int count = PyTuple_Size(pyVar);
|
||||||
plSimpleVarDescriptor::Type type = var->GetSimpleVarDescriptor()->GetType();
|
plSimpleVarDescriptor::Type type = var->GetSimpleVarDescriptor()->GetType();
|
||||||
|
|
||||||
|
// Ensure that variable length arrays match.
|
||||||
|
if (var->GetSimpleVarDescriptor()->IsVariableLength()) {
|
||||||
|
if (var->GetCount() != count)
|
||||||
|
var->Alloc(count);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
PyObject* pyVarItem = PyTuple_GetItem(pyVar, i);
|
PyObject* pyVarItem = PyTuple_GetItem(pyVar, i);
|
||||||
|
@ -256,6 +256,22 @@ hsBool pyAudioControl::IsMuted()
|
|||||||
return plgAudioSys::IsMuted();
|
return plgAudioSys::IsMuted();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enable or disable displaying speech subtitles
|
||||||
|
void pyAudioControl::EnableSubtitles()
|
||||||
|
{
|
||||||
|
plgAudioSys::SetEnableSubtitles(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pyAudioControl::DisableSubtitles()
|
||||||
|
{
|
||||||
|
plgAudioSys::SetEnableSubtitles(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pyAudioControl::AreSubtitlesEnabled() const
|
||||||
|
{
|
||||||
|
return plgAudioSys::AreSubtitlesEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
hsBool pyAudioControl::SupportEAX(const char *deviceName)
|
hsBool pyAudioControl::SupportEAX(const char *deviceName)
|
||||||
{
|
{
|
||||||
return plgAudioSys::SupportsEAX(deviceName);
|
return plgAudioSys::SupportsEAX(deviceName);
|
||||||
|
@ -109,6 +109,11 @@ public:
|
|||||||
virtual void UnmuteAll();
|
virtual void UnmuteAll();
|
||||||
virtual hsBool IsMuted();
|
virtual hsBool IsMuted();
|
||||||
|
|
||||||
|
// Enable or disable displaying speech subtitles
|
||||||
|
void EnableSubtitles();
|
||||||
|
void DisableSubtitles();
|
||||||
|
bool AreSubtitlesEnabled() const;
|
||||||
|
|
||||||
virtual void SetAudioSystemMode(int mode); // sets the current mode
|
virtual void SetAudioSystemMode(int mode); // sets the current mode
|
||||||
virtual int GetAudioSystemMode(); // returns the current mode
|
virtual int GetAudioSystemMode(); // returns the current mode
|
||||||
virtual int GetHighestAudioMode(); // returns the highest mode the card is capable of handling
|
virtual int GetHighestAudioMode(); // returns the highest mode the card is capable of handling
|
||||||
|
@ -242,6 +242,14 @@ PYTHON_METHOD_DEFINITION_NOARGS(ptAudioControl, isMuted)
|
|||||||
PYTHON_RETURN_BOOL(self->fThis->IsMuted());
|
PYTHON_RETURN_BOOL(self->fThis->IsMuted());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PYTHON_BASIC_METHOD_DEFINITION(ptAudioControl, enableSubtitles, EnableSubtitles)
|
||||||
|
PYTHON_BASIC_METHOD_DEFINITION(ptAudioControl, disableSubtitles, DisableSubtitles)
|
||||||
|
|
||||||
|
PYTHON_METHOD_DEFINITION_NOARGS(ptAudioControl, areSubtitlesEnabled)
|
||||||
|
{
|
||||||
|
PYTHON_RETURN_BOOL(self->fThis->AreSubtitlesEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
PYTHON_METHOD_DEFINITION_NOARGS(ptAudioControl, canSetMicLevel)
|
PYTHON_METHOD_DEFINITION_NOARGS(ptAudioControl, canSetMicLevel)
|
||||||
{
|
{
|
||||||
PYTHON_RETURN_BOOL(self->fThis->CanSetMicLevel());
|
PYTHON_RETURN_BOOL(self->fThis->CanSetMicLevel());
|
||||||
@ -484,6 +492,9 @@ PYTHON_START_METHODS_TABLE(ptAudioControl)
|
|||||||
PYTHON_BASIC_METHOD(ptAudioControl, muteAll, "Mutes all sounds."),
|
PYTHON_BASIC_METHOD(ptAudioControl, muteAll, "Mutes all sounds."),
|
||||||
PYTHON_BASIC_METHOD(ptAudioControl, unmuteAll, "Unmutes all sounds."),
|
PYTHON_BASIC_METHOD(ptAudioControl, unmuteAll, "Unmutes all sounds."),
|
||||||
PYTHON_METHOD_NOARGS(ptAudioControl, isMuted, "Are all sounds muted? Returns 1 if true otherwise returns 0."),
|
PYTHON_METHOD_NOARGS(ptAudioControl, isMuted, "Are all sounds muted? Returns 1 if true otherwise returns 0."),
|
||||||
|
PYTHON_BASIC_METHOD(ptAudioControl, enableSubtitles, "Enables audio subtitles."),
|
||||||
|
PYTHON_BASIC_METHOD(ptAudioControl, disableSubtitles, "Disables audio subtitles."),
|
||||||
|
PYTHON_METHOD_NOARGS(ptAudioControl, areSubtitlesEnabled, "Are audio subtitles enabled? Returns 1 if true otherwise returns 0."),
|
||||||
PYTHON_METHOD_NOARGS(ptAudioControl, canSetMicLevel, "Can the microphone level be set? Returns 1 if true otherwise returns 0."),
|
PYTHON_METHOD_NOARGS(ptAudioControl, canSetMicLevel, "Can the microphone level be set? Returns 1 if true otherwise returns 0."),
|
||||||
PYTHON_METHOD(ptAudioControl, setMicLevel, "Params: level\nSets the microphone recording level (0.0 to 1.0)."),
|
PYTHON_METHOD(ptAudioControl, setMicLevel, "Params: level\nSets the microphone recording level (0.0 to 1.0)."),
|
||||||
PYTHON_METHOD_NOARGS(ptAudioControl, getMicLevel, "Returns the microphone recording level (0.0 to 1.0)."),
|
PYTHON_METHOD_NOARGS(ptAudioControl, getMicLevel, "Returns the microphone recording level (0.0 to 1.0)."),
|
||||||
|
@ -587,16 +587,17 @@ std::wstring pyGUIControlListBox::GetElementW( UInt16 idx )
|
|||||||
{
|
{
|
||||||
// if its a text element type then it should be safe to cast it to a pfGUIListText
|
// if its a text element type then it should be safe to cast it to a pfGUIListText
|
||||||
pfGUIListText* letext = (pfGUIListText*)le;
|
pfGUIListText* letext = (pfGUIListText*)le;
|
||||||
return letext->GetText();
|
return (letext->GetText() != nullptr) ? letext->GetText() : L"";
|
||||||
}
|
}
|
||||||
else if ( le->GetType() == pfGUIListElement::kTreeRoot )
|
else if ( le->GetType() == pfGUIListElement::kTreeRoot )
|
||||||
{
|
{
|
||||||
pfGUIListTreeRoot* elroot = (pfGUIListTreeRoot*)le;
|
pfGUIListTreeRoot* elroot = (pfGUIListTreeRoot*)le;
|
||||||
return elroot->GetTitle();
|
return (elroot->GetTitle() != nullptr) ? elroot->GetTitle() : L"";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return L"";
|
return L"";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,9 +34,9 @@ work.
|
|||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||||
or by snail mail at:
|
or by snail mail at:
|
||||||
Cyan Worlds, Inc.
|
Cyan Worlds, Inc.
|
||||||
14617 N Newport Hwy
|
14617 N Newport Hwy
|
||||||
Mead, WA 99021
|
Mead, WA 99021
|
||||||
|
|
||||||
*==LICENSE==*/
|
*==LICENSE==*/
|
||||||
|
|
||||||
@ -46,19 +46,19 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|||||||
#include "plClassIndexMacros.h" // for CLASS_INDEX macro defn
|
#include "plClassIndexMacros.h" // for CLASS_INDEX macro defn
|
||||||
|
|
||||||
CLASS_INDEX_LIST_START
|
CLASS_INDEX_LIST_START
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
// hsKeyedObjects should appear in the first section of the enum list
|
// hsKeyedObjects should appear in the first section of the enum list
|
||||||
// And everything else in the next section
|
// And everything else in the next section
|
||||||
// Otherwise you will get an Assert
|
// Otherwise you will get an Assert
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
CLASS_INDEX(plSceneNode),
|
CLASS_INDEX(plSceneNode),
|
||||||
CLASS_INDEX(plSceneObject),
|
CLASS_INDEX(plSceneObject),
|
||||||
CLASS_INDEX(hsKeyedObject),
|
CLASS_INDEX(hsKeyedObject),
|
||||||
CLASS_INDEX(plBitmap),
|
CLASS_INDEX(plBitmap),
|
||||||
CLASS_INDEX(plMipmap),
|
CLASS_INDEX(plMipmap),
|
||||||
CLASS_INDEX(plCubicEnvironmap),
|
CLASS_INDEX(plCubicEnvironmap),
|
||||||
CLASS_INDEX(plLayer),
|
CLASS_INDEX(plLayer),
|
||||||
CLASS_INDEX(hsGMaterial),
|
CLASS_INDEX(hsGMaterial),
|
||||||
CLASS_INDEX(plParticleSystem),
|
CLASS_INDEX(plParticleSystem),
|
||||||
CLASS_INDEX(plParticleEffect),
|
CLASS_INDEX(plParticleEffect),
|
||||||
CLASS_INDEX(plParticleCollisionEffectBeat),
|
CLASS_INDEX(plParticleCollisionEffectBeat),
|
||||||
@ -74,7 +74,7 @@ CLASS_INDEX_LIST_START
|
|||||||
CLASS_INDEX(plWinAudible),
|
CLASS_INDEX(plWinAudible),
|
||||||
CLASS_INDEX(plCoordinateInterface),
|
CLASS_INDEX(plCoordinateInterface),
|
||||||
CLASS_INDEX(plDrawInterface),
|
CLASS_INDEX(plDrawInterface),
|
||||||
CLASS_INDEX(plDrawable),
|
CLASS_INDEX(plDrawable),
|
||||||
CLASS_INDEX(plDrawableMesh),
|
CLASS_INDEX(plDrawableMesh),
|
||||||
CLASS_INDEX(plDrawableIce),
|
CLASS_INDEX(plDrawableIce),
|
||||||
CLASS_INDEX(plPhysical),
|
CLASS_INDEX(plPhysical),
|
||||||
@ -131,7 +131,7 @@ CLASS_INDEX_LIST_START
|
|||||||
CLASS_INDEX(UNUSED_plDrawablePatchSet),
|
CLASS_INDEX(UNUSED_plDrawablePatchSet),
|
||||||
CLASS_INDEX(plInputManager),
|
CLASS_INDEX(plInputManager),
|
||||||
CLASS_INDEX(plLogicModBase),
|
CLASS_INDEX(plLogicModBase),
|
||||||
CLASS_INDEX(plFogEnvironment),
|
CLASS_INDEX(plFogEnvironment),
|
||||||
CLASS_INDEX(plNetApp),
|
CLASS_INDEX(plNetApp),
|
||||||
CLASS_INDEX(plNetClientMgr),
|
CLASS_INDEX(plNetClientMgr),
|
||||||
CLASS_INDEX(pl2WayWinAudible),
|
CLASS_INDEX(pl2WayWinAudible),
|
||||||
@ -243,7 +243,7 @@ CLASS_INDEX_LIST_START
|
|||||||
CLASS_INDEX(pfGUIDynDisplayCtrl),
|
CLASS_INDEX(pfGUIDynDisplayCtrl),
|
||||||
CLASS_INDEX(UNUSED_plLayerProject),
|
CLASS_INDEX(UNUSED_plLayerProject),
|
||||||
CLASS_INDEX(plInputInterfaceMgr),
|
CLASS_INDEX(plInputInterfaceMgr),
|
||||||
CLASS_INDEX(plRailCameraMod),
|
CLASS_INDEX(plRailCameraMod),
|
||||||
CLASS_INDEX(plMultistageBehMod),
|
CLASS_INDEX(plMultistageBehMod),
|
||||||
CLASS_INDEX(plCameraBrain1_Circle),
|
CLASS_INDEX(plCameraBrain1_Circle),
|
||||||
CLASS_INDEX(plParticleWindEffect),
|
CLASS_INDEX(plParticleWindEffect),
|
||||||
@ -368,14 +368,15 @@ CLASS_INDEX_LIST_START
|
|||||||
CLASS_INDEX(plRidingAnimatedPhysicalDetector),
|
CLASS_INDEX(plRidingAnimatedPhysicalDetector),
|
||||||
CLASS_INDEX(plVolumeSensorConditionalObjectNoArbitration),
|
CLASS_INDEX(plVolumeSensorConditionalObjectNoArbitration),
|
||||||
CLASS_INDEX(plPXSubWorld),
|
CLASS_INDEX(plPXSubWorld),
|
||||||
//---------------------------------------------------------
|
CLASS_INDEX(pfConfirmationMgr),
|
||||||
// Keyed objects above this line, unkeyed (such as messages) below..
|
//---------------------------------------------------------
|
||||||
//---------------------------------------------------------
|
// Keyed objects above this line, unkeyed (such as messages) below..
|
||||||
|
//---------------------------------------------------------
|
||||||
|
|
||||||
CLASS_INDEX_NONKEYED_OBJ_START
|
CLASS_INDEX_NONKEYED_OBJ_START
|
||||||
CLASS_INDEX(plObjRefMsg),
|
CLASS_INDEX(plObjRefMsg),
|
||||||
CLASS_INDEX(plNodeRefMsg),
|
CLASS_INDEX(plNodeRefMsg),
|
||||||
CLASS_INDEX(plMessage),
|
CLASS_INDEX(plMessage),
|
||||||
CLASS_INDEX(plRefMsg),
|
CLASS_INDEX(plRefMsg),
|
||||||
CLASS_INDEX(plGenRefMsg),
|
CLASS_INDEX(plGenRefMsg),
|
||||||
CLASS_INDEX(plTimeMsg),
|
CLASS_INDEX(plTimeMsg),
|
||||||
@ -411,12 +412,12 @@ CLASS_INDEX_LIST_START
|
|||||||
CLASS_INDEX(hsSfxObjDistFade),
|
CLASS_INDEX(hsSfxObjDistFade),
|
||||||
CLASS_INDEX(hsSfxObjDistShade),
|
CLASS_INDEX(hsSfxObjDistShade),
|
||||||
CLASS_INDEX(hsDynamicValue),
|
CLASS_INDEX(hsDynamicValue),
|
||||||
CLASS_INDEX(hsDynamicScalar),
|
CLASS_INDEX(hsDynamicScalar),
|
||||||
CLASS_INDEX(hsDynamicColorRGBA),
|
CLASS_INDEX(hsDynamicColorRGBA),
|
||||||
CLASS_INDEX(hsDynamicMatrix33),
|
CLASS_INDEX(hsDynamicMatrix33),
|
||||||
CLASS_INDEX(hsDynamicMatrix44),
|
CLASS_INDEX(hsDynamicMatrix44),
|
||||||
CLASS_INDEX(plOmniSqApplicator),
|
CLASS_INDEX(plOmniSqApplicator),
|
||||||
CLASS_INDEX(plPreResourceMsg),
|
CLASS_INDEX(plPreResourceMsg),
|
||||||
CLASS_INDEX(UNUSED_hsDynamicColorRGBA),
|
CLASS_INDEX(UNUSED_hsDynamicColorRGBA),
|
||||||
CLASS_INDEX(UNUSED_hsDynamicMatrix33),
|
CLASS_INDEX(UNUSED_hsDynamicMatrix33),
|
||||||
CLASS_INDEX(UNUSED_hsDynamicMatrix44),
|
CLASS_INDEX(UNUSED_hsDynamicMatrix44),
|
||||||
@ -427,7 +428,7 @@ CLASS_INDEX_LIST_START
|
|||||||
CLASS_INDEX(UNUSED_plPosController),
|
CLASS_INDEX(UNUSED_plPosController),
|
||||||
CLASS_INDEX(UNUSED_plScalarController),
|
CLASS_INDEX(UNUSED_plScalarController),
|
||||||
CLASS_INDEX(UNUSED_plPoint3Controller),
|
CLASS_INDEX(UNUSED_plPoint3Controller),
|
||||||
CLASS_INDEX(UNUSED_plScaleValueController),
|
CLASS_INDEX(UNUSED_plScaleValueController),
|
||||||
CLASS_INDEX(UNUSED_plQuatController),
|
CLASS_INDEX(UNUSED_plQuatController),
|
||||||
CLASS_INDEX(UNUSED_plMatrix33Controller),
|
CLASS_INDEX(UNUSED_plMatrix33Controller),
|
||||||
CLASS_INDEX(UNUSED_plMatrix44Controller),
|
CLASS_INDEX(UNUSED_plMatrix44Controller),
|
||||||
@ -437,7 +438,7 @@ CLASS_INDEX_LIST_START
|
|||||||
CLASS_INDEX(plCompoundRotController),
|
CLASS_INDEX(plCompoundRotController),
|
||||||
CLASS_INDEX(UNUSED_plSimplePosController),
|
CLASS_INDEX(UNUSED_plSimplePosController),
|
||||||
CLASS_INDEX(plCompoundPosController),
|
CLASS_INDEX(plCompoundPosController),
|
||||||
CLASS_INDEX(plTMController),
|
CLASS_INDEX(plTMController),
|
||||||
CLASS_INDEX(hsFogControl),
|
CLASS_INDEX(hsFogControl),
|
||||||
CLASS_INDEX(plIntRefMsg),
|
CLASS_INDEX(plIntRefMsg),
|
||||||
CLASS_INDEX(plCollisionReactor),
|
CLASS_INDEX(plCollisionReactor),
|
||||||
@ -577,8 +578,8 @@ CLASS_INDEX_LIST_START
|
|||||||
CLASS_INDEX(plNetServerMsgPing),
|
CLASS_INDEX(plNetServerMsgPing),
|
||||||
CLASS_INDEX(plNetMsgAlive),
|
CLASS_INDEX(plNetMsgAlive),
|
||||||
CLASS_INDEX(plNetMsgTerminated),
|
CLASS_INDEX(plNetMsgTerminated),
|
||||||
CLASS_INDEX(plSDLModifierMsg),
|
CLASS_INDEX(plSDLModifierMsg),
|
||||||
CLASS_INDEX(plNetMsgSDLState),
|
CLASS_INDEX(plNetMsgSDLState),
|
||||||
CLASS_INDEX(plNetServerMsgSessionReset),
|
CLASS_INDEX(plNetServerMsgSessionReset),
|
||||||
CLASS_INDEX(plCCRBanLinkingMsg),
|
CLASS_INDEX(plCCRBanLinkingMsg),
|
||||||
CLASS_INDEX(plCCRSilencePlayerMsg),
|
CLASS_INDEX(plCCRSilencePlayerMsg),
|
||||||
@ -780,17 +781,17 @@ CLASS_INDEX_LIST_START
|
|||||||
CLASS_INDEX(plShadowCastMsg),
|
CLASS_INDEX(plShadowCastMsg),
|
||||||
CLASS_INDEX(plBoundsIsect),
|
CLASS_INDEX(plBoundsIsect),
|
||||||
CLASS_INDEX(plResMgrHelperMsg),
|
CLASS_INDEX(plResMgrHelperMsg),
|
||||||
CLASS_INDEX(plNetCommAuthMsg),
|
CLASS_INDEX(plNetCommAuthMsg),
|
||||||
CLASS_INDEX(plNetCommFileListMsg),
|
CLASS_INDEX(plNetCommFileListMsg),
|
||||||
CLASS_INDEX(plNetCommFileDownloadMsg),
|
CLASS_INDEX(plNetCommFileDownloadMsg),
|
||||||
CLASS_INDEX(plNetCommLinkToAgeMsg),
|
CLASS_INDEX(plNetCommLinkToAgeMsg),
|
||||||
CLASS_INDEX(plNetCommPlayerListMsg),
|
CLASS_INDEX(plNetCommPlayerListMsg),
|
||||||
CLASS_INDEX(plNetCommActivePlayerMsg),
|
CLASS_INDEX(plNetCommActivePlayerMsg),
|
||||||
CLASS_INDEX(plNetCommCreatePlayerMsg),
|
CLASS_INDEX(plNetCommCreatePlayerMsg),
|
||||||
CLASS_INDEX(plNetCommDeletePlayerMsg),
|
CLASS_INDEX(plNetCommDeletePlayerMsg),
|
||||||
CLASS_INDEX(plNetCommPublicAgeListMsg),
|
CLASS_INDEX(plNetCommPublicAgeListMsg),
|
||||||
CLASS_INDEX(plNetCommPublicAgeMsg),
|
CLASS_INDEX(plNetCommPublicAgeMsg),
|
||||||
CLASS_INDEX(plNetCommRegisterAgeMsg),
|
CLASS_INDEX(plNetCommRegisterAgeMsg),
|
||||||
CLASS_INDEX(plVaultAdminInitializationTask),
|
CLASS_INDEX(plVaultAdminInitializationTask),
|
||||||
CLASS_INDEX(plMultistageModMsg),
|
CLASS_INDEX(plMultistageModMsg),
|
||||||
CLASS_INDEX(plSoundVolumeApplicator),
|
CLASS_INDEX(plSoundVolumeApplicator),
|
||||||
@ -948,6 +949,17 @@ CLASS_INDEX_LIST_START
|
|||||||
CLASS_INDEX(plAngularVelocityMsg),
|
CLASS_INDEX(plAngularVelocityMsg),
|
||||||
CLASS_INDEX(plRideAnimatedPhysMsg),
|
CLASS_INDEX(plRideAnimatedPhysMsg),
|
||||||
CLASS_INDEX(plAvBrainRideAnimatedPhysical),
|
CLASS_INDEX(plAvBrainRideAnimatedPhysical),
|
||||||
|
CLASS_INDEX(pfGameScoreMsg), // This index and below are unused currently and placed for indexing plSubtitleMsg consistently with H'uru
|
||||||
|
CLASS_INDEX(pfGameScoreListMsg),
|
||||||
|
CLASS_INDEX(pfGameScoreTransferMsg),
|
||||||
|
CLASS_INDEX(pfGameScoreUpdateMsg),
|
||||||
|
CLASS_INDEX(plLoadClothingMsg),
|
||||||
|
CLASS_INDEX(plNullPipeline),
|
||||||
|
CLASS_INDEX(plGLPipeline),
|
||||||
|
CLASS_INDEX(plSDLModifierStateMsg),
|
||||||
|
CLASS_INDEX(plConfirmationMsg),
|
||||||
|
CLASS_INDEX(plLocalizedConfirmationMsg), // This index and above are unused currently and placed for indexing plSubtitleMsg consistently with H'uru
|
||||||
|
CLASS_INDEX(plSubtitleMsg),
|
||||||
CLASS_INDEX_LIST_END
|
CLASS_INDEX_LIST_END
|
||||||
|
|
||||||
#endif // plCreatableIndex_inc
|
#endif // plCreatableIndex_inc
|
@ -43,7 +43,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|||||||
#ifndef plLogicModBase_inc
|
#ifndef plLogicModBase_inc
|
||||||
#define plLogicModBase_inc
|
#define plLogicModBase_inc
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <cstdint>
|
||||||
#include "plSingleModifier.h"
|
#include "plSingleModifier.h"
|
||||||
#include "../pnNetCommon/plSynchedValue.h"
|
#include "../pnNetCommon/plSynchedValue.h"
|
||||||
#include "hsTemplates.h"
|
#include "hsTemplates.h"
|
||||||
|
@ -994,6 +994,7 @@ hsBool plgAudioSys::fInit = false;
|
|||||||
hsBool plgAudioSys::fActive = false;
|
hsBool plgAudioSys::fActive = false;
|
||||||
hsBool plgAudioSys::fUseHardware = false;
|
hsBool plgAudioSys::fUseHardware = false;
|
||||||
hsBool plgAudioSys::fMuted = true;
|
hsBool plgAudioSys::fMuted = true;
|
||||||
|
bool plgAudioSys::fEnableSubtitles = true;
|
||||||
hsBool plgAudioSys::fDelayedActivate = false;
|
hsBool plgAudioSys::fDelayedActivate = false;
|
||||||
hsBool plgAudioSys::fEnableEAX = false;
|
hsBool plgAudioSys::fEnableEAX = false;
|
||||||
hsWindowHndl plgAudioSys::fWnd = nil;
|
hsWindowHndl plgAudioSys::fWnd = nil;
|
||||||
@ -1047,6 +1048,11 @@ void plgAudioSys::SetMuted( hsBool b )
|
|||||||
SetGlobalFadeVolume(1.0);
|
SetGlobalFadeVolume(1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void plgAudioSys::SetEnableSubtitles(bool b)
|
||||||
|
{
|
||||||
|
fEnableSubtitles = b;
|
||||||
|
}
|
||||||
|
|
||||||
void plgAudioSys::SetUseHardware(hsBool b)
|
void plgAudioSys::SetUseHardware(hsBool b)
|
||||||
{
|
{
|
||||||
fUseHardware = b;
|
fUseHardware = b;
|
||||||
|
@ -193,11 +193,13 @@ public:
|
|||||||
static void SetUseHardware(hsBool b);
|
static void SetUseHardware(hsBool b);
|
||||||
static void SetActive(hsBool b);
|
static void SetActive(hsBool b);
|
||||||
static void SetMuted( hsBool b );
|
static void SetMuted( hsBool b );
|
||||||
|
static void SetEnableSubtitles(bool b);
|
||||||
static void EnableEAX( hsBool b );
|
static void EnableEAX( hsBool b );
|
||||||
static hsBool Active() { return fInit; }
|
static hsBool Active() { return fInit; }
|
||||||
static void Shutdown();
|
static void Shutdown();
|
||||||
static void Activate(hsBool b);
|
static void Activate(hsBool b);
|
||||||
static hsBool IsMuted( void ) { return fMuted; }
|
static hsBool IsMuted( void ) { return fMuted; }
|
||||||
|
static bool AreSubtitlesEnabled() { return fEnableSubtitles; }
|
||||||
static hsWindowHndl hWnd() { return fWnd; }
|
static hsWindowHndl hWnd() { return fWnd; }
|
||||||
static plAudioSystem* Sys() { return fSys; }
|
static plAudioSystem* Sys() { return fSys; }
|
||||||
static void Restart( void );
|
static void Restart( void );
|
||||||
@ -258,6 +260,7 @@ private:
|
|||||||
static hsBool fInit;
|
static hsBool fInit;
|
||||||
static hsBool fActive;
|
static hsBool fActive;
|
||||||
static hsBool fMuted;
|
static hsBool fMuted;
|
||||||
|
static bool fEnableSubtitles;
|
||||||
static hsWindowHndl fWnd;
|
static hsWindowHndl fWnd;
|
||||||
static hsBool fUseHardware;
|
static hsBool fUseHardware;
|
||||||
static hsBool fDelayedActivate;
|
static hsBool fDelayedActivate;
|
||||||
|
@ -710,9 +710,9 @@ hsBool plDSoundBuffer::IsEAXAccelerated( void ) const
|
|||||||
|
|
||||||
//// BytePosToMSecs //////////////////////////////////////////////////////////
|
//// BytePosToMSecs //////////////////////////////////////////////////////////
|
||||||
|
|
||||||
UInt32 plDSoundBuffer::BytePosToMSecs( UInt32 bytePos ) const
|
UInt32 plDSoundBuffer::BytePosToMSecs(UInt32 bytePos) const
|
||||||
{
|
{
|
||||||
return (UInt32)(bytePos * 1000 / (hsScalar)fBufferDesc->fAvgBytesPerSec);
|
return (UInt32)(bytePos / ((float)fBufferDesc->fAvgBytesPerSec / 1000.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
//// GetBufferBytePos ////////////////////////////////////////////////////////
|
//// GetBufferBytePos ////////////////////////////////////////////////////////
|
||||||
|
@ -53,10 +53,12 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|||||||
#include "plWavFile.h"
|
#include "plWavFile.h"
|
||||||
|
|
||||||
#include "../plAudible/plWinAudible.h"
|
#include "../plAudible/plWinAudible.h"
|
||||||
|
#include "../plAudioCore/plSrtFileReader.h"
|
||||||
|
#include "../pnMessage/plEventCallbackMsg.h"
|
||||||
|
#include "../pnMessage/plSoundMsg.h"
|
||||||
|
#include "../plMessage/plSubtitleMsg.h"
|
||||||
#include "../plNetMessage/plNetMessage.h"
|
#include "../plNetMessage/plNetMessage.h"
|
||||||
#include "../pnNetCommon/plNetApp.h"
|
#include "../pnNetCommon/plNetApp.h"
|
||||||
#include "../pnMessage/plSoundMsg.h"
|
|
||||||
#include "../pnMessage/plEventCallbackMsg.h"
|
|
||||||
#include "../plPipeline/plPlates.h"
|
#include "../plPipeline/plPlates.h"
|
||||||
#include "../plStatusLog/plStatusLog.h"
|
#include "../plStatusLog/plStatusLog.h"
|
||||||
|
|
||||||
@ -108,6 +110,23 @@ void plWin32Sound::IFreeBuffers( void )
|
|||||||
|
|
||||||
void plWin32Sound::Update()
|
void plWin32Sound::Update()
|
||||||
{
|
{
|
||||||
|
plSoundBuffer* buf = GetDataBuffer();
|
||||||
|
if (buf != nullptr) {
|
||||||
|
plSrtFileReader* srtReader = buf->GetSrtReader();
|
||||||
|
if (srtReader != nullptr) {
|
||||||
|
uint32_t currentTimeMs = (uint32_t)(GetActualTimeSec() * 1000.0f);
|
||||||
|
if (currentTimeMs <= srtReader->GetLastEntryEndTime()) {
|
||||||
|
while (plSrtEntry* nextEntry = srtReader->GetNextEntryStartingBeforeTime(currentTimeMs)) {
|
||||||
|
if (plgAudioSys::AreSubtitlesEnabled()) {
|
||||||
|
// add a plSubtitleMsg to go... to whoever is listening (probably the KI)
|
||||||
|
plSubtitleMsg* msg = new plSubtitleMsg(nextEntry->GetSubtitleText(), nextEntry->GetSpeakerName());
|
||||||
|
msg->Send();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
plSound::Update();
|
plSound::Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,6 +139,17 @@ void plWin32Sound::IActuallyPlay( void )
|
|||||||
{
|
{
|
||||||
if (fDSoundBuffer && plgAudioSys::Active() )
|
if (fDSoundBuffer && plgAudioSys::Active() )
|
||||||
{
|
{
|
||||||
|
if (!fReallyPlaying && fSynchedStartTimeSec > 0) {
|
||||||
|
// advance past any subtitles that would end before the synched start time
|
||||||
|
// not sure when this actually happens...
|
||||||
|
plSoundBuffer* buf = GetDataBuffer();
|
||||||
|
if (buf != nullptr) {
|
||||||
|
plSrtFileReader* srtReader = buf->GetSrtReader();
|
||||||
|
if (srtReader != nullptr) {
|
||||||
|
srtReader->AdvanceToTime(fSynchedStartTimeSec * 1000.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Sometimes base/derived classes can be annoying
|
// Sometimes base/derived classes can be annoying
|
||||||
IDerivedActuallyPlay();
|
IDerivedActuallyPlay();
|
||||||
|
@ -455,21 +455,24 @@ void plWin32StreamingSound::IActuallyStop()
|
|||||||
|
|
||||||
unsigned plWin32StreamingSound::GetByteOffset()
|
unsigned plWin32StreamingSound::GetByteOffset()
|
||||||
{
|
{
|
||||||
if(fDataStream && fDSoundBuffer)
|
if (fDataStream && fDSoundBuffer)
|
||||||
{
|
{
|
||||||
|
UInt32 totalSize = fDataStream->GetDataSize();
|
||||||
|
UInt32 bytesRemaining = fDataStream->NumBytesLeft();
|
||||||
unsigned bytesQueued = fDSoundBuffer->BuffersQueued() * STREAM_BUFFER_SIZE;
|
unsigned bytesQueued = fDSoundBuffer->BuffersQueued() * STREAM_BUFFER_SIZE;
|
||||||
unsigned offset = fDSoundBuffer->GetByteOffset();
|
unsigned offset = fDSoundBuffer->GetByteOffset();
|
||||||
long byteoffset = ((fDataStream->GetDataSize() - fDataStream->NumBytesLeft()) - bytesQueued) + offset;
|
long byteoffset = ((totalSize - bytesRemaining) - bytesQueued) + offset;
|
||||||
|
|
||||||
return byteoffset < 0 ? fDataStream->GetDataSize() - abs(byteoffset) : byteoffset;
|
return byteoffset < 0 ? totalSize - std::abs(byteoffset) : byteoffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
float plWin32StreamingSound::GetActualTimeSec()
|
float plWin32StreamingSound::GetActualTimeSec()
|
||||||
{
|
{
|
||||||
if(fDataStream && fDSoundBuffer)
|
if (fDataStream && fDSoundBuffer)
|
||||||
return fDSoundBuffer->BytePosToMSecs(fDataStream->NumBytesLeft()) / 1000.0f;
|
return fDSoundBuffer->BytePosToMSecs(this->GetByteOffset()) / 1000.0f;
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,9 +45,11 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|||||||
|
|
||||||
#include "hsStream.h"
|
#include "hsStream.h"
|
||||||
#include "hsUtils.h"
|
#include "hsUtils.h"
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
#include "plgDispatch.h"
|
#include "plgDispatch.h"
|
||||||
#include "hsResMgr.h"
|
#include "hsResMgr.h"
|
||||||
|
#include "plSrtFileReader.h"
|
||||||
#include "../pnMessage/plRefMsg.h"
|
#include "../pnMessage/plRefMsg.h"
|
||||||
#include "../plFile/plFileUtils.h"
|
#include "../plFile/plFileUtils.h"
|
||||||
#include "../plFile/hsFiles.h"
|
#include "../plFile/hsFiles.h"
|
||||||
@ -117,20 +119,35 @@ static void LoadCallback(void *)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
plAudioFileReader *reader = nil;
|
plAudioFileReader *reader = nil;
|
||||||
|
plSrtFileReader* srtReader = nullptr;
|
||||||
|
|
||||||
while(plSoundBuffer *buffer = templist.Head())
|
while(plSoundBuffer *buffer = templist.Head())
|
||||||
{
|
{
|
||||||
if(buffer->GetData())
|
if(buffer->GetData())
|
||||||
{
|
{
|
||||||
reader = CreateReader(true, buffer->GetFileName(), buffer->GetAudioReaderType(), buffer->GetReaderSelect());
|
const char* srcFilename = buffer->GetFileName();
|
||||||
|
reader = CreateReader(true, srcFilename, buffer->GetAudioReaderType(), buffer->GetReaderSelect());
|
||||||
|
|
||||||
if( reader )
|
if( reader )
|
||||||
{
|
{
|
||||||
unsigned readLen = buffer->GetAsyncLoadLength() ? buffer->GetAsyncLoadLength() : buffer->GetDataLength();
|
unsigned readLen = buffer->GetAsyncLoadLength() ? buffer->GetAsyncLoadLength() : buffer->GetDataLength();
|
||||||
reader->Read( readLen, buffer->GetData() );
|
reader->Read( readLen, buffer->GetData() );
|
||||||
buffer->SetAudioReader(reader); // give sound buffer reader, since we may need it later
|
buffer->SetAudioReader(reader); // give sound buffer reader, since we may need it later
|
||||||
|
|
||||||
|
plSrtFileReader* srtReader = buffer->GetSrtReader();
|
||||||
|
if (srtReader != nullptr && (strcmp(srtReader->GetCurrentAudioFileName(), srcFilename) == 0)) {
|
||||||
|
// same file we were playing before, so start the SRT feed over instead of deleting and reloading
|
||||||
|
srtReader->StartOver();
|
||||||
|
} else {
|
||||||
|
std::unique_ptr<plSrtFileReader> newSrtFileReader(new plSrtFileReader(srcFilename));
|
||||||
|
if (newSrtFileReader->ReadFile())
|
||||||
|
buffer->SetSrtReader(newSrtFileReader.release());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
buffer->SetError();
|
buffer->SetError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
templist.Unlink(buffer);
|
templist.Unlink(buffer);
|
||||||
@ -194,6 +211,8 @@ plSoundBuffer::~plSoundBuffer()
|
|||||||
ASSERT(!link.IsLinked());
|
ASSERT(!link.IsLinked());
|
||||||
delete [] fFileName;
|
delete [] fFileName;
|
||||||
UnLoad();
|
UnLoad();
|
||||||
|
|
||||||
|
delete fSrtReader;
|
||||||
}
|
}
|
||||||
|
|
||||||
void plSoundBuffer::IInitBuffer()
|
void plSoundBuffer::IInitBuffer()
|
||||||
@ -206,6 +225,7 @@ void plSoundBuffer::IInitBuffer()
|
|||||||
fFlags = 0;
|
fFlags = 0;
|
||||||
fDataRead = 0;
|
fDataRead = 0;
|
||||||
fReader = nil;
|
fReader = nil;
|
||||||
|
fSrtReader = nullptr;
|
||||||
fLoaded = 0;
|
fLoaded = 0;
|
||||||
fLoading = false;
|
fLoading = false;
|
||||||
fHeader.fFormatTag = 0;
|
fHeader.fFormatTag = 0;
|
||||||
@ -458,6 +478,12 @@ void plSoundBuffer::SetLoaded(bool loaded)
|
|||||||
fLoaded = loaded;
|
fLoaded = loaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void plSoundBuffer::SetSrtReader(plSrtFileReader* reader)
|
||||||
|
{
|
||||||
|
delete fSrtReader;
|
||||||
|
fSrtReader = reader;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
|
@ -61,6 +61,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|||||||
|
|
||||||
class plUnifiedTime;
|
class plUnifiedTime;
|
||||||
class plAudioFileReader;
|
class plAudioFileReader;
|
||||||
|
class plSrtFileReader;
|
||||||
class plSoundBuffer : public hsKeyedObject
|
class plSoundBuffer : public hsKeyedObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -118,6 +119,8 @@ public:
|
|||||||
plAudioFileReader * GetAudioReader(); // transfers ownership to caller
|
plAudioFileReader * GetAudioReader(); // transfers ownership to caller
|
||||||
void SetAudioReader(plAudioFileReader *reader);
|
void SetAudioReader(plAudioFileReader *reader);
|
||||||
void SetLoaded(bool loaded);
|
void SetLoaded(bool loaded);
|
||||||
|
plSrtFileReader* GetSrtReader() const { return fSrtReader; } // does not transfer ownership
|
||||||
|
void SetSrtReader(plSrtFileReader* reader);
|
||||||
|
|
||||||
plAudioFileReader::StreamType GetAudioReaderType() { return fStreamType; }
|
plAudioFileReader::StreamType GetAudioReaderType() { return fStreamType; }
|
||||||
unsigned GetAsyncLoadLength() { return fAsyncLoadLength ? fAsyncLoadLength : fDataLength; }
|
unsigned GetAsyncLoadLength() { return fAsyncLoadLength ? fAsyncLoadLength : fDataLength; }
|
||||||
@ -148,7 +151,8 @@ protected:
|
|||||||
bool fLoading;
|
bool fLoading;
|
||||||
bool fError;
|
bool fError;
|
||||||
|
|
||||||
plAudioFileReader * fReader;
|
plAudioFileReader * fReader;
|
||||||
|
plSrtFileReader* fSrtReader;
|
||||||
UInt8 * fData;
|
UInt8 * fData;
|
||||||
plWAVHeader fHeader;
|
plWAVHeader fHeader;
|
||||||
UInt32 fDataLength;
|
UInt32 fDataLength;
|
||||||
|
196
Sources/Plasma/PubUtilLib/plAudioCore/plSrtFileReader.cpp
Normal file
196
Sources/Plasma/PubUtilLib/plAudioCore/plSrtFileReader.cpp
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
/*==LICENSE==*
|
||||||
|
|
||||||
|
CyanWorlds.com Engine - MMOG client, server and tools
|
||||||
|
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Additional permissions under GNU GPL version 3 section 7
|
||||||
|
|
||||||
|
If you modify this Program, or any covered work, by linking or
|
||||||
|
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||||
|
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||||
|
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||||
|
(or a modified version of those libraries),
|
||||||
|
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||||
|
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||||
|
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||||
|
licensors of this Program grant you additional
|
||||||
|
permission to convey the resulting work. Corresponding Source for a
|
||||||
|
non-source form of such a combination shall include the source code for
|
||||||
|
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||||
|
work.
|
||||||
|
|
||||||
|
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||||
|
or by snail mail at:
|
||||||
|
Cyan Worlds, Inc.
|
||||||
|
14617 N Newport Hwy
|
||||||
|
Mead, WA 99021
|
||||||
|
|
||||||
|
*==LICENSE==*/
|
||||||
|
|
||||||
|
#include "plSrtFileReader.h"
|
||||||
|
|
||||||
|
#include "hsStream.h"
|
||||||
|
|
||||||
|
#include "../plStatusLog/plStatusLog.h"
|
||||||
|
#include "../pnUtils/pnUtils.h"
|
||||||
|
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
static const std::regex speakerTextRegex("^((([\\w.]+(\\s\\w+)?):) )?(.*)");
|
||||||
|
static const std::regex timingsRegex("^(\\d{2}):(\\d{2}):(\\d{2}),(\\d{3}) --> (\\d{2}):(\\d{2}):(\\d{2}),(\\d{3})$");
|
||||||
|
|
||||||
|
bool plSrtFileReader::ReadFile()
|
||||||
|
{
|
||||||
|
wchar path[MAX_PATH];
|
||||||
|
StrPrintf(path, arrsize(path), L"sfx\\%S", fAudioFileName);
|
||||||
|
PathSetExtension(path, path, L".sub", arrsize(path));
|
||||||
|
|
||||||
|
if (PathDoesFileExist(path)) {
|
||||||
|
// read sets of SRT data until end of file
|
||||||
|
hsUNIXStream srtFileStream;
|
||||||
|
|
||||||
|
// if file exists and was opened successfully
|
||||||
|
if (srtFileStream.Open(path, L"r")) {
|
||||||
|
plStatusLog::AddLineS("audio.log", "Successfully opened subtitle file %S", path);
|
||||||
|
|
||||||
|
uint32_t subtitleNumber = 0;
|
||||||
|
uint32_t subtitleStartTimeMs = 0;
|
||||||
|
uint32_t subtitleEndTimeMs = 0;
|
||||||
|
char line[4096];
|
||||||
|
std::string speakerName;
|
||||||
|
std::string subtitleText;
|
||||||
|
std::cmatch matches;
|
||||||
|
|
||||||
|
for (unsigned int lnCounter = 0; !srtFileStream.AtEnd(); lnCounter++) {
|
||||||
|
if (lnCounter % 4 == 0 && srtFileStream.ReadLn(line)) {
|
||||||
|
subtitleNumber = std::stoul(line);
|
||||||
|
} else if (lnCounter % 4 == 1 && srtFileStream.ReadLn(line)) {
|
||||||
|
if (std::regex_match(line, matches, timingsRegex)) {
|
||||||
|
if (matches.size() < 9) {
|
||||||
|
// add error message and ensure this subtitle line won't be added to the entries
|
||||||
|
plStatusLog::AddLineS("audio.log", plStatusLog::kRed, " Subtitle timings '%s' are formatted incorrectly.", line);
|
||||||
|
subtitleNumber = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// matches[0] is the entire match, we don't do anything with it
|
||||||
|
// matches[1] is the first group -- the start hour number
|
||||||
|
subtitleStartTimeMs += std::stoul(matches[1].str()) * 3600000;
|
||||||
|
// matches[2] is the second group -- the start minute number
|
||||||
|
subtitleStartTimeMs += std::stoul(matches[2].str()) * 60000;
|
||||||
|
// matches[3] is the third group -- the start seconds number
|
||||||
|
subtitleStartTimeMs += std::stoul(matches[3].str()) * 1000;
|
||||||
|
// matches[4] is the fourth group -- the start milliseconds number
|
||||||
|
subtitleStartTimeMs += std::stoul(matches[4].str());
|
||||||
|
|
||||||
|
// matches[5] is the fifth group -- the end hour number
|
||||||
|
subtitleEndTimeMs += std::stoul(matches[5].str()) * 3600000;
|
||||||
|
// matches[6] is the sixth group -- the end minute number
|
||||||
|
subtitleEndTimeMs += std::stoul(matches[6].str()) * 60000;
|
||||||
|
// matches[7] is the seventh group -- the end seconds number
|
||||||
|
subtitleEndTimeMs += std::stoul(matches[7].str()) * 1000;
|
||||||
|
// matches[8] is the eighth group -- the end milliseconds number
|
||||||
|
subtitleEndTimeMs += std::stoul(matches[8].str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (lnCounter % 4 == 2 && srtFileStream.ReadLn(line)) {
|
||||||
|
if (std::regex_match(line, matches, speakerTextRegex)) {
|
||||||
|
if (matches.size() < 5) {
|
||||||
|
// add error message and ensure this subtitle line won't be added to the entries
|
||||||
|
plStatusLog::AddLineS("audio.log", plStatusLog::kRed, " Subtitle text and/or speaker name '%s' are formatted incorrectly.", line);
|
||||||
|
subtitleNumber = 0;
|
||||||
|
} else {
|
||||||
|
// matches[0] is the entire match, we don't do anything with it
|
||||||
|
// matches[2] is the second group (the optional subtitle speaker with colon but no space at the end)
|
||||||
|
speakerName = matches[2];
|
||||||
|
|
||||||
|
// matches[5] is the fourth group (the subtitle text)
|
||||||
|
subtitleText = matches[5];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (lnCounter % 4 == 3 && subtitleNumber > 0 && subtitleStartTimeMs >= 0 && subtitleEndTimeMs >= 0 && !subtitleText.empty()) {
|
||||||
|
// entry is complete, add to the queue and reset our temp variables
|
||||||
|
if (!speakerName.empty())
|
||||||
|
fEntries.emplace_back(plSrtEntry(subtitleNumber, subtitleStartTimeMs, subtitleEndTimeMs, std::move(subtitleText), std::move(speakerName)));
|
||||||
|
else
|
||||||
|
fEntries.emplace_back(plSrtEntry(subtitleNumber, subtitleStartTimeMs, subtitleEndTimeMs, std::move(subtitleText)));
|
||||||
|
|
||||||
|
subtitleNumber = 0;
|
||||||
|
subtitleStartTimeMs = 0;
|
||||||
|
subtitleEndTimeMs = 0;
|
||||||
|
subtitleText.clear();
|
||||||
|
speakerName.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (subtitleNumber > 0 && subtitleStartTimeMs >= 0 && subtitleEndTimeMs >= 0 && !subtitleText.empty()) {
|
||||||
|
// enqueue the last subtitle from the file if we didn't have an extra blank line at the end
|
||||||
|
if (!speakerName.empty())
|
||||||
|
fEntries.emplace_back(plSrtEntry(subtitleNumber, subtitleStartTimeMs, subtitleEndTimeMs, std::move(subtitleText), std::move(speakerName)));
|
||||||
|
else
|
||||||
|
fEntries.emplace_back(plSrtEntry(subtitleNumber, subtitleStartTimeMs, subtitleEndTimeMs, std::move(subtitleText)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void plSrtFileReader::AdvanceToTime(uint32_t timeMs)
|
||||||
|
{
|
||||||
|
while (fCurrentEntryIndex < fEntries.size() && fEntries.at(fCurrentEntryIndex).GetEndTimeMs() <= timeMs) {
|
||||||
|
fCurrentEntryIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
plSrtEntry* plSrtFileReader::GetNextEntryStartingBeforeTime(uint32_t timeMs)
|
||||||
|
{
|
||||||
|
if (fCurrentEntryIndex < fEntries.size()) {
|
||||||
|
plSrtEntry& nextEntry = fEntries.at(fCurrentEntryIndex);
|
||||||
|
|
||||||
|
if (nextEntry.GetStartTimeMs() <= timeMs) {
|
||||||
|
fCurrentEntryIndex++;
|
||||||
|
return &nextEntry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
plSrtEntry* plSrtFileReader::GetNextEntryEndingBeforeTime(uint32_t timeMs)
|
||||||
|
{
|
||||||
|
if (fCurrentEntryIndex < fEntries.size()) {
|
||||||
|
plSrtEntry& nextEntry = fEntries.at(fCurrentEntryIndex);
|
||||||
|
|
||||||
|
if (nextEntry.GetEndTimeMs() <= timeMs) {
|
||||||
|
fCurrentEntryIndex++;
|
||||||
|
return &nextEntry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t plSrtFileReader::GetLastEntryEndTime()
|
||||||
|
{
|
||||||
|
if (!fEntries.empty()) {
|
||||||
|
return fEntries.back().GetEndTimeMs();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
108
Sources/Plasma/PubUtilLib/plAudioCore/plSrtFileReader.h
Normal file
108
Sources/Plasma/PubUtilLib/plAudioCore/plSrtFileReader.h
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/*==LICENSE==*
|
||||||
|
|
||||||
|
CyanWorlds.com Engine - MMOG client, server and tools
|
||||||
|
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Additional permissions under GNU GPL version 3 section 7
|
||||||
|
|
||||||
|
If you modify this Program, or any covered work, by linking or
|
||||||
|
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||||
|
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||||
|
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||||
|
(or a modified version of those libraries),
|
||||||
|
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||||
|
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||||
|
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||||
|
licensors of this Program grant you additional
|
||||||
|
permission to convey the resulting work. Corresponding Source for a
|
||||||
|
non-source form of such a combination shall include the source code for
|
||||||
|
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||||
|
work.
|
||||||
|
|
||||||
|
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||||
|
or by snail mail at:
|
||||||
|
Cyan Worlds, Inc.
|
||||||
|
14617 N Newport Hwy
|
||||||
|
Mead, WA 99021
|
||||||
|
|
||||||
|
*==LICENSE==*/
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// //
|
||||||
|
// plSrtFileReader - Class for reading an SRT format file and //
|
||||||
|
// storing the read entries for access later //
|
||||||
|
// //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef _plSrtFileReader_h
|
||||||
|
#define _plSrtFileReader_h
|
||||||
|
|
||||||
|
#include "hsTypes.h"
|
||||||
|
#include "../pnUtils/pnUtils.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class plSrtEntry
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
plSrtEntry(uint32_t entryNum, uint32_t startTimeMs, uint32_t endTimeMs, std::string subtitleText, std::string speakerName)
|
||||||
|
: fEntryNum(entryNum), fStartTimeMs(startTimeMs), fEndTimeMs(endTimeMs), fSubtitleText(std::move(subtitleText)),
|
||||||
|
fSpeakerName(std::move(speakerName)) { }
|
||||||
|
|
||||||
|
plSrtEntry(uint32_t entryNum, uint32_t startTimeMs, uint32_t endTimeMs, std::string subtitleText)
|
||||||
|
: fEntryNum(entryNum), fStartTimeMs(startTimeMs), fEndTimeMs(endTimeMs), fSubtitleText(std::move(subtitleText)) { }
|
||||||
|
|
||||||
|
std::string GetSubtitleText() const { return fSubtitleText; }
|
||||||
|
std::string GetSpeakerName() const { return fSpeakerName; }
|
||||||
|
uint32_t GetStartTimeMs() const { return fStartTimeMs; }
|
||||||
|
uint32_t GetEndTimeMs() const { return fEndTimeMs; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
uint32_t fEntryNum;
|
||||||
|
uint32_t fStartTimeMs;
|
||||||
|
uint32_t fEndTimeMs;
|
||||||
|
std::string fSubtitleText;
|
||||||
|
std::string fSpeakerName;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class plSrtFileReader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
plSrtFileReader(const char* audioFileName)
|
||||||
|
: fAudioFileName(StrDup(audioFileName)), fCurrentEntryIndex(0) { }
|
||||||
|
virtual ~plSrtFileReader() { delete[] fAudioFileName; }
|
||||||
|
|
||||||
|
bool ReadFile();
|
||||||
|
void StartOver() { fCurrentEntryIndex = 0; }
|
||||||
|
const char* GetCurrentAudioFileName() const { return fAudioFileName; }
|
||||||
|
void AdvanceToTime(uint32_t timeMs);
|
||||||
|
plSrtEntry* GetNextEntryStartingBeforeTime(uint32_t timeMs);
|
||||||
|
plSrtEntry* GetNextEntryEndingBeforeTime(uint32_t timeMs);
|
||||||
|
uint32_t GetLastEntryEndTime();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
const char* fAudioFileName;
|
||||||
|
std::vector<plSrtEntry> fEntries;
|
||||||
|
uint32_t fCurrentEntryIndex;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //_plSrtFileReader_h
|
@ -326,7 +326,7 @@ bool plAvBrainClimb::IProcessExitStage(double time, float elapsed)
|
|||||||
|
|
||||||
float curBlend = ai->GetBlend();
|
float curBlend = ai->GetBlend();
|
||||||
|
|
||||||
if(curBlend > .99) // reached peak strength
|
if(fCurStage && curBlend > .99) // reached peak strength
|
||||||
{
|
{
|
||||||
fCurStage->Detach(fAvMod); // remove the (now completely masked) underlying anim
|
fCurStage->Detach(fAvMod); // remove the (now completely masked) underlying anim
|
||||||
fCurStage = nil;
|
fCurStage = nil;
|
||||||
|
@ -176,16 +176,19 @@ void plKeyboardDevice::HandleKeyEvent(plOSMsg message, plKeyDef key, bool bKeyDo
|
|||||||
if (key == KEY_SHIFT)
|
if (key == KEY_SHIFT)
|
||||||
{
|
{
|
||||||
fShiftKeyDown = bKeyDown;
|
fShiftKeyDown = bKeyDown;
|
||||||
|
// return;
|
||||||
}
|
}
|
||||||
if (key == KEY_CTRL)
|
if (key == KEY_CTRL)
|
||||||
{
|
{
|
||||||
fCtrlKeyDown = bKeyDown;
|
fCtrlKeyDown = bKeyDown;
|
||||||
|
// return;
|
||||||
}
|
}
|
||||||
if (key == KEY_CAPSLOCK)
|
if (key == KEY_CAPSLOCK)
|
||||||
{
|
{
|
||||||
if (!bKeyRepeat)
|
// Keyboards toggle the light on key-down, so I'm going with that.
|
||||||
|
if (bKeyDown && !bKeyRepeat)
|
||||||
{
|
{
|
||||||
fCapsLockLock = (GetKeyState(KEY_CAPSLOCK) & 1) == 1;
|
fCapsLockLock = !fCapsLockLock;
|
||||||
plAvatarInputInterface::GetInstance()->ForceAlwaysRun(fCapsLockLock);
|
plAvatarInputInterface::GetInstance()->ForceAlwaysRun(fCapsLockLock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -205,8 +208,7 @@ void plKeyboardDevice::HandleWindowActivate(bool bActive, HWND hWnd)
|
|||||||
{
|
{
|
||||||
if (bActive)
|
if (bActive)
|
||||||
{
|
{
|
||||||
// Refresh the caps lock state
|
fCtrlKeyDown = false;
|
||||||
HandleKeyEvent(KEYDOWN, KEY_CAPSLOCK, nil, false);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -479,8 +481,8 @@ void plMouseDevice::SetCursorY(hsScalar y)
|
|||||||
|
|
||||||
void plMouseDevice::HideCursor(hsBool override)
|
void plMouseDevice::HideCursor(hsBool override)
|
||||||
{
|
{
|
||||||
if( fInstance->fCursor != nil )
|
if (fInstance && fInstance->fCursor)
|
||||||
fInstance->fCursor->SetVisible( false );
|
fInstance->fCursor->SetVisible(false);
|
||||||
|
|
||||||
plMouseDevice::bCursorOverride = (override != 0);
|
plMouseDevice::bCursorOverride = (override != 0);
|
||||||
plMouseDevice::bCursorHidden = true;
|
plMouseDevice::bCursorHidden = true;
|
||||||
@ -497,9 +499,11 @@ void plMouseDevice::ShowCursor(hsBool override)
|
|||||||
plMouseDevice::bCursorHidden = false;
|
plMouseDevice::bCursorHidden = false;
|
||||||
plMouseDevice::bCursorOverride = false;
|
plMouseDevice::bCursorOverride = false;
|
||||||
|
|
||||||
if( fInstance->fCursor == nil )
|
if (fInstance) {
|
||||||
fInstance->CreateCursor( fInstance->fCursorID );
|
if (!fInstance->fCursor)
|
||||||
fInstance->fCursor->SetVisible( true );
|
fInstance->CreateCursor(fInstance->fCursorID);
|
||||||
|
fInstance->fCursor->SetVisible(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void plMouseDevice::NewCursor(char* cursor)
|
void plMouseDevice::NewCursor(char* cursor)
|
||||||
|
@ -133,6 +133,10 @@ REGISTER_CREATABLE( plSpawnModMsg );
|
|||||||
|
|
||||||
REGISTER_CREATABLE( plSpawnRequestMsg );
|
REGISTER_CREATABLE( plSpawnRequestMsg );
|
||||||
|
|
||||||
|
#include "plSubtitleMsg.h"
|
||||||
|
|
||||||
|
REGISTER_CREATABLE(plSubtitleMsg);
|
||||||
|
|
||||||
#include "plNodeCleanupMsg.h"
|
#include "plNodeCleanupMsg.h"
|
||||||
|
|
||||||
REGISTER_CREATABLE( plNodeCleanupMsg );
|
REGISTER_CREATABLE( plNodeCleanupMsg );
|
||||||
|
82
Sources/Plasma/PubUtilLib/plMessage/plSubtitleMsg.h
Normal file
82
Sources/Plasma/PubUtilLib/plMessage/plSubtitleMsg.h
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/*==LICENSE==*
|
||||||
|
|
||||||
|
CyanWorlds.com Engine - MMOG client, server and tools
|
||||||
|
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Additional permissions under GNU GPL version 3 section 7
|
||||||
|
|
||||||
|
If you modify this Program, or any covered work, by linking or
|
||||||
|
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||||
|
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||||
|
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||||
|
(or a modified version of those libraries),
|
||||||
|
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||||
|
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||||
|
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||||
|
licensors of this Program grant you additional
|
||||||
|
permission to convey the resulting work. Corresponding Source for a
|
||||||
|
non-source form of such a combination shall include the source code for
|
||||||
|
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||||
|
work.
|
||||||
|
|
||||||
|
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||||
|
or by snail mail at:
|
||||||
|
Cyan Worlds, Inc.
|
||||||
|
14617 N Newport Hwy
|
||||||
|
Mead, WA 99021
|
||||||
|
|
||||||
|
*==LICENSE==*/
|
||||||
|
|
||||||
|
#ifndef plSubtitleMsg_inc
|
||||||
|
#define plSubtitleMsg_inc
|
||||||
|
|
||||||
|
#include "../pnMessage/plMessage.h"
|
||||||
|
|
||||||
|
/** Show subtitle text for in-game audio */
|
||||||
|
class plSubtitleMsg : public plMessage
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
std::string fText;
|
||||||
|
std::string fSpeaker;
|
||||||
|
|
||||||
|
public:
|
||||||
|
plSubtitleMsg() : plMessage()
|
||||||
|
{
|
||||||
|
SetBCastFlag(plMessage::kBCastByExactType);
|
||||||
|
}
|
||||||
|
|
||||||
|
plSubtitleMsg(std::string msgText) : plMessage(), fText(std::move(msgText))
|
||||||
|
{
|
||||||
|
SetBCastFlag(plMessage::kBCastByExactType);
|
||||||
|
}
|
||||||
|
|
||||||
|
plSubtitleMsg(std::string msgText, std::string msgSpeaker) : plMessage(), fText(std::move(msgText)),
|
||||||
|
fSpeaker(std::move(msgSpeaker))
|
||||||
|
{
|
||||||
|
SetBCastFlag(plMessage::kBCastByExactType);
|
||||||
|
}
|
||||||
|
|
||||||
|
CLASSNAME_REGISTER(plSubtitleMsg);
|
||||||
|
GETINTERFACE_ANY(plSubtitleMsg, plMessage);
|
||||||
|
|
||||||
|
void Read(hsStream*, hsResMgr*) override { FATAL("no"); }
|
||||||
|
void Write(hsStream*, hsResMgr*) override { FATAL("no"); }
|
||||||
|
|
||||||
|
std::string GetText() const { return fText; }
|
||||||
|
std::string GetSpeaker() const { return fSpeaker; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // plSubtitleMsg_inc
|
@ -504,25 +504,56 @@ bool plNetLinkingMgr::IProcessVaultNotifyMsg(plVaultNotifyMsg* msg)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cVaultLink != nil)
|
if (cVaultLink != nil) {
|
||||||
{
|
// Verify that if the Age vault already exists that it matches the requested
|
||||||
// This is something that Cyan does... >.<
|
// deferred link. If it doesn't exist, well, I hope you're happy with the result.
|
||||||
// It's very useful though...
|
|
||||||
VaultAgeLinkNode accLink(cVaultLink);
|
VaultAgeLinkNode accLink(cVaultLink);
|
||||||
accLink.CopyTo(cur);
|
if (RelVaultNode* rvnInfo = cVaultLink->GetChildNodeIncRef(plVault::kNodeType_AgeInfo, 1)) {
|
||||||
if (RelVaultNode* rvnInfo = cVaultLink->GetChildNodeIncRef(plVault::kNodeType_AgeInfo, 1))
|
plAgeInfoStruct dest;
|
||||||
{
|
|
||||||
VaultAgeInfoNode accInfo(rvnInfo);
|
VaultAgeInfoNode accInfo(rvnInfo);
|
||||||
accInfo.CopyTo(cur->GetAgeInfo());
|
accInfo.CopyTo(&dest);
|
||||||
|
if (!dest.IsEqualTo(fDeferredLink->GetAgeLink()->GetAgeInfo())) {
|
||||||
|
hsLogEntry(
|
||||||
|
plNetClientMgr::GetInstance()->DebugMsg(
|
||||||
|
"Waiting for a deferred link to '%s' but got AgeInfo for '%s' instead.",
|
||||||
|
fDeferredLink->GetAgeLink()->AsStdString().c_str(),
|
||||||
|
dest.AsStdString().c_str()
|
||||||
|
);
|
||||||
|
);
|
||||||
|
|
||||||
|
rvnInfo->DecRef();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
rvnInfo->DecRef();
|
rvnInfo->DecRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we're still here, that means the links match. Set the vault copy as our current
|
||||||
|
// AgeLink and AgeInfo. Note this mainly copies the AgeInfo.
|
||||||
|
accLink.CopyTo(cur);
|
||||||
|
hsLogEntry(
|
||||||
|
plNetClientMgr::GetInstance()->DebugMsg(
|
||||||
|
"Performing deferred link to '%s'",
|
||||||
|
cur->AsStdString().c_str()
|
||||||
|
);
|
||||||
|
);
|
||||||
|
|
||||||
|
// Steals fDeferredLink
|
||||||
IDoLink(fDeferredLink);
|
IDoLink(fDeferredLink);
|
||||||
fDeferredLink = nil;
|
fDeferredLink = nil;
|
||||||
return true;
|
|
||||||
|
|
||||||
cVaultLink->DecRef();
|
cVaultLink->DecRef();
|
||||||
}
|
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
hsLogEntry(
|
||||||
|
plNetClientMgr::GetInstance()->ErrorMsg(
|
||||||
|
"Waiting for a deferred link to '%s' but got a garbage link?",
|
||||||
|
fDeferredLink->GetAgeLink()->AsStdString().c_str()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1328,9 +1328,9 @@ void plPXPhysical::GetSyncState(hsPoint3& pos, hsQuat& rot, hsVector3& linV, hsV
|
|||||||
|
|
||||||
void plPXPhysical::SetSyncState(hsPoint3* pos, hsQuat* rot, hsVector3* linV, hsVector3* angV)
|
void plPXPhysical::SetSyncState(hsPoint3* pos, hsQuat* rot, hsVector3* linV, hsVector3* angV)
|
||||||
{
|
{
|
||||||
bool initialSync = plNetClientApp::GetInstance()->IsLoadingInitialAgeState() &&
|
bool isLoading = plNetClientApp::GetInstance()->IsLoadingInitialAgeState();
|
||||||
plNetClientApp::GetInstance()->GetJoinOrder() == 0;
|
bool isFirstIn = plNetClientApp::GetInstance()->GetJoinOrder() == 0;
|
||||||
|
bool initialSync = isLoading && isFirstIn;
|
||||||
// If the physical has fallen out of the sim, and this is initial age state, and we're
|
// If the physical has fallen out of the sim, and this is initial age state, and we're
|
||||||
// the first person in, reset it to the original position. (ie, prop the default state
|
// the first person in, reset it to the original position. (ie, prop the default state
|
||||||
// we've got right now)
|
// we've got right now)
|
||||||
@ -1350,6 +1350,13 @@ void plPXPhysical::SetSyncState(hsPoint3* pos, hsQuat* rot, hsVector3* linV, hsV
|
|||||||
SetLinearVelocitySim(*linV);
|
SetLinearVelocitySim(*linV);
|
||||||
if (angV)
|
if (angV)
|
||||||
SetAngularVelocitySim(*angV);
|
SetAngularVelocitySim(*angV);
|
||||||
|
// If we're loading the age, then we should ensure the objects stay asleep if they're supposed to be asleep.
|
||||||
|
// NOTE: We should only do this if the objects are not at their initial locations. Otherwise, they might
|
||||||
|
// sleep inside each other and explode or float randomly in midair
|
||||||
|
if (isLoading && GetProperty(plSimulationInterface::kStartInactive) && !fActor->readBodyFlag(NX_BF_KINEMATIC)) {
|
||||||
|
if (!pos && !rot)
|
||||||
|
fActor->putToSleep();
|
||||||
|
}
|
||||||
|
|
||||||
SendNewLocation(false, true);
|
SendNewLocation(false, true);
|
||||||
}
|
}
|
||||||
|
@ -1299,7 +1299,7 @@ void plResManager::PageInAge(const char *age)
|
|||||||
|
|
||||||
hsBool plResManager::VerifyPages()
|
hsBool plResManager::VerifyPages()
|
||||||
{
|
{
|
||||||
hsTArray<plRegistryPageNode*> invalidPages, newerPages;
|
PageSet invalidPages, newerPages;
|
||||||
|
|
||||||
// Step 1: verify major/minor version changes
|
// Step 1: verify major/minor version changes
|
||||||
if (plResMgrSettings::Get().GetFilterNewerPageVersions() ||
|
if (plResMgrSettings::Get().GetFilterNewerPageVersions() ||
|
||||||
@ -1313,7 +1313,7 @@ hsBool plResManager::VerifyPages()
|
|||||||
|
|
||||||
if (page->GetPageCondition() == kPageTooNew && plResMgrSettings::Get().GetFilterNewerPageVersions())
|
if (page->GetPageCondition() == kPageTooNew && plResMgrSettings::Get().GetFilterNewerPageVersions())
|
||||||
{
|
{
|
||||||
newerPages.Append(page);
|
newerPages.insert(page);
|
||||||
fAllPages.erase(page);
|
fAllPages.erase(page);
|
||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
@ -1321,21 +1321,21 @@ hsBool plResManager::VerifyPages()
|
|||||||
page->GetPageCondition() == kPageOutOfDate)
|
page->GetPageCondition() == kPageOutOfDate)
|
||||||
&& plResMgrSettings::Get().GetFilterOlderPageVersions())
|
&& plResMgrSettings::Get().GetFilterOlderPageVersions())
|
||||||
{
|
{
|
||||||
invalidPages.Append(page);
|
invalidPages.insert(page);
|
||||||
fAllPages.erase(page);
|
fAllPages.erase(page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle all our invalid pages now
|
// Handle all our invalid pages now
|
||||||
if (invalidPages.GetCount() > 0)
|
if (!invalidPages.empty())
|
||||||
{
|
{
|
||||||
if (!IDeleteBadPages(invalidPages, false))
|
if (!IDeleteBadPages(invalidPages, false))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Warn about newer pages
|
// Warn about newer pages
|
||||||
if (newerPages.GetCount() > 0)
|
if (!newerPages.empty())
|
||||||
{
|
{
|
||||||
if (!IWarnNewerPages(newerPages))
|
if (!IWarnNewerPages(newerPages))
|
||||||
return false;
|
return false;
|
||||||
@ -1343,22 +1343,35 @@ hsBool plResManager::VerifyPages()
|
|||||||
|
|
||||||
// Step 2 of verification: make sure no sequence numbers conflict
|
// Step 2 of verification: make sure no sequence numbers conflict
|
||||||
PageSet::iterator it = fAllPages.begin();
|
PageSet::iterator it = fAllPages.begin();
|
||||||
for (; it != fAllPages.end(); it++)
|
for (; it != fAllPages.end();)
|
||||||
{
|
{
|
||||||
plRegistryPageNode* page = *it;
|
plRegistryPageNode* page = *it;
|
||||||
|
|
||||||
PageSet::iterator itUp = it;
|
PageSet::iterator itUp = it;
|
||||||
itUp++;
|
itUp++;
|
||||||
for (; itUp != fAllPages.end(); itUp++)
|
bool amValid = true;
|
||||||
|
for (; itUp != fAllPages.end();)
|
||||||
{
|
{
|
||||||
plRegistryPageNode* upPage = *itUp;
|
plRegistryPageNode* upPage = *itUp;
|
||||||
if (page->GetPageInfo().GetLocation() == upPage->GetPageInfo().GetLocation())
|
if (page->GetPageInfo().GetLocation() == upPage->GetPageInfo().GetLocation()) {
|
||||||
{
|
invalidPages.insert(upPage);
|
||||||
invalidPages.Append(upPage);
|
itUp = fAllPages.erase(itUp);
|
||||||
fAllPages.erase(itUp);
|
amValid = false;
|
||||||
break;
|
} else {
|
||||||
|
itUp++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete *all* conflicting pages, not just conflicting - 1.
|
||||||
|
// If we leave in a single conflicting page, a new conflict can trivially
|
||||||
|
// be introduced if the page we leave behind is defunct and a new version
|
||||||
|
// is later downloaded from the FileSrv.
|
||||||
|
if (!amValid) {
|
||||||
|
invalidPages.insert(page);
|
||||||
|
it = fAllPages.erase(it);
|
||||||
|
} else {
|
||||||
|
it++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Redo our loaded pages list, since Verify() might force the page's keys to load or unload
|
// Redo our loaded pages list, since Verify() might force the page's keys to load or unload
|
||||||
@ -1374,7 +1387,7 @@ hsBool plResManager::VerifyPages()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle all our conflicting pages now
|
// Handle all our conflicting pages now
|
||||||
if (invalidPages.GetCount() > 0)
|
if (!invalidPages.empty())
|
||||||
return IDeleteBadPages(invalidPages, true);
|
return IDeleteBadPages(invalidPages, true);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -1384,9 +1397,10 @@ hsBool plResManager::VerifyPages()
|
|||||||
// Given an array of pages that are invalid (major version out-of-date or
|
// Given an array of pages that are invalid (major version out-of-date or
|
||||||
// whatnot), asks the user what we should do about them.
|
// whatnot), asks the user what we should do about them.
|
||||||
|
|
||||||
static void ICatPageNames(hsTArray<plRegistryPageNode*>& pages, char* buf, int bufSize)
|
static void ICatPageNames(const std::set<plRegistryPageNode*>& pages, char* buf, int bufSize)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < pages.GetCount(); i++)
|
int i = 0;
|
||||||
|
for (auto it = pages.cbegin(); it != pages.cend(); ++it, ++i)
|
||||||
{
|
{
|
||||||
if (i >= 25)
|
if (i >= 25)
|
||||||
{
|
{
|
||||||
@ -1394,7 +1408,7 @@ static void ICatPageNames(hsTArray<plRegistryPageNode*>& pages, char* buf, int b
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* pagePath = pages[i]->GetPagePath();
|
const char* pagePath = (*it)->GetPagePath();
|
||||||
const char* pageFile = plFileUtils::GetFileName(pagePath);
|
const char* pageFile = plFileUtils::GetFileName(pagePath);
|
||||||
|
|
||||||
if (strlen(buf) + strlen(pageFile) > bufSize - 5)
|
if (strlen(buf) + strlen(pageFile) > bufSize - 5)
|
||||||
@ -1408,7 +1422,7 @@ static void ICatPageNames(hsTArray<plRegistryPageNode*>& pages, char* buf, int b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hsBool plResManager::IDeleteBadPages(hsTArray<plRegistryPageNode*>& invalidPages, hsBool conflictingSeqNums)
|
hsBool plResManager::IDeleteBadPages(PageSet& invalidPages, hsBool conflictingSeqNums)
|
||||||
{
|
{
|
||||||
#ifndef PLASMA_EXTERNAL_RELEASE
|
#ifndef PLASMA_EXTERNAL_RELEASE
|
||||||
if (!hsMessageBox_SuppressPrompts)
|
if (!hsMessageBox_SuppressPrompts)
|
||||||
@ -1430,12 +1444,12 @@ hsBool plResManager::IDeleteBadPages(hsTArray<plRegistryPageNode*>& invalidPages
|
|||||||
#endif // PLASMA_EXTERNAL_RELEASE
|
#endif // PLASMA_EXTERNAL_RELEASE
|
||||||
|
|
||||||
// Delete 'em
|
// Delete 'em
|
||||||
for (int i = 0; i < invalidPages.GetCount(); i++)
|
for (PageSet::iterator it = invalidPages.begin(); it != invalidPages.end(); ++it)
|
||||||
{
|
{
|
||||||
invalidPages[i]->DeleteSource();
|
(*it)->DeleteSource();
|
||||||
delete invalidPages[i];
|
delete *it;
|
||||||
}
|
}
|
||||||
invalidPages.Reset();
|
invalidPages.clear();
|
||||||
|
|
||||||
fLastFoundPage = nil;
|
fLastFoundPage = nil;
|
||||||
|
|
||||||
@ -1447,7 +1461,7 @@ hsBool plResManager::IDeleteBadPages(hsTArray<plRegistryPageNode*>& invalidPages
|
|||||||
// than the "current" one), warns the user about them but does nothing to
|
// than the "current" one), warns the user about them but does nothing to
|
||||||
// them.
|
// them.
|
||||||
|
|
||||||
hsBool plResManager::IWarnNewerPages(hsTArray<plRegistryPageNode*> &newerPages)
|
hsBool plResManager::IWarnNewerPages(PageSet &newerPages)
|
||||||
{
|
{
|
||||||
#ifndef PLASMA_EXTERNAL_RELEASE
|
#ifndef PLASMA_EXTERNAL_RELEASE
|
||||||
if (!hsMessageBox_SuppressPrompts)
|
if (!hsMessageBox_SuppressPrompts)
|
||||||
@ -1465,9 +1479,9 @@ hsBool plResManager::IWarnNewerPages(hsTArray<plRegistryPageNode*> &newerPages)
|
|||||||
|
|
||||||
|
|
||||||
// Not deleting the files, just delete them from memory
|
// Not deleting the files, just delete them from memory
|
||||||
for (int i = 0; i < newerPages.GetCount(); i++)
|
for (PageSet::iterator it = newerPages.begin(); it != newerPages.end(); ++it)
|
||||||
delete newerPages[i];
|
delete *it;
|
||||||
newerPages.Reset();
|
newerPages.clear();
|
||||||
|
|
||||||
fLastFoundPage = nil;
|
fLastFoundPage = nil;
|
||||||
|
|
||||||
|
@ -61,6 +61,9 @@ typedef void(*plProgressProc)(plKey key);
|
|||||||
|
|
||||||
class plResManager : public hsResMgr
|
class plResManager : public hsResMgr
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
|
typedef std::set<plRegistryPageNode*> PageSet;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
plResManager();
|
plResManager();
|
||||||
virtual ~plResManager();
|
virtual ~plResManager();
|
||||||
@ -194,8 +197,8 @@ protected:
|
|||||||
|
|
||||||
void IUnloadPageKeys(plRegistryPageNode* pageNode, hsBool dontClear = false);
|
void IUnloadPageKeys(plRegistryPageNode* pageNode, hsBool dontClear = false);
|
||||||
|
|
||||||
hsBool IDeleteBadPages(hsTArray<plRegistryPageNode*>& invalidPages, hsBool conflictingSeqNums);
|
hsBool IDeleteBadPages(PageSet& invalidPages, hsBool conflictingSeqNums);
|
||||||
hsBool IWarnNewerPages(hsTArray<plRegistryPageNode*>& newerPages);
|
hsBool IWarnNewerPages(PageSet& newerPages);
|
||||||
|
|
||||||
void ILockPages();
|
void ILockPages();
|
||||||
void IUnlockPages();
|
void IUnlockPages();
|
||||||
@ -233,7 +236,6 @@ protected:
|
|||||||
UInt8 fPageListLock; // Number of locks on the page lists. If it's greater than zero, they can't be modified
|
UInt8 fPageListLock; // Number of locks on the page lists. If it's greater than zero, they can't be modified
|
||||||
hsBool fPagesNeedCleanup; // True if something modified the page lists while they were locked.
|
hsBool fPagesNeedCleanup; // True if something modified the page lists while they were locked.
|
||||||
|
|
||||||
typedef std::set<plRegistryPageNode*> PageSet;
|
|
||||||
PageSet fAllPages; // All the pages, loaded or not
|
PageSet fAllPages; // All the pages, loaded or not
|
||||||
PageSet fLoadedPages; // Just the loaded pages
|
PageSet fLoadedPages; // Just the loaded pages
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user