1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-01 19:00:34 +02:00

#15 Linux vibration improvements; #11 turn off gamepad vibration for inventory and loading screen

This commit is contained in:
XProger
2018-03-06 03:50:23 +03:00
parent 9c0573116c
commit 6fb0e2781e
8 changed files with 62 additions and 48 deletions

9
bin/.gitignore vendored Normal file
View File

@@ -0,0 +1,9 @@
*.PHD
*.ogg
*.PSX
*.PNG
*.PCX
*.RAW
*.zip
*.txt

View File

@@ -345,7 +345,7 @@ struct Camera : ICamera {
virtual void update() { virtual void update() {
if (shake > 0.0f) { if (shake > 0.0f) {
shake = max(0.0f, shake - Core::deltaTime); shake = max(0.0f, shake - Core::deltaTime);
Input::setJoyVibrate(cameraIndex, clamp(shake, 0.0f, 1.0f), 0); Input::setJoyVibration(cameraIndex, clamp(shake, 0.0f, 1.0f), 0);
} }
if (mode == MODE_CUTSCENE) { if (mode == MODE_CUTSCENE) {
@@ -562,4 +562,4 @@ struct Camera : ICamera {
} }
}; };
#endif #endif

View File

@@ -14,6 +14,7 @@ namespace Game {
Stream *nextLevel; Stream *nextLevel;
void startLevel(Stream *lvl) { void startLevel(Stream *lvl) {
Input::stopJoyVibration();
delete level; delete level;
level = new Level(*lvl); level = new Level(*lvl);
UI::game = level; UI::game = level;
@@ -179,4 +180,4 @@ namespace Game {
} }
} }
#endif #endif

View File

@@ -117,11 +117,16 @@ namespace Input {
setJoyDown(index, key, pos.x > 0.0f); // gamepad LT, RT auto-down state setJoyDown(index, key, pos.x > 0.0f); // gamepad LT, RT auto-down state
} }
void setJoyVibrate(int playerIndex, float L, float R) { void setJoyVibration(int playerIndex, float L, float R) {
if (!Core::settings.controls[playerIndex].vibration) if (!Core::settings.controls[playerIndex].vibration)
return; return;
osJoyVibrate(Core::settings.controls[playerIndex].joyIndex, L, R); osJoyVibrate(Core::settings.controls[playerIndex].joyIndex, L, R);
} }
void stopJoyVibration() {
osJoyVibrate(Core::settings.controls[0].joyIndex, 0.0f, 0.0f);
osJoyVibrate(Core::settings.controls[1].joyIndex, 0.0f, 0.0f);
}
InputKey getTouch(int id) { InputKey getTouch(int id) {
for (int i = 0; i < COUNT(touch); i++) for (int i = 0; i < COUNT(touch); i++)
@@ -284,4 +289,4 @@ namespace Input {
} }
} }
#endif #endif

View File

