Главная Случайная страница


Полезное:

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


Категории:

АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника






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

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.

Date: 2015-09-18; view: 382; Нарушение авторских прав; Помощь в написании работы --> СЮДА...



mydocx.ru - 2015-2024 year. (0.005 sec.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав - Пожаловаться на публикацию