Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АрхитектураБиологияГеографияДругоеИностранные языки
ИнформатикаИсторияКультураЛитератураМатематика
МедицинаМеханикаОбразованиеОхрана трудаПедагогика
ПолитикаПравоПрограммированиеПсихологияРелигия
СоциологияСпортСтроительствоФизикаФилософия
ФинансыХимияЭкологияЭкономикаЭлектроника

Листинг 3.3. Программа работы с джойстиком (JOY.C).

Листинг 2.1. Прототип процедуры для MASM 5.0 и более старших версий. | Листинг 2.2. Простая процедура сложения. | Листинг 2.3. Модифицированная версия Add_Int. | Листинг 2.4. Корректировка регистра SP. | Листинг 2.5. Программа Timer. | Листинг 2.7. Ассемблерная часть примера. | Листинг 2.9. Си-функция, тестирующая видеорежим (SETMOPEC.C). | Листинг 2.11, Программа на Си для тестирования программы 2.10 (FILLC.C). | ОСНОВЫ РАБОТЫ С УСТРОЙСТВАМИ ВВОДА | Листинг 3.1. Чтение кнопок джойстика. |


Читайте также:
  1. I. Задание для самостоятельной работы
  2. I. Задания для самостоятельной работы
  3. I. Задания для самостоятельной работы
  4. I. Задания для самостоятельной работы
  5. I. Задания для самостоятельной работы
  6. I. Задания для самостоятельной работы
  7. I. Задания для самостоятельной работы

// ВКЛЮЧАЕМЫЕ ФАЙЛЫ,///////////////////////////////////

#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; запрещаем прерывания

mov ah, byte ptr stick; в регистр АН заносим маску

; для выбора джойстика

хоr аl,аl; обнуляем AL

хоr сх,сх; обнуляем СХ

mov dx,JOYPORT; в DX помещаем номер порта джойстика

out dx,al; обнуляем содержимое порта

discharge:

in al,dx; читаем данные из порта

test al,ah; установился ли бит?

loopne discharge; если нет - повторяем чтение

sti; разрешаем прерывания

хог ах,ах; обнуляем АХ

sub ах,сх; теперь АХ содержит искомое значение

} // конец ассемблерного блока

} // конец функции

//////////////////////////////////////////////////////

unsigned int Joystick_Bios(unsigned char stick)

(

// версия функции чтения состояния джойстика

// работающая через BIOS

union _REGS inregs, outregs;

inregs.h.ah = 0х84; // нам нужна функция 84h

inregs.x.dx = 0х01;

// подфункция 01h - чтение состояния джойстика

_int86(0х15,&inregs, &outregs); // вызываем BIOS

// возвращаем требуемое значение

switch(stick)

{

case JOYSTICK_1_X:

{

return(outregs.x.ax);

} break;

case JOYSTICK1_Y:

{

return(outregs. x. bx};

} break;

case JOYSTICK_2_X:

{

return(outregs.x.ex);

} break;

case JOYSTICK_2_Y:

{

return(outregs.x.dx);

} break;

default:break;

} // конец оператора switch

} // конец функции

///////////////////////////////////////////////////////

unsigned char Buttons_Bios(unsigned char button)

{

// версия функции для чтения статуса кнопок джойстика,

// работающая через BIOS

union _REGS inregs, outregs;

inregs.h.ah = 0х84; // обращение к джойстику - функция 84h

inregs.x.dx = 0х00; // подфункция 0 - чтение статуса кнопок

_int86 (0х15, &inregs, &outregs);

// инвертируем результат и комбинируем с переданной маской

return((~outregs.h.al) & button);

} // конец функции //////////////////////////////////////////////////////

void Joystick_Calibrate(int stick)

