Add more rumble events (#627)

* Add more rumble events

* Add check for haptic
This commit is contained in:
Christian Semmler 2025-07-18 15:52:42 -07:00 committed by GitHub
parent 6b551b14c0
commit 10195dcbcb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 57 additions and 10 deletions

View File

@ -806,12 +806,31 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
SDL_Log("Game started"); SDL_Log("Game started");
} }
} }
else if (event->user.type == g_legoSdlEvents.m_hitActor && g_isle->GetHaptic()) { else if (event->user.type == g_legoSdlEvents.m_gameEvent) {
if (!InputManager()->HandleRumbleEvent(0.5f, 0.5f, 0.5f, 700)) { auto rumble = [](float p_strength, float p_lowFrequencyRumble, float p_highFrequencyRumble, MxU32 p_milliseconds
) {
if (g_isle->GetHaptic() &&
!InputManager()
->HandleRumbleEvent(p_strength, p_lowFrequencyRumble, p_highFrequencyRumble, p_milliseconds)) {
// Platform-specific handling // Platform-specific handling
#ifdef __EMSCRIPTEN__ #ifdef __EMSCRIPTEN__
Emscripten_HandleRumbleEvent(0.5f, 0.5f, 700); Emscripten_HandleRumbleEvent(p_lowFrequencyRumble, p_highFrequencyRumble, p_milliseconds);
#endif #endif
}
};
switch (event->user.code) {
case e_hitActor:
rumble(0.5f, 0.5f, 0.5f, 700);
break;
case e_skeletonKick:
rumble(0.8f, 0.8f, 0.8f, 2500);
break;
case e_raceFinished:
case e_goodEnding:
case e_badEnding:
rumble(1.0f, 1.0f, 1.0f, 3000);
break;
} }
} }

View File

@ -32,6 +32,14 @@ enum Cursor {
e_cursorNone e_cursorNone
}; };
enum GameEvent {
e_hitActor,
e_skeletonKick,
e_raceFinished,
e_badEnding,
e_goodEnding
};
class BoundingSphere; class BoundingSphere;
class MxAtomId; class MxAtomId;
class LegoEntity; class LegoEntity;
@ -71,7 +79,7 @@ LegoNamedTexture* ReadNamedTexture(LegoStorage* p_storage);
void WriteDefaultTexture(LegoStorage* p_storage, const char* p_name); void WriteDefaultTexture(LegoStorage* p_storage, const char* p_name);
void WriteNamedTexture(LegoStorage* p_storage, LegoNamedTexture* p_namedTexture); void WriteNamedTexture(LegoStorage* p_storage, LegoNamedTexture* p_namedTexture);
void LoadFromNamedTexture(LegoNamedTexture* p_namedTexture); void LoadFromNamedTexture(LegoNamedTexture* p_namedTexture);
void HitActorEvent(); void EmitGameEvent(GameEvent p_event);
// FUNCTION: BETA10 0x100260a0 // FUNCTION: BETA10 0x100260a0
inline void StartIsleAction(IsleScript::Script p_objectId) inline void StartIsleAction(IsleScript::Script p_objectId)

View File

@ -784,9 +784,10 @@ void LoadFromNamedTexture(LegoNamedTexture* p_namedTexture)
} }
} }
void HitActorEvent() void EmitGameEvent(GameEvent p_event)
{ {
SDL_Event event; SDL_Event event;
event.user.type = g_legoSdlEvents.m_hitActor; event.user.type = g_legoSdlEvents.m_gameEvent;
event.user.code = p_event;
SDL_PushEvent(&event); SDL_PushEvent(&event);
} }

View File

@ -235,7 +235,9 @@ MxResult LegoExtraActor::HitActor(LegoPathActor* p_actor, MxBool p_bool)
assert(m_roi); assert(m_roi);
assert(SoundManager()->GetCacheSoundManager()); assert(SoundManager()->GetCacheSoundManager());
SoundManager()->GetCacheSoundManager()->Play("crash5", m_roi->GetName(), FALSE); SoundManager()->GetCacheSoundManager()->Play("crash5", m_roi->GetName(), FALSE);
HitActorEvent(); if (p_actor->GetUserNavFlag()) {
EmitGameEvent(e_hitActor);
}
m_scheduledTime = Timer()->GetTime() + m_disAnim->GetDuration(); m_scheduledTime = Timer()->GetTime() + m_disAnim->GetDuration();
m_prevWorldSpeed = GetWorldSpeed(); m_prevWorldSpeed = GetWorldSpeed();
VTable0xc4(); VTable0xc4();
@ -249,7 +251,9 @@ MxResult LegoExtraActor::HitActor(LegoPathActor* p_actor, MxBool p_bool)
LegoROI* roi = GetROI(); LegoROI* roi = GetROI();
assert(roi); assert(roi);
SoundManager()->GetCacheSoundManager()->Play("crash5", m_roi->GetName(), FALSE); SoundManager()->GetCacheSoundManager()->Play("crash5", m_roi->GetName(), FALSE);
HitActorEvent(); if (p_actor->GetUserNavFlag()) {
EmitGameEvent(e_hitActor);
}
VTable0xc4(); VTable0xc4();
SetActorState(c_two | c_noCollide); SetActorState(c_two | c_noCollide);
Mx3DPointFloat dir = p_actor->GetWorldDirection(); Mx3DPointFloat dir = p_actor->GetWorldDirection();

