Unverified Commit a44247cb authored by Libretro-Admin's avatar Libretro-Admin Committed by GitHub
Browse files

Merge pull request #94 from jdgleaver/rumble-support

Improved rumble support
parents d2c077f0 f6d01fd3
...@@ -84,7 +84,6 @@ unsigned device_type = 0; ...@@ -84,7 +84,6 @@ unsigned device_type = 0;
unsigned MEMSIZE_MB; unsigned MEMSIZE_MB;
static struct retro_rumble_interface rumble;
static bool libretro_supports_bitmasks = false; static bool libretro_supports_bitmasks = false;
#if defined(HW_DOL) #if defined(HW_DOL)
...@@ -218,7 +217,9 @@ gp_layout_t classic_alt = { ...@@ -218,7 +217,9 @@ gp_layout_t classic_alt = {
gp_layout_t *gp_layoutp = NULL; gp_layout_t *gp_layoutp = NULL;
static float framerate = 60.0f; static float framerate = 60.0f;
static float frametime_usec = 1000.0f / 60.0f;
static bool initial_resolution_set = false; static bool initial_resolution_set = false;
static int invert_y_axis = 1; static int invert_y_axis = 1;
...@@ -247,6 +248,61 @@ static void extract_basename(char *buf, const char *path, size_t size) ...@@ -247,6 +248,61 @@ static void extract_basename(char *buf, const char *path, size_t size)
*ext = '\0'; *ext = '\0';
} }
static struct retro_rumble_interface rumble = {0};
static bool rumble_enabled = false;
static uint16_t rumble_damage_strength = 0;
static uint16_t rumble_touch_strength = 0;
static int16_t rumble_touch_counter = -1;
void retro_set_rumble_damage(int damage)
{
/* Rumble scales linearly from 0xFFF to 0xFFFF
* as damage increases from 1 to 50 */
int capped_damage = (damage < 50) ? damage : 50;
uint16_t strength = 0;
if (!rumble.set_rumble_state ||
(!rumble_enabled && (capped_damage > 0)))
return;
if (capped_damage > 0)
strength = 0xFFF + (capped_damage * 0x4CC);
/* Return early if strength matches last
* set value */
if (strength == rumble_damage_strength)
return;
rumble.set_rumble_state(0, RETRO_RUMBLE_STRONG, strength);
rumble_damage_strength = strength;
}
void retro_set_rumble_touch(unsigned intensity, float duration)
{
/* Rumble scales linearly from 0xFF to 0xFFFF
* as intensity increases from 1 to 20 */
unsigned capped_intensity = (intensity < 20) ? intensity : 20;
uint16_t strength = 0;
if (!rumble.set_rumble_state ||
(!rumble_enabled && (capped_intensity > 0)))
return;
if ((capped_intensity > 0) && (duration > 0.0f))
{
strength = 0xFF + (capped_intensity * 0xCC0);
rumble_touch_counter = (int16_t)((duration / frametime_usec) + 1.0f);
}
/* Return early if strength matches last
* set value */
if (strength == rumble_touch_strength)
return;
rumble.set_rumble_state(0, RETRO_RUMBLE_WEAK, strength);
rumble_touch_strength = strength;
}
// ======================================================================= // =======================================================================
// General routines // General routines
// ======================================================================= // =======================================================================
...@@ -438,6 +494,15 @@ void retro_deinit(void) ...@@ -438,6 +494,15 @@ void retro_deinit(void)
free(heap); free(heap);
libretro_supports_bitmasks = false; libretro_supports_bitmasks = false;
retro_set_rumble_damage(0);
retro_set_rumble_touch(0, 0.0f);
memset(&rumble, 0, sizeof(struct retro_rumble_interface));
rumble_enabled = false;
rumble_damage_strength = 0;
rumble_touch_strength = 0;
rumble_touch_counter = -1;
} }
unsigned retro_api_version(void) unsigned retro_api_version(void)
...@@ -697,27 +762,8 @@ void Sys_Sleep(void) ...@@ -697,27 +762,8 @@ void Sys_Sleep(void)
const char *argv[MAX_NUM_ARGVS]; const char *argv[MAX_NUM_ARGVS];
static const char *empty_string = ""; static const char *empty_string = "";
void retro_set_rumble_strong(void)
{
uint16_t strength_strong = 0xffff;
if (!rumble.set_rumble_state)
return;
rumble.set_rumble_state(0, RETRO_RUMBLE_STRONG, strength_strong);
}
void retro_unset_rumble_strong(void)
{
if (!rumble.set_rumble_state)
return;
rumble.set_rumble_state(0, RETRO_RUMBLE_STRONG, 0);
}
extern int coloredlights; extern int coloredlights;
bool state_rumble;
static void update_variables(bool startup) static void update_variables(bool startup)
{ {
struct retro_variable var; struct retro_variable var;
...@@ -745,6 +791,8 @@ static void update_variables(bool startup) ...@@ -745,6 +791,8 @@ static void update_variables(bool startup)
else else
framerate = 60.0f; framerate = 60.0f;
frametime_usec = 1000.0f / framerate;
/* Note: The audio handling code of the game engine /* Note: The audio handling code of the game engine
* completely falls apart below 50 FPS. To go any * completely falls apart below 50 FPS. To go any
* lower than this, we have to manipulate the actual * lower than this, we have to manipulate the actual
...@@ -804,9 +852,15 @@ static void update_variables(bool startup) ...@@ -804,9 +852,15 @@ static void update_variables(bool startup)
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
{ {
if (strcmp(var.value, "disabled") == 0) if (strcmp(var.value, "disabled") == 0)
state_rumble = false; rumble_enabled = false;
else else
state_rumble = true; rumble_enabled = true;
}
if (!rumble_enabled)
{
retro_set_rumble_damage(0);
retro_set_rumble_touch(0, 0.0f);
} }
var.key = "tyrquake_invert_y_axis"; var.key = "tyrquake_invert_y_axis";
...@@ -871,12 +925,17 @@ void retro_run(void) ...@@ -871,12 +925,17 @@ void retro_run(void)
update_env_variables(); update_env_variables();
has_set_username = true; has_set_username = true;
} }
if (!state_rumble)
retro_unset_rumble_strong();
Host_Frame(1.0 / framerate); Host_Frame(1.0 / framerate);
if (rumble_touch_counter > -1)
{
rumble_touch_counter--;
if (rumble_touch_counter == 0)
retro_set_rumble_touch(0, 0.0f);
}
if (shutdown_core) if (shutdown_core)
return; return;
......
...@@ -73,6 +73,11 @@ float v_oldz, v_stepz; ...@@ -73,6 +73,11 @@ float v_oldz, v_stepz;
float v_steptime; float v_steptime;
/* EOF - Framerate-independent stair-step smoothing */ /* EOF - Framerate-independent stair-step smoothing */
static int old_health = 100;
static float old_velocity_z = 0.0;
extern void retro_set_rumble_damage(int damage);
extern void retro_set_rumble_touch(unsigned intensity, float duration);
/* /*
=============== ===============
V_CalcRoll V_CalcRoll
...@@ -149,6 +154,14 @@ float V_CalcBob(void) ...@@ -149,6 +154,14 @@ float V_CalcBob(void)
else if (bob < -7) else if (bob < -7)
bob = -7; bob = -7;
/* Check for a sudden stop in downwards motion
* > Means we've just 'touched' the ground, so
* trigger a weak touch-type rumble */
if ((old_velocity_z < 0.0) &&
(cl.velocity[2] == 0.0))
retro_set_rumble_touch(6, 120.0f);
old_velocity_z = cl.velocity[2];
return bob; return bob;
} }
...@@ -407,6 +420,10 @@ void V_BonusFlash_f(void) ...@@ -407,6 +420,10 @@ void V_BonusFlash_f(void)
cl.cshifts[CSHIFT_BONUS].initialpct = 50; cl.cshifts[CSHIFT_BONUS].initialpct = 50;
cl.cshifts[CSHIFT_BONUS].time = cl.time; cl.cshifts[CSHIFT_BONUS].time = cl.time;
/* EOF - Frame-rate independent damage and bonus shifts */ /* EOF - Frame-rate independent damage and bonus shifts */
/* We have touched an item - trigger a moderate
* touch-type rumble */
retro_set_rumble_touch(9, 140.0f);
} }
/* /*
...@@ -677,10 +694,6 @@ V_CalcViewRoll ...@@ -677,10 +694,6 @@ V_CalcViewRoll
Roll is induced by movement and damage Roll is induced by movement and damage
============== ==============
*/ */
static int old_health = 100;
void retro_set_rumble_strong(void);
void retro_unset_rumble_strong(void);
void V_CalcViewRoll(void) void V_CalcViewRoll(void)
{ {
float side = V_CalcRoll(cl_entities[cl.viewentity].angles, cl.velocity); float side = V_CalcRoll(cl_entities[cl.viewentity].angles, cl.velocity);
...@@ -695,12 +708,12 @@ void V_CalcViewRoll(void) ...@@ -695,12 +708,12 @@ void V_CalcViewRoll(void)
v_dmg_time -= host_frametime; v_dmg_time -= host_frametime;
if (old_health > cl.stats[STAT_HEALTH]) if (old_health > cl.stats[STAT_HEALTH])
retro_set_rumble_strong(); retro_set_rumble_damage(old_health - cl.stats[STAT_HEALTH]);
old_health = cl.stats[STAT_HEALTH]; old_health = cl.stats[STAT_HEALTH];
} }
else else
retro_unset_rumble_strong(); retro_set_rumble_damage(0);
if (cl.stats[STAT_HEALTH] <= 0) { if (cl.stats[STAT_HEALTH] <= 0) {
r_refdef.viewangles[ROLL] = 80; // dead view angle r_refdef.viewangles[ROLL] = 80; // dead view angle
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment