mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-14 14:37:41 +00:00
Compare commits
9 Commits
OPENURU_BU
...
working_su
Author | SHA1 | Date | |
---|---|---|---|
6678ab215c | |||
d3fb073fed | |||
d285b0b4d7 | |||
a8c211af28 | |||
3360ac478e | |||
d96be9ab30 | |||
f4b1de5826 | |||
d0d8dd246e | |||
436d3d754c |
@ -244,6 +244,7 @@
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release_Internal|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudioCore\plSrtFileReader.cpp" />
|
||||
<ClCompile Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudio\plOGGCodec.cpp">
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug_Internal|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\plBufferedFileReader.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\plAudioCore\plSoundBuffer.h" />
|
||||
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudioCore\plSoundDeswizzler.h" />
|
||||
|
@ -32,6 +32,9 @@
|
||||
<ClCompile Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudio\plWavFile.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudioCore\plSrtFileReader.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudioCore\plAudioCore.h">
|
||||
@ -61,5 +64,8 @@
|
||||
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudio\plWavFile.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plAudioCore\plSrtFileReader.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -817,6 +817,7 @@
|
||||
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plMessage\plSimStateMsg.h" />
|
||||
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plMessage\plSpawnModMsg.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\plSynchEnableMsg.h" />
|
||||
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plMessage\plTimerCallbackMsg.h" />
|
||||
|
@ -361,5 +361,8 @@
|
||||
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plMessage\plVaultNotifyMsg.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\..\..\Sources\Plasma\PubUtilLib\plMessage\plSubtitleMsg.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -2313,6 +2313,7 @@ void plClient::IDetectAudioVideoSettings()
|
||||
WriteInt(stream, "Audio.SetChannelVolume Ambience", 1);
|
||||
WriteInt(stream, "Audio.SetChannelVolume NPCVoice", 1);
|
||||
WriteInt(stream, "Audio.EnableVoiceRecording", 1);
|
||||
WriteInt(stream, "Audio.EnableSubtitles", false);
|
||||
WriteString(stream, "Audio.SetDeviceName", deviceName );
|
||||
stream->Close();
|
||||
delete stream;
|
||||
|
@ -3391,6 +3391,11 @@ PF_CONSOLE_CMD( Audio, MuteAll, "bool on", "Mute or unmute all sounds")
|
||||
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")
|
||||
{
|
||||
if(plgAudioSys::Sys())
|
||||
|
@ -94,6 +94,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
#include "../pfGameMgr/pfGameMgr.h"
|
||||
#include "../plMessage/plAIMsg.h"
|
||||
#include "../plAvatar/plAvBrainCritter.h"
|
||||
#include "../plMessage/plSubtitleMsg.h"
|
||||
|
||||
#include "plProfile.h"
|
||||
|
||||
@ -189,6 +190,7 @@ char* plPythonFileMod::fFunctionNames[] =
|
||||
{ "OnGameMgrMsg" }, // kfunc_OnGameMgrMsg
|
||||
{ "OnGameCliMsg" }, // kfunc_OnGameCliMsg
|
||||
{ "OnAIMsg" }, // kfunc_OnAIMsg
|
||||
{ "OnSubtitleMsg" }, // kfunc_OnSubtitleMsg
|
||||
{ nil }
|
||||
};
|
||||
|
||||
@ -828,6 +830,8 @@ void plPythonFileMod::AddTarget(plSceneObject* sobj)
|
||||
// the message that is spammed to anyone who will listen
|
||||
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
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -202,6 +202,7 @@ public:
|
||||
kfunc_OnGameMgrMsg,
|
||||
kfunc_OnGameCliMsg,
|
||||
kfunc_OnAIMsg,
|
||||
kfunc_OnSubtitleMsg,
|
||||
kfunc_lastone
|
||||
};
|
||||
// array of matching Python instance where the functions are, if defined
|
||||
|
@ -256,6 +256,22 @@ hsBool pyAudioControl::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)
|
||||
{
|
||||
return plgAudioSys::SupportsEAX(deviceName);
|
||||
|
@ -109,6 +109,11 @@ public:
|
||||
virtual void UnmuteAll();
|
||||
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 int GetAudioSystemMode(); // returns the current mode
|
||||
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_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_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, unmuteAll, "Unmutes all sounds."),
|
||||
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(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)."),
|
||||
|
@ -34,9 +34,9 @@ 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
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
|
||||
@ -46,19 +46,19 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
#include "plClassIndexMacros.h" // for CLASS_INDEX macro defn
|
||||
|
||||
CLASS_INDEX_LIST_START
|
||||
//---------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------
|
||||
// hsKeyedObjects should appear in the first section of the enum list
|
||||
// And everything else in the next section
|
||||
// Otherwise you will get an Assert
|
||||
//---------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------
|
||||
CLASS_INDEX(plSceneNode),
|
||||
CLASS_INDEX(plSceneObject),
|
||||
CLASS_INDEX(plSceneObject),
|
||||
CLASS_INDEX(hsKeyedObject),
|
||||
CLASS_INDEX(plBitmap),
|
||||
CLASS_INDEX(plMipmap),
|
||||
CLASS_INDEX(plCubicEnvironmap),
|
||||
CLASS_INDEX(plLayer),
|
||||
CLASS_INDEX(hsGMaterial),
|
||||
CLASS_INDEX(plLayer),
|
||||
CLASS_INDEX(hsGMaterial),
|
||||
CLASS_INDEX(plParticleSystem),
|
||||
CLASS_INDEX(plParticleEffect),
|
||||
CLASS_INDEX(plParticleCollisionEffectBeat),
|
||||
@ -74,7 +74,7 @@ CLASS_INDEX_LIST_START
|
||||
CLASS_INDEX(plWinAudible),
|
||||
CLASS_INDEX(plCoordinateInterface),
|
||||
CLASS_INDEX(plDrawInterface),
|
||||
CLASS_INDEX(plDrawable),
|
||||
CLASS_INDEX(plDrawable),
|
||||
CLASS_INDEX(plDrawableMesh),
|
||||
CLASS_INDEX(plDrawableIce),
|
||||
CLASS_INDEX(plPhysical),
|
||||
@ -131,7 +131,7 @@ CLASS_INDEX_LIST_START
|
||||
CLASS_INDEX(UNUSED_plDrawablePatchSet),
|
||||
CLASS_INDEX(plInputManager),
|
||||
CLASS_INDEX(plLogicModBase),
|
||||
CLASS_INDEX(plFogEnvironment),
|
||||
CLASS_INDEX(plFogEnvironment),
|
||||
CLASS_INDEX(plNetApp),
|
||||
CLASS_INDEX(plNetClientMgr),
|
||||
CLASS_INDEX(pl2WayWinAudible),
|
||||
@ -243,7 +243,7 @@ CLASS_INDEX_LIST_START
|
||||
CLASS_INDEX(pfGUIDynDisplayCtrl),
|
||||
CLASS_INDEX(UNUSED_plLayerProject),
|
||||
CLASS_INDEX(plInputInterfaceMgr),
|
||||
CLASS_INDEX(plRailCameraMod),
|
||||
CLASS_INDEX(plRailCameraMod),
|
||||
CLASS_INDEX(plMultistageBehMod),
|
||||
CLASS_INDEX(plCameraBrain1_Circle),
|
||||
CLASS_INDEX(plParticleWindEffect),
|
||||
@ -368,14 +368,15 @@ CLASS_INDEX_LIST_START
|
||||
CLASS_INDEX(plRidingAnimatedPhysicalDetector),
|
||||
CLASS_INDEX(plVolumeSensorConditionalObjectNoArbitration),
|
||||
CLASS_INDEX(plPXSubWorld),
|
||||
//---------------------------------------------------------
|
||||
// Keyed objects above this line, unkeyed (such as messages) below..
|
||||
//---------------------------------------------------------
|
||||
CLASS_INDEX(pfConfirmationMgr),
|
||||
//---------------------------------------------------------
|
||||
// Keyed objects above this line, unkeyed (such as messages) below..
|
||||
//---------------------------------------------------------
|
||||
|
||||
CLASS_INDEX_NONKEYED_OBJ_START
|
||||
CLASS_INDEX(plObjRefMsg),
|
||||
CLASS_INDEX(plObjRefMsg),
|
||||
CLASS_INDEX(plNodeRefMsg),
|
||||
CLASS_INDEX(plMessage),
|
||||
CLASS_INDEX(plMessage),
|
||||
CLASS_INDEX(plRefMsg),
|
||||
CLASS_INDEX(plGenRefMsg),
|
||||
CLASS_INDEX(plTimeMsg),
|
||||
@ -411,12 +412,12 @@ CLASS_INDEX_LIST_START
|
||||
CLASS_INDEX(hsSfxObjDistFade),
|
||||
CLASS_INDEX(hsSfxObjDistShade),
|
||||
CLASS_INDEX(hsDynamicValue),
|
||||
CLASS_INDEX(hsDynamicScalar),
|
||||
CLASS_INDEX(hsDynamicScalar),
|
||||
CLASS_INDEX(hsDynamicColorRGBA),
|
||||
CLASS_INDEX(hsDynamicMatrix33),
|
||||
CLASS_INDEX(hsDynamicMatrix44),
|
||||
CLASS_INDEX(plOmniSqApplicator),
|
||||
CLASS_INDEX(plPreResourceMsg),
|
||||
CLASS_INDEX(plPreResourceMsg),
|
||||
CLASS_INDEX(UNUSED_hsDynamicColorRGBA),
|
||||
CLASS_INDEX(UNUSED_hsDynamicMatrix33),
|
||||
CLASS_INDEX(UNUSED_hsDynamicMatrix44),
|
||||
@ -427,7 +428,7 @@ CLASS_INDEX_LIST_START
|
||||
CLASS_INDEX(UNUSED_plPosController),
|
||||
CLASS_INDEX(UNUSED_plScalarController),
|
||||
CLASS_INDEX(UNUSED_plPoint3Controller),
|
||||
CLASS_INDEX(UNUSED_plScaleValueController),
|
||||
CLASS_INDEX(UNUSED_plScaleValueController),
|
||||
CLASS_INDEX(UNUSED_plQuatController),
|
||||
CLASS_INDEX(UNUSED_plMatrix33Controller),
|
||||
CLASS_INDEX(UNUSED_plMatrix44Controller),
|
||||
@ -437,7 +438,7 @@ CLASS_INDEX_LIST_START
|
||||
CLASS_INDEX(plCompoundRotController),
|
||||
CLASS_INDEX(UNUSED_plSimplePosController),
|
||||
CLASS_INDEX(plCompoundPosController),
|
||||
CLASS_INDEX(plTMController),
|
||||
CLASS_INDEX(plTMController),
|
||||
CLASS_INDEX(hsFogControl),
|
||||
CLASS_INDEX(plIntRefMsg),
|
||||
CLASS_INDEX(plCollisionReactor),
|
||||
@ -577,8 +578,8 @@ CLASS_INDEX_LIST_START
|
||||
CLASS_INDEX(plNetServerMsgPing),
|
||||
CLASS_INDEX(plNetMsgAlive),
|
||||
CLASS_INDEX(plNetMsgTerminated),
|
||||
CLASS_INDEX(plSDLModifierMsg),
|
||||
CLASS_INDEX(plNetMsgSDLState),
|
||||
CLASS_INDEX(plSDLModifierMsg),
|
||||
CLASS_INDEX(plNetMsgSDLState),
|
||||
CLASS_INDEX(plNetServerMsgSessionReset),
|
||||
CLASS_INDEX(plCCRBanLinkingMsg),
|
||||
CLASS_INDEX(plCCRSilencePlayerMsg),
|
||||
@ -780,17 +781,17 @@ CLASS_INDEX_LIST_START
|
||||
CLASS_INDEX(plShadowCastMsg),
|
||||
CLASS_INDEX(plBoundsIsect),
|
||||
CLASS_INDEX(plResMgrHelperMsg),
|
||||
CLASS_INDEX(plNetCommAuthMsg),
|
||||
CLASS_INDEX(plNetCommFileListMsg),
|
||||
CLASS_INDEX(plNetCommFileDownloadMsg),
|
||||
CLASS_INDEX(plNetCommLinkToAgeMsg),
|
||||
CLASS_INDEX(plNetCommPlayerListMsg),
|
||||
CLASS_INDEX(plNetCommActivePlayerMsg),
|
||||
CLASS_INDEX(plNetCommCreatePlayerMsg),
|
||||
CLASS_INDEX(plNetCommDeletePlayerMsg),
|
||||
CLASS_INDEX(plNetCommPublicAgeListMsg),
|
||||
CLASS_INDEX(plNetCommPublicAgeMsg),
|
||||
CLASS_INDEX(plNetCommRegisterAgeMsg),
|
||||
CLASS_INDEX(plNetCommAuthMsg),
|
||||
CLASS_INDEX(plNetCommFileListMsg),
|
||||
CLASS_INDEX(plNetCommFileDownloadMsg),
|
||||
CLASS_INDEX(plNetCommLinkToAgeMsg),
|
||||
CLASS_INDEX(plNetCommPlayerListMsg),
|
||||
CLASS_INDEX(plNetCommActivePlayerMsg),
|
||||
CLASS_INDEX(plNetCommCreatePlayerMsg),
|
||||
CLASS_INDEX(plNetCommDeletePlayerMsg),
|
||||
CLASS_INDEX(plNetCommPublicAgeListMsg),
|
||||
CLASS_INDEX(plNetCommPublicAgeMsg),
|
||||
CLASS_INDEX(plNetCommRegisterAgeMsg),
|
||||
CLASS_INDEX(plVaultAdminInitializationTask),
|
||||
CLASS_INDEX(plMultistageModMsg),
|
||||
CLASS_INDEX(plSoundVolumeApplicator),
|
||||
@ -948,6 +949,17 @@ CLASS_INDEX_LIST_START
|
||||
CLASS_INDEX(plAngularVelocityMsg),
|
||||
CLASS_INDEX(plRideAnimatedPhysMsg),
|
||||
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
|
||||
|
||||
#endif // plCreatableIndex_inc
|
||||
#endif // plCreatableIndex_inc
|
@ -43,7 +43,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
#ifndef plLogicModBase_inc
|
||||
#define plLogicModBase_inc
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cstdint>
|
||||
#include "plSingleModifier.h"
|
||||
#include "../pnNetCommon/plSynchedValue.h"
|
||||
#include "hsTemplates.h"
|
||||
|
@ -994,6 +994,7 @@ hsBool plgAudioSys::fInit = false;
|
||||
hsBool plgAudioSys::fActive = false;
|
||||
hsBool plgAudioSys::fUseHardware = false;
|
||||
hsBool plgAudioSys::fMuted = true;
|
||||
bool plgAudioSys::fEnableSubtitles = false;
|
||||
hsBool plgAudioSys::fDelayedActivate = false;
|
||||
hsBool plgAudioSys::fEnableEAX = false;
|
||||
hsWindowHndl plgAudioSys::fWnd = nil;
|
||||
@ -1047,6 +1048,11 @@ void plgAudioSys::SetMuted( hsBool b )
|
||||
SetGlobalFadeVolume(1.0);
|
||||
}
|
||||
|
||||
void plgAudioSys::SetEnableSubtitles(bool b)
|
||||
{
|
||||
fEnableSubtitles = b;
|
||||
}
|
||||
|
||||
void plgAudioSys::SetUseHardware(hsBool b)
|
||||
{
|
||||
fUseHardware = b;
|
||||
|
@ -193,11 +193,13 @@ public:
|
||||
static void SetUseHardware(hsBool b);
|
||||
static void SetActive(hsBool b);
|
||||
static void SetMuted( hsBool b );
|
||||
static void SetEnableSubtitles(bool b);
|
||||
static void EnableEAX( hsBool b );
|
||||
static hsBool Active() { return fInit; }
|
||||
static void Shutdown();
|
||||
static void Activate(hsBool b);
|
||||
static hsBool IsMuted( void ) { return fMuted; }
|
||||
static bool AreSubtitlesEnabled() { return fEnableSubtitles; }
|
||||
static hsWindowHndl hWnd() { return fWnd; }
|
||||
static plAudioSystem* Sys() { return fSys; }
|
||||
static void Restart( void );
|
||||
@ -258,6 +260,7 @@ private:
|
||||
static hsBool fInit;
|
||||
static hsBool fActive;
|
||||
static hsBool fMuted;
|
||||
static bool fEnableSubtitles;
|
||||
static hsWindowHndl fWnd;
|
||||
static hsBool fUseHardware;
|
||||
static hsBool fDelayedActivate;
|
||||
|
@ -710,9 +710,9 @@ hsBool plDSoundBuffer::IsEAXAccelerated( void ) const
|
||||
|
||||
//// 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 ////////////////////////////////////////////////////////
|
||||
|
@ -53,10 +53,12 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
#include "plWavFile.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 "../pnNetCommon/plNetApp.h"
|
||||
#include "../pnMessage/plSoundMsg.h"
|
||||
#include "../pnMessage/plEventCallbackMsg.h"
|
||||
#include "../plPipeline/plPlates.h"
|
||||
#include "../plStatusLog/plStatusLog.h"
|
||||
|
||||
@ -108,6 +110,19 @@ void plWin32Sound::IFreeBuffers( void )
|
||||
|
||||
void plWin32Sound::Update()
|
||||
{
|
||||
plSoundBuffer* buf = GetDataBuffer();
|
||||
if (plgAudioSys::AreSubtitlesEnabled() && buf != nullptr) {
|
||||
plSrtFileReader* srtReader = buf->GetSrtReader();
|
||||
if (srtReader != nullptr) {
|
||||
uint32_t currentTimeMs = (uint32_t)(GetActualTimeSec() * 1000.0f);
|
||||
while (plSrtEntry* nextEntry = srtReader->GetNextEntryStartingBeforeTime(currentTimeMs)) {
|
||||
// add a plSubtitleMsg to go... to whoever is listening (probably the KI)
|
||||
plSubtitleMsg* msg = new plSubtitleMsg(nextEntry->GetSubtitleText(), nextEntry->GetSpeakerName());
|
||||
msg->Send();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
plSound::Update();
|
||||
}
|
||||
|
||||
@ -120,6 +135,17 @@ void plWin32Sound::IActuallyPlay( void )
|
||||
{
|
||||
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
|
||||
IDerivedActuallyPlay();
|
||||
|
@ -455,21 +455,24 @@ void plWin32StreamingSound::IActuallyStop()
|
||||
|
||||
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 offset = fDSoundBuffer->GetByteOffset();
|
||||
long byteoffset = ((fDataStream->GetDataSize() - fDataStream->NumBytesLeft()) - bytesQueued) + offset;
|
||||
|
||||
return byteoffset < 0 ? fDataStream->GetDataSize() - abs(byteoffset) : byteoffset;
|
||||
long byteoffset = ((totalSize - bytesRemaining) - bytesQueued) + offset;
|
||||
|
||||
return byteoffset < 0 ? totalSize - std::abs(byteoffset) : byteoffset;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
float plWin32StreamingSound::GetActualTimeSec()
|
||||
{
|
||||
if(fDataStream && fDSoundBuffer)
|
||||
return fDSoundBuffer->BytePosToMSecs(fDataStream->NumBytesLeft()) / 1000.0f;
|
||||
if (fDataStream && fDSoundBuffer)
|
||||
return fDSoundBuffer->BytePosToMSecs(this->GetByteOffset()) / 1000.0f;
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
|
@ -45,9 +45,11 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
|
||||
#include "hsStream.h"
|
||||
#include "hsUtils.h"
|
||||
#include <cstring>
|
||||
|
||||
#include "plgDispatch.h"
|
||||
#include "hsResMgr.h"
|
||||
#include "plSrtFileReader.h"
|
||||
#include "../pnMessage/plRefMsg.h"
|
||||
#include "../plFile/plFileUtils.h"
|
||||
#include "../plFile/hsFiles.h"
|
||||
@ -117,20 +119,35 @@ static void LoadCallback(void *)
|
||||
else
|
||||
{
|
||||
plAudioFileReader *reader = nil;
|
||||
plSrtFileReader* srtReader = nullptr;
|
||||
|
||||
while(plSoundBuffer *buffer = templist.Head())
|
||||
{
|
||||
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 )
|
||||
{
|
||||
unsigned readLen = buffer->GetAsyncLoadLength() ? buffer->GetAsyncLoadLength() : buffer->GetDataLength();
|
||||
reader->Read( readLen, buffer->GetData() );
|
||||
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
|
||||
{
|
||||
buffer->SetError();
|
||||
}
|
||||
}
|
||||
|
||||
templist.Unlink(buffer);
|
||||
@ -194,6 +211,8 @@ plSoundBuffer::~plSoundBuffer()
|
||||
ASSERT(!link.IsLinked());
|
||||
delete [] fFileName;
|
||||
UnLoad();
|
||||
|
||||
delete fSrtReader;
|
||||
}
|
||||
|
||||
void plSoundBuffer::IInitBuffer()
|
||||
@ -206,6 +225,7 @@ void plSoundBuffer::IInitBuffer()
|
||||
fFlags = 0;
|
||||
fDataRead = 0;
|
||||
fReader = nil;
|
||||
fSrtReader = nullptr;
|
||||
fLoaded = 0;
|
||||
fLoading = false;
|
||||
fHeader.fFormatTag = 0;
|
||||
@ -458,6 +478,12 @@ void plSoundBuffer::SetLoaded(bool 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 plAudioFileReader;
|
||||
class plSrtFileReader;
|
||||
class plSoundBuffer : public hsKeyedObject
|
||||
{
|
||||
public:
|
||||
@ -118,6 +119,8 @@ public:
|
||||
plAudioFileReader * GetAudioReader(); // transfers ownership to caller
|
||||
void SetAudioReader(plAudioFileReader *reader);
|
||||
void SetLoaded(bool loaded);
|
||||
plSrtFileReader* GetSrtReader() const { return fSrtReader; } // does not transfer ownership
|
||||
void SetSrtReader(plSrtFileReader* reader);
|
||||
|
||||
plAudioFileReader::StreamType GetAudioReaderType() { return fStreamType; }
|
||||
unsigned GetAsyncLoadLength() { return fAsyncLoadLength ? fAsyncLoadLength : fDataLength; }
|
||||
@ -148,7 +151,8 @@ protected:
|
||||
bool fLoading;
|
||||
bool fError;
|
||||
|
||||
plAudioFileReader * fReader;
|
||||
plAudioFileReader * fReader;
|
||||
plSrtFileReader* fSrtReader;
|
||||
UInt8 * fData;
|
||||
plWAVHeader fHeader;
|
||||
UInt32 fDataLength;
|
||||
|
187
Sources/Plasma/PubUtilLib/plAudioCore/plSrtFileReader.cpp
Normal file
187
Sources/Plasma/PubUtilLib/plAudioCore/plSrtFileReader.cpp
Normal file
@ -0,0 +1,187 @@
|
||||
/*==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;
|
||||
}
|
107
Sources/Plasma/PubUtilLib/plAudioCore/plSrtFileReader.h
Normal file
107
Sources/Plasma/PubUtilLib/plAudioCore/plSrtFileReader.h
Normal file
@ -0,0 +1,107 @@
|
||||
/*==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);
|
||||
|
||||
protected:
|
||||
|
||||
const char* fAudioFileName;
|
||||
std::vector<plSrtEntry> fEntries;
|
||||
uint32_t fCurrentEntryIndex;
|
||||
|
||||
};
|
||||
|
||||
#endif //_plSrtFileReader_h
|
@ -133,6 +133,10 @@ REGISTER_CREATABLE( plSpawnModMsg );
|
||||
|
||||
REGISTER_CREATABLE( plSpawnRequestMsg );
|
||||
|
||||
#include "plSubtitleMsg.h"
|
||||
|
||||
REGISTER_CREATABLE(plSubtitleMsg);
|
||||
|
||||
#include "plNodeCleanupMsg.h"
|
||||
|
||||
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
|
Reference in New Issue
Block a user