Консультация № 187566
09.10.2013, 19:31
168.06 руб.
0 3 1
Уважаемые эксперты! Пожалуйста, ответьте на вопрос:
Как разработать функцию, организующую вывод в заданное место экрана окна заданных размеров. Окно должно "проявляться" из отдельных частей (последовательность "проявления" частей - случайная, размеры частей - произвольны, но процесс "проявления" должен занимать не менее 10 этапов) c замедлением по времени. После нажатия <enter> окно должно также постепенно исчезать. И исходник скиньте, пожалуйста.

Обсуждение

давно
Старший Модератор
31795
6196
10.10.2013, 15:31
общий
Уточните свой вопрос.
Что именно подразумевается под окном и его отдельными частями?
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
10.10.2013, 16:28
общий
вывод на экран осуществлять с помощью прямого обращения к видеопамяти. Библиотечные функции, реализующие вывод на экран (conio.h), к программному файлу не подключать. Содержательную часть задачи реализовать с помощью функции пользователя. Программа должна вызвать данную функцию несколько раз с различным набором аргументов. Это все, что есть в задании, больше никаких пояснений не было.
давно
Старший Модератор
31795
6196
12.10.2013, 04:13
общий
это ответ
Здравствуйте, Быков Евгений Андреевич!

Если нельзя подключать библиотеки - не будем.
Смотрите код(ТС++ 3.00; Win XP):
[code h=200]#define maxCount 13

//глобальные переменные
char far *VM=(char far*)0x0B8000000;//адрес начала физического адреса видеобуфера
char far *v;//переменная для работы с видеобуфером
int attr;//переменная для атрибутов
int x_L=5,y_L=5,x_R=55,y_R=12;//размеры окна

//подпрограмма получения кода нажатой клавиши
//return a - скен-код нажатой клавиши,и не важно сколько клавиш нажато одновременно
char GetAnyKey(){
char a;
asm xor ax,ax//читаем символ с клавиатуры
asm int 0x16//функция БИОС
asm mov a,ah//запоминаем скен-код
return a;
};//GetAnyKey

//подпрограмма рисования фона
// _x - левый верхний угол окна
// _y - см. выше
// d_x- размер по горизонтали
// d_y - размер по вертикали
void OutXYbg(int _x,int _y,int d_x,int d_y){
int i,j;
for(i=_y;i<d_y;i++){//цикл по вертикали
v=VM+2*(i*80+_x);// физический адрес адресуемой памяти
for(j=_x;j<d_x;j++){//цикл по горизонтали
v++;//значение пропускаем
*v++=attr;//записываем атрибут позиции
};//for j
};//for i
};

//подпрограмма вывода символа в нужную позицию
// _x -коорджинаты позиции
// _y - см. выше
// z - выводимый символ
void OutXYchar(int _x,int _y,char z){
v=VM+2*(80*_y+_x);//считаем физический адрес
*v++=z;//записываем символ
*v=attr;//устанавливаем атрибуты
};//OutXYchar

//подпрограмма вывода несколько символов в одну линию
// _x - координаты начала вывода
// _y - см. выше
// _z - количество символов
// z - выводимый символ
// _d - приращение для следующей позиции
void OutXYline(int _x,int _y,int _z,char z,int _d){
for(int i=0;i<=_z;i++){
v=VM + 2*(80*_y + i*_d + _x);// !!! обратите внимание на приращение, как изменяется позиция !!!
*v++=z;//записываем символ
*v=attr;//и его атрибуты
};//for i
};//OutXYline

//подпроогрвамма вывода строки на экран в нужную позицию
// _x - координаты верхнего-левого угла
// _y - см. выше
// _z - количество строк в линии
// s - выводимая строка
void OutXYstr(int _x,int _y,int _z,char *s){
int i=0;
while(*s){//пока не закончилась строка
v=VM + 2*(80*(_y+(i / _z))+_x + (i % _z));//считаем физический адрес
*v++=*s++;//записываем символ и переходим к следующему
*v=attr;//устанавливаем атрибут
i++;//счетчик символов в строке
};//while
};//OutXYStr

