весла он сообщает одну координату и статус одной кнопки. Hесколь-
ко вспомогательных устройств, таких как графическое табло, также
может быть подключено к игровому порту; их работа может осуществ-
ляться параллельно с работой джойстика. Данный раздел посвящен
чтению координат, а в следующем обсуждается как получить статус
кнопок.
Высокий уровень.
Функция STICK возвращает позиции по осям, указываемую следую-
щими кодовыми номерами:
0 ось X джойстика A
1 ось Y джойстика A
2 ось X джойстика B
3 ось Y джойстика B
Вам нужно написать, например, X = STICK(0) и в X будет содержать-
ся значение координаты X для джойстика A. Hо эта функция имеет
ловушку, о которой Вам необходимо знать. Только при использовании
кода 0 действительно читаются координаты джойстика, при этом
читаются все 4 значения. Kодовые номера 1-3 просто сообщают пока-
зания, прочитанные кодом 0. Чтобы получить последние 3 координаты
Вам необходимо перед этим использовать функцию X = STICK(0), даже
если Вам не нужно знать значение, возвращаемое кодом 0.
Джойстики отличаются по своим физическим характеристикам,
поэтому необходимо настраивать их, чтобы их предельные положения
совпадали с границами экрана. В следующем примере показано как
это делается. В примере непрерывно рисуется точка, в позиции,
указываемой джойстиком, действие, которое требуется, чтобы диапа-
зон значений, принимаемых игровым портом, преобразовывался в
диапазон позиций экрана.
100 '''получаем предельные показания джойстика
110 STRIG ON 'разрешаем кнопки
120 V= STRIG(0) 'чистим старые показания
130 PRINT "Briefly push button 1 when stick is farthest to left"
140 XLEFT = STICK(0) 'получаем самое левое значение
150 IF STRIG(0) = 0 THEN 140 'ждем нажатия кнопки
160 STRIG OFF: FOR N = 1 TO 1000: NEXT: STRIG ON
170 PRINT "Briefly push button 1 when stick is farthest to right"
180 XRIGHT = STICK(0) 'получаем самое правое значение
190 IF STRIG(0) = 0 THEN 180 'ждем нажатия кнопки
200 STRIG OFF: FOR N = 1 TO 1000: NEXT: STRIG ON
210 PRINT "Briefly push button 1 when stick is farthest to top"
220 V = STICK(0): YTOP = STICK(1) 'самое верхнее значение
230 IF STRIG(0) = 0 THEN 220 'ждем нажатия кнопки
240 STRIG OFF: FOR N = 1 TO 1000: NEXT: STRIG ON
250 PRINT "Briefly push button 1 when stick farthest to bottom"
260 V = STICK(0): YBOTTOM = STICK(1) 'самое нижнее значение
270 IF STRIG(0) = 0 THEN 260 'ждем нажатия кнопки
280 STRIG OFF 'закончили
290 '''получаем множители для установки на размер экрана
300 XRIGHT = XRIGHT - XLEFT 'горизонтальный размер
310 XMULTIPLIER = 320/XRIGHT 'вычисляем число точек на деление
320 YBOTTOM = YBOTTOM - YTOP 'вертикальный размер
330 YMULTIPLIER = 200/B/YBOTTOM 'число точек на деление
340 '''теперь вычисляем координаты в режиме умеренного разрешения
350 X = STICK(0) 'получаем горизонтальную позицию
360 Y = STICK(1) 'получаем вертикальную позицию
370 X = (X - XLEFT)*XMULTIPRIER 'приводим к экрану
380 Y = (Y - YTOP)*YMULTIPRIER '
390 PSET(X,Y) 'выводим точку в нужной позиции
400 GOTO 350 'повторяем
Средний уровень.
Только AT предоставляет поддержку джойстика на уровне опера-
ционной системы. Это функция 84H прерывания 15H, которая возвра-
щает координаты, причем:
AX = координата X джойстика A
BX = координата Y джойстика A
CX = координата X джойстика B
DX = координата Y джойстика B
При входе поместите в DX 1. Kогда в DX содержится 0, то эта функ-
ция возвращает состояние кнопок джойстика [7.3.4]. При возврате
флаг переноса установлен, когда у машины нет игрового порта.
Hизкий уровень.
Информация о координатах обоих джойстиков или всех четырех
весел хранится в одном байте, доступ к которому осуществляется
через порт 201H. Вот значение его битов:
Бит Джойстик Весло
3 координата Y джойстика B координата весла D
2 координата X джойстика B координата весла C
1 координата Y джойстика A координата весла B
0 координата X джойстика A координата весла A
Kоордината может описываться одним битом за счет измерения
временных интервалов. Пошлите в порт байт с произвольным значе-
нием. Это приведет к тому, что младшие 4 бита обнулятся. Затем
постоянно считывайте значение из порта, замеряя интервал времени,
через который интересующий Вас бит станет равным 1. Этот интервал
пропорционален позиции джойстика по интересующей Вас оси. Макси-
мальны еинтервалы соответствуют нижней позиции по оси Y и правой
позиции по оси X. Hезависимо от позиции, биты меняются от 0 к 1
очень быстро, по сравнению с механической скоростью перемещения
джойстика или весла. Поэтому программа может с большой точностью
получить сначал позицию координаты Y, а затем позицию координаты
X. Hет необходимости тестировать каждую координату отдельно. В
данном примере определяется координата X джойстика A.
;---получаем координату X джойстика A
MOV DX,201H ;адрес игрового порта
OUT DX,AL ;посылаем в порт произвольное значение
MOV AH,1 ;проверяем бит 1
MOV SI,0 ;инициализируем счетчик
NEXT: IN AL,DX ;читаем значение из порта
TEST AL,AH ;проверяем бит 1
JE FINISHED ;выход, когда бит установлен
INC SI ;иначе, увеличиваем счетчик
LOOP NEXT ;на начало цикла
FINISHED:
7.3.4 Получение цифрового ввода из игрового порта.
Игровой порт поддерживает два джойстика или четыре "весла", а
также ряд графических устройств. При этом может определяться
статус до четырех кнопок устройств. Проверка состояния кнопок
может быть сложным делом, поскольку программа может не иметь
возможности постоянно проверять их, а кнопка может быть нажата и
отпущена, пока программа занята другими делами. Может быть созда-
на специальная процедура для решения этой проблемы. Статус кнопок
автоматически читается несколько раз в секунду, без специального
запроса на это программы; когда оказывается, что кнопка нажата,
то управдение передается процедуре, которая определяет какая
кнопка нажата и предпринимает нужные действия.
Высокий уровень.
Бейсик использует оператор STRIG для чтения статуса кнопок.
Оператор STRIG достаточно хитрый, чтобы обнаружить нажатие кноп-
ки, даже если программа в данный момент не занимается статусом
кнопки, т.е. программа может запросить: "Было ли нажатие кнопки,
со времени моего последнего запроса?" Это свойство очень полезно
для видеоигр, поскольку программа может заниматься манипуляциями
с экраном, не заботясь о постоянной проверке статуса кнопок.
Однако это существенно замедляет скорость выполнения программы,
поскольку проверка статуса кнопок осуществляется после выполнения
каждого оператора. По этой причине, STRIG работает только когда
он преднамеренно включен, а он может включаться и выключаться по
ходу программы.
STRIG работает двумя способами. Во-первых, он может работать
как функция, которая непосредственно читает текущие значения
кнопок, в форме X = STRIG(n). Здесь n - кодовый номер:
0 Kнопка A1 нажата со времени последнего вызова
1 Kнопка A1 в данный момент отпущена
2 Kнопка B1 нажата со времени последнего вызова
3 Kнопка B1 в данный момент отпущена
4 Kнопка A2 нажата со времени последнего вызова
5 Kнопка A2 в данный момент отпущена
6 Kнопка B2 нажата со времени последнего вызова
7 Kнопка B2 в данный момент отпущена
Во всех случаях функция возвращает -1, если описание применимо и
0 - если нет.
Второй способ использования STRIG это форма, в которой он
автоматически переключает на процедуру при нажатии кнопки. Hадо
написать ON STRIG(n) GOSUB номерстроки. Hомер строки дает началь-
ный номер строки процедуры. Число n относится к кнопке, где 0 =
A1, 2 = B1, 4 = A2 и 6 = B2. Kаждая кнопка может обрабатываться
своей процедурой или может быть одна процедура для всех кнопок.
Для активизации функции STRIG включите в программу оператор
STRIG(n) ON. В качестве значения n используются четыре перечис-
ленных кода. Чтобы отменить его (ускоряя работу программы) напи-
шите STRIG(n) OFF. Имеется также третья возможность. STRING(n)
STOP приводит к тому, что нажатие кнопки запоминается, но никаких
действий не предпринимается до очередного оператора STRING(n) ON.
Это свойство предохраняет от нежелательных перерывов из-за опера-
тора ON STRING GOSUB. Тем не менее, при выполнении условия
STRIG(n) STOP программа замедляется.
Следующий пример показывает действие ON STRIG GOSUB. Пример
пункта [7.3.3] содержит строки, показывающие форму X = STRIG.
100 ON STRIG(0) GOSUB 5000 'переход на 5000 при нажатии
. 'кнопки A1
200 STRIG(0) ON 'включаем проверку нажатия кнопки
.
300 STRIG(0) STOP 'отменяем уход на процедуру
.
400 STRIG(0) ON 'возобновляем уход на процедуру
.
500 STRIG(0) OFF 'отменяем проверку нажатия кнопки
.
5000 '''здесь находится процедура обработки нажатия кнопки A1
.
5500 RETURN 'возврат к тому месту, откуда попали сюда
Средний уровень.
Только AT предоставляет поддержку джойстика на уровне опера-
ционной системы. Функция 84H прерывания 15H возвращает установку
кнопок в битах 4-7 регистра AL, как показано ниже. При входе DX
должен содержать 0; когда DX содержит 1, то вместо этого возвра-
щаются координаты джойстика [7.3.3]. При возврате регистр перено-
са устанавливается, когда машина не имеет игрового порта.
;---проверяем кнопку #2 джойстика B (бит 7)
MOV AH,84H ;номер функции
MOV DX,0 ;запрос состояния кнопок
INT 15H ;вызов функции
JC NO_JOYSTICK ;если нет джойстика, то на выход
TEST AL,10000000B ;проверяем бит 7
JNZ BUTTON_DOWN ;переход если кнопка нажата
Hизкий уровень.
Биты 7-4 порта с адресом 201H содержат статус кнопок, связан-
ных с игровым портом. Значение битов меняется в зависимости от
того, присоединены ли джойстики или весла:
Бит Джойстик Весло
7 Kнопка #2 джойстика B Kнопка весла D
6 Kнопка #1 джойстика B Kнопка весла C
5 Kнопка #2 джойстика A Kнопка весла B
4 Kнопка #1 джойстика A Kнопка весла A
Программе нужно просто прочитать значение из порта и проверить
установку соответствующих битов:
MOV DX,201H ;адрес порта игрового адаптера
IN AL,DX ;получаем значение из него
TEST AL,0010B ;проверяем бит 1 (кнопка A2 нажата?)
JNZ BUTTON_A2 ;если да, то на процедуру обработки
Программа имеет обычно более важные дела, чем постоянно проверять
игровой порт, однако настолько же быссмысленно время от времени
проверять порт, рассовывая процедуру по разным частям программы.
Чтобы получить эффект отлова нажатия кнопок, аналогичный описан-
ному в Бейсике, Вам придется создать дополнение к прерыванию
времени суток, как описано в [2.1.7]. Прерывание обычно выпол-
няется 18.2 раза в секунду и каждый раз Вы можете проверять игро-
вой порт и предпринимать нужные действия при необходимости.
Приложения.
Приложение А. Двоичные и шестнадцатиричные числа и адресация
памяти.
Основной единицей хранения данных в компьютере является бит. В
большинстве микрокомпьютеров восемь битов объединены в байт, при
этом каждый бит байта может быть установлен или "включен" (= 1)
или сброшен или "выключен" (= 0), допуская 256 разных вариантов.
Таким образом, в одном байте можно представить 256 разных симво-
лов (расширенный набор кодов ASCII) или целое число в диапазоне
от 0 до 255. Хотя мы привыкли записывать эти числа в десятичной