/*------Лабораторная работа N7-----------------*/
/*-----Управление видеоадаптером.---------------*/
#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);
}