5. Linux 的力反饋¶
- 作者:
Johann Deneux <johann.deneux@gmail.com> 於 2001/04/22。
- 更新:
Anssi Hannula <anssi.hannula@gmail.com> 於 2006/04/09。
您可以重新分發此檔案。請記住同時包含 shape.svg 和 interactive.svg。
5.1. 介紹¶
本文件描述瞭如何在 Linux 下使用力反饋裝置。 目標不是像它們是簡單的只輸入裝置一樣支援這些裝置(就像已經存在的情況一樣),而是真正實現力效果的渲染。 本文件僅描述 Linux 輸入介面的力反饋部分。 在進一步閱讀本文件之前,請閱讀 介紹 和 介紹。
5.2. 使用者須知¶
要啟用力反饋,您必須
核心配置了 evdev 並且驅動程式支援您的裝置。
確保 evdev 模組已載入,並且 /dev/input/event* 裝置檔案已建立。
在您開始之前,讓我警告您,某些裝置在初始化階段會劇烈震動。 例如,我的 “AVB Top Shot Pegasus” 就會發生這種情況。 要停止這種煩人的行為,請將您的操縱桿移動到其極限位置。 無論如何,您應該用手扶住您的裝置,以避免在出現問題時將其損壞。
如果您有序列 iforce 裝置,則需要啟動 inputattach。 有關詳細資訊,請參見 介紹。
5.2.1. 它能工作嗎?¶
有一個名為 fftest 的實用程式,可用於測試驅動程式
% fftest /dev/input/eventXX
5.3. 開發者須知¶
所有互動均使用 event API 完成。 也就是說,您可以在 /dev/input/eventXX 上使用 ioctl() 和 write()。 此資訊可能會更改。
5.3.1. 查詢裝置功能¶
#include <linux/input.h>
#include <sys/ioctl.h>
#define BITS_TO_LONGS(x) \
(((x) + 8 * sizeof (unsigned long) - 1) / (8 * sizeof (unsigned long)))
unsigned long features[BITS_TO_LONGS(FF_CNT)];
int ioctl(int file_descriptor, int request, unsigned long *features);
“request” 必須是 EVIOCGBIT(EV_FF, 功能陣列的大小,以位元組為單位)
返回裝置支援的功能。 功能是一個位域,包含以下位
FF_CONSTANT 可以渲染恆定力效果
FF_PERIODIC 可以渲染具有以下波形的週期性效果
FF_SQUARE 方波
FF_TRIANGLE 三角波
FF_SINE 正弦波
FF_SAW_UP 鋸齒波向上
FF_SAW_DOWN 鋸齒波向下
FF_CUSTOM 自定義波形
FF_RAMP 可以渲染斜坡效果
FF_SPRING 可以模擬彈簧的存在
FF_FRICTION 可以模擬摩擦
FF_DAMPER 可以模擬阻尼效果
FF_RUMBLE 隆隆聲效果
FF_INERTIA 可以模擬慣性
FF_GAIN 增益可調
FF_AUTOCENTER 自動居中可調
注意
在大多數情況下,您應該使用 FF_PERIODIC 代替 FF_RUMBLE。 所有支援 FF_RUMBLE 的裝置都支援 FF_PERIODIC(方波、三角波、正弦波),反之亦然。
由於目前沒有驅動程式支援,FF_CUSTOM 的確切語法尚未定義。
int ioctl(int fd, EVIOCGEFFECTS, int *n);
返回裝置可以儲存在其記憶體中的效果數量。
5.3.2. 將效果上傳到裝置¶
#include <linux/input.h>
#include <sys/ioctl.h>
int ioctl(int file_descriptor, int request, struct ff_effect *effect);
“request” 必須是 EVIOCSFF。
“effect” 指向描述要上傳的效果的結構。 該效果已上傳,但未播放。 effect 的內容可能會被修改。 特別是,它的欄位 “id” 被設定為驅動程式分配的唯一 id。 執行某些操作(刪除效果、控制播放)需要此資料。 使用者必須將 “id” 欄位設定為 -1,以告知驅動程式分配新的效果。
效果是檔案描述符特定的。
有關 ff_effect 結構的描述,請參見 <uapi/linux/input.h>。 您還應該在 shape.svg 和 interactive.svg 檔案中找到一些草圖的幫助。
形狀¶
互動¶
5.3.3. 從裝置中刪除效果¶
int ioctl(int fd, EVIOCRMFF, effect.id);
這為裝置記憶體中的新效果騰出了空間。 請注意,如果效果正在播放,這也會停止效果。
5.3.4. 控制效果的播放¶
播放控制透過 write() 完成。 下面是一個示例
#include <linux/input.h>
#include <unistd.h>
struct input_event play;
struct input_event stop;
struct ff_effect effect;
int fd;
...
fd = open("/dev/input/eventXX", O_RDWR);
...
/* Play three times */
play.type = EV_FF;
play.code = effect.id;
play.value = 3;
write(fd, (const void*) &play, sizeof(play));
...
/* Stop an effect */
stop.type = EV_FF;
stop.code = effect.id;
stop.value = 0;
write(fd, (const void*) &stop, sizeof(stop));
5.3.5. 設定增益¶
並非所有裝置都具有相同的強度。 因此,使用者應根據他們希望效果有多強來設定增益因子。 此設定在對驅動程式的訪問中是持久的。
/* Set the gain of the device
int gain; /* between 0 and 100 */
struct input_event ie; /* structure used to communicate with the driver */
ie.type = EV_FF;
ie.code = FF_GAIN;
ie.value = 0xFFFFUL * gain / 100;
if (write(fd, &ie, sizeof(ie)) == -1)
perror("set gain");
5.3.6. 啟用/停用自動居中¶
在我看來,自動居中功能非常干擾效果的渲染,我認為它應該是一種效果,其計算取決於遊戲型別。 但是,如果您願意,可以啟用它。
int autocenter; /* between 0 and 100 */
struct input_event ie;
ie.type = EV_FF;
ie.code = FF_AUTOCENTER;
ie.value = 0xFFFFUL * autocenter / 100;
if (write(fd, &ie, sizeof(ie)) == -1)
perror("set auto-center");
值為 0 表示 “無自動居中”。
5.3.7. 動態更新效果¶
像要上傳新效果一樣進行操作,只是不是將 id 欄位設定為 -1,而是將其設定為想要的效果 id。 通常,效果不會停止並重新啟動。 但是,根據裝置型別,並非所有引數都可以動態更新。 例如,使用 iforce 裝置無法更新效果的方向。 在這種情況下,驅動程式會停止效果,上傳它,然後重新啟動它。
因此,建議僅當可以重新啟動重播計數為 1 的效果時,才在效果播放時動態更改方向。
5.3.8. 有關效果狀態的資訊¶
每次效果的狀態發生更改時,都會發送一個事件。 事件欄位的值和含義如下
struct input_event {
/* When the status of the effect changed */
struct timeval time;
/* Set to EV_FF_STATUS */
unsigned short type;
/* Contains the id of the effect */
unsigned short code;
/* Indicates the status */
unsigned int value;
};
FF_STATUS_STOPPED The effect stopped playing
FF_STATUS_PLAYING The effect started to play
注意
只有 iforce 驅動程式支援狀態反饋。 如果您有充分的理由使用此功能,請聯絡 linux-joystick@atrey.karlin.mff.cuni.cz 或 anssi.hannula@gmail.com,以便可以將其新增到其餘驅動程式中。