+----------------+
|CÉČKOVÉ ZDROJÁKY|
+----------------+
Ing. Aleš Zíka se zamyslel nad mými zdrojáky k seriálu
naprogramujte si vlastní DEMO a převedl je do Céčka. Od příště už
budou zdrojáky vždy dva. Pascal i Céčko.
Aleš k tomu napsal své úvodní slovo, které vám tu
předhazuji...
Seriál Naprogramujte si vlastní demo mě velice zaujal, a chtěl
jsem všechny příklady prakticky vyzkoušet. Pascal ale ovládám pouze
pasivně a v současné době se začínám stále více věnovat jazyku
C/C++, proto jsem všechny demonstrační programy přepsal do tohoto
jazyka. A asi by byla škoda, aby se tím zbytečně zabývalo více lidí,
tak jsem se rozhodl výsledky svého úsilí zveřejnit jako přílohu k
tomuto seriálu.
Všechny předvedené programy jsem odladil na překladači Borland
C++, verze 3.1. Překládám sice plusplusovou variantou překladače,
ale zatím jsem nepoužil žádné objektové konstrukce, takže by nemělo
mít problémy ani normální céčko, taktéž s jinými parametry by neměly
být problémy, vše jsem překládal v modelu Small a pokud je potřeba
vzdálený ukazatel, definuji ho explicitně. Komentáře jsem převzal
z originálních příkladů, kde jsem cítil potřebu, doplnil jsem ještě
vlastní.
Na závěr bych ještě rád upozornil, že v céčku jsem dost
začátečník, takže moje výtvory mohou obsahovat prapodivné konstrukce
nebo dokonce závažné chyby, které se neprojevily jen náhodou. Proto
pokud tam cokoliv objevíte, neváhejte a křičte. Pokud by se někdo
chtěl spojit přímo se mnou, tak jsem na adrese
unicode@cb.bohem-net.cz
Ing. Aleš Zíka, Pelhřimov
unicode@cb.bohem-net.cz
/* Demonstracni program k prvnimu dilu kursu */
#include <mem.h> // pro fci _fmemset()
#include <conio.h> // kbhit(), getch(), clrscr()
#include <stdlib.h> // random()
#include <stdio.h> // printf()
// #define VIDEO_ARRAY
// Odkomentovanim predchozi radky, se zmeni definice
// ukaztele na videopamet.
#ifdef VIDEO_ARRAY
typedef char V_ARR[200][320];
V_ARR _seg *VGA = (V_ARR _seg*)0xA000;
/* Ukazatel do videopameti neni definovan jako prosty ukazatel
na retezec, ale jako ukazatel na pole s dimenzemi odpovidajicimi
rozmerum obrazovky, to nam pozdeji ve fci MEMPutpixel() vyrazne
zprehledni zapis na obrazovku. */
#else
char _seg *VGA = (char _seg*)0xA000; // ukazatel na seg videopameti
#endif
/* Pri primem pristupu do videopameti budu dost casto pouzivat
ruzne spinave triky s pretypovavanim integeru na ukazatel a
pretypovavanim mezi ruznymi typy ukazatelu. Nejsem v teto oblasti
prilis silny v kramflecich, predlozeny tvar je vysledkem slozitych
experimetu, koncicich zpravidla zasekem pocitace, proto uvitam
jakoukoli radu zkusenejsiho ceckare. Klidne mi vynadejte, ze takovou
prasarnu jste za cely zivot nevideli, ja se neurazim, neni ostuda
nepoucenym byti, ale je ostuda nepoucenym zustavati. */
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 SetMCGA()
// Tato fce zapne mod 320x200x256.
{
asm mov ax, 0x13
asm int 0x10
}
void SetText()
// Zapnuti textoveho modu.
{
asm mov ax, 0x3
asm int 0x10
}
void Cls(unsigned char Col)
// Maze obrazovku zadanou barvou.
{
_fmemset(VGA, Col, 64000);
// Cistejsi tvar by byl s explicitnim pretypovanim:
// _fmemset((void far*)VGA, (int)Col, 64000);
}
void INTPutpixel(int X, int Y, unsigned char Col)
// Kresli bod pomoci INT.
{
asm mov ah, 0xC // sluzba 0xC
asm mov al, [Col] // barva do AL
asm mov cx, [X] // souradnice x do CX
asm mov dx, [Y] // souradnice y do DX
asm mov bx, [1] // BX = 1
asm int 0x10 // a vyvolame preruseni 0x10
}
void TestINTPutpixel()
// Test kresleni bodu pomoci preruseni.
{
int loop1, loop2;
for (loop1 = 0;loop1 <= 319; loop1++)
for (loop2 = 0; loop2 <= 199; loop2++)
INTPutpixel(loop1, loop2, random(256));
Readkey();
Cls(0);
}
void MEMPutpixel (int X, int Y, unsigned char Col)
// Kresleni bodu primym zapisem do videopameti.
{
#ifdef VIDEO_ARRAY
(*VGA)[Y][X] = Col;
/* Diky definici ukazatele jako ukazatele na dvourozmerne
pole, nyni nemusime prepocitavat souradnice obrazovky, ale obrazovka
se chova jako virtualni dvourozmerna matice a my primo prirazujeme
jejim prvkum - pixelum. Jedinou drobnou komplikaci je, ze je zde
otoceno poradi souradnic Y, X oproti beznym zvyklostem, vyplyva to
ze zpusobu implementace vycerozmernych poli v C, mozna ale nekdo
prijdete na to, ja to jednoduse obejit - nevahejte, NAPISTE!! */
#else
VGA[X + Y * 320] = Col;
// Opet lze napsat i jinak:
// *(VGA + (char near*)(X + Y * 320)) = Col;
#endif
}
void TestMEMPutpixel()
// Nahodne zaplneni obrazovky pomoci MEMPutpixel.
{
int loop1, loop2;
for (loop1 = 0;loop1 <= 319; loop1++)
for (loop2 = 0; loop2 <= 199; loop2++)
MEMPutpixel(loop1, loop2, random(256));
Readkey();
Cls(0);
}
void main(void)
// HLAVNI PROGRAM
{
clrscr();
printf ("Pockam na klavesu, smazu obrazovku,\n");
printf ("pockam na klavesu,\n");
printf ("smazu znova obrazovku, ale jinou barvou,\n");
printf ("pockam na klavesu,\n");
printf ("naplnim obrazovku nahodnym vzorkem.\n");
printf ("Poprve pomoci INT,\n");
printf ("podruhe primym zapisem do videopameti.\n");
printf ("Mezi obema pockam na klavesu.\n");
printf ("Na zaver znovu zapnu textovy mod.\n\n\n");
printf ("Zmackni klavesu a jedem ...");
Readkey();
SetMCGA();
Cls(32);
Readkey();
Cls(90);
Readkey();
TestINTPutpixel();
TestMEMPutpixel();
SetText();
}
výheň