![]() Полезное:
Как сделать разговор полезным и приятным
Как сделать объемную звезду своими руками
Как сделать то, что делать не хочется?
Как сделать погремушку
Как сделать так чтобы женщины сами знакомились с вами
Как сделать идею коммерческой
Как сделать хорошую растяжку ног?
Как сделать наш разум здоровым?
Как сделать, чтобы люди обманывали меньше
Вопрос 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: 420; Нарушение авторских прав |