diff --git a/libzhl/IsaacRepentance_static.cpp b/libzhl/IsaacRepentance_static.cpp index f7d5728eb..9a0590d21 100644 --- a/libzhl/IsaacRepentance_static.cpp +++ b/libzhl/IsaacRepentance_static.cpp @@ -601,3 +601,9 @@ bool Music::ValidateMusicID(int id, int& max) { return id >= 0 && id < max; } + +bool SoundEffects::ValidateSoundID(int id, int& max) { + max = _sounds.size(); + + return id >= 0 && id < max; +} diff --git a/libzhl/LuaCore.cpp b/libzhl/LuaCore.cpp index e73032195..bf20a0a31 100644 --- a/libzhl/LuaCore.cpp +++ b/libzhl/LuaCore.cpp @@ -782,6 +782,8 @@ namespace lua { const char* MinimapMT = "Minimap"; const char* ModsMenuMT = "ModsMenu"; const char* MultiShotParamsMT = "MultiShotParams"; + const char* MusicEntryMT = "MusicEntry"; + const char* MusicLayerMT = "MusicLayer"; const char* NightmareSceneMT = "NightmareScene"; const char* NullFrameMT = "NullFrame"; const char* OptionsMenuMT = "OptionsMenu"; @@ -804,7 +806,12 @@ namespace lua { const char* RoomTransitionMT = "RoomTransition"; const char* SaveMenuMT = "SaveMenu"; const char* ScoreSheetMT = "ScoreSheet"; + const char* SFXEntryMT = "SFXEntry"; + const char* SFXEntrySampleMT = "SFXEntrySample"; const char* ShapeMT = "Shape"; + const char* SoundActorMT = "SoundActor"; + const char* SoundStreamMT = "SoundStream"; + const char* SoundStreamSetMT = "SoundStreamSet"; const char* SpecialSeedsMenuMT = "SpecialSeedsMenu"; const char* StageTransitionMT = "StageTransition"; const char* StatsMenuMT = "StatsMenu"; diff --git a/libzhl/LuaCore.h b/libzhl/LuaCore.h index cb41d287f..102fbc7de 100644 --- a/libzhl/LuaCore.h +++ b/libzhl/LuaCore.h @@ -217,6 +217,8 @@ namespace lua { extern LIBZHL_API const char* MinimapMT; extern LIBZHL_API const char* ModsMenuMT; extern LIBZHL_API const char* MultiShotParamsMT; + extern LIBZHL_API const char* MusicEntryMT; + extern LIBZHL_API const char* MusicLayerMT; extern LIBZHL_API const char* NightmareSceneMT; extern LIBZHL_API const char* NullFrameMT; extern LIBZHL_API const char* OptionsMenuMT; @@ -239,7 +241,12 @@ namespace lua { extern LIBZHL_API const char* RoomTransitionMT; extern LIBZHL_API const char* SaveMenuMT; extern LIBZHL_API const char* ScoreSheetMT; + extern LIBZHL_API const char* SFXEntryMT; + extern LIBZHL_API const char* SFXEntrySampleMT; extern LIBZHL_API const char* ShapeMT; + extern LIBZHL_API const char* SoundActorMT; + extern LIBZHL_API const char* SoundStreamMT; + extern LIBZHL_API const char* SoundStreamSetMT; extern LIBZHL_API const char* SpecialSeedsMenuMT; extern LIBZHL_API const char* StageTransitionMT; extern LIBZHL_API const char* StatsMenuMT; diff --git a/libzhl/functions/Music.zhl b/libzhl/functions/Music.zhl index 2247442ab..26c39b8d8 100644 --- a/libzhl/functions/Music.zhl +++ b/libzhl/functions/Music.zhl @@ -5,7 +5,7 @@ __thiscall void Music::Play(int musicid,float volume); __thiscall void Music::Crossfade(int musicid,float faderate); "558bec51568bf1578b860c030000": -__thiscall void Music::PlayJingle(int musicid, int unusedInt, bool unusedBool); +__thiscall void Music::PlayJingle(int musicid, int unusedLength, bool unusedBool); "558bec5651": __thiscall void Music::Fadein(unsigned int Id, float Volume, float FadeRate); @@ -40,24 +40,19 @@ __thiscall void Music::UpdateVolume(); "558beca1????????f30f1045": __thiscall void Music::VolumeSlide(float TargetVolume, float FadeRate); -struct Music depends (MusicEntry) { +struct Music depends (MusicEntry, SoundStream, SoundStreamSet) { {{ - inline void StopJingle() { - *(int*)((char*)this + 0x348) = 0; - *(int*)((char*)this + 0x364) = -99; - }; - bool LIBZHL_API ValidateMusicID(int id, int& max); }} unsigned int _currentStream : 0x0; - // i'll add StreamSet later + SoundStreamSet _streamSets[2] : 0x4; unsigned int _currentId : 0x30c; unsigned int _queuedId : 0x310; float _pitch : 0x314; float _targetPitch : 0x318; vector_MusicEntry _entries : 0x31c; bool _enabled : 0x328; - // and Stream - float _jingleVolumeMaybe : 0x360; - int _jingleCountdownMaybe : 0x364; + SoundStream _jingleStream : 0x32c; + float _jingleVolume : 0x360; + int _jingleCountdown : 0x364; } : 0x368; \ No newline at end of file diff --git a/libzhl/functions/MusicEntry.zhl b/libzhl/functions/MusicEntry.zhl index ddd2d3ad2..3ea2b129e 100644 --- a/libzhl/functions/MusicEntry.zhl +++ b/libzhl/functions/MusicEntry.zhl @@ -1,4 +1,13 @@ -struct MusicEntry +struct MusicEntry depends (MusicLayer) { - std_string _string1 : 0x4; + int _id : 0x0; + std_string _name : 0x4; + std_string _introFilename : 0x1c; + std_string _filename : 0x34; + bool _loop : 0x4c; + unsigned char _layerMode : 0x4d; + float _multiplier : 0x50; + float _layerFadeRate : 0x54; + MusicLayer* _layers : 0x58; + unsigned int _numLayers : 0x5c; } : 0x60; diff --git a/libzhl/functions/MusicLayer.zhl b/libzhl/functions/MusicLayer.zhl new file mode 100644 index 000000000..20e1c0aae --- /dev/null +++ b/libzhl/functions/MusicLayer.zhl @@ -0,0 +1,6 @@ +struct MusicLayer +{ + std_string _intro : 0x0; + std_string _path : 0x18; + float _mul : 0x30; +} : 0x34; diff --git a/libzhl/functions/SampleSourceBase.zhl b/libzhl/functions/SampleSourceBase.zhl new file mode 100644 index 000000000..b0f4c399f --- /dev/null +++ b/libzhl/functions/SampleSourceBase.zhl @@ -0,0 +1,59 @@ +struct SampleSourceBase : public SoundSourcePlatformBase { + __vtable { + override + "558bec6aff68????????64a1????????505657a1????????33c5508d45??64a3????????8bf1c706????????8d7e": + void * Free(bool param_1); + + skip; // ApplyDataToHardware + + override + "8b41??8b40??c3??????????????????8b41": + int GetHardwareBufferSize(); + + skip; // open_file_dunno + skip; // Queue + skip; // Deque + skip; // HasQueuedData + + override + "8b41??8b11c641??01": + bool Open(char * path); + + override + "558bec6aff68????????64a1????????5083ec08535657a1????????33c5508d45??64a3????????8bd98b75??85f60f84": + bool Clone(SoundSourceBase * param_1); + + override + "558bec518bc18378??00": + void Close(); + + skip; // IsOpen + + override + "558bec568bf18b06ff50??ff75": + void Play(bool unk); + + skip; // Pause + skip; // Resume + skip; // IsPlaying + skip; // Stop + skip; // SetLooping + skip; // IsLooping + skip; // SetVolume + skip; // GetVolume + skip; // SetPan + skip; // GetPan + skip; // SetPitch + skip; // GetPitch + skip; // GetNumChannels + skip; // GetSourceFormat + skip; // GetSampleRate + skip; // SystemSuspend + skip; // SystemResume + skip; // ProcessData + skip; // ActivateNextQueuedData + skip; // Update + skip; // IsPlaybackFinished + skip; // IsProcessingFinished + }; +} : 0x48; \ No newline at end of file diff --git a/libzhl/functions/SampleSourceOgg.zhl b/libzhl/functions/SampleSourceOgg.zhl new file mode 100644 index 000000000..c47bd3da2 --- /dev/null +++ b/libzhl/functions/SampleSourceOgg.zhl @@ -0,0 +1,58 @@ +struct SampleSourceOgg : public SampleSourceBase { + __vtable { + override + "558bec6aff68????????64a1????????505657a1????????33c5508d45??64a3????????8bf1c745??00000000837e??00c706????????74??e8????????84c074??ff76??ff15????????83c404ff15????????85c074??5068????????6a02e8????????83c40c8bcee8": + void * Free(bool param_1); + + skip; // ApplyDataToHardware + skip; // GetHardwareBufferSize + skip; // open_file_dunno + skip; // Queue + skip; // Deque + skip; // HasQueuedData + + override + "558bec83e4f883ec24535657ff75": + bool Open(char * path); + + override + "558bec8b55??85d274??8b41??8942??8b41": + bool Clone(SoundSourceBase * param_1); + + skip; // Close + skip; // IsOpen + skip; // Play + skip; // Pause + skip; // Resume + skip; // IsPlaying + skip; // Stop + skip; // SetLooping + skip; // IsLooping + skip; // SetVolume + skip; // GetVolume + skip; // SetPan + skip; // GetPan + skip; // SetPitch + skip; // GetPitch + + override + "8b41??c3????????????????????????558bec6aff68????????64a1????????505156": + uint16_t GetNumChannels(); + + override + "8b41??c3????????????????????????8b41??c3????????????????????????558bec6aff68????????64a1????????505153": + int GetSourceFormat(); + + override + "8b41??c3????????????????????????558bec6aff68????????64a1????????505153": + unsigned int GetSampleRate(); + + skip; // SystemSuspend + skip; // SystemResume + skip; // ProcessData + skip; // ActivateNextQueuedData + skip; // Update + skip; // IsPlaybackFinished + skip; // IsProcessingFinished + }; +} : 0x48; \ No newline at end of file diff --git a/libzhl/functions/SampleSourceOrg.zhl b/libzhl/functions/SampleSourceOrg.zhl new file mode 100644 index 000000000..4ba37f013 --- /dev/null +++ b/libzhl/functions/SampleSourceOrg.zhl @@ -0,0 +1,61 @@ +struct SampleSourceOrg : public SampleSourceBase { + __vtable { + override + "558bec568bf1e8????????f645??0174??68b01b0000": + void * Free(bool param_1); + + skip; // ApplyDataToHardware + skip; // GetHardwareBufferSize + skip; // open_file_dunno + skip; // Queue + skip; // Deque + skip; // HasQueuedData + + override + "558bec6aff68????????64a1????????5083ec4c535657a1????????33c5508d45??64a3????????8bd9": + bool Open(char * param_1); + + override + "558bec5668": + bool Clone(SoundSourceBase * param_1); + + override + "558bec51538bd95657bf10000000": + void Close(); + + skip; // IsOpen + skip; // Play + skip; // Pause + skip; // Resume + skip; // IsPlaying + skip; // Stop + skip; // SetLooping + skip; // IsLooping + skip; // SetVolume + skip; // GetVolume + skip; // SetPan + skip; // GetPan + skip; // SetPitch + skip; // GetPitch + + override + "b802000000c3????????????????????b822560000": + uint16_t GetNumChannels(); + + override + "b801000000c3????????????????????8b81": + int GetSourceFormat(); + + override + "b822560000": + unsigned int GetSampleRate(); + + skip; // SystemSuspend + skip; // SystemResume + skip; // ProcessData + skip; // ActivateNextQueuedData + skip; // Update + skip; // IsPlaybackFinished + skip; // IsProcessingFinished + }; +} : 0x60; \ No newline at end of file diff --git a/libzhl/functions/SampleSourceWav.zhl b/libzhl/functions/SampleSourceWav.zhl new file mode 100644 index 000000000..78576cc44 --- /dev/null +++ b/libzhl/functions/SampleSourceWav.zhl @@ -0,0 +1,61 @@ +struct SampleSourceWav : public SampleSourceBase { + __vtable { + override + "558bec6aff68????????64a1????????505657a1????????33c5508d45??64a3????????8bf1c745??00000000837e??00c706????????74??e8????????84c074??ff76??ff15????????83c404ff15????????85c074??5068????????6a02e8????????83c40c8bcec746??00000000": + void * Free(bool param_1); + + skip; // ApplyDataToHardware + skip; // GetHardwareBufferSize + skip; // open_file_dunno + skip; // Queue + skip; // Deque + skip; // HasQueuedData + + override + "558bec83e4f883ec1ca1????????33c4894424??53": + bool Open(char * param_1); + + override + "558bec568b75??85f674??8b41": + bool Clone(SoundSourceBase * param_1); + + override + "c741??00000000c741??00000000e9??????????????????????????????????0fb741": + void Close(); + + skip; // IsOpen + skip; // Play + skip; // Pause + skip; // Resume + skip; // IsPlaying + skip; // Stop + skip; // SetLooping + skip; // IsLooping + skip; // SetVolume + skip; // GetVolume + skip; // SetPan + skip; // GetPan + skip; // SetPitch + skip; // GetPitch + + override + "0fb741??c3??????????????????????33c0": + uint16_t GetNumChannels(); + + override + "33c0668379??10": + int GetSourceFormat(); + + override + "8b41??c3????????????????????????558bec83e4f8": + unsigned int GetSampleRate(); + + skip; // SystemSuspend + skip; // SystemResume + skip; // ProcessData + skip; // ActivateNextQueuedData + skip; // Update + skip; // IsPlaybackFinished + skip; // IsProcessingFinished + }; +} : 0x60; \ No newline at end of file diff --git a/libzhl/functions/SoundActor.zhl b/libzhl/functions/SoundActor.zhl new file mode 100644 index 000000000..bc7f3776c --- /dev/null +++ b/libzhl/functions/SoundActor.zhl @@ -0,0 +1,11 @@ +struct SoundActor depends (SoundSourceBase) +{ + SoundSourceBase * _source : 0x0; + void * _sp2 : 0x4; + bool _loop : 0x8; + bool _playing : 0x9; + bool _paused : 0xa; + float _volume : 0xc; + float _pan : 0x10; + float _pitch : 0x14; +} : 0x18; diff --git a/libzhl/functions/SoundEffects.zhl b/libzhl/functions/SoundEffects.zhl index 4b5774203..0dbe8461f 100644 --- a/libzhl/functions/SoundEffects.zhl +++ b/libzhl/functions/SoundEffects.zhl @@ -11,14 +11,30 @@ __thiscall void SoundEffects::LoadConfig(char* filename, bool ismod); __thiscall void SoundEffect::Load(); -struct SoundEffect{ - unsigned int _id : 0x0; +struct SoundEffectSample depends (SoundActor) { + std_string _filename : 0x0; + SoundActor _actor : 0x18; + bool _unk_reload : 0x30; + int _weight : 0x34; +} : 0x38; + +struct SoundEffect depends (SoundEffectSample) { + unsigned int _framePlayed : 0x0; + unsigned int _nextPlayableFrame : 0x4; + SoundEffectSample _samples[7] : 0x8; + unsigned int _sampleCount : 0x190; + float _volume : 0x194; bool _loaded : 0x198; - bool _shouldPreload : 0x199; + bool _shouldPreload : 0x199; + std_string _name : 0x1a0; } : 0x1b8; -struct SoundEffects depends (SoundEffect){ +struct SoundEffects depends (SoundEffect) { +{{ + bool LIBZHL_API ValidateSoundID(int id, int& max); +}} vector_SoundEffect _sounds : 0x0; int _count : 0xc; float _volume : 0x10; + float _volumeSlideRate : 0x14; } : 0x18; diff --git a/libzhl/functions/SoundSourceBase.zhl b/libzhl/functions/SoundSourceBase.zhl new file mode 100644 index 000000000..719bcc5a3 --- /dev/null +++ b/libzhl/functions/SoundSourceBase.zhl @@ -0,0 +1,105 @@ +struct SoundSourceBase { + __vtable { + "558bec568bf18d4e??c706????????e8????????f645??0174??6a24": + void * Free(bool param_1); + + pure + bool ApplyDataToHardware(int param_1, int param_2); + + pure + int GetHardwareBufferSize(); + + "32c0c20800": + bool open_file_dunno(char * param_1, bool param_2); + + "558bec8b51??568d71": + void Queue(uint64_t UNK_param_1, int UNK_param_2); + + "558bec568bf18b56??8b46??4a": + void Deque(void * UNK_param_1); + + "8379??000f97c0c3????????????????c641??01": + bool HasQueuedData(); + + "c641??01b001c20400": + bool Open(char * path); + + "558bec8b55??85d274??8b41??8942??8a41": + bool Clone(SoundSourceBase* right); + + "558bec83ec0c568bf18b46": + void Close(); + + "8a41??c3????????????????????????8a41": + bool IsOpen(); + + pure + void Play(bool unk); + + pure + void Pause(); + + pure + void Resume(); + + pure + bool IsPlaying(); + + pure + void Stop(); + + "558bec8a45??8841??5dc20400??????558bec6aff": + void SetLooping(bool value); + + "8a41??c3????????????????????????c641??01": + bool IsLooping(); + + pure + void SetVolume(float param_1); + + pure + float GetVolume(); + + pure + void SetPan(float param_1); + + pure + float GetPan(); + + pure + void SetPitch(float param_1); + + pure + float GetPitch(); + + pure + uint16_t GetNumChannels(); + + pure + int GetSourceFormat(); + + pure + unsigned int GetSampleRate(); + + pure + void SystemSuspend(); + + pure + void SystemResume(); + + pure + int ProcessData(void * param_1); + + pure + bool ActivateNextQueuedData(); + + pure + void Update(); + + pure + bool IsPlayingFinished(); + + pure + bool IsProcessingFinished(); + }; +} : 0x4; \ No newline at end of file diff --git a/libzhl/functions/SoundSourcePlatformBase.zhl b/libzhl/functions/SoundSourcePlatformBase.zhl new file mode 100644 index 000000000..23ae37b0c --- /dev/null +++ b/libzhl/functions/SoundSourcePlatformBase.zhl @@ -0,0 +1,89 @@ +struct SoundSourcePlatformBase : public SoundSourceBase { + __vtable { + override + "558bec568bf18d4e??c706????????e8????????f645??0174??6a40": + void * Free(bool param_1); + + override + "558bec8b45??568bf18946??8b45": + bool ApplyDataToHardware(int param_1, int param_2); + + skip; // GetHardwareBufferSize + skip; // open_file_dunno + skip; // Queue + skip; // Deque + skip; // HasQueuedData + skip; // Open + skip; // Clone + skip; // Close + skip; // IsOpen + + override + "558bec83ec08578bf9": + void Play(bool unk); + + override + "568bf1837e??0074??8b068b40??ffd084c074??ff76??ff15????????83c404ff15????????85c074??5068????????6a02e8????????83c40c5ec3????????56": + void Pause(); + + override + "568bf1837e??0074??8b068b40??ffd084c075??ff76": + void Resume(); + + override + "558bec518b41??85c075": + bool IsPlaying(); + + override + "568bf1837e??0074??8b068b40??ffd084c074??ff76??ff15????????83c404ff15????????85c074??5068????????6a02e8????????83c40c5ec3????????55": + void Stop(); + + override + "558bec538a5d??568bf1": + void SetLooping(bool param_1); + + skip; // IsLooping + + override + "558becf30f1045??8b41??f30f1141??85c074??51f30f110424680a100000": + void SetVolume(float param_1); + + override + "d941??c3????????????????????????558becf30f1045??56": + float GetVolume(); + + override + "558becf30f1045??56": + void SetPan(float param_1); + + override + "d941??c3????????????????????????558becf30f1045??8b41": + float GetPan(); + + override + "558becf30f1045??8b41??f30f1141??85c074??51f30f1104246803100000": + void SetPitch(float param_1); + + override + "d941??c3????????????????????????56": + float GetPitch(); + + skip; // GetNumChannels + skip; // GetSourceFormat + skip; // GetSampleRate + + override + "568bf1ff15????????85c074??6a0168????????6a02e8????????83c40c5ec38b46": + void SystemSuspend(); + + override + "568bf1ff15????????85c074??6a0168????????6a02e8????????83c40c5ec3807e??00": + void SystemResume(); + + skip; // ProcessData + skip; // ActivateNextQueuedData + skip; // Update + skip; // IsPlaybackFinished + skip; // IsProcessingFinished + }; +} : 0x4; \ No newline at end of file diff --git a/libzhl/functions/SoundStream.zhl b/libzhl/functions/SoundStream.zhl new file mode 100644 index 000000000..1f4f0e9ce --- /dev/null +++ b/libzhl/functions/SoundStream.zhl @@ -0,0 +1,14 @@ +"538bdc83ec0883e4f883c404558b6b??896c24??8bec83ec0cf30f1005": +__thiscall void SoundStream::Update(bool checkIfPlaying); + +struct SoundStream depends (SoundActor) { + SoundActor _actor : 0x0; + float _volumeMod : 0x18; + float _volume : 0x1c; + float _targetVolume : 0x20; + float _fadeRate : 0x24; + bool _playing : 0x28; + uint8_t _HIJACK_id : 0x2b; + unsigned int _frameCount : 0x2c; + SoundStreamSet* _setRef : 0x30; +} : 0x34; \ No newline at end of file diff --git a/libzhl/functions/SoundStreamSet.zhl b/libzhl/functions/SoundStreamSet.zhl new file mode 100644 index 000000000..56366537b --- /dev/null +++ b/libzhl/functions/SoundStreamSet.zhl @@ -0,0 +1,16 @@ +"558bec6aff68????????64a1????????5083ec0856a1????????33c5508d45??64a3????????8bf18975??e8": +__thiscall SoundStreamSet * SoundStreamSet::game_constructor(); + +"538bd956578b0b": +__thiscall void SoundStreamSet::Play(); + +struct SoundStreamSet depends (SoundStream) { + SoundStream _streams[7] : 0x0; + unsigned int _layerBitfield : 0x16c; + int _volumeMode : 0x170; + float _volume : 0x174; + float _targetVolume : 0x178; + float _fadeRate : 0x17c; + bool _playing : 0x180; + uint8_t _HIJACK_id : 0x183; +} : 0x184; \ No newline at end of file diff --git a/libzhl/functions/StreamSourceBase.zhl b/libzhl/functions/StreamSourceBase.zhl new file mode 100644 index 000000000..8481fc571 --- /dev/null +++ b/libzhl/functions/StreamSourceBase.zhl @@ -0,0 +1,76 @@ +struct StreamSourceBase : public SoundSourcePlatformBase { + __vtable { + override + "558bec6aff68????????64a1????????5056a1????????33c5508d45??64a3????????8bf168????????6a046a0c8d46??c745??00000000": + void * Free(bool param_1); + + skip; // ApplyDataToHardware + + override + "b800000400c3": + int GetHardwareBufferSize(); + + skip; // open_file_dunno + skip; // Queue + skip; // Deque + skip; // HasQueuedData + + override + "558bec83e4f8515356578bf9bb04000000": + bool Open(char * path); + + override + "68????????6a03e8????????83c40832c0": + bool Clone(SoundSourceBase* right); + + override + "5356578bf98b4f??85c9": + void Close(); + + skip; // IsOpen + + override + "558bec51568bf18b068b40??ffd084c00f85": + void Play(bool unk); + + skip; // Pause + skip; // Resume + skip; // IsPlaying + + override + "568bf156": + void Stop(); + + override + "558bec8a45??3a41": + void SetLooping(bool param_1); + + skip; // IsLooping + skip; // SetVolume + skip; // GetVolume + skip; // SetPan + skip; // GetPan + skip; // SetPitch + skip; // GetPitch + skip; // GetNumChannels + skip; // GetSourceFormat + skip; // GetSampleRate + skip; // SystemSuspend + skip; // SystemResume + skip; // ProcessData + skip; // ActivateNextQueuedData + + override + "558bec83ec1053568bf133c9": + void Update(); + + override + "80b9????????0074??33d2": + bool IsPlayingFinished(); + + override + "8a81????????c3??????????????????558bec6aff68????????64a1????????5056": + bool IsProcessingFinished(); + + }; +} : 0x4; \ No newline at end of file diff --git a/libzhl/functions/StreamSourceOgg.zhl b/libzhl/functions/StreamSourceOgg.zhl new file mode 100644 index 000000000..69592fa0b --- /dev/null +++ b/libzhl/functions/StreamSourceOgg.zhl @@ -0,0 +1,70 @@ +struct StreamSourceOgg : public StreamSourcePlatformBase { + __vtable { + override + "558bec568bf1e8????????f645??0174??68c0000000": + void * Free(bool param_1); + + skip; // ApplyDataToHardware + skip; // GetHardwareBufferSize + + override + "558bec83ec188bc1": + bool open_file_dunno(char * param_1, bool param_2); + + skip; // Queue + skip; // Deque + skip; // HasQueuedData + + override + "558bec51538b5d??56578bf1": + bool Open(char * param_1); + + skip; // Clone + + override + "558bec83ec0c53578bf9": + void Close(); + + skip; // IsOpen + skip; // Play + skip; // Pause + skip; // Resume + skip; // IsPlaying + skip; // Stop + skip; // SetLooping + skip; // IsLooping + skip; // SetVolume + skip; // GetVolume + skip; // SetPan + skip; // GetPan + skip; // SetPitch + skip; // GetPitch + + override + "8b81????????8b40??c3????????????b801000000": + uint16_t GetNumChannels(); + + override + "b801000000c3????????????????????8b81": + int GetSourceFormat(); + + override + "8b81????????8b00": + unsigned int GetSampleRate(); + + skip; // SystemSuspend + skip; // SystemResume + + override + "558bec53578bf9": + int ProcessData(void * param_1); + + override + "558bec83ec0c568bf1578b06": + bool ActivateNextQueuedData(); + + skip; // Update + skip; // IsPlaybackFinished + skip; // IsProcessingFinished + }; +} : 0x4; \ No newline at end of file diff --git a/libzhl/functions/StreamSourceOrg.zhl b/libzhl/functions/StreamSourceOrg.zhl new file mode 100644 index 000000000..873d36603 --- /dev/null +++ b/libzhl/functions/StreamSourceOrg.zhl @@ -0,0 +1,66 @@ +struct StreamSourceOrg : public StreamSourcePlatformBase { + __vtable { + override + "558bec6aff68????????64a1????????50535657a1????????33c5508d45??64a3????????8bf9c745??00000000": + void * Free(bool param_1); + + skip; // ApplyDataToHardware + skip; // GetHardwareBufferSize + skip; // open_file_dunno + skip; // Queue + skip; // Deque + skip; // HasQueuedData + + override + "558bec83ec0853560fb735": + bool Open(char * param_1); + + skip; // Clone + + override + "5356578bf98b87????????85c074": + void Close(); + + skip; // IsOpen + skip; // Play + skip; // Pause + skip; // Resume + skip; // IsPlaying + skip; // Stop + skip; // SetLooping + skip; // IsLooping + skip; // SetVolume + skip; // GetVolume + skip; // SetPan + skip; // GetPan + skip; // SetPitch + skip; // GetPitch + + override + "b802000000c3????????????????????b822560000": + uint16_t GetNumChannels(); + + override + "b801000000c3????????????????????8b81": + int GetSourceFormat(); + + override + "b822560000": + unsigned int GetSampleRate(); + + skip; // SystemSuspend + skip; // SystemResume + + override + "558bec6aff68????????64a1????????5083ec54535657a1????????33c5508d45??64a3????????8bf9": + int ProcessData(void * param_1); + + override + "558bec83ec0c568bf1578b06": + bool ActivateNextQueuedData(); + + skip; // Update + skip; // IsPlaybackFinished + skip; // IsProcessingFinished + }; +} : 0x4; \ No newline at end of file diff --git a/libzhl/functions/StreamSourcePlatformBase.zhl b/libzhl/functions/StreamSourcePlatformBase.zhl new file mode 100644 index 000000000..3193d0dd1 --- /dev/null +++ b/libzhl/functions/StreamSourcePlatformBase.zhl @@ -0,0 +1,63 @@ +struct StreamSourcePlatformBase : public StreamSourceBase { + __vtable { + override + "558bec568bf18d4e??c706????????e8????????f645??0174??6a54": + void * Free(bool param_1); + + override + "558bec515356578bf9897d??8b07": + bool ApplyDataToHardware(int param_1, int param_2); + + skip; // GetHardwareBufferSize + skip; // open_file_dunno + skip; // Queue + skip; // Deque + skip; // HasQueuedData + + override + "51568bf18d46": + bool Open(char * path); + + skip; // Clone + + override + "56578bf1e8????????837e??00": + void Close(); + + skip; // IsOpen + + override + "568bf1837e??0074??8b068b40??ffd084c075??a1": + void Play(bool unk); + + skip; // Pause + skip; // Resume + skip; // IsPlaying + skip; // Stop + skip; // SetLooping + skip; // IsLooping + skip; // SetVolume + skip; // GetVolume + skip; // SetPan + skip; // GetPan + skip; // SetPitch + skip; // GetPitch + skip; // GetNumChannels + skip; // GetSourceFormat + skip; // GetSampleRate + + override + "538b1d????????568bf1ffd3": + void SystemSuspend(); + + override + "568b35????????578bf9ffd6": + void SystemResume(); + + skip; // ProcessData + skip; // ActivateNextQueuedData + skip; // Update + skip; // IsPlaybackFinished + skip; // IsProcessingFinished + }; +} : 0x4; \ No newline at end of file diff --git a/libzhl/functions/StreamSourceWav.zhl b/libzhl/functions/StreamSourceWav.zhl new file mode 100644 index 000000000..5ef26dac7 --- /dev/null +++ b/libzhl/functions/StreamSourceWav.zhl @@ -0,0 +1,63 @@ +struct StreamSourceWav : public StreamSourcePlatformBase { + __vtable { + override + "558bec6aff68????????64a1????????5056a1????????33c5508d45??64a3????????8bf1c745??00000000c706????????e8????????8bce": + void * Free(bool param_1); + + skip; // ApplyDataToHardware + skip; // GetHardwareBufferSize + skip; // open_file_dunno + skip; // Queue + skip; // Deque + skip; // HasQueuedData + + override + "558bec56ff75??8bf1b9": + bool Open(char * param_1); + + skip; // Clone + + override + "558bec83ec0c53578bf9": + void Close(); + + skip; // IsOpen + skip; // Play + skip; // Pause + skip; // Resume + skip; // IsPlaying + skip; // Stop + skip; // SetLooping + skip; // IsLooping + skip; // SetVolume + skip; // GetVolume + skip; // SetPan + skip; // GetPan + skip; // SetPitch + skip; // GetPitch + + override + "0fb781????????c3????????????????33c0": + uint16_t GetNumChannels(); + + override + "33c06683b9????????10": + int GetSourceFormat(); + + override + "8b81????????c3??????????????????558bec83e4f883ec0c56": + unsigned int GetSampleRate(); + + skip; // SystemSuspend + skip; // SystemResume + + override + "558bec56578bf96800000100": + int ProcessData(void * param_1); + + skip; // ActivateNextQueuedData + skip; // Update + skip; // IsPlaybackFinished + skip; // IsProcessingFinished + }; +} : 0x4; \ No newline at end of file diff --git a/repentogon/LuaInterfaces/LuaMusicEntry.cpp b/repentogon/LuaInterfaces/LuaMusicEntry.cpp new file mode 100644 index 000000000..4dce62666 --- /dev/null +++ b/repentogon/LuaInterfaces/LuaMusicEntry.cpp @@ -0,0 +1,153 @@ +#include "IsaacRepentance.h" +#include "LuaCore.h" +#include "HookSystem.h" + +LUA_FUNCTION(Lua_MusicManager_GetEntry) +{ + Music* music = lua::GetUserdata(L, 1, lua::Metatables::MUSIC_MANAGER, "MusicManager"); + int musicId = (int)luaL_checkinteger(L, 2); + int max; + + if (!music->ValidateMusicID(musicId, max)) { + return luaL_error(L, "Invalid music ID %d. Min = 0, Max = %d", musicId, max - 1); + } + + MusicEntry* toLua = &music->_entries[musicId]; + MusicEntry** luaMusicEntry = (MusicEntry**)lua_newuserdata(L, sizeof(MusicEntry*)); + *luaMusicEntry = toLua; + luaL_setmetatable(L, lua::metatables::MusicEntryMT); + return 1; +} + +LUA_FUNCTION(Lua_MusicEntryGetID) +{ + MusicEntry* entry = *lua::GetUserdata(L, 1, lua::metatables::MusicEntryMT); + lua_pushinteger(L, entry->_id); + return 1; +} + +LUA_FUNCTION(Lua_MusicEntryGetName) +{ + MusicEntry* entry = *lua::GetUserdata(L, 1, lua::metatables::MusicEntryMT); + lua_pushstring(L, entry->_name.empty() ? "" : entry->_name.c_str()); + return 1; +} + +LUA_FUNCTION(Lua_MusicEntryGetIntroFilename) +{ + MusicEntry* entry = *lua::GetUserdata(L, 1, lua::metatables::MusicEntryMT); + lua_pushstring(L, entry->_introFilename.empty() ? "" : entry->_introFilename.c_str()); + return 1; +} + +LUA_FUNCTION(Lua_MusicEntryGetFilename) +{ + MusicEntry* entry = *lua::GetUserdata(L, 1, lua::metatables::MusicEntryMT); + lua_pushstring(L, entry->_filename.empty() ? "" : entry->_filename.c_str()); + return 1; +} + +LUA_FUNCTION(Lua_MusicEntryGetLoop) +{ + MusicEntry* entry = *lua::GetUserdata(L, 1, lua::metatables::MusicEntryMT); + lua_pushboolean(L, entry->_loop); + return 1; +} + +LUA_FUNCTION(Lua_MusicEntryGetLayerMode) +{ + MusicEntry* entry = *lua::GetUserdata(L, 1, lua::metatables::MusicEntryMT); + lua_pushinteger(L, entry->_layerMode); + return 1; +} + +LUA_FUNCTION(Lua_MusicEntryGetMultiplier) +{ + MusicEntry* entry = *lua::GetUserdata(L, 1, lua::metatables::MusicEntryMT); + lua_pushnumber(L, entry->_multiplier); + return 1; +} + +LUA_FUNCTION(Lua_MusicEntryGetLayerFadeRate) +{ + MusicEntry* entry = *lua::GetUserdata(L, 1, lua::metatables::MusicEntryMT); + lua_pushnumber(L, entry->_layerFadeRate); + return 1; +} + +LUA_FUNCTION(Lua_MusicEntryGetLayerCount) +{ + MusicEntry* entry = *lua::GetUserdata(L, 1, lua::metatables::MusicEntryMT); + lua_pushinteger(L, entry->_numLayers); + return 1; +} + +LUA_FUNCTION(Lua_MusicEntryGetLayer) +{ + MusicEntry* entry = *lua::GetUserdata(L, 1, lua::metatables::MusicEntryMT); + int id = (int)luaL_checkinteger(L, 2); + if (id < 0 || id > entry->_numLayers-1) { + return luaL_error(L, "Invalid layer ID %d. Min = 0, Max = %d", id, entry->_numLayers - 1); + } + MusicLayer* toLua = &entry->_layers[id]; + MusicLayer** luaMusicLayer = (MusicLayer**)lua_newuserdata(L, sizeof(MusicLayer*)); + *luaMusicLayer = toLua; + luaL_setmetatable(L, lua::metatables::MusicLayerMT); + return 1; +} + +LUA_FUNCTION(Lua_MusicLayerGetIntroFilename) +{ + MusicLayer* layer = *lua::GetUserdata(L, 1, lua::metatables::MusicLayerMT); + lua_pushstring(L, layer->_intro.empty() ? "" : layer->_intro.c_str()); + return 1; +} + +LUA_FUNCTION(Lua_MusicLayerGetFilename) +{ + MusicLayer* layer = *lua::GetUserdata(L, 1, lua::metatables::MusicLayerMT); + lua_pushstring(L, layer->_path.empty() ? "" : layer->_path.c_str()); + return 1; +} + +LUA_FUNCTION(Lua_MusicLayerGetMultiplier) +{ + MusicLayer* layer = *lua::GetUserdata(L, 1, lua::metatables::MusicLayerMT); + lua_pushnumber(L, layer->_mul); + return 1; +} + +static void RegisterMusicEntry(lua_State* L) +{ + lua::RegisterFunction(L, lua::Metatables::MUSIC_MANAGER, "GetEntry", Lua_MusicManager_GetEntry); + + luaL_Reg entryFunctions[] = { + { "GetId", Lua_MusicEntryGetID}, + { "GetName", Lua_MusicEntryGetID}, + { "GetIntroFilename", Lua_MusicEntryGetIntroFilename}, + { "GetFilename", Lua_MusicEntryGetFilename}, + { "GetLoop", Lua_MusicEntryGetLoop}, + { "GetLayerMode", Lua_MusicEntryGetLayerMode}, + { "GetMultiplier", Lua_MusicEntryGetMultiplier}, + { "GetLayerFadeRate", Lua_MusicEntryGetLayerFadeRate}, + { "GetLayerCount", Lua_MusicEntryGetLayerCount}, + { "GetLayer", Lua_MusicEntryGetLayer}, + { NULL, NULL } + }; + lua::RegisterNewClass(L, lua::metatables::MusicEntryMT, lua::metatables::MusicEntryMT, entryFunctions); + + luaL_Reg layerFunctions[] = { + { "GetIntroFilename", Lua_MusicLayerGetIntroFilename}, + { "GetFilename", Lua_MusicLayerGetFilename}, + { "GetMultiplier", Lua_MusicLayerGetMultiplier}, + { NULL, NULL } + }; + lua::RegisterNewClass(L, lua::metatables::MusicLayerMT, lua::metatables::MusicLayerMT, layerFunctions); +} + +HOOK_METHOD(LuaEngine, RegisterClasses, () -> void) { + super(); + + lua::LuaStackProtector protector(_state); + RegisterMusicEntry(_state); +} \ No newline at end of file diff --git a/repentogon/LuaInterfaces/LuaMusicManager.cpp b/repentogon/LuaInterfaces/LuaMusicManager.cpp index 0e96199f0..e530e8441 100644 --- a/repentogon/LuaInterfaces/LuaMusicManager.cpp +++ b/repentogon/LuaInterfaces/LuaMusicManager.cpp @@ -53,15 +53,17 @@ LUA_FUNCTION(Lua_MusicManager_PlayJingle) { return luaL_argerror(L, 3, "Duration must be greater than zero!"); music->PlayJingle(musicId, 140, false); - //duration was inlined and (at least most) calls to the func had it stripped from the args, just set it ourselves - music->_jingleCountdownMaybe = duration; + if (luaL_checkinteger(L, 3)) + //duration was inlined and (at least most) calls to the func had it stripped from the args, just set it ourselves + music->_jingleCountdown = duration; return 0; } LUA_FUNCTION(Lua_MusicManager_StopJingle) { Music* music = lua::GetUserdata(L, 1, lua::Metatables::MUSIC_MANAGER, "MusicManager"); - music->StopJingle(); + music->_jingleVolume = 0.f; + music->_jingleCountdown = 0; return 0; } @@ -92,4 +94,4 @@ HOOK_METHOD(LuaEngine, RegisterClasses, () -> void) { lua::RegisterFunction(_state, lua::Metatables::MUSIC_MANAGER, "StopJingle", Lua_MusicManager_StopJingle); lua::RegisterFunction(_state, lua::Metatables::MUSIC_MANAGER, "GetCurrentPitch", Lua_MusicManager_GetCurrentPitch); lua::RegisterFunction(_state, lua::Metatables::MUSIC_MANAGER, "SetCurrentPitch", Lua_MusicManager_SetCurrentPitch); -} +} \ No newline at end of file diff --git a/repentogon/LuaInterfaces/LuaSFXEntry.cpp b/repentogon/LuaInterfaces/LuaSFXEntry.cpp new file mode 100644 index 000000000..3a4f4df27 --- /dev/null +++ b/repentogon/LuaInterfaces/LuaSFXEntry.cpp @@ -0,0 +1,142 @@ +#include "IsaacRepentance.h" +#include "LuaCore.h" +#include "HookSystem.h" + +LUA_FUNCTION(Lua_SFXManager_GetEntry) +{ + SoundEffects* sound = lua::GetUserdata(L, 1, lua::Metatables::SFX_MANAGER, "SFXManager"); + int soundId = (int)luaL_checkinteger(L, 2); + int max; + + if (!sound->ValidateSoundID(soundId, max)) { + return luaL_error(L, "Invalid sound ID %d. Min = 0, Max = %d", soundId, max - 1); + } + + SoundEffect* toLua = &sound->_sounds[soundId]; + SoundEffect** luaSoundEntry = (SoundEffect**)lua_newuserdata(L, sizeof(SoundEffect*)); + *luaSoundEntry = toLua; + luaL_setmetatable(L, lua::metatables::SFXEntryMT); + return 1; +} + +LUA_FUNCTION(Lua_SFXEntryGetLastFramePlayed) +{ + SoundEffect* entry = *lua::GetUserdata(L, 1, lua::metatables::SFXEntryMT); + lua_pushinteger(L, entry->_framePlayed); + return 1; +} + +LUA_FUNCTION(Lua_SFXEntryGetNextPlayableFrame) +{ + SoundEffect* entry = *lua::GetUserdata(L, 1, lua::metatables::SFXEntryMT); + lua_pushinteger(L, entry->_nextPlayableFrame); + return 1; +} + +LUA_FUNCTION(Lua_SFXEntryGetVolume) +{ + SoundEffect* entry = *lua::GetUserdata(L, 1, lua::metatables::SFXEntryMT); + lua_pushnumber(L, entry->_volume); + return 1; +} + +LUA_FUNCTION(Lua_SFXEntryGetLoaded) +{ + SoundEffect* entry = *lua::GetUserdata(L, 1, lua::metatables::SFXEntryMT); + lua_pushboolean(L, entry->_loaded); + return 1; +} + +LUA_FUNCTION(Lua_SFXEntryGetPreload) +{ + SoundEffect* entry = *lua::GetUserdata(L, 1, lua::metatables::SFXEntryMT); + lua_pushboolean(L, entry->_shouldPreload); + return 1; +} + +LUA_FUNCTION(Lua_SFXEntryGetName) +{ + SoundEffect* entry = *lua::GetUserdata(L, 1, lua::metatables::SFXEntryMT); + lua_pushstring(L, entry->_name.empty() ? "" : entry->_name.c_str()); + return 1; +} + +LUA_FUNCTION(Lua_SFXEntryGetSampleCount) +{ + SoundEffect* entry = *lua::GetUserdata(L, 1, lua::metatables::SFXEntryMT); + lua_pushinteger(L, entry->_sampleCount); + return 1; +} + +LUA_FUNCTION(Lua_SFXEntryGetSample) +{ + SoundEffect* entry = *lua::GetUserdata(L, 1, lua::metatables::SFXEntryMT); + int id = (int)luaL_checkinteger(L, 2); + + if (id < 0 || id > entry->_sampleCount-1) { + return luaL_error(L, "Invalid sample ID %d. Min = 0, Max = %d", id, entry->_sampleCount - 1); + } + + SoundEffectSample* toLua = &entry->_samples[id]; + SoundEffectSample** luaSoundSample = (SoundEffectSample**)lua_newuserdata(L, sizeof(SoundEffectSample*)); + *luaSoundSample = toLua; + luaL_setmetatable(L, lua::metatables::SFXEntrySampleMT); + return 1; +} + +LUA_FUNCTION(Lua_SFXEntrySampleGetFilename) +{ + SoundEffectSample* sample = *lua::GetUserdata(L, 1, lua::metatables::SFXEntrySampleMT); + lua_pushstring(L, sample->_filename.empty() ? "" : sample->_filename.c_str()); + return 1; +} + +LUA_FUNCTION(Lua_SFXEntrySampleGetActor) +{ + SoundEffectSample* sample = *lua::GetUserdata(L, 1, lua::metatables::SFXEntrySampleMT); + SoundActor* toLua = &sample->_actor; + SoundActor** luaSoundActor = (SoundActor**)lua_newuserdata(L, sizeof(SoundActor*)); + *luaSoundActor = toLua; + luaL_setmetatable(L, lua::metatables::SoundActorMT); + return 1; +} + +LUA_FUNCTION(Lua_SFXEntrySampleGetWeight) +{ + SoundEffectSample* sample = *lua::GetUserdata(L, 1, lua::metatables::SFXEntrySampleMT); + lua_pushinteger(L, sample->_weight); + return 1; +} + +static void RegisterSFXEntry(lua_State* L) +{ + lua::RegisterFunction(L, lua::Metatables::SFX_MANAGER, "GetEntry", Lua_SFXManager_GetEntry); + + luaL_Reg entryFunctions[] = { + { "Get", Lua_SFXEntryGetName}, + { "GetLastFramePlayed", Lua_SFXEntryGetLastFramePlayed}, + { "GetNextPlayableFrame", Lua_SFXEntryGetNextPlayableFrame}, + { "GetVolume", Lua_SFXEntryGetVolume}, + { "GetLoaded", Lua_SFXEntryGetLoaded}, + { "GetPreload", Lua_SFXEntryGetPreload}, + { "GetSampleCount", Lua_SFXEntryGetSampleCount}, + { "GetSample", Lua_SFXEntryGetSample}, + { NULL, NULL } + }; + lua::RegisterNewClass(L, lua::metatables::SFXEntryMT, lua::metatables::SFXEntryMT, entryFunctions); + + luaL_Reg sampleFunctions[] = { + { "GetFilename", Lua_SFXEntrySampleGetFilename}, + { "GetActor", Lua_SFXEntrySampleGetActor}, + { "GetWeight", Lua_SFXEntrySampleGetWeight}, + { NULL, NULL } + }; + lua::RegisterNewClass(L, lua::metatables::SFXEntrySampleMT, lua::metatables::SFXEntrySampleMT, sampleFunctions); +} + +HOOK_METHOD(LuaEngine, RegisterClasses, () -> void) { + super(); + + lua::LuaStackProtector protector(_state); + RegisterSFXEntry(_state); +} \ No newline at end of file diff --git a/repentogon/LuaInterfaces/LuaSoundActor.cpp b/repentogon/LuaInterfaces/LuaSoundActor.cpp new file mode 100644 index 000000000..a83348449 --- /dev/null +++ b/repentogon/LuaInterfaces/LuaSoundActor.cpp @@ -0,0 +1,183 @@ +/* +// This currently goes unused because I can't figure out +// why these virtual function calls either don't work or crash outright. +*/ + +/* +#include "IsaacRepentance.h" +#include "LuaCore.h" +#include "HookSystem.h" + +bool IsSourceOpen(SoundActor* actor) { + return (actor->_source != nullptr && actor->_source->IsOpen()); +} + +LUA_FUNCTION(Lua_SoundActorPlay) { + SoundActor* actor = *lua::GetUserdata(L, 1, lua::metatables::SoundActorMT); + if (IsSourceOpen(actor)) + { + actor->_source->Play(true); + } + else + return luaL_error(L, "SoundSource is not open!"); + return 0; +} + +LUA_FUNCTION(Lua_SoundActorPause) { + SoundActor* actor = *lua::GetUserdata(L, 1, lua::metatables::SoundActorMT); + if (IsSourceOpen(actor)) + { + actor->_source->Pause(); + actor->_paused = true; + actor->_playing = false; + } + else + return luaL_error(L, "SoundSource is not open!"); + return 0; +} + +LUA_FUNCTION(Lua_SoundActorResume) { + SoundActor* actor = *lua::GetUserdata(L, 1, lua::metatables::SoundActorMT); + if (IsSourceOpen(actor)) + { + actor->_source->Resume(); + actor->_paused = false; + actor->_playing = true; + } + else + return luaL_error(L, "SoundSource is not open!"); + return 0; +} + +LUA_FUNCTION(Lua_SoundActorStop) { + SoundActor* actor = *lua::GetUserdata(L, 1, lua::metatables::SoundActorMT); + if (actor->_source == nullptr) + return luaL_error(L, "SoundSource is uninitialized!"); + actor->_source->Stop(); + actor->_playing = false; + return 0; +} + +LUA_FUNCTION(Lua_SoundActorGetPitch) { + SoundActor* actor = *lua::GetUserdata(L, 1, lua::metatables::SoundActorMT); + if (actor->_source == nullptr) + return luaL_error(L, "SoundSource is uninitialized!"); + lua_pushnumber(L, actor->_source->GetPitch()); + return 1; +} + +LUA_FUNCTION(Lua_SoundActorSetPitch) { + SoundActor* actor = *lua::GetUserdata(L, 1, lua::metatables::SoundActorMT); + float pitch = luaL_checknumber(L, 2); + if (IsSourceOpen(actor)) + actor->_source->SetPitch(pitch); + else + return luaL_error(L, "SoundSource is not open!"); + return 0; +} + +LUA_FUNCTION(Lua_SoundActorGetPan) { + SoundActor* actor = *lua::GetUserdata(L, 1, lua::metatables::SoundActorMT); + if (actor->_source == nullptr) + return luaL_error(L, "SoundSource is uninitialized!"); + lua_pushnumber(L, actor->_source->GetPan()); + return 1; +} + +LUA_FUNCTION(Lua_SoundActorSetPan) { + SoundActor* actor = *lua::GetUserdata(L, 1, lua::metatables::SoundActorMT); + float pan = luaL_checknumber(L, 2); + if (IsSourceOpen(actor)) + actor->_source->SetPan(pan); + else + return luaL_error(L, "SoundSource is not open!"); + return 0; +} + +LUA_FUNCTION(Lua_SoundActorGetVolume) { + SoundActor* actor = *lua::GetUserdata(L, 1, lua::metatables::SoundActorMT); + if (IsSourceOpen(actor)) + lua_pushnumber(L, actor->_source->GetVolume()); + else + return luaL_error(L, "SoundSource is not open!"); + return 1; +} + +LUA_FUNCTION(Lua_SoundActorSetVolume) { + SoundActor* actor = *lua::GetUserdata(L, 1, lua::metatables::SoundActorMT); + float volume = luaL_checknumber(L, 2); + if (IsSourceOpen(actor)) + actor->_source->SetVolume(volume); + else + return luaL_error(L, "SoundSource is not open!"); + return 0; +} + +LUA_FUNCTION(Lua_SoundActorGetLooping) { + SoundActor* actor = *lua::GetUserdata(L, 1, lua::metatables::SoundActorMT); + if (actor->_source == nullptr) + return luaL_error(L, "SoundSource is uninitialized!"); + lua_pushboolean(L, actor->_source->IsLooping()); + return 1; +} + +LUA_FUNCTION(Lua_SoundActorSetLooping) { + SoundActor* actor = *lua::GetUserdata(L, 1, lua::metatables::SoundActorMT); + bool loop = lua::luaL_checkboolean(L, 2); + if (IsSourceOpen(actor)) + actor->_source->SetLooping(loop); + else + return luaL_error(L, "SoundSource is not open!"); + return 0; +} + +LUA_FUNCTION(Lua_SoundActorGetNumChannels) { + SoundActor* actor = *lua::GetUserdata(L, 1, lua::metatables::SoundActorMT); + if (actor->_source == nullptr) + return luaL_error(L, "SoundSource is uninitialized!"); + lua_pushinteger(L, actor->_source->GetNumChannels()); + return 1; +} + +LUA_FUNCTION(Lua_SoundActorGetSampleRate) { + SoundActor* actor = *lua::GetUserdata(L, 1, lua::metatables::SoundActorMT); + if (actor->_source == nullptr) + return luaL_error(L, "SoundSource is uninitialized!"); + lua_pushinteger(L, actor->_source->GetSampleRate()); + return 1; +} + +LUA_FUNCTION(Lua_SoundActorGetSourceFormat) { + SoundActor* actor = *lua::GetUserdata(L, 1, lua::metatables::SoundActorMT); + if (actor->_source == nullptr) + return luaL_error(L, "SoundSource is uninitialized!"); + lua_pushinteger(L, actor->_source->GetSourceFormat()); + return 1; +} + +static void RegisterSoundActor(lua_State* L) +{ + luaL_Reg functions[] = { + { "Play", Lua_SoundActorPlay}, + { "Pause", Lua_SoundActorPause}, + { "Resume", Lua_SoundActorResume}, + { "Stop", Lua_SoundActorStop}, + { "GetPitch", Lua_SoundActorGetPitch}, + { "GetPan", Lua_SoundActorGetPan}, + { "GetVolume", Lua_SoundActorGetVolume}, + { "GetLooping", Lua_SoundActorGetLooping}, + { "GetNumChannels", Lua_SoundActorGetNumChannels}, + { "GetSampleRate", Lua_SoundActorGetSampleRate}, + { "GetSourceFormat", Lua_SoundActorGetSourceFormat}, + { NULL, NULL } + }; + lua::RegisterNewClass(L, lua::metatables::SoundActorMT, lua::metatables::SoundActorMT, functions); +} + +HOOK_METHOD(LuaEngine, RegisterClasses, () -> void) { + super(); + + lua::LuaStackProtector protector(_state); + RegisterSoundActor(_state); +} +*/ \ No newline at end of file diff --git a/repentogon/LuaInterfaces/LuaSoundStream.cpp b/repentogon/LuaInterfaces/LuaSoundStream.cpp new file mode 100644 index 000000000..f88275be1 --- /dev/null +++ b/repentogon/LuaInterfaces/LuaSoundStream.cpp @@ -0,0 +1,85 @@ +#include "IsaacRepentance.h" +#include "LuaCore.h" +#include "HookSystem.h" +#include "Log.h" + +// Lua_SoundActor currently disabled +/* +LUA_FUNCTION(Lua_SoundStreamGetActor) +{ + SoundStream* stream = *lua::GetUserdata(L, 1, lua::metatables::SoundStreamMT); + SoundActor* toLua = &stream->_actor; + + ZHL::Logger logger(true); + logger.Log("getting actor at addr %d\n", &stream->_actor); + + SoundActor** luaSoundActor = (SoundActor**)lua_newuserdata(L, sizeof(SoundActor*)); + *luaSoundActor = toLua; + luaL_setmetatable(L, lua::metatables::SoundActorMT); + return 1; +} +*/ + +LUA_FUNCTION(Lua_SoundStreamGetVolume) +{ + SoundStream* stream = *lua::GetUserdata(L, 1, lua::metatables::SoundStreamMT); + lua_pushnumber(L, stream->_volume); + return 1; +} + +LUA_FUNCTION(Lua_SoundStreamGetTargetVolume) +{ + SoundStream* stream = *lua::GetUserdata(L, 1, lua::metatables::SoundStreamMT); + lua_pushnumber(L, stream->_targetVolume); + return 1; +} + +LUA_FUNCTION(Lua_SoundStreamGetVolumeModifier) +{ + SoundStream* stream = *lua::GetUserdata(L, 1, lua::metatables::SoundStreamMT); + lua_pushnumber(L, stream->_volumeMod); + return 1; +} + +LUA_FUNCTION(Lua_SoundStreamGetFadeRate) +{ + SoundStream* stream = *lua::GetUserdata(L, 1, lua::metatables::SoundStreamMT); + lua_pushnumber(L, stream->_volume); + return 1; +} + +LUA_FUNCTION(Lua_SoundStreamIsPlaying) +{ + SoundStream* stream = *lua::GetUserdata(L, 1, lua::metatables::SoundStreamMT); + lua_pushboolean(L, stream->_playing); + return 1; +} + +LUA_FUNCTION(Lua_SoundStreamGetFrameCount) +{ + SoundStream* stream = *lua::GetUserdata(L, 1, lua::metatables::SoundStreamMT); + lua_pushinteger(L, stream->_frameCount); + return 1; +} + +static void RegisterSoundStream(lua_State* L) +{ + luaL_Reg functions[] = { + //{ "GetActor", Lua_SoundStreamGetActor}, + { "GetVolume", Lua_SoundStreamGetVolume}, + { "GetTargetVolume", Lua_SoundStreamGetTargetVolume}, + { "GetVolumeModifier", Lua_SoundStreamGetVolumeModifier}, + { "GetFadeRate", Lua_SoundStreamGetFadeRate}, + { "IsPlaying", Lua_SoundStreamIsPlaying}, + { "GetFrameCount", Lua_SoundStreamGetFrameCount}, + { NULL, NULL } + }; + lua::RegisterNewClass(L, lua::metatables::SoundStreamMT, lua::metatables::SoundStreamMT, functions); +} + +HOOK_METHOD(LuaEngine, RegisterClasses, () -> void) { + super(); + + lua::LuaStackProtector protector(_state); + RegisterSoundStream(_state); +} \ No newline at end of file diff --git a/repentogon/LuaInterfaces/LuaSoundStreamSet.cpp b/repentogon/LuaInterfaces/LuaSoundStreamSet.cpp new file mode 100644 index 000000000..902aec6a0 --- /dev/null +++ b/repentogon/LuaInterfaces/LuaSoundStreamSet.cpp @@ -0,0 +1,186 @@ +#include "IsaacRepentance.h" +#include "LuaCore.h" +#include "HookSystem.h" + +float musicVolumes[2][7] = { { 1, 1, 1, 1, 1, 1, 1 }, { 1, 1, 1, 1, 1, 1, 1 } }; + +HOOK_METHOD(SoundStreamSet, game_constructor, () -> SoundStreamSet*) { + SoundStreamSet* set = super(); + + for (size_t i = 0; i < 7; i++) { + set->_streams[i]._HIJACK_id = (uint8_t)i; + } + + set->_HIJACK_id = this == &g_Manager->_musicmanager._streamSets[1] ? 1 : 0; + + return set; +} + +HOOK_METHOD(SoundStreamSet, Play, () -> void) { + // get opposite stream id + int target = g_Manager->_musicmanager._currentStream ^ 1; + for (int i = 0; i < 7; i++) { + musicVolumes[target][i] = 1.f; + } + + super(); +} + +HOOK_METHOD(SoundStream, Update, (bool checkIfPlaying) -> void) { + // exclude jingle stream + if (this->_setRef) { + // main stream target volume isn't constantly recalculated like layers are + float target = this->_HIJACK_id == 0 ? 1 : this->_targetVolume; + this->_targetVolume = target * musicVolumes[this->_setRef->_HIJACK_id][this->_HIJACK_id]; + } + + super(checkIfPlaying); +} + +LUA_FUNCTION(Lua_MusicManager_GetCurrentStreamSetId) +{ + Music* music = lua::GetUserdata(L, 1, lua::Metatables::MUSIC_MANAGER, "MusicManager"); + lua_pushinteger(L, music->_currentStream); + return 1; +} + +LUA_FUNCTION(Lua_MusicManager_GetCurrentStreamSet) +{ + Music* music = lua::GetUserdata(L, 1, lua::Metatables::MUSIC_MANAGER, "MusicManager"); + SoundStreamSet* toLua = &music->_streamSets[music->_currentStream]; + SoundStreamSet** luaStreamSet = (SoundStreamSet**)lua_newuserdata(L, sizeof(SoundStreamSet*)); + *luaStreamSet = toLua; + luaL_setmetatable(L, lua::metatables::SoundStreamSetMT); + return 1; +} + +LUA_FUNCTION(Lua_MusicManager_GetStreamSet) +{ + Music* music = lua::GetUserdata(L, 1, lua::Metatables::MUSIC_MANAGER, "MusicManager"); + int setId = (int)luaL_checkinteger(L, 2); + + if (setId < 0 || setId > 1) { + return luaL_error(L, "Invalid set ID %d. Min = 0, Max = 1", setId); + } + + SoundStreamSet* toLua = &music->_streamSets[setId]; + SoundStreamSet** luaStreamSet = (SoundStreamSet**)lua_newuserdata(L, sizeof(SoundStreamSet*)); + *luaStreamSet = toLua; + luaL_setmetatable(L, lua::metatables::SoundStreamSetMT); + return 1; +} + +LUA_FUNCTION(Lua_SoundStreamSetGetStream) +{ + SoundStreamSet* set = *lua::GetUserdata(L, 1, lua::metatables::SoundStreamSetMT); + int streamId = (int)luaL_checkinteger(L, 2); + + if (streamId < 0 || streamId > 6) { + return luaL_error(L, "Invalid music ID %d. Min = 0, Max = 6", streamId); + } + + SoundStream* toLua = &set->_streams[streamId]; + SoundStream** luaStream = (SoundStream**)lua_newuserdata(L, sizeof(SoundStream*)); + *luaStream = toLua; + luaL_setmetatable(L, lua::metatables::SoundStreamMT); + return 1; +} + +LUA_FUNCTION(Lua_SoundStreamSetGetActiveLayers) +{ + SoundStreamSet* set = *lua::GetUserdata(L, 1, lua::metatables::SoundStreamSetMT); + lua_pushinteger(L, set->_layerBitfield); + return 1; +} + +LUA_FUNCTION(Lua_SoundStreamSetGetVolumeMode) +{ + SoundStreamSet* set = *lua::GetUserdata(L, 1, lua::metatables::SoundStreamSetMT); + lua_pushinteger(L, set->_volumeMode); + return 1; +} + +LUA_FUNCTION(Lua_SoundStreamSetGetVolume) +{ + SoundStreamSet* set = *lua::GetUserdata(L, 1, lua::metatables::SoundStreamSetMT); + lua_pushnumber(L, set->_volume); + return 1; +} + +LUA_FUNCTION(Lua_SoundStreamSetGetTargetVolume) +{ + SoundStreamSet* set = *lua::GetUserdata(L, 1, lua::metatables::SoundStreamSetMT); + lua_pushnumber(L, set->_targetVolume); + return 1; +} + +LUA_FUNCTION(Lua_SoundStreamSetGetFadeRate) +{ + SoundStreamSet* set = *lua::GetUserdata(L, 1, lua::metatables::SoundStreamSetMT); + lua_pushnumber(L, set->_fadeRate); + return 1; +} + +LUA_FUNCTION(Lua_SoundStreamSetIsPlaying) +{ + SoundStreamSet* set = *lua::GetUserdata(L, 1, lua::metatables::SoundStreamSetMT); + lua_pushboolean(L, set->_playing); + return 1; +} + +LUA_FUNCTION(Lua_SoundStreamSetGetTargetVolumeMultiplier) +{ + SoundStreamSet* set = *lua::GetUserdata(L, 1, lua::metatables::SoundStreamSetMT); + + int streamId = (int)luaL_checkinteger(L, 2); + + if (streamId < 0 || streamId > 6) { + return luaL_error(L, "Invalid music ID %d. Min = 0, Max = 6", streamId); + } + lua_pushnumber(L, musicVolumes[g_Manager->_musicmanager._currentStream][streamId]); + + return 1; +} + +LUA_FUNCTION(Lua_SoundStreamSetSetTargetVolumeMultiplier) +{ + SoundStreamSet* set = *lua::GetUserdata(L, 1, lua::metatables::SoundStreamSetMT); + + int streamId = (int)luaL_checkinteger(L, 2); + + if (streamId < 0 || streamId > 6) { + return luaL_error(L, "Invalid music ID %d. Min = 0, Max = 6", streamId); + } + + musicVolumes[g_Manager->_musicmanager._currentStream][streamId] = (float)luaL_checknumber(L, 3); + + return 0; +} + +static void RegisterSoundStreamSet(lua_State* L) +{ + lua::RegisterFunction(L, lua::Metatables::MUSIC_MANAGER, "GetStreamSet", Lua_MusicManager_GetStreamSet); + lua::RegisterFunction(L, lua::Metatables::MUSIC_MANAGER, "GetCurrentStreamSet", Lua_MusicManager_GetCurrentStreamSet); + lua::RegisterFunction(L, lua::Metatables::MUSIC_MANAGER, "GetCurrentStreamSetId", Lua_MusicManager_GetCurrentStreamSetId); + + luaL_Reg functions[] = { + { "GetStream", Lua_SoundStreamSetGetStream}, + { "GetActiveLayers", Lua_SoundStreamSetGetActiveLayers}, + { "GetLayerMode", Lua_SoundStreamSetGetVolumeMode}, + { "GetVolume", Lua_SoundStreamSetGetVolume}, + { "GetTargetVolume", Lua_SoundStreamSetGetTargetVolume}, + { "GetFadeRate", Lua_SoundStreamSetGetFadeRate}, + { "IsPlaying", Lua_SoundStreamSetIsPlaying}, + { "GetTargetVolumeMultiplier", Lua_SoundStreamSetGetTargetVolumeMultiplier}, + { "SetTargetVolumeMultiplier", Lua_SoundStreamSetSetTargetVolumeMultiplier}, + { NULL, NULL } + }; + lua::RegisterNewClass(L, lua::metatables::SoundStreamSetMT, lua::metatables::SoundStreamSetMT, functions); +} + +HOOK_METHOD(LuaEngine, RegisterClasses, () -> void) { + super(); + + lua::LuaStackProtector protector(_state); + RegisterSoundStreamSet(_state); +} \ No newline at end of file