© Иван Рощин, Москва
| ZXNet | : 500:95/462.53 |
| : bestview@mtu-net.ru | |
| WWW | : http://www.ivr.da.ru |
(«Радиомир. Ваш компьютер» 9/2003)
При программировании графических эффектов, работающих в
Вы задаёте (непосредственно в тексте программы см. комментарии) длину переопределяемого участка палитры, базовые цвета (между которыми и будет происходить плавный переход), указываете, будет палитра зацикленной или нет (если да значит, после последнего цвета будет плавный переход к первому), определяете имя файла, в который будет записана вычисленная информация, и формат, в котором она будет записана (двоичный, или же текстовый для последующего включения в вашу программу на ассемблере). Можно указать, и чтобы информация вообще не записывалась в файл например, если вы хотите сначала просто подобрать наиболее подходящее сочетание цветов.
После запуска программа показывает на экране все вычисленные цвета палитры (см. рис. 1, 2), а после нажатия любой клавиши записывает (если нужно) файл c компонентами этих цветов и завершает свою работу.
Базовые цвета (их можно задать произвольное количество) определяются путём
указания их
| Цвет | R | G | B |
|---|---|---|---|
| чёрный | 0 | 0 | 0 |
| синий | 0 | 0 | 63 |
| зелёный | 0 | 63 | 0 |
| голубой | 0 | 63 | 63 |
| красный | 63 | 0 | 0 |
| фиолетовый | 63 | 0 | 63 |
| жёлтый | 63 | 63 | 0 |
| белый | 63 | 63 | 63 |
/* Программа формирования VGA-палитры
с плавным переходом между заданными цветами.
(с) Иван Рощин, Москва, 2002. */
#include <dos.h>
#include <stdio.h>
#define pal_len 256 /* Длина палитры (1-256). */
#define pal_loop 0 /* 0 - незацикленная палитра, 1 - зацикленная. */
/* Базовые цвета (между которыми будет плавный переход): */
int base_colors[]={0,0,0, 63,63,63};
#define save_mode 0 /* 0 - не записывать палитру,
1 - записать в двоичный файл,
2 - записать в текстовый файл (asm). */
char *save_name=""; /* Имя записываемого файла. */
void main ()
{
int palette_r [pal_len]; /* Компоненты формируемой палитры. */
int palette_g [pal_len];
int palette_b [pal_len];
int n=sizeof(base_colors)/(sizeof(int)*3); /* Количество базовых цветов. */
int i,j;
int base;
float part;
union REGS rg;
unsigned char mode;
FILE *f_dst;
/* Формируем палитру. */
#if (pal_loop==0)
/* Палитра не зациклена. */
/* Для всех элементов палитры, кроме последнего: */
for (i=0; i<(pal_len-1); i++)
{
base=i/(((float)(pal_len-1))/(n-1));
part=i/(((float)(pal_len-1))/(n-1))-base;
palette_r[i]=base_colors[base*3]*(1-part)+base_colors[base*3+3]*part+0.5;
palette_g[i]=base_colors[base*3+1]*(1-part)+base_colors[base*3+4]*part+0.5;
palette_b[i]=base_colors[base*3+2]*(1-part)+base_colors[base*3+5]*part+0.5;
}
/* Цвет последнего элемента палитры
равен последнему базовому цвету: */
palette_r[pal_len-1]=base_colors[(n-1)*3];
palette_g[pal_len-1]=base_colors[(n-1)*3+1];
palette_b[pal_len-1]=base_colors[(n-1)*3+2];
#else
/* Палитра зациклена. */
for (i=0; i<pal_len; i++)
{
base=i/(((float)pal_len)/n);
part=i/(((float)pal_len)/n)-base;
if (base<(n-1))
{
palette_r[i]=base_colors[base*3]*(1-part)+base_colors[base*3+3]*part+0.5;
palette_g[i]=base_colors[base*3+1]*(1-part)+base_colors[base*3+4]*part+0.5;
palette_b[i]=base_colors[base*3+2]*(1-part)+base_colors[base*3+5]*part+0.5;
}
else /* base=n-1 */
{
palette_r[i]=base_colors[(n-1)*3]*(1-part)+base_colors[0]*part+0.5;
palette_g[i]=base_colors[(n-1)*3+1]*(1-part)+base_colors[1]*part+0.5;
palette_b[i]=base_colors[(n-1)*3+2]*(1-part)+base_colors[2]*part+0.5;
}
}
#endif
/* Определяем и запоминаем текущий режим работы видеоадаптера: */
rg.h.ah=0x0f;
int86 (0x10, &rg, &rg);
mode=rg.h.al;
/* Включаем режим 320*200*256: */
rg.x.ax=0x0013;
int86 (0x10, &rg, &rg);
/* Выводим в центре экрана прямоугольник, в котором представлены все цвета
сформированной палитры. Если сформированная палитра содержит менее 256
элементов, то первые элементы текущей палитры не будут затронуты; таким
образом, фон останется чёрным. Иначе фон будет таким, каков цвет первого
элемента палитры. */
for (i=0; i<pal_len; i++)
{
rg.h.ah=0x10; /* Устанавливаем новое значение */
rg.h.al=0x10; /* элемента палитры. */
rg.h.bh=0;
rg.h.bl=i+(256-pal_len);
rg.h.dh=palette_r[i];
rg.h.ch=palette_g[i];
rg.h.cl=palette_b[i];
int86 (0x10, &rg, &rg);
for (j=90; j<110; j++) /* Изображаем вертикальную линию */
{ /* соответствующего цвета. */
rg.h.ah=0x0c;
rg.h.al=i+(256-pal_len);
rg.h.bh=0;
rg.x.cx=i+((320-pal_len)/2);
rg.x.dx=j;
int86 (0x10, &rg, &rg);
}
}
/* Ждём нажатия клавиши и восстанавливаем прежний режим
работы видеоадаптера: */
while (bioskey(1)==0);
rg.h.ah=0;
rg.h.al=mode;
int86 (0x10, &rg, &rg);
/* Если надо, записываем палитру в файл: */
#if (save_mode==1)
f_dst=fopen(save_name,"wb");
for (i=0; i<pal_len; i++)
{
fputc(palette_r[i],f_dst);
fputc(palette_g[i],f_dst);
fputc(palette_b[i],f_dst);
}
fclose(f_dst);
#endif
#if (save_mode==2)
f_dst=fopen(save_name,"wt");
for (i=0; i<pal_len; i++)
{
fprintf (f_dst,"%s"," db ");
fprintf (f_dst,"%u%c",palette_r[i],',');
fprintf (f_dst,"%u%c",palette_g[i],',');
fprintf (f_dst,"%u%c",palette_b[i],'\n');
}
fclose(f_dst);
#endif
}
Пример 1. Нужно получить
Устанавливаем в тексте программы следующие значения:
#define pal_len 240
#define pal_loop 0
int base_colors[]={63,63,0, 63,0,0};
#define save_mode 1
char *save_name="primer_1.bin";
После компиляции и запуска на экране будут изображены требуемые 240 цветов (рис. 1).
![]() |
После нажатия любой клавиши компоненты будут записаны в двоичный файл. На каждую компоненту выделяется один байт, порядок следования r1, g1, b1, r2, g2, b2, , r240, g240, b240:
0000: 3F 3F 00 3F 3F 00 3F 3E 00 3F 3E 00 3F 3E 00 3F 0010: 3E 00 3F 3D 00 3F 3D 00 3F 3D 00 3F 3D 00 3F 3C 0020: 00 3F 3C 00 3F 3C 00 3F 3C 00 3F 3B 00 3F 3B 00 ..................................................... 02C0: 00 3F 01 00 3F 01 00 3F 01 00 3F 00 00 3F 00 00 |
Пример 2. Нужно получить
Устанавливаем в тексте программы следующие значения:
#define pal_len 200
#define pal_loop 1
int base_colors[]={63,0,0, 63,63,0, 0,63,0, 63,0,63};
#define save_mode 2
char *save_name="primer_2.txt";
После компиляции и запуска на экране будут изображены требуемые 200 цветов (рис. 2).
![]() |
После нажатия любой клавиши компоненты будут записаны в текстовый файл:
db 63,0,0
db 63,1,0
db 63,3,0
.........
db 63,0,1