{

// функция выполняет калибровку джойстика путем нахождения

// минимального и максимального значений по осям Х и У. Затем

// полученные значения сохраняются в глобальных переменных.

unsigned int x_new,у_new; // позиция джойстика

if (stick==JOY_1_CAL) {

printf("\nCalibrating Joystick #1: Swirl stick, then release it and press FIRE");

// придаем переменным заведомо невозможные значения

joy_1_max_x=0;

joy_1_max_y=0;

joy_1_min_x=10000;

joy_1_min_y=10000;

// пользователь должен покрутить джойстик, поставить его в среднее

// положение и затем нажать любую кнопку

while(!Buttons(BUTTON_1_A | BUTTON_1_B))

{

// читаем новые значения потенциометра и пытаемся улучшить

// калибровку

x_new = Joystick_Bios(JOYSTICK_1_X);

y_new = Joystick_Bios(JOYSTICK_1_Y};

// обрабатываем ось X

if (x_new >= joy_1_max x) joy_1_max x = x_new;

if (x_new <= joy_1_min_x) joy_1_min_x = x_new;

// обрабатываем ось Y

if (y_new >= joy_1_max_y) joy_1_max_y = y_new;

if (y_new <= joy_1_ min y) joy_1_min у = у_new;

} // конец цикла while

// получаем значения потенциометра, соответствующие нейтральному

// положению

joy_1_cx = x_new;

 

joy_l_cy = y_new;

} // конец калибровки джойстика А

else

if (stick==JOY_2_CAL)

{

printf("\nCalibrating Joystick #2: Swirl stick, then release it and pres's FIRE");

// придаем переменным заведомо невозможные значения

joy_2_max x=0;

joy_2_max_y=0;

joy_2_min_x=10000;

joy_2_min_y=10000;

// пользователь должен покрутить джойстик, поставить его в

// нейтральное положение и нажать любую кнопку

while(!Buttons(BUTTON_2_A | BUTTON_2_B))

{

// читаем значение потенциометра и пытаемся улучшить калибровку

x_new = Joystick (JOYSTICK_2_X);

y_new = Joystick(JOYSTICK_2_Y);

// обрабатываем ось Х

if (x_new >= joy_2_max_x)

joy_2_max x = x_new;

else if (x_new <= joy_2_min_x)

joy_2_min_x = x_new;

// обрабатываем ось Y

if (y_new >=joy_2_max_y)

joy_2_max_y = y_new;

else if (y_new <= joy_2_min_y)

joy_2_min_y = y_new;

} // конец цикла while

// читаем значения, соответствующие нейтральному положению

joy_2_cx = x_new;

joy_2_су = y_new;

} // конец калибровки джойстика В

printf ("\nCalibration Complete... hit any key to continue.");

getch();

} // конец функции калибровки джойстика

// ОСНОВНАЯ ПРОГРАММА ////////////////////////////////////////

void main(void) (

// калибруем джойстик

Joystick_Calibrate(JOY_1_CAL);

_clearscreen(_GCLEARSCREEN);

// даем пользователю поиграть с джойстиком

while(!kbhit())

{

_settextposition(2,0);

printf("Joystick 1 = [%u,%u] ", Joystick__Bios(JOYSTICK_1_X), Joystick_Bios(JOYSTICK_1_Y));

if (Buttons_Bios(BUTTON_1_A))

printf("\nButton 1 pressed ");

else if (Buttons_Bios(BUTTON_1_B))

printf("\nButton 2 pressed ");

else

printf("\nNo Button Pressed ");

} // конец цикла while

// даем пользователю посмотреть, на калибровочные данные

printf("\nmax x=%u/ max y=%u,min x=%u,min y=%u, cx=%u, cy=%u", joy_1_max_x, joy_1_max_y, joy_1_min_x, joy_1_min_y, joy_1_cx, joy_1_cy);

// кое-что будем добавлять позже

} // конец функции main

 

Если вы введете программу с Листинга 3.3, то увидите, как джойстик А изменяет свои значения в процессе работы с ним.

Клавиатура

Клавиатура - это наиболее сложное устройство ввода, которое есть в ПК. Она даже имеет свою собственную микросхему - контроллер ввода. Я провел много бессонных ночей, вчитываясь в листинги BIOS и пытаясь понять тайны, скрытые в работе с клавиатурой.

В этой жизни есть множество непонятных вещей - курс доллара, термический - коэффициент расширения рубидия и т. д. Несомненно одно - любовь людей к клавиатуре абсолютно необъяснима.

Для наших целей (для написания видеоигр) мы должны научиться хорошо работать с клавиатурой. Для этого вовсе не стоит разбираться с прерываниями, регистрами и портами. Мы будем использовать функции языка Си и BIOS для работы с очередью клавиатуры. Говоря о Си, я не имею в виду функции типа getch () и scanf (). Речь пойдет, скорее, о функциях типа _bios_keyboard ().

Примечание

Давайте приостановимся и немного подумаем, Общее правило для авторов игр - никогда не использовать BIOS. Верно? Хорошо, на самом деле BIOS вполне можно использовать для файловых операций и для выделения памяти. В общем, обращения к BIOS вполне допустимы в функциях, некритичных по времени. Попытка исполь­зовать его для работы с джойстиком или клавиатурой не будет для нас смертельна (в отличие от попыток организовать через BIOS вывод графики). Как я уже говорил, современные компьютеры достаточно быстры, чтобы нам не приходилось оптимизировать каждую запятую в тексте программы или писать ее целиком на ассемблере.

BIOS поддерживает несколько функций, которые мы будем использовать и которые приведены в таблице 3-1.

Таблица 3.1. Клавиатурные функции BIOS.


Дата добавления: 2015-07-12; просмотров: 79 | Нарушение авторских прав


<== предыдущая страница | следующая страница ==>
Листинг 3.2. Чтение позиции джойстика.| Bios INT 16h

mybiblioteka.su - 2015-2024 год. (0.03 сек.)