mirror of
https://github.com/zeldaret/ss
synced 2026-08-18 21:47:41 -04:00
Use BBA names and type for AnimSound, fixes fakematch
This commit is contained in:
@@ -5,7 +5,8 @@
|
||||
#include "nw4r/snd/snd_SoundHandle.h"
|
||||
#include "nw4r/snd/snd_SoundStartable.h"
|
||||
|
||||
// Class and non-inline function names from InazumaWii, everything else made up
|
||||
// Class and non-inlined function names from InazumaWii
|
||||
// Names of automatically inlined functions from BBA
|
||||
|
||||
namespace nw4r {
|
||||
namespace snd {
|
||||
@@ -39,22 +40,13 @@ public:
|
||||
return mIsRunning;
|
||||
}
|
||||
|
||||
void UpdateFrame() {
|
||||
if (!mHandle.IsAttachedSound()) {
|
||||
mpEvent = 0;
|
||||
}
|
||||
}
|
||||
void UpdateFrame();
|
||||
|
||||
void Stop() {
|
||||
if (IsAttachedSound()) {
|
||||
mHandle.detail_GetAttachedSound()->Stop(0);
|
||||
}
|
||||
mpEvent = 0;
|
||||
}
|
||||
void ForceStop();
|
||||
|
||||
void StopEvent(const AnimEvent *event) {
|
||||
if (mpEvent == event) {
|
||||
Stop();
|
||||
ForceStop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,8 +62,14 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void StartSound(const AnimEvent *event, SoundStartable *startable, bool b);
|
||||
void HoldSound(const AnimEvent *event, SoundStartable *startable, bool b);
|
||||
void StartEvent(const AnimEvent *event, SoundStartable *startable, bool b);
|
||||
void HoldEvent(const AnimEvent *event, SoundStartable *startable, bool b);
|
||||
|
||||
// Not sure about these, this could be related to
|
||||
// InitParam__Q44nw4r3snd6detail15AnimEventPlayerFPCQ44nw4r3snd6detail9AnimEventb
|
||||
// from BBA, but SetVariable is almost certainly an inline (duplicated code)
|
||||
// but the float argument is read from AnimSoundImpl so something seems to have
|
||||
// changed.
|
||||
void SetVolumePitch(const AnimEvent *event, bool b);
|
||||
void SetVariable(const AnimEvent *event, u32 varNo, f32 f);
|
||||
|
||||
@@ -97,19 +95,16 @@ public:
|
||||
void UpdateFrame(f32 frame, PlayDirection dir);
|
||||
void UpdateForward(f32 frame);
|
||||
void UpdateBackward(f32 frame);
|
||||
void UpdateOneFrame(s32 duration, PlayDirection direction);
|
||||
void UpdateTrigger(const AnimEventRef *, s32, PlayDirection);
|
||||
void UpdateForwardRange(const AnimEventRef *, s32);
|
||||
void UpdateBackwardRange(const AnimEventRef *, s32);
|
||||
|
||||
void StartEvent(const AnimEvent *, bool);
|
||||
void HoldEvent(const AnimEvent *, bool);
|
||||
// StartEvent is not inlined, but there seems to be
|
||||
// a corresponding StopEvent function that got inlined
|
||||
void StopEvent(const AnimEvent *);
|
||||
bool IsPlayableLoopCount(const nw4r::snd::detail::AnimEventFrameInfo&);
|
||||
|
||||
// Made up inlines
|
||||
bool ShouldPlayEvent(const AnimEventRef *ref) const;
|
||||
void UpdateEvents(s32 duration, PlayDirection direction);
|
||||
|
||||
typedef void (*Callback)(int, s32, const char *, UNKWORD, UNKWORD);
|
||||
|
||||
|
||||
@@ -5,6 +5,15 @@ namespace nw4r {
|
||||
namespace snd {
|
||||
namespace detail {
|
||||
|
||||
// Type and name revealed by BBA
|
||||
struct AnimEventFrameInfo {
|
||||
int field_0x00; // at 0x00
|
||||
int field_0x04; // at 0x04
|
||||
u8 flags; // at 0x08
|
||||
s8 field_0x09; // at 0x09
|
||||
u8 field_0x0A; // at 0x0A
|
||||
};
|
||||
|
||||
struct AnimEvent {
|
||||
u32 flags; // at 0x00
|
||||
u32 soundId; // at 0x04
|
||||
@@ -42,15 +51,13 @@ struct AnimEvent {
|
||||
}
|
||||
};
|
||||
|
||||
// Name from Inazuma, BBA
|
||||
struct AnimEventRef {
|
||||
int field_0x00; // at 0x08
|
||||
int field_0x04; // at 0x04
|
||||
u8 flags; // at 0x08
|
||||
s8 field_0x09; // at 0x09
|
||||
u8 field_0x0A; // at 0x0A
|
||||
AnimEventFrameInfo mInfo; // at 0x00
|
||||
Util::DataRef<AnimEvent> event; // at 0x0C
|
||||
};
|
||||
|
||||
// Names unknown
|
||||
struct AnimSoundFile {
|
||||
static u32 const SIGNATURE_FILE = NW4R_FOUR_BYTE('R', 'A', 'S', 'D');
|
||||
static int const FILE_VERSION = NW4R_FILE_VERSION(1, 0);
|
||||
@@ -71,6 +78,7 @@ struct AnimSoundFile {
|
||||
};
|
||||
};
|
||||
|
||||
// Name from Inazuma
|
||||
class AnimSoundFileReader {
|
||||
public:
|
||||
AnimSoundFileReader();
|
||||
|
||||
+115
-103
@@ -89,49 +89,6 @@ void AnimSoundImpl::UpdateFrame(f32 frame, PlayDirection dir) {
|
||||
field_0x1A = false;
|
||||
}
|
||||
|
||||
bool AnimSoundImpl::ShouldPlayEvent(const AnimEventRef *ref) const {
|
||||
if (!(ref->flags & 1) && (ref->flags & 4 || ref->flags & 2)) {
|
||||
return true;
|
||||
}
|
||||
int i1 = ut::Max((int)ref->field_0x09, 0);
|
||||
int i2 = ut::Abs(field_0x1C);
|
||||
if (ref->field_0x0A == 0) {
|
||||
if (i2 < i1) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (i2 < i1) {
|
||||
return false;
|
||||
}
|
||||
if ((i2 - i1) % ref->field_0x0A != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AnimSoundImpl::UpdateEvents(s32 duration, PlayDirection direction) {
|
||||
for (u32 eventIdx = 0; eventIdx < mReader.GetEventCount(); eventIdx++) {
|
||||
const AnimEventRef *ref = mReader.GetEventRef(eventIdx);
|
||||
if (ref == NULL) {
|
||||
continue;
|
||||
}
|
||||
if (ShouldPlayEvent(ref)) {
|
||||
// HACK/Fakematch: Force a reload
|
||||
if ((((AnimEventRef *)ref)->flags) & 1) {
|
||||
UpdateTrigger(ref, duration, direction);
|
||||
} else {
|
||||
if (direction == FORWARD) {
|
||||
UpdateForwardRange(ref, duration);
|
||||
} else {
|
||||
UpdateBackwardRange(ref, duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AnimSoundImpl::UpdateForward(f32 frame) {
|
||||
s32 duration = std::floorf(field_0x0C);
|
||||
s32 iFrame = std::floorf(frame);
|
||||
@@ -151,7 +108,7 @@ void AnimSoundImpl::UpdateForward(f32 frame) {
|
||||
field_0x1C++;
|
||||
}
|
||||
|
||||
UpdateEvents(loopFrame, FORWARD);
|
||||
UpdateOneFrame(loopFrame, FORWARD);
|
||||
|
||||
if (loopFrame == iFrame) {
|
||||
break;
|
||||
@@ -187,7 +144,7 @@ void AnimSoundImpl::UpdateBackward(f32 frame) {
|
||||
field_0x1C--;
|
||||
}
|
||||
|
||||
UpdateEvents(loopFrame, BACKWARD);
|
||||
UpdateOneFrame(loopFrame, BACKWARD);
|
||||
|
||||
if (loopFrame == iFrame) {
|
||||
break;
|
||||
@@ -196,13 +153,33 @@ void AnimSoundImpl::UpdateBackward(f32 frame) {
|
||||
}
|
||||
}
|
||||
|
||||
void AnimSoundImpl::UpdateOneFrame(s32 duration, PlayDirection direction) {
|
||||
for (u32 eventIdx = 0; eventIdx < mReader.GetEventCount(); eventIdx++) {
|
||||
const AnimEventRef *ref = mReader.GetEventRef(eventIdx);
|
||||
if (ref == NULL) {
|
||||
continue;
|
||||
}
|
||||
if (IsPlayableLoopCount(ref->mInfo)) {
|
||||
if ((ref->mInfo.flags) & 1) {
|
||||
UpdateTrigger(ref, duration, direction);
|
||||
} else {
|
||||
if (direction == FORWARD) {
|
||||
UpdateForwardRange(ref, duration);
|
||||
} else {
|
||||
UpdateBackwardRange(ref, duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AnimSoundImpl::UpdateTrigger(const AnimEventRef *ref, s32 frame, PlayDirection direction) {
|
||||
const AnimEvent *event = mReader.GetEvent(ref);
|
||||
if (event == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ref->flags & 4) {
|
||||
if (ref->mInfo.flags & 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -210,8 +187,8 @@ void AnimSoundImpl::UpdateTrigger(const AnimEventRef *ref, s32 frame, PlayDirect
|
||||
return;
|
||||
}
|
||||
|
||||
if ((ref->flags & 2)) {
|
||||
if (ref->field_0x00 == frame) {
|
||||
if ((ref->mInfo.flags & 2)) {
|
||||
if (ref->mInfo.field_0x00 == frame) {
|
||||
StopEvent(event);
|
||||
if (mCallback != NULL) {
|
||||
(mCallback)(0, frame, event->GetSoundLabel(), event->field_0x1C, field_0x24);
|
||||
@@ -219,7 +196,7 @@ void AnimSoundImpl::UpdateTrigger(const AnimEventRef *ref, s32 frame, PlayDirect
|
||||
StartEvent(event, true);
|
||||
}
|
||||
} else {
|
||||
if (ref->field_0x00 == frame) {
|
||||
if (ref->mInfo.field_0x00 == frame) {
|
||||
StopEvent(event);
|
||||
if (mCallback != NULL) {
|
||||
(mCallback)(0, frame, event->GetSoundLabel(), event->field_0x1C, field_0x24);
|
||||
@@ -229,9 +206,9 @@ void AnimSoundImpl::UpdateTrigger(const AnimEventRef *ref, s32 frame, PlayDirect
|
||||
|
||||
s32 u;
|
||||
if (direction == FORWARD) {
|
||||
u = ref->field_0x04;
|
||||
u = ref->mInfo.field_0x04;
|
||||
} else {
|
||||
u = ut::Max(ref->field_0x00 * 2 - ref->field_0x04, 0);
|
||||
u = ut::Max(ref->mInfo.field_0x00 * 2 - ref->mInfo.field_0x04, 0);
|
||||
}
|
||||
|
||||
if (u == frame) {
|
||||
@@ -249,41 +226,41 @@ void AnimSoundImpl::UpdateForwardRange(const AnimEventRef *ref, s32 frame) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ref->flags & 4 && ref->flags & 2) {
|
||||
if (ref->mInfo.flags & 4 && ref->mInfo.flags & 2) {
|
||||
HoldEvent(event, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ref->flags & 4) {
|
||||
if (ref->field_0x04 == frame && mCallback != NULL) {
|
||||
if (ref->mInfo.flags & 4) {
|
||||
if (ref->mInfo.field_0x04 == frame && mCallback != NULL) {
|
||||
(mCallback)(3, frame, event->GetSoundLabel(), event->field_0x1C, field_0x24);
|
||||
}
|
||||
if (field_0x1C < ref->field_0x09) {
|
||||
if (field_0x1C < ref->mInfo.field_0x09) {
|
||||
HoldEvent(event, true);
|
||||
} else if (field_0x1C == ref->field_0x09) {
|
||||
if (frame < ref->field_0x04) {
|
||||
} else if (field_0x1C == ref->mInfo.field_0x09) {
|
||||
if (frame < ref->mInfo.field_0x04) {
|
||||
HoldEvent(event, true);
|
||||
} else {
|
||||
StopEvent(event);
|
||||
}
|
||||
}
|
||||
} else if ((ref->flags & 2)) {
|
||||
if (ref->field_0x00 == frame && mCallback != NULL) {
|
||||
} else if ((ref->mInfo.flags & 2)) {
|
||||
if (ref->mInfo.field_0x00 == frame && mCallback != NULL) {
|
||||
(mCallback)(2, frame, event->GetSoundLabel(), event->field_0x1C, field_0x24);
|
||||
}
|
||||
if (field_0x1C > ref->field_0x09) {
|
||||
if (field_0x1C > ref->mInfo.field_0x09) {
|
||||
HoldEvent(event, true);
|
||||
} else if (field_0x1C == ref->field_0x09 && ref->field_0x00 <= frame) {
|
||||
} else if (field_0x1C == ref->mInfo.field_0x09 && ref->mInfo.field_0x00 <= frame) {
|
||||
HoldEvent(event, true);
|
||||
}
|
||||
} else {
|
||||
if (ref->field_0x00 == frame && mCallback != NULL) {
|
||||
if (ref->mInfo.field_0x00 == frame && mCallback != NULL) {
|
||||
(mCallback)(2, frame, event->GetSoundLabel(), event->field_0x1C, field_0x24);
|
||||
}
|
||||
if (ref->field_0x04 == frame && mCallback != NULL) {
|
||||
if (ref->mInfo.field_0x04 == frame && mCallback != NULL) {
|
||||
(mCallback)(3, frame, event->GetSoundLabel(), event->field_0x1C, field_0x24);
|
||||
}
|
||||
if (ref->field_0x00 <= frame && frame < ref->field_0x04) {
|
||||
if (ref->mInfo.field_0x00 <= frame && frame < ref->mInfo.field_0x04) {
|
||||
HoldEvent(event, true);
|
||||
} else {
|
||||
StopEvent(event);
|
||||
@@ -297,41 +274,41 @@ void AnimSoundImpl::UpdateBackwardRange(const AnimEventRef *ref, s32 frame) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ref->flags & 4 && ref->flags & 2) {
|
||||
if (ref->mInfo.flags & 4 && ref->mInfo.flags & 2) {
|
||||
HoldEvent(event, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ref->flags & 4) {
|
||||
if (ref->field_0x04 == frame && mCallback != NULL) {
|
||||
if (ref->mInfo.flags & 4) {
|
||||
if (ref->mInfo.field_0x04 == frame && mCallback != NULL) {
|
||||
(mCallback)(2, frame, event->GetSoundLabel(), event->field_0x1C, field_0x24);
|
||||
}
|
||||
if (field_0x1C < ref->field_0x09) {
|
||||
if (field_0x1C < ref->mInfo.field_0x09) {
|
||||
HoldEvent(event, true);
|
||||
} else if (field_0x1C == ref->field_0x09 && frame <= ref->field_0x04) {
|
||||
} else if (field_0x1C == ref->mInfo.field_0x09 && frame <= ref->mInfo.field_0x04) {
|
||||
HoldEvent(event, true);
|
||||
}
|
||||
} else if ((ref->flags & 2)) {
|
||||
if (ref->field_0x00 == frame && mCallback != NULL) {
|
||||
} else if ((ref->mInfo.flags & 2)) {
|
||||
if (ref->mInfo.field_0x00 == frame && mCallback != NULL) {
|
||||
(mCallback)(3, frame, event->GetSoundLabel(), event->field_0x1C, field_0x24);
|
||||
}
|
||||
if (field_0x1C > ref->field_0x09) {
|
||||
if (field_0x1C > ref->mInfo.field_0x09) {
|
||||
HoldEvent(event, true);
|
||||
} else if (field_0x1C == ref->field_0x09) {
|
||||
if (ref->field_0x00 < frame) {
|
||||
} else if (field_0x1C == ref->mInfo.field_0x09) {
|
||||
if (ref->mInfo.field_0x00 < frame) {
|
||||
HoldEvent(event, true);
|
||||
} else {
|
||||
StopEvent(event);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (ref->field_0x00 == frame && mCallback != NULL) {
|
||||
if (ref->mInfo.field_0x00 == frame && mCallback != NULL) {
|
||||
(mCallback)(3, frame, event->GetSoundLabel(), event->field_0x1C, field_0x24);
|
||||
}
|
||||
if (ref->field_0x04 == frame && mCallback != NULL) {
|
||||
if (ref->mInfo.field_0x04 == frame && mCallback != NULL) {
|
||||
(mCallback)(2, frame, event->GetSoundLabel(), event->field_0x1C, field_0x24);
|
||||
}
|
||||
if (ref->field_0x00 < frame && frame <= ref->field_0x04) {
|
||||
if (ref->mInfo.field_0x00 < frame && frame <= ref->mInfo.field_0x04) {
|
||||
HoldEvent(event, true);
|
||||
} else {
|
||||
StopEvent(event);
|
||||
@@ -355,11 +332,11 @@ void AnimSoundImpl::StartEvent(const AnimEvent *event, bool b) {
|
||||
}
|
||||
|
||||
if (i == mNumSounds) {
|
||||
mpSounds[leastPriorityIdx].Stop();
|
||||
mpSounds[leastPriorityIdx].ForceStop();
|
||||
i = leastPriorityIdx;
|
||||
}
|
||||
|
||||
mpSounds[i].StartSound(event, &mStartable, b);
|
||||
mpSounds[i].StartEvent(event, &mStartable, b);
|
||||
|
||||
u32 varNo = 0;
|
||||
if (event->GetVarNo(&varNo)) {
|
||||
@@ -388,11 +365,11 @@ void AnimSoundImpl::HoldEvent(const AnimEvent *event, bool b) {
|
||||
}
|
||||
|
||||
if (i == mNumSounds) {
|
||||
mpSounds[leastPriorityIdx].Stop();
|
||||
mpSounds[leastPriorityIdx].ForceStop();
|
||||
i = leastPriorityIdx;
|
||||
}
|
||||
|
||||
mpSounds[i].HoldSound(event, &mStartable, b);
|
||||
mpSounds[i].HoldEvent(event, &mStartable, b);
|
||||
|
||||
u32 varNo = 0;
|
||||
if (event->GetVarNo(&varNo)) {
|
||||
@@ -406,33 +383,26 @@ void AnimSoundImpl::StopEvent(const AnimEvent *event) {
|
||||
}
|
||||
}
|
||||
|
||||
void AnimEventPlayer::StartSound(const AnimEvent *event, SoundStartable *startable, bool b) {
|
||||
if (event->soundId == 0xFFFFFFFF) {
|
||||
if (!startable->StartSound(GetHandle(), event->GetSoundLabel())) {
|
||||
return;
|
||||
bool AnimSoundImpl::IsPlayableLoopCount(const nw4r::snd::detail::AnimEventFrameInfo &ref) {
|
||||
if (!(ref.flags & 1) && (ref.flags & 4 || ref.flags & 2)) {
|
||||
return true;
|
||||
}
|
||||
int i1 = ut::Max((int)ref.field_0x09, 0);
|
||||
int i2 = ut::Abs(field_0x1C);
|
||||
if (ref.field_0x0A == 0) {
|
||||
if (i2 < i1) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!startable->StartSound(GetHandle(), event->soundId)) {
|
||||
return;
|
||||
if (i2 < i1) {
|
||||
return false;
|
||||
}
|
||||
if ((i2 - i1) % ref.field_0x0A != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
SetVolumePitch(event, b);
|
||||
}
|
||||
|
||||
void AnimEventPlayer::HoldSound(const AnimEvent *event, SoundStartable *startable, bool b) {
|
||||
if (event->soundId == 0xFFFFFFFF) {
|
||||
if (!startable->HoldSound(GetHandle(), event->GetSoundLabel())) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!startable->HoldSound(GetHandle(), event->soundId)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
GetHandle()->detail_GetAttachedSound()->SetAutoStopCounter(0);
|
||||
SetVolumePitch(event, b);
|
||||
return true;
|
||||
}
|
||||
|
||||
void AnimEventPlayer::SetVolumePitch(const AnimEvent *event, bool b) {
|
||||
@@ -472,6 +442,48 @@ AnimEventPlayer::~AnimEventPlayer() {
|
||||
}
|
||||
}
|
||||
|
||||
void AnimEventPlayer::StartEvent(const AnimEvent *event, SoundStartable *startable, bool b) {
|
||||
if (event->soundId == 0xFFFFFFFF) {
|
||||
if (!startable->StartSound(GetHandle(), event->GetSoundLabel())) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!startable->StartSound(GetHandle(), event->soundId)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SetVolumePitch(event, b);
|
||||
}
|
||||
|
||||
void AnimEventPlayer::HoldEvent(const AnimEvent *event, SoundStartable *startable, bool b) {
|
||||
if (event->soundId == 0xFFFFFFFF) {
|
||||
if (!startable->HoldSound(GetHandle(), event->GetSoundLabel())) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!startable->HoldSound(GetHandle(), event->soundId)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
GetHandle()->detail_GetAttachedSound()->SetAutoStopCounter(0);
|
||||
SetVolumePitch(event, b);
|
||||
}
|
||||
|
||||
void AnimEventPlayer::ForceStop() {
|
||||
if (IsAttachedSound()) {
|
||||
mHandle.detail_GetAttachedSound()->Stop(0);
|
||||
}
|
||||
mpEvent = 0;
|
||||
}
|
||||
|
||||
void AnimEventPlayer::UpdateFrame() {
|
||||
if (!mHandle.IsAttachedSound()) {
|
||||
mpEvent = 0;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace snd
|
||||
} // namespace nw4r
|
||||
|
||||
Reference in New Issue
Block a user