If you want a practical example, I used FF in my port of Doom for the DC. The main code routines look like this
Code: Select all
static int ff_enable = 1;
static int ff_timeout = 0;
static int ff_frequency = 0;
static int ff_intensity = 0;
static int ff_select = 0x10;
...
// Force Feedback
void I_Tactile (int freq, int intensity, int select)
{
ff_frequency = freq;
ff_intensity = intensity;
ff_select = select;
ff_timeout = I_GetTime() + 35;
// FF will be handled at the same time as the events
}
...
static void dc_handle_ff(void)
{
maple_device_t * jump;
if (!ff_enable)
return; // early out
jump = maple_enum_type(0, MAPLE_FUNC_PURUPURU);
if (ff_timeout && jump)
{
if (I_GetTime() >= ff_timeout)
{
static purupuru_effect_t effect;
effect.duration = 0x00;
effect.effect2 = 0x00;
effect.effect1 = 0x00;
effect.special = PURUPURU_SPECIAL_MOTOR1;
purupuru_rumble(jump, &effect);
ff_timeout = 0;
ff_intensity = 0;
}
}
if (ff_intensity && jump)
{
static purupuru_effect_t effect;
effect.duration = 0x11;
effect.effect2 = ff_frequency;
effect.effect1 = PURUPURU_EFFECT1_INTENSITY(ff_intensity);
effect.special = PURUPURU_SPECIAL_MOTOR1 | ff_select;
purupuru_rumble(jump, &effect);
ff_intensity = 0;
}
}
Things that make it go thump call I_Tactil(). In the main loop, as part of checking the controllers, dc_handle_ff() is called. I_GetTime() returns 1/35th sec ticks, so the timeout on the ff is one second. Calls to I_Tactile() look like this
Code: Select all
player->damagecount += damage; // add damage after armor / invuln
if (player->damagecount > 100)
player->damagecount = 100; // teleport stomp does 10k points...
temp = damage < 100 ? damage : 100;
if (player == &players[consoleplayer])
I_Tactile (20, 1+(temp>>4), 0);
Frequency is always 20, and intensity varies between 1 and 7. Select is always 0 since Doom just uses the first controller. This seemed to work pretty good for most folks... never got any complaints about it.