Калибровка джойстика
Теперь разберемся с калибровкой джойстика. Как я уже говорил ранее, результат, который мы получим от чтения джойстика в цикле, будет разным на разных ПК. На одних компьютерах значения по оси Х окажется в пределах от 0 до 255, на других - от 0 до 10000.
Таким образом, нам надо нормализовать эти данные или масштабировать их. Стандартным приемом в данных случаях может служить калибровка джойстика самим игроком в setup'e игры. Во время этой процедуры игрок двигает джойстиком, а программа считывает и запоминает данные калибровки где-нибудь на диске для дальнейшего использования.
Для того чтобы проанализировать джойстик, программа должна:
§ Найти значения максимального и минимального отклонения по осям Х и Y;
§ Сохранить эту информацию;
§ Использовать полученные данные для выяснения, на какой угол игрок отклонил ручку джойстика.
Например, джойстик был откалиброван и мы обнаружим, что ось Х имеет значения от 0 до 255. Затем, если значение джойстика, например, по координате Х окажется равным 128, то можно с уверенностью сказать, что рукоятка находится в среднем положении (кстати, в процессе калибровки средняя позиция также запоминается).
Осталась одна маленькая деталь, о которой стоит сказать — это детектирование джойстика (то есть проверка его наличия). Обычная техника детектирования такая: в цикле опрашивается порт джойстика в течение определенного времени. Но надо сказать, что с помощью функций BIOS это можно сделать более надежно. Если после вызова функции значения по всем координатам равны 0, то никакого джойстика нет.
Я думаю, что мы уже сказали о джойстиках все. Теперь напишем небольшую программку, в, которой используем функции из Листингов 3.1 и 3.2. При старте она просит игрока:
§ Подвигать джойстиком;
§ Установить джойстик в среднее положение;
Программирование игр для Windows. Советы профессионала
программа сохраняет результаты процедуры калибровки
§ Понажимать на кнопки.
Затем, программа сохраняет результаты процедуры калибровки в глобальных переменных.
Листинг 3.3. Программа работы с джойстиком (JOY.C).
// ВКЛЮЧАЕМЫЕ ФАЙЛЫ,///////////////////////////////////
#include <dos.h>
#include <bios.h>
#include <stdio.h>
#include <math.h>
#include <conio.h>
#include <graph.h>
// ОПРЕДЕЛЕНИЯ ////////////////////////////////////////
#define JOYPORT 0х201 // порт джойстика - 201h
#define BUTTON_1_A 0х10 // джойстик А, кнопка 1
#define BUTTON_1 В 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 int
joy_1_max_x, // глобальные переменные для сохранения
joy_1_max_y, // калибровочных значений
joy_1_min_x,
joy_l_min_y,
joy_1_cx, joy_1_cy,
joy_2_max_x, joy_2_max_y,
joy_2_min_x, joy_2_min_y,
joy_2_cx, joy_2_cy;
// ФУНКЦИИ //////////////////////////////////////////////
unsigned char Buttons(unsigned char button)
{
// функция читает статус кнопок джойстика
outp(JOYPORT,0); // получаем запрос на получение статуса кнопок
// инвертируем полученное значение и комбинируем его с маской
return (~inp(JOYPORT) & button);
} //конец функции ///////////////////////////////////////////////////////
unsigned int Joystick(unsigned char stick)
{
// Функция читает положение счетчика на основании количества
// циклов, прошедших между сбросом и установкой бита в порту
// джойстика. Встроенный ассемблер - прекрасная вещь!
_asm{
cli ; запрещаем прерывания