26. Bölüm
Cenker Özkurt
C'de önemli olan diğer bir nokta da, esnek alt rutinlerin hazırlanmasıdır. Böylece her yeni bir program hazırlanışında eski rutinlerden de yararlanılır ve programın kısa sürede bitmesi sağlanır. Ayrıca sık sık karşınıza çıkan problemlerle yeniden uğraşmak zorunda kalmazsınız ve kalan zamanı yeni şeyler keşfetmek için kullanabilirsiniz. Bu olayı modüler çalışma olarak tarif etmek de mümkün. Modüler çalışma C'nin getirdiği avantajlardan en büyüğüdür. Bu ayki konumuzu da kısaca açıkladıktan sonra, ilgili örneklere geçebiliriz.
İlk olarak, aşağıda hazırlamış olduğum rutinleri yazdıktan sonra bir sefer derleyin. Derleme sonucunda oluşan, uzantısı '.o' olan dosyayı disketinize saklayın. Böylece programı her seferinde derlemenize gerek kalmaz ve zamandan oldukça fazla tasarruf etmiş olursunuz. Buna benzer library'leri kendiniz de oluşturup bir diskette saklayabilirsiniz. Bu library'ler sayesinde program yazmak kolaylaşacaktır. Şimdi örneğimizi bir inceleyelim;
/* Programming by CENKER OZKURT */
#include <stdio.h>
#include <exec/memory.h>
#include <graphics/gfxbase.h>
#include <intuition/intuitionbase.h>
#include <libraries/dos.h>
#include <jiff.h>
struct GfxBase *GfxBase;
struct DosBase *DosBase;
struct IntuitionBase *IntuitionBase;
struct ILBM info *info;
struct NewScreen scr={0,0,0,0,0,0,1,NULL,CUSTOMSCREEN,NULL,NULL,NULL};
/*-Screen Structures-*/
struct RastPort *scr_rastport[5];
struct ViewPort *scr_viewport[5];
struct Screen *screen[5];
/*-------------------*/
openlibrary()
{IntuitionBase=OpenLibrary("intuition.library",0);
if(!IntuitionBase) {
printf("Intuition Error!...");
closelibrary();
}
GfxBase=OpenLibrary("graphics.library",0);
if(!GfxBase) {
printf("Graphics Error!...");
closelibrary();
}
DosBase=OpenLibrary("dos.library",0);
if(!DosBase) {
printf("Dos Error!...");
closelibrary();
}
return(0); /* OK! */
}
closelibrary()
{
if(DosBase) CloseLibrary(DosBase);
if(GfxBase) CloseLibrary(GfxBase);
if(IntuitionBase) CloseLibrary(IntuitionBase);
exit(0);
}
s_rastport(s)
int s;
{
return((long)scr_rastport[s]);
}
s_viewport(s)
int s;
{
return((long)scr_viewport[s]);
}
openscreen(s,maxx,maxy,color)
int s; /* Screen number */
int color; /* Screen color number */
int maxx,maxy; /* Screen sizes */
{
int plane;
switch(color) {
case 2: plane=1;
case 4: plane=2;
case 8: plane=3;
case 16: plane=4;
case 32: plane=5;
case 4096: plane=6;
}
scr.Width=maxx;
scr.Height=maxy;
scr.Depth=plane;
if(maxx==320&&(maxy==200||maxy==256)) scr.ViewModes=NULL;
if(maxx==320&&(maxy==400||maxy==512)) scr.ViewModes=LACE;
if(maxx==640&&(maxy==200||maxy==256)) scr.ViewModes=HIRES;
if(maxx==640&&(maxy==400||maxy==512)) scr.ViewModes=HIRES|LACE;
if(maxx==320&&(maxy==200||maxy==256)&&plane==6) scr.ViewModes=HAM;
if(maxx==320&&(maxy==400||maxy==512)&&plane==6) scr.ViewModes=HAM|LACE;
screen[s]=OpenScreen(&scr);
if(!screen[s]) return(1);
scr_rastport[s]=&screen[s]->RastPort;
scr_viewport[s]=&screen[s]->ViewPort;
ScreenToFront(screen[s]);
return(0); /* OK! */
}
closescreen(s)
int s; /* Screen number */
{
CloseScreen(screen[s]);
}
scrfront(s)
int s; /* Screen number */
{
ScreenToFront(screen[s]);
}
scrback(s)
int s; /* Screen number */
{
ScreenToBack(screen[s]);
}
leftmouse()
{
#asm
clr.ld0
btst#6,$bfe001
bne.s lm
add.l #l,d0
lm:
#endasm
}
waitmouse()
{
#asm
loop1:btst#6,$bfe001
bne loop1
#endasm
}
waitkey()
int a,b;
unsigned char *key=0xbfec01;
a=*key;
while(a==(b=*key));
return(b);
}
plot(s,x,y)
int s; /* Screen number */
int x; /* x coordinates */
int y; /* y coordinates */
{
Move(scr_rastport[s],x,y);
Draw(scr_rastport[s],x,y);
}
line(s,x,y,x1,y1)
int s; /* Screen number */
int x,y; /* Start coordinates */
int x1,y1; /* Stop coordinates */
{
Move(scr_rastport[s],x,y);
Draw(scr_rastport[s],x1,y1);
}
box(s,x,y,x1,y1)
int s; /* Screen number */
int x,y; /* Start coordinates */
int x1,y1; /* Stop coordinates */
{
Move(scr_rastport[s],x,y);
Draw(scr_rastport[s],x1,y);
Draw(scr_rastport[s],x1,y1);
Draw(scr_rastport[s],x,y1);
Draw(scr_rastport[s],x,y);
}
circle(s,x,y,r)
int s; /* Screen number */
int x,y; /* Center coordinates */
int r; /* r */
{
DrawEllipse(scr_rastport[s],x,y,r,r);
}
print(s,x,y,string)
int s; /* Screen number */
int x,y; /* Center coordinates */
char string[40]; /* String */
{
Move(scr_rastport[s],x,y);
Text(scr_rastport[s],string,strlen(string));
}
ink(s,color)
int s; /* Screen number */
int color; /* ink color */
{
SetAPen(scr_rastport[s],color);
}
paper(s,color)
int s; /* Screen number */
int color; /* paper color */
{
SetBPen(scr_rastport[s],color);
}
mouse_x(s)
int s; /* Screen number */
{
return(screen[s]->MouseX);
}
mouse_y(s)
int s; /* Screen number */
{
return(screen[s]->MouseY);
}
set_palette(s,color,r,g,b)
int s; /* Screen number */
int color; /* Palette color */
int r,g,b; /* RGB values */
{
SetRGB4(scr_viewport[s],color,r,g,b);
}
LoadIFF(s,name)
int s; /* Screen number */
char name[]; /* Picture name */
{
info=read_iff(name,0);
if(info==NULL) {
printf("%s not found!...",name);
return(1);
}
BltBitMapRastPort(&info->bitmap,0,0,scr_rastport[s],0,0,320,256,0xc0);
free_planes(&info->bitmap);
put_cmap(s,(1<bitmap.Depth));
}
put_cmap(s,n)
int s; /* Screen number */
int n;
{
int i,r,g,b;
for(i=0;i<n;i++)
{
r=info->cmap[3*i]/16;
g=info->cmap[(3*i)+1]/16;
b=info->cmap[(3*i)+2]/16;
SetRGB4(scr_viewport[s],i,r,g,b);
}
}
Programda sık sık kullanacağımız alt rutinleri görüyorsunuz. Bu sayede bazı işlemleri yapmak oldukça kolaylaşacaktır. Şimdi programımızın içerisinde bulunan rutinleri örneklerle inceleyelim.
main()
{
openlibrary();
openscreen(0,320,256,32);
print(0,50,50,"Amiga C");
waitkey();
closescreen(0);
closelibrary();
}
Programımız dikkat ettiyseniz oldukça kısa. Çünkü işin zor kısımları ilk vermiş olduğumuz rutinlerde mevcut. Bize kalan bu rutinleri dikkatlice kullanmak. Programı çalıştırmak için ilk olarak;
openlibrary() ; bu alt rutinle, isminden de anlaşılacağı gibi, kullanılacak olan library'leri açıyoruz. Her programımızın başına bu rutini koymak zorundayız.
openscreen() ; ekran açmak için kullanıyoruz, içerisindeki parametreler sırasıyla; ekran numarası, x genişliği, y genişliği, ve renk sayısı. Ekran numarasını, birden fazla ekran kullanabilmek için kullanıyoruz. En fazla 5 adet ekran açabiliriz. Eğer ekrana bir yazı yazacaksak, o ekran numarasını da belirtmek gerekiyor. Evet, ekran açmak, artık bu kadar kolay hale geldi. Sizce de öyle değil mi?
print(); ile ekranımızın herhangi bir köşesine yazımızı yazıyoruz. Buradaki parametreler; ekran numarası, x noktası, y noktası ve yazı dizimiz.
waitkey(); ile bir tuşa basılıncaya kadar bekliyoruz. Ve daha sonra closelibrary(); ile bütün library'leri kapayarak programdan çıkıyoruz. Program bu kadar!!
Sıra geldi yeni bir örneğe;
/* Programming by Cenker Ozkurt */
#include <stdio.h>
main()
{
openlibrary();
openscreen(0,320,256,32);
LoadIFF(0,"df0:picture");
waitmouse();
palet_off();
closescreen(0);
closelibrary();
}
palet_off()
{
int i,j;
for(i=15;i>=0;i--) {
Delay(1);
for(j=1;j<=15;j++)
set_palette(0,j,i,i,i);
}
}
Resim yüklemek artık bu kadar kolay. Buradaki farklı rutin LoadIFF(); rutini. İlk parametre resmin yükleneceği ekran numarası, ikinci parametre ise doğal olarak resmimizin yeri ye ismi. Program içerisindeki palet_off() rutini ise mouse tuşuna basıldıktan sonra parlama effekti vermemizi sağlıyor. Kullanmak zorunda değiliz. Aşağıdaki örnek ise kısa bir resim şovu!
/* Programming by Cenker Ozkurt */
main()
{
openlibrary();
openscreen(0,320,256,32);
openscreen(1,320,256,32);
scrfront(0);
LoadIFF(0,"df0:picture1");
LoadIFF(1,"df0:picture2");
waitmouse();
scrfront(1);
waitmouse();
closescreen(1);
closescreen(0);
closelibrary();
}
İki ekran kullanıyoruz. scrfront(); istediğimiz ekranı ön plana alıyor. Aynı şekilde scrback(); rutinini de kullanmak mümkün.
Programda kullanabileceğimiz diğer alt rutinlerin kullanımı da aşağıda olduğu gibi;
main()
{
char s[40];
openlibrary();
openscreen(0,320,256,32);
ink(0,2); /* Kalem rengimizi değiştiriyor */
print(0,50,50,"Amiga C");
/* mouse_x() ve mouse_y() ile mouse koordinatlarini okuyoruz */
sprintf(s,"x mouse=%d y mouse %d ",mouse_x(0),mouse_y(0));
while(!leftmouse()) {
int(0,5);
print(0,50,100,s);
}
box(0,0,0,319,255); /* Ekrana bir kutu çiziyoruz */
plot(0,1,1); /* Nokta koymak için */
fine(0,0,0,319,255); /* Çizgi rutini */
set_palette(0,0,15,15,15); /* Zeminin paletini değiştiriyoruz */
waitmouse(); /* Mouse'u bekliyor */
closescreen(0);
closelibrary();
}
Kullanabileceğimiz rutinler bunlar. Bu programa başka rutinler ekleyerek istediğinizi yapabilirsiniz. Şimdilik bu kadar. Gelecek ay buluşmak üzere hepinize yapısal günler!...