
Nyilván nem fogjuk a legújabb photoshop összes funkcióját implementálni, de azért egyszerű rajzokhoz elégséges mennyiségű dolgot implementálunk majd.
A kód első verzióját 2013-ban egy demoscene rendezvényre készítették, de egyszerűsége és rövidsége okán bárki képes elkészíteni. Ebben a cikkben arról lesz szó, hogy hogyan is készül egy rajzprogram, amivel az alábbi remekmű is készült:
A tervezés első lépéseként vegyük számításba hogy mire is kell alapvetően egy ilyen program használatához:
- grafikus képernyő
- egér
Ugyan ezek mind adottak a mai számítógépeken, de álmodjunk nagyot, és készítsünk olyan szoftvert ami támogatja a pc-ket visszamenőleg mondjuk 5-10-20-30 évre. Ha másban nem is, legalább ebben jobbak lehetünk :)
Lássunk is hozzá! Első megoldandó kérdés, hogy hogyan is használhatjuk a grafikus képernyőt. Ha a windows szolgáltatásaira építünk, akkor bizony nem nagyon tudunk 30 évre visszamenni, így legcélravezetőbb ha néhány réteget kihagyva indulunk el, és közvetlenül a BIOS által szolgáltatott grafikus képességeket használjuk. Ehhez egy mai gépen dosbox-ot használunk, míg a régi gépeken ez nem szükséges :) A BIOS egy betűszó, ami a számítógép alapszolgáltatásait magába foglaló csak olvasható memóriába égetett kódcsomag (Basic Input Output System). Ahhoz hogy a BIOS segitségével rajzolhassunk, először grafikus üzemmódba kell váltani, mert a dos/dosbox alapvetően karakteres képernyőt biztosít számunkra. Ehhez az INT 0x10 megszakításvektort használjuk:
1 2 |
MOV AL, 0x12 INT 0x10 |
Ezt követően lekérdezzük az egér aktuális állapotát az erre szolgáló megszakításvektor (INT 0x33) segítségével.
1 2 |
MOV AX, 0x03 INT 0x33 |
Ez visszatér az aktuális pozícióval és a gombok aktuális állapotával, majd kirajzolunk egy képpontot az aktuális helyre, az állapottól függő színnel szintén az INT 0x10 vektor segítségével:
1 2 3 |
XCHG AX, BX MOV AH, 0x0C INT 0x10 |
Itt pont kapóra jött, hogy az egér pozícióját azokban a regiszterekben kaptuk, mint amiben a képpont kirajzoláshoz a pozíciót be kellett állítani. Egyedül a kirajzolt képpont színét – amit az egér aktuális állapotából határozunk meg – kellett áttrükközni az AX regiszterbe.
Tulajdonképpen ennyi az egész, ezt kell ismételgetnünk a végtelenségig hogy folyamatos rajzolást biztosítsunk. Viszont kódismétlést figyelhetünk meg a videómegszakítás hívásakor (INT 0x10). Ezt eliminálva a kódból máris 12,5%-os méretcsökkenést érünk el.
Tehát a végső kód:
1 2 3 4 5 6 7 |
MOV AL, 0x12 drawloop: INT 0x10 MOV AX, 0x03 INT 0x33 XCHG AX, BX JMP drawloop |
A kód fordítás után (amit megtehetünk például flat assemblerrel) 14 byte méretű lesz (ne felejtsünk el “org 0x100-at” írni a kód elejére, ha tényleg .com programot szeretnénk fordítani). Fun fact: maga a kód rövidebb lett mint a cikk címe, és ugyan nem tud élsimítást, vagy layereket kezelni, de rajzolni nagyszerűen lehet vele.
Jó szórakozást hozzá!
2015. szeptember 8.