Skip to content

Commit a91c825

Browse files
committed
feat(doom): Add haptic support to doom
* Update doom to have callbacks for when the player is damaged and when they fire a weapon * Update doom implementation to trigger different haptic effects depending on the weapon fired and the amount of damage taken Haptics are awesome, and with doom we have the actual source code so we can do some fun stuff :) Build and run `main` on Box-Emu v0 which has haptics and ensure it feels good.
1 parent ee3115e commit a91c825

File tree

6 files changed

+73
-1
lines changed

6 files changed

+73
-1
lines changed

components/doom/prboom/p_inter.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -808,9 +808,10 @@ void P_DamageMobj(mobj_t *target,mobj_t *inflictor, mobj_t *source, int damage)
808808
(player->cheats&CF_GODMODE || player->powers[pw_invulnerability]))
809809
return;
810810

811+
int saved = 0;
811812
if (player->armortype)
812813
{
813-
int saved = player->armortype == 1 ? damage/3 : damage/2;
814+
saved = player->armortype == 1 ? damage/3 : damage/2;
814815
if (player->armorpoints <= saved)
815816
{
816817
// armor is used up
@@ -825,6 +826,14 @@ void P_DamageMobj(mobj_t *target,mobj_t *inflictor, mobj_t *source, int damage)
825826
if (player->health < 0)
826827
player->health = 0;
827828

829+
// [WILLIAM]: trigger haptic effect for the player getting injured based
830+
// on the amount of damage received (armor/base). Use damage
831+
// (hits to health) and saved (hits to armor) to determine.
832+
//
833+
// printf("Player %d took %d damage (%d saved)\n",
834+
// player - players, damage, saved);
835+
R_PlayerHurt(player, damage, saved);
836+
828837
player->attacker = source;
829838
player->damagecount += damage; // add damage after armor / invuln
830839

components/doom/prboom/p_pspr.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,12 @@ static void P_FireWeapon(player_t *player)
282282
newstate = weaponinfo[player->readyweapon].atkstate;
283283
P_SetPsprite(player, ps_weapon, newstate);
284284
P_NoiseAlert(player->mo, player->mo);
285+
// [WILLIAM]: trigger haptic effect for firing the weapon based on the
286+
// weaponinfo[player->readyweapon]. player->readyweapon is the
287+
// weapon enum (e.g. 0 is fist, 1 is gun, 2 is shotgun, etc.).
288+
//
289+
// printf("P_FireWeapon: %d\n", player->readyweapon);
290+
R_PlayerFire(player);
285291
}
286292

287293
//

components/doom/prboom/r_main.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,4 +117,21 @@ void R_Init(void); // Called by startup code.
117117
void R_SetViewSize(int blocks); // Called by M_Responder.
118118
void R_ExecuteSetViewSize(void); // cph - called by D_Display to complete a view resize
119119

120+
//
121+
// HAPTICS - functions to call for various events that should trigger haptics
122+
//
123+
124+
// called when the player fires a weapon, can get player->readyweapon to know
125+
// which weapon to use for the haptic feedback
126+
void R_PlayerFire(player_t *player);
127+
128+
// called when the player picks up a weapon, can get player->readyweapon to know
129+
// which weapon
130+
void R_PlayerPickupWeapon(player_t *player);
131+
132+
// called when the player is hurt. damage is the amount of health lost, saved is
133+
// the amount of health saved by armor (which is the same as the amount of armor
134+
// lost)
135+
void R_PlayerHurt(player_t *player, int damage, int saved);
136+
120137
#endif

components/doom/src/doom.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,41 @@ extern "C" {
9696
{(int)GamepadState::Button::Y, &key_weapontoggle},
9797
};
9898

99+
void R_PlayerFire(player_t *player) {
100+
static auto& box = BoxEmu::get();
101+
int haptic_effect_index = 0;
102+
int weapon_fired = player->readyweapon;
103+
if (weapon_fired == wp_fist) {
104+
haptic_effect_index = 3;
105+
} else if (weapon_fired == wp_pistol) {
106+
haptic_effect_index = 2;
107+
} else if (weapon_fired == wp_shotgun) {
108+
haptic_effect_index = 10;
109+
} else if (weapon_fired == wp_chaingun) {
110+
haptic_effect_index = 12;
111+
} else if (weapon_fired == wp_missile) {
112+
haptic_effect_index = 27;
113+
} else if (weapon_fired == wp_plasma) {
114+
haptic_effect_index = 14;
115+
} else if (weapon_fired == wp_bfg) {
116+
haptic_effect_index = 47;
117+
} else if (weapon_fired == wp_supershotgun) {
118+
haptic_effect_index = 52;
119+
}
120+
box.play_haptic_effect(haptic_effect_index);
121+
}
122+
123+
void R_PlayerHurt(player_t *player, int damage, int saved) {
124+
static auto& box = BoxEmu::get();
125+
int haptic_effect_index = 0;
126+
if (damage > 5) {
127+
haptic_effect_index = saved > 0 ? 70 : 75;
128+
} else if (damage > 0) {
129+
haptic_effect_index = saved > 0 ? 78 : 64;
130+
}
131+
box.play_haptic_effect(haptic_effect_index);
132+
}
133+
99134
void I_StartFrame(void) {
100135
}
101136

components/gui/include/gui.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ class Gui {
103103
paused_ = false;
104104
}
105105

106+
int get_haptic_waveform() const {
107+
return haptic_waveform_;
108+
}
109+
106110
void set_haptic_waveform(int new_waveform) {
107111
if (new_waveform > 123) {
108112
new_waveform = 1;

main/main.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ extern "C" void app_main(void) {
8888
}
8989

9090
// have broken out of the loop, let the user know we're processing...
91+
emu.set_haptic_effect(gui.get_haptic_waveform());
9192
emu.play_haptic_effect();
9293

9394
gui.pause();

0 commit comments

Comments
 (0)