Кнопки джойстика

Есть джойстики с множеством кнопок, например, Trustmaster. Несмотря ни на что, его работа ничем не отличается от других джойстиков, а состояние лишних кнопок можно прочитать через другие порты ввода/вывода. Эти порты обычно указываются производителем в соответствующей документации. Обычно, порт 201h — это то окно, через которое можно общаться с джойстиком. Как показано на рисунке 3.2, этот порт связан и с джойстиком А, и с джойстиком В.
Мы узнаем назначение битов 0-3 чуть позже — в разделе «Чтение позиции джойстика». Биты 4-7 предназначены для чтения кнопок джойстика. Когда одна из кнопок нажата, то соответствующий бит порта 201h изменяется. Есть только одна маленькая деталь: значения битов всегда инвертированы. Это значит, что если вы, например, жмете кнопку 1 на джойстике А, то бит 0 изменит значение с \ на 0. Но в общем, это не особенно принципиально.
Листинг 3.1 содержит программный код чтения кнопки.
Листинг 3.1. Чтение кнопок джойстика.
#define JOYPORT 0х201 // порт джойстика = 201h
#define BUTTON_1_A 0х10 // джойстик А, кнопка 1
#define BUTTON_1_B 0х20 // джойстик А, кнопка 2
#define BUTTON_2_A 0х40 // джойстик В, кнопка 1
#define BUTTON_2_B 0х80 // джойстик В, кнопка 2
#define JOYSTICK_1_X 0х01 // джойстик А, ось ,Х
#define JOYSTICK_1_Y 0х02 // джойстик А, ось Y
#define JOYSTICK_2_X 0х04 // джойстик В, ось Х
#define JOYSTICK_2_Y 0х08 // джойстик В, ось Y
#define JOY_1_CAL 1 // эта команда калибрует джойстик А
#define JOY_2_CAL 2 // эта команда калибрует джойстик В
unsigned char Buttons(unsigned char button)
(
// эта функция читает статус кнопок джойстика
// сбрасываем содержимое порта 201h
outp (JOYPORT, 0);
// инвертируем прочитанное из порта значение и комбинируем
// его
с маской
return (~inp( JOYPORT) & button) ;
}
unsigned char Buttons_Bios (unsigned char button)
{ // чтение кнопок через обращение к BIOS
union _REGS inregs, outregs;
inregs.h.ah == 0х84; // функция джойстика 84h
inregs.x.dx = 0х00; // подфункция 0h - чтение кнопок
// вызов BIOS
_int86 (0х15, &inregs, &outr.egs);
// инвертируем полученное значение и комбинируем его с маской
return(~outregs.h.al) & button);
}
Теперь посмотрим на детали Листинга 3.1.
§ Функция Buttons() и Buttons_Bios() возвращают одинаковый результат. Buttons() посылает 0 в порт джойстика (это делается для того, чтобы инициировать порт) и затем читает данные;
§ Как только данные получены, мы маскируем младшие четыре бита и инвертируем четыре старших;
§ Этот листинг включает также определение констант (#define), что делает интерфейс более удобным;
§ Buttons_Bios() для чтения джойстика использует BIOS. Как только выполняется вызов, результат помещается в регистр AL. В принципе, для таких простых вещей, как кнопки, я использую прямой доступ к портам. Я уже говорил, что использование функций BIOS более медлительно. Правда, по отношению к джойстику это, может быть, и не самый плохой подход. Если вы хотите читать с помощью BIOS - читайте.