View File

@ -267,6 +267,8 @@ MxLong CarRace::HandlePathStruct(LegoPathStructNotificationParam& p_param)
FALSE, FALSE,
TRUE TRUE
); );
EmitGameEvent(e_raceFinished);
} }
result = 1; result = 1;

View File

@ -206,6 +206,7 @@ MxLong JetskiRace::HandlePathStruct(LegoPathStructNotificationParam& p_param)
m_destLocation = LegoGameState::e_jetrace2; m_destLocation = LegoGameState::e_jetrace2;
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
EmitGameEvent(e_raceFinished);
} }
result = 1; result = 1;

View File

@ -392,6 +392,7 @@ MxU32 LegoRaceCar::HandleSkeletonKicks(float p_param1)
m_kickStart = p_param1; m_kickStart = p_param1;
SoundManager()->GetCacheSoundManager()->Play(g_soundSkel3, NULL, FALSE); SoundManager()->GetCacheSoundManager()->Play(g_soundSkel3, NULL, FALSE);
EmitGameEvent(e_skeletonKick);
return TRUE; return TRUE;
} }
@ -528,6 +529,9 @@ MxResult LegoRaceCar::HitActor(LegoPathActor* p_actor, MxBool p_bool)
} }
} }
} }
else {
EmitGameEvent(e_hitActor);
}
return SUCCESS; return SUCCESS;
} }
@ -726,6 +730,9 @@ MxResult LegoJetski::HitActor(LegoPathActor* p_actor, MxBool p_bool)
} }
} }
} }
else {
EmitGameEvent(e_hitActor);
}
return SUCCESS; return SUCCESS;
} }

View File

@ -793,6 +793,8 @@ void Act3::GoodEnding(const Matrix4& p_destination)
m_copter->m_unk0x1a8, m_copter->m_unk0x1a8,
m_copter->m_unk0x1f4 m_copter->m_unk0x1f4
); );
EmitGameEvent(e_goodEnding);
} }
// FUNCTION: LEGO1 0x10073500 // FUNCTION: LEGO1 0x10073500
@ -872,6 +874,8 @@ void Act3::BadEnding(const Matrix4& p_destination)
m_copter->m_unk0x1a8, m_copter->m_unk0x1a8,
m_copter->m_unk0x1f4 m_copter->m_unk0x1f4
); );
EmitGameEvent(e_badEnding);
} }
// FUNCTION: LEGO1 0x10073a60 // FUNCTION: LEGO1 0x10073a60

View File

@ -939,6 +939,7 @@ MxResult LegoAct2::BadEnding()
MxTrace("Bad End of Act2\n"); MxTrace("Bad End of Act2\n");
m_unk0x10c4 = 14; m_unk0x10c4 = 14;
EmitGameEvent(e_badEnding);
return SUCCESS; return SUCCESS;
} }

View File

@ -10,7 +10,7 @@
struct LegoSdlEvents { struct LegoSdlEvents {
Uint32 m_windowsMessage; Uint32 m_windowsMessage;
Uint32 m_presenterProgress; Uint32 m_presenterProgress;
Uint32 m_hitActor; Uint32 m_gameEvent;
}; };
LEGO1_EXPORT extern LegoSdlEvents g_legoSdlEvents; LEGO1_EXPORT extern LegoSdlEvents g_legoSdlEvents;

View File

@ -166,7 +166,7 @@ MxResult MxOmni::Create(MxOmniCreateParam& p_param)
Uint32 event = SDL_RegisterEvents(3); Uint32 event = SDL_RegisterEvents(3);
g_legoSdlEvents.m_windowsMessage = event + 0; g_legoSdlEvents.m_windowsMessage = event + 0;
g_legoSdlEvents.m_presenterProgress = event + 1; g_legoSdlEvents.m_presenterProgress = event + 1;
g_legoSdlEvents.m_hitActor = event + 2; g_legoSdlEvents.m_gameEvent = event + 2;
} }
result = SUCCESS; result = SUCCESS;