/* Demonstracni program k druhemu dilu kursu */
#include <dos.h> // outportb(), inportb()
#include <conio.h> // gotoxy(), textcolor(), textbackground()...
#include <stdlib.h> // random()
#define READ_COL 0x3C7 // port pro vyber cteni barvy
#define WRITE_COL 0x3C8 // port pro vyber zapisu barvy
#define RGB_COL 0x3C9 // port pro cteni/zapis barevnych slozek
// #define PLYNULE
// Odkomentovanim predchozi radky bude program snizovat
// jas barevnych slozek tak, aby dosly na nulu soucasne.
typedef struct Color {
unsigned char R;
unsigned char G;
unsigned char B;
}; // typ pro ulozeni RGB
unsigned char R, G, B;
void Readkey()
// Ceka na stisk klavesy
// nahrazuje stejnojmennou pascalskou proceduru.
{
while (!kbhit()) // cekam na klavesu
;
if (getch() == 0) // vyberu ji z bufferu
getch(); // pri rozsirenem kodu
}
void NactiPal(Color *Pole)
// Ulozi paletu.
{
int Citac;
outportb(READ_COL, 0); // zacinam barvou cislo 0
for (Citac = 0; Citac <= 255; Citac++)
// tolik je barev v palete
{
Pole[Citac].R = inportb(RGB_COL);
Pole[Citac].G = inportb(RGB_COL);
Pole[Citac].B = inportb(RGB_COL);
}
}
void ObnovPal(Color *Pole)
// Obnovi paletu.
{
int Citac;
outportb(WRITE_COL, 0); // zacinam barvou cislo 0
for(Citac = 0; Citac <= 255; Citac++) // tolik je barev v palete
{
outportb(RGB_COL, Pole[Citac].R);
outportb(RGB_COL, Pole[Citac].G);
outportb(RGB_COL, Pole[Citac].B);
}
}
void VezmiBarvu(unsigned char Barva)
// Nacte zadanou barvu z palety.
{
outportb(READ_COL, Barva);
R = inportb(RGB_COL);
G = inportb(RGB_COL);
B = inportb(RGB_COL);
}
void UlozBarvu(unsigned char Barva)
// Ulozi RGB do zadane barvy palety.
{
outportb(WRITE_COL, Barva);
outportb(RGB_COL, R);
outportb(RGB_COL, G);
outportb(RGB_COL, B);
}
void Smeti(void)
// Zaplni obrazovku barevnymi pismeny.
{
int X, Y;
for (X = 1; X <= 80; X++) // 80 sloupcu
for (Y = 1; Y <= 24; Y++) // 24 radku, pri zapisu na 25. radek
// by obrazovka poskocila nahoru
{
gotoxy(X, Y);
textcolor(random(255)); // nahodna barva popredi
textbackground(random(255)); // nahodna barva pozadi
cprintf("@");
}
}
void main(void)
{
int Citac, Barva;
Color Zaloha[255]; // ulozeni palety
clrscr();
Smeti(); // nasypu na obrazovku barevne zavinace
NactiPal(Zaloha); // nejdrive uchovam puvodni paletu
for (Citac = 1; Citac <= 63; Citac++) // RGB jsou 0 - 63
{
for (Barva = 0; Barva <= 255; Barva++) // barev je 0 - 255
{
VezmiBarvu(Barva); // nactu barvu
#ifdef PLYNULE
if (R > 1) R -= R / (64 - Citac);
if (G > 1) G -= G / (64 - Citac);
if (B > 1) B -= B / (64 - Citac);
/* Nevim jestli je to zrovna ono, ale je to viditelne jine nez
puvodni verze. Ono to totiz neni zas tak jednoduche, protoze tam
dochazi k pomerne znacnym zaokrouhlovacim chybam pri prevodech z
float na integer a zpet. */
#else
if (R > 1) R--; // ztlumim vsechny jeji slozky
if (G > 1) G--;
if (B > 1) B--;
#endif
UlozBarvu(Barva); // ulozim ji zpatky
}
delay(20); // cely proces trosku zpomalim
}
Readkey(); // obrazovka zhasnuta, cekam na klavesu
ObnovPal(Zaloha); // obnovim puvodni paletu, aby bylo neco videt
}
výheň