| 
			| 
					
						| Oksy 
								Гость
 | 
								|  | «  : 18-03-2006 06:24 »  |  | 
 
 Люди, помогите, если кто знает.Материал взят из книги Г.Шилдта(название не знаю):
 
 Сохраниение части экрана
 Прерывание 16, функция 8 возвращает символ из текущей позиции курсора в AL и его атрибут в AH. Функция save_video(), показанная здесь, считывает часть экрана, сохраняет информацию в буфер, и очищает эту часть экрана.
 
 void save_video(startx,endx,starty,endy,buf_ptr)
 int startx,endx,starty,endy;
 unsigned int *buf_ptr;
 {
 union REGS r;
 register int i,j;
 
 for(i=starty;i for(j=startx;j goto_xy(j,i);
 r.h.ah=8; /* функция чтения символа */
 r.h.bh=0; /* видео страница */
 *buf_ptr++ = int86(0x10,&r,&r);
 putchar(' '); /* очистка экрана */
 }
 }
 
 Восстановление экрана
 Восстановление экрана после сделанного выбора из меню, заключается просто в записи предварительно запомненной информации назад в видео память. Для того, чтобы сделать это, используйте прерывание 16, функцию 9, которая требует, чтобы символ был в AL, аттрибут в BL, видео страница в ВН, а количество записываемых символов в CX (в нашем случае 1). Функция restore_video(), описанная здесь, помещает информацию из буфера, на который указывает buf_ptr, на экран, заданный начальными и конечными координатами X и Y.
 
 void restore_video(startx,endx,starty,endy,buf_ptr)
 int startx,endx,starty,endy;
 unsigned int *buf_ptr;
 {
 union REGS r;
 register int i,j;
 
 for(i=starty;i for(j=startx;j goto_xy(j,i);>BR? r.h.ah=9; /* функция записи символа */
 r.h.bh=0; /* видео страница */
 r.x.cx=1; /* число повторений символа */
 r.h.al=*buf_ptr++; /* символ */
 r.h.bl=*buf_ptr++; /* атрибут */
 *buf_ptr++ = int86(0x10,&r,&r);
 }
 }
 
 Как я поняла, здесь используется "старомодный" стиль ситаксиса.
 Вопрос:
 как это будет выглядеть в стиле "модерн"?
 Пробовала преобразовать сама. Почти получилось, но функция restore_video(...) возвлащает на экран белиберду, скорее всего из-за непереведенного мной >BR? в функции restore_video(...), эта часть просто отсутствует в моем варианте.
 Кто знает, что это такое и как оно выглядит в "модерне"?
 |  
						| 
								|  |  
								| « Последнее редактирование: 13-12-2007 20:59 от Алексей1153++ » |  Записан | 
 |  |  | 
	| 
			| 
					
						| Oksy 
								Гость
 | 
								|  | « Ответ #1 : 18-03-2006 08:49 »  |  | 
 
 Так выглядит мой вариант:#include <dos.h>
 #include <conio.h>
 #include <stdio.h>
 void save_video(int x1, int y1, int x2, int y2,  unsigned int *buf)
 {
 union REGS r;
 register int i, j;
 for(i=y1;i<y2;i++)
 {
 for(j=x1;j<x2;j++)
 {
 gotoxy(j,i);
 r.h.ah=8;
 r.h.bh=1;
 *buf++=int86(0x10,&r,&r);
 putchar(' ');
 }
 }
 }
 
 void restore_video(int x1, int y1, int x2, int y2, unsigned int *buf)
 {
 union REGS r;
 register int i, j;
 for(i=y1;i<y2;i++)
 {
 for(j=x1;j<x2;j++)
 {
 gotoxy(j,i);
 r.h.ah=9;
 r.h.bh=0;
 r.x.cx=1;
 r.h.al=*buf++;
 r.h.bl=*buf++;
 *buf++=int86(0x10,&r,&r);
 }
 }
 }
 
 void main()
 {
 clrscr();
 _setcursortype(_NOCURSOR);
 int i=0;
 for(i; i<=2078; i++)
 printf("0");
 unsigned int *buf;
 getch();
 save_video(10,5,13,8,buf);
 getch();
 restore_video(1,1,4,4,buf);
 getch();
 }
 
 |  
						| 
								|  |  
								| « Последнее редактирование: 13-12-2007 20:59 от Алексей1153++ » |  Записан | 
 |  |  | 
	| 
			| 
					
						| Dimka 
								ДеятельКоманда клуба    Offline 
								Пол:    | 
								|  | « Ответ #2 : 18-03-2006 11:42 »  |  | 
 
 for(i=starty;i for(j=startx;j goto_xy(j,i);r.h.ah=8; /* функция чтения символа */
 r.h.bh=0; /* видео страница */
 *buf_ptr++ = int86(0x10,&r,&r);
 putchar(' '); /* очистка экрана */
 }
 }
Здесь же синтаксическая ошибка. Не верю, чтобы работало. Так циклы отродясь (языка C) не писались. Далее по сути задачи. Можно, конечно, использовать прерывание 10h (видео в BIOS), но "белые" люди со времён распространения CGA и более развитых адаптеров работают напрямую с видеопамятью. Для цветного текстового режима видеопамять экрана начинается по адресу B800h:0000h. Каждый символ описывается двумя байтами: первый байт - ASCII код символа, второй байт - цветовой атрибут (тот, что устанавливается функцией textattr - в помощи Turbo C описано, как им пользоваться). Такими парами байтов описывается весь экран построчно от левого верхнего угла. Т.е. первые 160 байт описывают символы первой строки экрана, вторые 160 байт - вторую строку и т.д. Всего для обычного текстового режима используется 80*25*2=4000 байт. Соответственно, несложными арифметическими преобразованиями можно получить адрес конкретного знакоместа и прочитать записанный там символ и его цвет. Можно осуществлять и запись. Поищу примеры... |  
						| 
								|  |  
								| « Последнее редактирование: 13-12-2007 21:00 от Алексей1153++ » |  Записан | 
 
 Программировать - значит понимать (К. Нюгард)Невывернутое лучше, чем вправленное (М. Аврелий)
 Многие готовы скорее умереть, чем подумать (Б. Рассел)
 |  |  | 
	| 
			| 
					
						| nikedeforest | 
								|  | « Ответ #3 : 18-03-2006 12:39 »  |  | 
 
 Вот пример реализации функции putpixel. В файле отчет по лабораторной и текст программы. Вроде там должно быть все понятно. P.S. Прошу особо не придираться, это я достал лабораторную со второго курса   . |  
						| 
								| 
 |  
								|  |  Записан | 
 
 ещё один вопрос ... |  |  | 
	| 
			| 
					
						| Dimka 
								ДеятельКоманда клуба    Offline 
								Пол:    | 
								|  | « Ответ #4 : 18-03-2006 13:09 »  |  | 
 
 Примеров не нашёл, поэтому сам собрал программку. #include <conio.h>#include <dos.h>
 #include <stdlib.h>
 
 /* ОПРЕДЕЛЕНИЕ ВИДЕОПАМЯТИ */
 
 /* Структура знакоместа в видеопамяти */
 struct videochar
 {
 char ascii;	/* ASCII код символа */
 char color;	/* цветовой атрибут символа */
 };
 
 /* Определение типа видеопамяти */
 typedef struct videochar far *videomem;
 
 /* Адресация переменной video таким образом, чтобы через
 эту переменную можно было обращаться к
 видеопамяти */
 videomem video = (videomem)MK_FP(0xB800, 0);
 
 /* ФУНКЦИИ РАБОТЫ С ВИДЕОПАМЯТЬЮ */
 
 /* Получает указатель на знакоместо в видеопамяти, находящееся
 в позиции x, y */
 videomem get_vidchptr(int x, int y)
 {
 /* Перемещаем указатель на строку y - отсчитываем y-1
 раз по 80 знакомест */
 /* Затем перемещаемся в столбец x - отсчитываем x-1
 знакоместо */
 return video + (y - 1) * 80 + (x - 1);
 }
 
 /* Сохранение куска изображения в буфер */
 void save_video(int x1, int y1, int x2, int y2,
 struct videochar **buffer)
 {
 int x, y;
 struct videochar *iter;
 /* Определяем, сколько нам нужно памяти для буфера */
 size_t bufsize = (y2 - y1 + 1) * (x2 - x1 + 1) *
 sizeof(struct videochar);
 /* Выделяем память под буфер */
 *buffer = (struct videochar *)malloc(bufsize);
 /* Чтобы не потерять указатель на начало буфера,
 пользуемся вспомогательным указателем. */
 iter = *buffer;
 for(x = x1; x <= x2; ++x)
 for(y = y1; y <= y2; ++y, iter++)
 /* Копируем знакоместо из
 видепамяти в буфер */
 *iter = *get_vidchptr(x, y);
 }
 
 /* Восстановление куска изображения из буфера */
 void restore_video(int x1, int y1, int x2, int y2,
 struct videochar **buffer)
 {
 int x, y;
 struct videochar *iter;
 /* Чтобы не потерять указатель на начало буфера,
 пользуемся вспомогательным указателем. */
 iter = *buffer;
 for(x = x1; x <= x2; ++x)
 for(y = y1; y <= y2; ++y, iter++)
 /* Копируем знакоместо из
 буфера в видепамять */
 *get_vidchptr(x, y) = *iter;
 /* Освобождаем память буфера */
 free(*buffer);
 }
 
 /* ОСНОВНАЯ ПРОГРАММА */
 
 int main()
 {
 struct videochar *buffer;
 /* Перед запуском заполните чем-нибудь экран для
 наглядности. */
 getch();
 /* Запоминаем кусок экрана между 10 и 70 столбцами
 и 10 и 20 строками */
 save_video(10, 10, 70, 20, &buffer);
 /* Очищаем экран - убеждаемся, что картинки нет */
 clrscr();
 getch();
 /* Восстанавливаем кусок экрана - убеждаемся, что всё
 работает */
 restore_video(10, 10, 70, 20, &buffer);
 getch();
 return 0;
 }
Обращаю внимание, что в программе нет проверок при работе с памятью. Это означает, что: - перед сохранением буфер ничего не содержит, иначе будет утечка памяти; - оперативной памяти на буфер всегда хватает - факт выделения не проверяется - иначе будет ошибка; - видеопамять в самом деле начинается с B800:0000, т.е не какой-нибудь там монохромный Hercules 20-илетней давности; - размер восстанавливаемого изображения совпадает с размером сохраняемого, иначе могут быть ошибки. Последний случай можно обойти, используя такую структуру видеобуфера: struct videobuffer{
 int x1, y1, x2, y2;
 struct videochar *buffer;
 };
 
т.е. чтобы размеры и позиция сохранялись вместе с видеобуфером и случайно не потерялись бы где-нибудь в недрах программы, тогда при восстановлении не нужно будет передавать координаты области восстановления. |  
						| 
								|  |  
								| « Последнее редактирование: 07-04-2006 05:34 от dimka » |  Записан | 
 
 Программировать - значит понимать (К. Нюгард)Невывернутое лучше, чем вправленное (М. Аврелий)
 Многие готовы скорее умереть, чем подумать (Б. Рассел)
 |  |  | 
	| 
			| 
					
						| Dimka 
								ДеятельКоманда клуба    Offline 
								Пол:    | 
								|  | « Ответ #5 : 18-03-2006 13:17 »  |  | 
 
 Вот ведь... Чего было мучаться...
 в conio.h есть функции gettext и puttext - они делают всё, что нужно.
 |  
						| 
								|  |  
								|  |  Записан | 
 
 Программировать - значит понимать (К. Нюгард)Невывернутое лучше, чем вправленное (М. Аврелий)
 Многие готовы скорее умереть, чем подумать (Б. Рассел)
 |  |  | 
	| 
			| 
					
						| nikedeforest | 
								|  | « Ответ #6 : 18-03-2006 13:25 »  |  | 
 
  Будем надеяться не напрасно ты мучался, ведь возможно для Oksy важно поработать с видеопамятью напрямую. |  
						| 
								|  |  
								|  |  Записан | 
 
 ещё один вопрос ... |  |  | 
	| 
			| 
					
						| PooH 
								Глобальный модератор
								
								   Offline 
								Пол:    
								... и можно без хлеба!
								
								
								
								
								
							 | 
								|  | « Ответ #7 :  18-03-2006 15:15 »   |  | 
 
 for(i=starty;i for(j=startx;j goto_xy(j,i);>BR? скорее всего книга в HTML и СИ-шнуй знак "<" воспринялся как открытие HTML-тэга |  
						| 
								|  |  
								|  |  Записан | 
 
 Удачного всем кодинга! -=x[PooH]x=- |  |  | 
	| 
			| 
					
						| Dimka 
								ДеятельКоманда клуба    Offline 
								Пол:    | 
								|  | « Ответ #8 : 18-03-2006 16:51 »  |  | 
 
 Будем надеяться не напрасно ты мучался, ведь возможно для Oksy важно поработать с видеопамятью напрямую. Это врядли. Если только "для общего развития", но совсем не для решения задачи. К тому же gettext и puttext и так работают с видеопамятью напрямую (если directvideo включено, иначе через BIOS). |  
						| 
								|  |  
								|  |  Записан | 
 
 Программировать - значит понимать (К. Нюгард)Невывернутое лучше, чем вправленное (М. Аврелий)
 Многие готовы скорее умереть, чем подумать (Б. Рассел)
 |  |  | 
	| 
			| 
					
						| Oksy 
								Гость
 | 
								|  | « Ответ #9 : 19-03-2006 07:16 »  |  | 
 
 dimka, спасибо за подробный ликбез!:) Как разгребусь с дипломом, сразу же займусь "общим развитием"  |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| МАКСИМ. 
								Гость
 | 
								|  | « Ответ #10 : 06-04-2006 17:19 »  |  | 
 
 привет !я тоже считал Шилдта и сталкнулся с проблемой  функций Save_Video()и Restore_Video(). там с предачей   аттрибута байта в функцию.   у меня так получилось в BORLAND C 3.1 c этими функциями:  /*------save screen-------*/ void Save_Video(int startx,int endx,        int starty,int endy, unsigned  int  *buf_ptr){  union REGS r;  register int i,j;  for(i = starty;i<endy; i++)     for(j = startx;j<endx; j++) {    goto_xy(j,i);    r.h.ah = 8;    r.h.bh = 0;    *buf_ptr++ = int86(0x10,&r,&r);    putchar(' ');//clear screen     } } /*-----return of screen-----*/ void  Restore_Video(int startx,int endx,             int starty,int endy, unsigned  int  *buf_ptr){     union REGS r;     register int i,j;    for( i=starty; i<endy; i++)        for( j=startx; j<endx; j++){     goto_xy(j,i);     r.h.ah = 9;//func write simbol     r.h.bh = 0;//videopage     r.x.cx = 1;// 1 simbol     r.h.al = *buf_ptr++;     r.h.bl = 0x90;// !!! attrib - цвет фона(9)  и цвет символа(0) я задал сам;     int86(0x10,&r,&r);// !        } } с синтаксисом в стиле "модерн" я немного не понял что имелось ввиду.  это программирование на Си под виндос?   |  
						| 
								|  |  
								| « Последнее редактирование: 13-12-2007 21:01 от Алексей1153++ » |  Записан | 
 |  |  | 
	| 
			| 
					
						| Finch 
								СпокойныйАдминистратор    Offline 
								Пол:    
								Пролетал мимо
								
								
								
								
								
							 | 
								|  | « Ответ #11 : 06-04-2006 19:50 »  |  | 
 
 МАКСИМ., В виндовсе практически нельзя напрямую лазить в видеопамять. Так что, покажи не понятный участок кода. Будем разбираться и объяснять. |  
						| 
								|  |  
								|  |  Записан | 
 
 Не будите спашяго дракона.              Джаффар (Коша) |  |  | 
	| 
			| 
					
						| МАКСИМ. 
								Гость
 | 
								|  | « Ответ #12 : 07-04-2006 01:28 »  |  | 
 
 Finch, я через функции BIOS-а  только начал работать с видеопамятью.а про функции(Save_Video()и Restore_Video() ) что я писал - я их реализовал в своих программах.я в DOs-е  пишу программки.до винды еще не дошел.но немного программировал на делфи, ассемблере в винде.
 А вообще программировать хочу научиться и перенять некоторый опыт  от профессионалов.сейчас и я изучаю Си и по возможности  Ассемблер.
 
 
 
 |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	|  |