+----------------+ |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ň