//подпроограмма задержки
// z - количество итераций z*z
void TimeOut(int z){
int x,y;
x=z;
while(x>0){//внешний цикл
y=z;
while(y>0){//внутренний цикл
y--;};//while y>0
x--;
};//while x>0
};//TimeOut

//подпрограмма получения случайного значения
// z - макимальное значение, т.е. 0..z-1
int GetRnd(int z){
int gr;
v=(char far*)0x0040006C;//адрес системого времени
gr=*v;//считываем значение
return gr % z;//возвращаем остаток от милисекунды деленные на размер
};

//подпрограмма рисования частей окна
void Draw(){
int i,j;
j=GetRnd(maxCount);//получаем начальное значение изменений
i=maxCount+1;//количество частей окна
while(i>=0){
i--;//уменьшаем итерацию
j+=3;//получаем псевдослучайное число
j%=maxCount;//в нужном диапазоне значений
// !!! коментарии case хх первоначальные значения - нужно будет изменить !!!
switch(j){
//левый верхний угол
case 0:{OutXYchar(x_L,y_L,0xC9);
break;};//case 0
//правый верхний угол
case 1:{OutXYchar(x_R,y_L,0xBB);
break;};//case 4
//правый нижний угол
case 2:{OutXYchar(x_R,y_R,0xBC);
break;};//case 6
//левый нижний угол
case 3:{OutXYchar(x_L,y_R,0xC8);
break;};//case 8
//левая верхняя горизонталь
case 4:{OutXYline(x_L+1,y_L,15,0xCD,1);
break;};//case 1
//правая верхняя горизонталь
case 5:{OutXYline(x_L+36,y_L,13,0xCD,1);
break;};//case 3
//нижняя горизонталь
case 6:{OutXYline(x_L+1,y_R,48,0xCD,1);
break;};//case 7
//горизонталь квази 3D-изображения
case 7:{OutXYline(x_L+1,y_R+1,49,0xDB,1);
break;};//case 12
//левая вертикаль
case 8:{OutXYline(x_L,y_L+1,5,0xBA,80);
break;};//case 9
//правая вертикаль
case 9:{OutXYline(x_R,y_L+1,5,0xBA,80);
break;};//case 5
//вертикаль квази 3D-изображения
case 10:{OutXYline(x_R+1,y_L+1,7,0xDB,80);
break;};//case 11
//имя выводимого окна
case 11:{OutXYstr(x_L+17,y_L,30,"-= С п р а в к а =-");
break;};//case 2
//фон выводимого окна
case 12:{OutXYbg(x_L+1,y_L+1,x_R,y_R);
break;};//case 10
};//switch
TimeOut(30000);
};//while
//дополнительная опция - вывод текста в окно :)))
if(attr!=0){OutXYstr(x_L+1,y_L+1,49,
"Окно должно 'проявляться' из отдельных частей (последовательность 'проявления' частей - случайная, размеры частей - произвольныe, но процесс 'проявления' должен занимать не менее 10 этапов) c замедлением по времени. После нажатия <enter> окно должно также постепенно исчезать.");
};
};//Draw

//основная функция задания
void MyFuncMain(){
attr=0x1f;//синий фон + белый текст
Draw();//выводим
do{}while(GetAnyKey()!=0x1c);//цикл ожидания клавиши "ВВОД"
attr=0x0;// всё черное
Draw();//выводим, т.е. стираем.
};//MyFuncMain

//основная процедура
void main(void)
{
//устанавливаем видео режим
asm mov ax,0x03;
asm int 0x10;
//адресуем переменную на видео-буфер
v=VM;
for(int i=0;i<2*(80*24);i++){*v++=0x0;}//стираем всё
//вызываем основную функцию задания
MyFuncMain();
//финальное сообщение и ожидание клавиши
attr=13;
OutXYstr(10,10,50,"press any key ...");
GetAnyKey();
}//main[/code]

В программе релаизована псевдослучайная последовательность т.к. ожидать нормального распределения значений при таком генераторе и диапазоне - трудно, появляются не предскаазуемые задержки и т.п..

Код выше в кодировке ср1251, для DOS нужна ср866. Всё находится в прилагаемом архиве(*.срр + *.ехе +*.obj):q187566.zip (10.0 кб)
ps:вопросы задавайте в минифорум.
Удачи!
5
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Форма ответа