@@ -647,6 +647,8 @@ struct Inventory {
} }
bool toggle(int playerIndex = 0, Page curPage = PAGE_INVENTORY, TR::Entity::Type type = TR::Entity::LARA) { bool toggle(int playerIndex = 0, Page curPage = PAGE_INVENTORY, TR::Entity::Type type = TR::Entity::LARA) {
Input::stopJoyVibration();
this->playerIndex = playerIndex; this->playerIndex = playerIndex;
titleTimer = 0.0f; titleTimer = 0.0f;

View File

@@ -2733,9 +2733,9 @@ struct Lara : Character {
if (hitTimer > 0.0f) { if (hitTimer > 0.0f) {
hitTimer -= Core::deltaTime; hitTimer -= Core::deltaTime;
if (hitTimer > 0.0f) if (hitTimer > 0.0f)
Input::setJoyVibrate(camera->cameraIndex, 0.5f, 0.5f); Input::setJoyVibration(camera->cameraIndex, 0.5f, 0.5f);
else else
Input::setJoyVibrate(camera->cameraIndex, 0, 0); Input::setJoyVibration(camera->cameraIndex, 0, 0);
} }
if (level->isCutsceneLevel()) if (level->isCutsceneLevel())

View File

@@ -139,7 +139,6 @@ void* sndFill(void *arg) {
} }
void sndInit() { void sndInit() {
return;
static const pa_sample_spec spec = { static const pa_sample_spec spec = {
.format = PA_SAMPLE_S16LE, .format = PA_SAMPLE_S16LE,
.rate = 44100, .rate = 44100,
@@ -198,15 +197,18 @@ InputKey mouseToInputKey(int btn) {
return ikNone; return ikNone;
} }
#define JOY_DEAD_ZONE_STICK 8192
#define JOY_DEAD_ZONE_TRIGGER 8192
#define JOY_MIN_UPDATE_FX_TIME 50.0f
struct JoyDevice { struct JoyDevice {
int fd; int fd; // device file descriptor
int fe; int fe; // event file descriptor
vec2 L, R; vec2 L, R; // left/right stick axes values
ff_effect fx; float vL, vR; // current value for left/right motor vibration
char event[128]; float oL, oR; // last applied value
int time; int time; // time when we can send effect update
ff_effect fx; // effect structure
float vL, vR, oL, oR;
} joyDevice[INPUT_JOY_COUNT]; } joyDevice[INPUT_JOY_COUNT];
bool osJoyReady(int index) { bool osJoyReady(int index) {
@@ -219,10 +221,6 @@ void osJoyVibrate(int index, float L, float R) {
joyDevice[index].vR = R; joyDevice[index].vR = R;
} }
#define JOY_DEAD_ZONE_STICK 8192
#define JOY_DEAD_ZONE_TRIGGER 8192
#define TEST_BIT(arr, bit) ((arr[bit / 32] >> (bit % 32)) & 1)
void joyInit() { void joyInit() {
LOG("init gamepads:\n"); LOG("init gamepads:\n");
char name[128]; char name[128];
@@ -261,8 +259,8 @@ void joyInit() {
DIR *dir = opendir(name); DIR *dir = opendir(name);
if (!dir) continue; if (!dir) continue;
closedir(dir); closedir(dir);
sprintf(joy.event, "/dev/input/event%d", j); sprintf(name, "/dev/input/event%d", j);
joy.fe = open(joy.event, O_RDWR); joy.fe = open(name, O_RDWR);
break; break;
} }
@@ -273,11 +271,16 @@ void joyInit() {
} }
if (joy.fe > -1) { if (joy.fe > -1) {
LOG(" vibration feature\n"); int n_effects;
joy.fx.id = -1; if (ioctl(joy.fe, EVIOCGEFFECTS, &n_effects) == -1) {
joy.time = osGetTime(); perror("Ioctl query");
}
LOG(" vibration feature %d\n", n_effects);
joy.fx.id = -1;
joy.fx.type = FF_RUMBLE;
joy.fx.replay.delay = 0;
joy.vL = joy.oL = joy.vR = joy.oR = 0.0f; joy.vL = joy.oL = joy.vR = joy.oR = 0.0f;
close(joy.fe); joy.time = osGetTime();
} }
} }
} }
@@ -316,40 +319,33 @@ void joyRumble(JoyDevice &joy) {
if (osGetTime() < joy.time) if (osGetTime() < joy.time)
return; return;
close(joy.fe);
joy.fe = open(joy.event, O_RDWR);
if (joy.fe == -1)
LOG("can't open event\n");
input_event event; input_event event;
event.type = EV_FF; event.type = EV_FF;
if (joy.oL != 0.0f || joy.oR != 0.0f) {
event.value = 0;
event.code = joy.fx.id;
if (write(joy.fe, &event, sizeof(event)) == -1)
LOG("! joy stop fx\n");
}
if (joy.vL != 0.0f || joy.vR != 0.0f) { if (joy.vL != 0.0f || joy.vR != 0.0f) {
joy.fx.type = FF_RUMBLE; // update effect
joy.fx.u.rumble.strong_magnitude = int(joy.vL * 65535); joy.fx.u.rumble.strong_magnitude = int(joy.vL * 65535);
joy.fx.u.rumble.weak_magnitude = int(joy.vR * 65535); joy.fx.u.rumble.weak_magnitude = int(joy.vR * 65535);
joy.fx.replay.length = int(max(50.0f, 1000.0f / Core::stats.fps)); joy.fx.replay.length = int(max(JOY_MIN_UPDATE_FX_TIME, 1000.0f / Core::stats.fps));
joy.fx.replay.delay = 0;
joy.fx.id = -1;
if (ioctl(joy.fe, EVIOCSFF, &joy.fx) == -1) { if (ioctl(joy.fe, EVIOCSFF, &joy.fx) == -1) {
LOG("! joy drv send fx\n"); LOG("! joy update fx\n");
return;
} }
// play effect
event.value = 1; event.value = 1;
event.code = joy.fx.id; event.code = joy.fx.id;
if (write(joy.fe, &event, sizeof(event)) == -1) if (write(joy.fe, &event, sizeof(event)) == -1)
LOG("! joy play fx\n"); LOG("! joy play fx\n");
} } else
if (joy.oL != 0.0f || joy.oR != 0.0f) {
// stop effect
event.value = 0;
event.code = joy.fx.id;
if (write(joy.fe, &event, sizeof(event)) == -1)
LOG("! joy stop fx\n");
}
joy.oL = joy.vL; joy.oL = joy.vL;
joy.oR = joy.vR; joy.oR = joy.vR;

View File

@@ -73,10 +73,11 @@ typedef unsigned char uint8;
typedef unsigned short uint16; typedef unsigned short uint16;
typedef unsigned int uint32; typedef unsigned int uint32;
#define FOURCC(str) uint32(((uint8*)(str))[0] | (((uint8*)(str))[1] << 8) | (((uint8*)(str))[2] << 16) | (((uint8*)(str))[3] << 24) ) #define FOURCC(str) uint32(((uint8*)(str))[0] | (((uint8*)(str))[1] << 8) | (((uint8*)(str))[2] << 16) | (((uint8*)(str))[3] << 24) )
#define COUNT(arr) (sizeof(arr) / sizeof(arr[0])) #define COUNT(arr) (sizeof(arr) / sizeof(arr[0]))
#define OFFSETOF(T, E) ((size_t)&(((T*)0)->E)) #define OFFSETOF(T, E) ((size_t)&(((T*)0)->E))
#define TEST_BIT(arr, bit) ((arr[bit / 32] >> (bit % 32)) & 1)
template <typename T> template <typename T>
inline const T& min(const T &a, const T &b) { inline const T& min(const T &a, const T &b) {