![]() |
Главная Случайная страница Контакты | Мы поможем в написании вашей работы! | |
|
В абсолютном большинстве применений ПЭВМ комплектуются видеоадаптером одного из четырех основных типов:
· MDA (Monochrome Display Adapter - монохромный дисплейный адаптер) - текстовый режим: 80 колонок x 25 строк, разрешающая способность 720 x 348 точек, матрица символа 7 x 9, черно-белый;
· CGA (Color Graphics Adapter - цветной графический адаптер) - текстовый режим: 80 колонок x 25 строк, матрица символа 8 x 8, 16 цветов; графический режим: 640 x 200 точек - монохромный или 320 x 200 точек - 4 цвета из 16-цветовой палитры;
· EGA (Enhanched Graphics Adapter - улучшенный графический адаптер) - текстовый режим: 80 колонок x 25 строк, матрица символа 8 x 14, 16 цветов из 64-цветовой палитры; графический режим: 640 x 350 точек, 16 цветов из 64-цветовой палитры;
· VGA (Video Graphics Array - видеографический массив) - текстовый режим: 80 колонок x 25 строк, матрица символа 8 x 14, 16 цветов из 4096-цветовой палитры; графический режим: 640 x 480 точек при 16 цветах из 4096 и 320 x 200 при 256 цветах.
Видеоадаптер обслуживается прерыванием BIOS 0x10. Начиная с модели EGA обработчик этого прерывания располагается не в основном ПЗУ BIOS, а в расширении ПЗУ по адресу C000:0000. Это прерывание и в исходном своем варианте имело много функций, а для новых типов адаптеров список его функций расширяется.
Видеоадаптер может функционировать в одном из нескольких режимов, отличающихся возможностями текст/графика и разрешающей способностью.
В текстовом режиме видеопамять для CGA, EGA, VGA начинается с адреса B800:0000 (для MDA - B000:0000). Видеопамять физически расположена на плате адаптера, но ее адреса входят в общее адресное пространство ПЭВМ и доступны программисту для чтения и для записи. Каждое знакоместо экрана в видеопамяти представлено двумя байтами, первый из которых содержит ASCIIZ-код символа, а второй - цветовой атрибут в формате: H R G B h r g b, где h, r, g, b - соответственно яркостная, красная, зеленая, синяя составляющие цвета символа; R, G, B - красная, зеленая, синяя составляющие цвета фона; H - атрибут мигания (или яркостная составляющая цвета фона). Таким образом, комбинация hrgb определяет номер одного из 16 возможных цветов отображения символов.
Пример:
Применяя прямую запись в видеопамять получить на экране оригинальный, желательно динамический видеоэффект.
Программа состоит из основной функции main() и семи вспомогательных функций.
byte GetSym(x1,y1) - функция читает символ с заданной позиции экрана дисплея.
byte GetAtr(x1,y1) - функция читает атрибут символа с заданной позиции экрана дисплея.
void PutSym(x1,y1,sym) - функция выводит на экран дисплея символ в заданную позицию (x1,y1).
void PutAtr(x1,y1,atr) - функция меняет на экране дисплея атрибут символа в заданной позиции (x1,y1).
void Invert(x1,y1) - функция инвертирует участок на экране размером (10х5), координаты (x1,y1) задают один из участков на экране.
void Change(x,y) - функция обменивает содержимое текущего участка с содержимым левого верхнего участка на экране. Координаты (x,y) задают положение текущего участка.
void RandText(void) - функция псевдослучайным образом перетасовывает все участки на экране.
Переменные, глобальные для всей программы:
xk - координата X текущего участка;
yk - координата Y текущего участка;
Координаты участка задаются в пределах: X - [0..7], Y - [0..4].
Основная функция main() проверяет, был ли в командной строке дополнительный параметр. Если нет, программа не очищает старый экран. Если какой-нибудь параметр был, то экран очищается и выводится инструкция по управлению программой. Далее в основной программе выполняется бесконечный цикл, в котором обрабатываются коды нажатых клавиш и, в зависимости от них, вызываются вспомогательные функции. Выход из цикла - по клавише Esc.
Функции GetSym(x1,y1), GetAtr(x1,y1) читают непосредственно из видеопамяти дисплея символ и атрибут соответственно.
Функции PutSym(x1,y1,sym), PutAtr(x1,y1,atr) выводят непосредственно в видеопамять дисплея символ и атрибут соответственно. Во всех этих четырех функциях координаты задаются в квадрате 79х24 символов (нумерация начинается с нуля).
Функция Invert(x1,y1) использует функции GetAtr и PutAtr для инверсии прямоугольника экрана размером 10х5 по маске 0x7f, при этом независимо выполняется инверсия фона и цвета символа. Функция Change(x,y) обменивает содержимое текущего участка с содержимым левого верхнего участка путем последовательного побайтного обмену атрибутов и символов. Она использует функции GetSym, GetAtr, PutSym, PutAtr.
Функция RandText(void) - псевдослучайным образом перетасовывает все участки на экране, при этом она в цикле увеличивает на единицу локальные в данной функции координаты текущего участка xk, yk и обращается к функции Change. Таким образом достигается эффект перемешивания. Функция работает, пока не будет нажата любая клавиша.
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>
/*-----------------------Константы----------------------- */
#define VSEG 0xb800 /* Сегментный адрес видеопамяти */
#define byte unsigned char
#define word unsigned int
#define Esc 27
#define Spase 32
#define Enter 13
#define Up 0x48
#define Down 0x50
#define Left 0x4b
#define Right 0x4d
#define Home 0x47
int xk,yk;
/*--------------Чтение символа из видеопамяти-------------*/
byte GetSym(x1,y1)
int x1,y1;
{
return(peekb(VSEG,y1*160+x1*2));
}
/*-------------Чтение атрибута из видеопамяти-------------*/
byte GetAtr(x1,y1)
int x1,y1;
{
return(peekb(VSEG,y1*160+x1*2+1));
}
/*-------------Запись символа в видеопамять--------------*/
void PutSym(x1,y1,sym)
int x1,y1;
byte sym;
{
pokeb(VSEG,y1*160+x1*2,sym);
}
/*-------------Запись атрибута в видеопамять--------------*/
void PutAtr(x1,y1,atr)
int x1,y1;
byte atr;
{
pokeb(VSEG,y1*160+x1*2+1,atr);
}
/*------------Инверсия квадрата на экране-----------------*/
void Invert(x1,y1)
int x1,y1;
{
byte b;
int i,j;
for (j=0;j<5;j++)
for (i=0;i<10;i++)
{
b=GetAtr(x1*10+i,y1*5+j);
PutAtr(x1*10+i,y1*5+j,(b^0x7f));
}
}
/*-------Замена текущего квадрата на левый верхний--------*/
void Change(x,y)
byte x,y;
{
int i,j;
byte ba,bs;
if ((x!=0)||(y!=0))
for (j=0;j<5;j++)
for (i=0;i<10;i++)
{
bs=GetSym(x*10+i,y*5+j);
ba=GetAtr(x*10+i,y*5+j);
PutSym(x*10+i,y*5+j,GetSym(i,j));
PutAtr(x*10+i,y*5+j,GetAtr(i,j));
PutSym(i,j,bs);
PutAtr(i,j,ba);
}
}
/*------Перемешивание квадратов до нажатия клавиши------*/
void RandText(void)
{
Invert(xk,yk);
xk=5;
yk=1;
while(!kbhit())
{
Change(xk,yk);
xk++;
if (xk>7) xk=0;
yk++;
if (yk>4) yk=0;
}
Invert(xk,yk);
}
/*----------------Начало основной программы---------------*/
main(int argn,char *argc[])
{
int i;
xk=0;
yk=0;
if (argn>1){}
else /* Если параметров нет, вывод инструкции */
{
textattr(10);
clrscr();
cprintf("---------------");
cprintf(" Лабораторная работа N7 ");
cprintf("---------------");
cprintf("---------------");
cprintf(" Управление видеоадаптером. ");
cprintf("---------------");
textattr(15);
gotoxy(23,4);cprintf("Демонстрация работы с видеопамятью.");
textattr(12);
gotoxy(30,6);cprintf("<< М О З А И К А >>");
textattr(14);
gotoxy(30,8);cprintf("Клавиши управления:");
gotoxy(7,10);cprintf("< Left, Right, Up, Down> - ");
cprintf("управление выделенним квадратом.");
gotoxy(7,11);cprintf("<Spase Bar> - Обмен содержимым ");
cprintf("между выделенным квадратом");
gotoxy(7,12);cprintf(" и левым верхним");
cprintf(" квадратом.");
gotoxy(7,13);cprintf("<Enter> - перемешивание квадратов");
cprintf(" до нажатия любой клавиши.");
gotoxy(7,14);cprintf("<Esc> - вихiд.");
textattr(11);
gotoxy(28,16);cprintf("З А Д А Ч А И Г Р И:");
gotoxy(14,17);cprintf("Собрать при помощи клавиш ");
cprintf("управления начальный экран.");
textattr(12);
gotoxy(27,19);cprintf("Ж е л а е м у с п е х а!");
textattr(7);
gotoxy(1,21);cprintf("Примечание: При запуске с ");
cprintf("параметром <->");
gotoxy(13,22);cprintf("начальным экраном для игри ");
cprintf("является текущий.");
}
Invert(xk,yk);
for(i=0;i==0;)
switch(getch())
{ /* Обработка нажатых клавиш */
case Esc: i++; break;
case Enter:RandText();break;
case Spase:Invert(xk,yk);
Change(xk,yk);
Invert(xk,yk);
break;
case 0:
switch (getch()) {
case Left:Invert(xk,yk);
xk--;
if(xk<0) xk=7;
Invert(xk,yk);
break;
case Right:Invert(xk,yk);
xk++;
if(xk>7) xk=0;
Invert(xk,yk);
break;
case Up:Invert(xk,yk);
yk--;
if(yk<0) yk=4;
Invert(xk,yk);
break;
case Down:Invert(xk,yk);
yk++;
if(yk>4) yk=0;
Invert(xk,yk);
break;
}
}
Invert(xk,yk);
}
Задания для лабораторной работы:
Применяя прямую запись в видеопамять получить на экране оригинальный, желательно динамический видеоэффект. Возможны такие варианты видеоэффектов:
"теннисный мячик" - шарик, который летает по экрану и отражается от рамок и границ экраны;
"сухой лист" - опадание букв с экрана;
"жук-пожиратель" - фигурка, которая перемещается по экрану по случайной траектории и "съедает" буквы;
"удав" - то же, что и "жук", но к тому же он увеличивается в размерах, по мере "поедания" букв.
Контрольные вопросы:
1. Назовите и опишите основные типы видеоадаптеров.
2. Что такое разрешающая способность?
3. Назовите характеристики видеопамяти.
4. Как считается адрес видеопамяти.
5. Расшифруйте HRGBhrgb?
Дата публикования: 2015-11-01; Прочитано: 454 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!