Полезное:
Как сделать разговор полезным и приятным
Как сделать объемную звезду своими руками
Как сделать то, что делать не хочется?
Как сделать погремушку
Как сделать так чтобы женщины сами знакомились с вами
Как сделать идею коммерческой
Как сделать хорошую растяжку ног?
Как сделать наш разум здоровым?
Как сделать, чтобы люди обманывали меньше
Вопрос 4. Как сделать так, чтобы вас уважали и ценили?
Как сделать лучше себе и другим людям
Как сделать свидание интересным?
Категории:
АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника
|
Листинг 12.7. Киберточка (CYBER.C)._____// ВКЛЮЧАЕМЫЕ ФАЙЛЫ/////////////////////////////////////// #include <dos.h> #include <bios.h> #include <stdio.h> #include <math.h> #include <conio.h> #include <graph.h> // ОПРЕДЕЛЕНИЯ ////////////////////////////////////////// #define KEYBOARD_INT 0х09 #define KEY_BUFFER 0х60 #define KEY_CONTROL 0х61 #define INT_CONTROL 0х20 // коды нажатия и отпускания для клавиш со стрелками #define MAKE_RIGHT 77 #define MAKE_LEFT 75 #define MAKE_UP 72 #define MAKE_DOWN 80 #define BREAK__RIGHT 205 #define BREAK_LEFT 203 #define BREAK_UP 200 #define BREAK_DOWN 208 // индексы в таблице состояния клавиш со стрелками #define INDEX_UP 0 #define INDEX_DOWN 1 #define INDEX_RIGHT 2 #define INDEX_LEFT 3 // ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ //////////////////////////////// void (_interrupt _far *01d_Isr)(void); // хранит старый обработчик прерывания unsigned char far *video_buffer = (char far *)0xA0000000L; // указатель на видеобуфер int raw_key; // необработанные данные от клавиатуры int key_table[4] = {0,0,0,0}; // таблица состояний клавиш со стрелками // ФУНКЦИИ ////////////////////////////////////////////// void Plot_Pixel_Fast(int x,int y,unsigned char color) { // эта функция рисует точку заданного цвета несколько быстрее, // чем обычно за счет применения операции сдвига вместо операции // умножения // используем известный факт, что 320*у = 256*у + 64*у = у<<8 + у<<6 video_buffer[((y<<8) + (у<<6)) + х] = color; } // конец Plot_Pixel_Fast ///////////////////////////////////////////// void Fun_Back(void) { int index; // несомненно запоминающийся рисунок фона _setcolor(1); _rectangle(_GFILLINTERIOR, 0,0,320,200); _setcolor{15); for (index=0; index<10; index++) { _moveto(16+index*32,0); _lineto(16+index*32,199); } // конец цикла for (index=0; index<10; index++) { _moveto(0,10+index*20); _lineto(319,10+index*20); } // конец цикла } // конец Fun Back /////////////////////////////////////// void _interrupt _far New_Key_Int(void) { // я в настроении немного попрограммировать на ассемблере! _asm{ sti; разрешаем прерывания in al,KEY BUFFER; получаем нажатую клавишу xor ah,ah; обнуляем старшие 8 бит регистра АХ mov raw_key, ax; сохраняем код клавиши in al,KEY_CONTROL; читаем управляющий регистр or al,82h; устанавливаем необходимые биты для сброса FF out KEY_CONTROL,al; посылаем новые данные в управляющий регистр and al,7fh out KEY_CONTROL,al; завершаем сброс mov al,20h out INT CONTROL,al; завершаем прерывание } // конец ассемблерной вставки // теперь вернемся К Си, чтобы изменить данные // в таблице состояния клавиш со стрелками // обработка нажатой клавиши и изменение таблицы switch(raw_key) { case MAKE_UP: // нажатие стрелки вверх { key_table[INDEX_UP] = 1; } break; case MAKE_DOWN: // нажатие стрелки вниз { key_table[INDEX_DOWN] = 1; ) break; case MAKE_RIGHT: // нажатие' стрелки вправо { key_table[INDEX_RIGHT] = 1; } break; case MAKE_LEFT: // нажатие стрелки влево { key__table[INDEX_LEFT] = 1; } break; case BREAK_UP: // отпускание стрелки вверх { key_table[INDEX_UP] = 0; } break; case BREAK DOWN: // отпускание стрелки вниз { key_table[INDEX_DOWN] = 0; } break; case BREAK_RIGHT; // отпускание стрелки вправо { key_table[INDEX_RIGHT] = 0; } break; case BREAK_LEFT: // отпускание стрелки влево { key_table[INDEX_LEFT] = 0; } break; default: break; } // конец оператора switch } // конец New_Key_Int // ОСНОВНАЯ ПРОГРАММА //////////////////////////////// void main(void) { int dопе=0, x=160, y=100;// флаг выхода и координаты точки //установка видеорежима 320x200x256 _setvideomode(_MRES256COLOR); Fun_Back(); // оригинальная картинка, не так ли? printf("\nPress ESC to Exit."); // установка нового обработчика прерывания Old_Isr = _dos_getvect(KEYBOARD_INT); _dos_setvect(KEYBOARD_INT, New_Key_Int); // основной цикл while(!done) { _settextposition(24,2); printf("raw key=%d ",raw_key); // смотрим в таблицу и перемещаем маленькую точку if (key_table[INDEX_RIGHT]) х++; if (key_table[INDEX_LEFT]) х--; if (key_table[INDEX_UP]) y--; if (key_table[INDEX_DOWN]) y++; // рисуем киберточку Plot_Pixel_Fast(x,y,10); // Наша клавиша завершения. Значение кода нажатия ESC равно 1 if (raw_key==1) done=l; } // конец while // восстановление старого обработчика прерывания _dos_setvect(KEYBOARD_INT, Old_Isr); _setvideomode (_DEFAULTMODE); } // конец функции main Уфф... Вот и все, ребята! Заключение В этой главе мы изучили некоторые нетривиальные приемы управления работой персонального компьютера. Мы узнали, как работает таймер, как можно использовать прерывания (включая и клавиатурные) и многое другое. Мы научились писать обработчики прерываний на языке Си и регистрировать их в таблице векторов прерываний. Кроме того, мы узнали много полезного о том, как при помощи автономных функций и функций ответа можно организовать на персональном компьютере синхронизацию программы и обработку наступления определенных событий. И, в конце концов, мы использовали полученные знания Для написания нескольких программ, которые брали на себя управление компьютером - одна из этих программ даже не пожелала вернуть управление обратно!
|