KICK Pascal
Retro bilgisayarGeçen ay meydana gelen yanlışlıktan dolayı yazımızı tekrar yayınlıyor ve özürlerimizi kabul etmenizi diliyoruz. “Tüm Pascal hayranları merhabalar. Söz verdiğimiz gibi bu aydan itibaren köşe haline gelerek her ay kısa örnek programlar yazacak ve bunların çalışmasını öğrenirken Amiga sistemi ile ilgili birkaç yararlı bilgi edineceğiz. Basic köşesinde olduğu gibi, bu örnek programları mümkün olduğu kadar kısa tutmaya çalışacağım. Böylece hatalar en aza indirgenmiş olacak ve siz de programları sıkılmadan yazabileceksiniz. Burada anlatılanlar sadece Pascal için geçerli konular değil. Programları istediğiniz dilde yazabilirsiniz, ama bu köşe dahilinde tüm program örnekleri Pascal dilinde olacak. Belki onuncu defadır tekrarlıyorum, merak ettiğiniz sorunları bana yazabilirsiniz (Cevap bile veriyorum!!), ancak konu seçimini bana bıraktığınız sürece ben belirli bir sıra izlemeden, fazla derin olmayan konulara atlayacağım. Mümkün olduğunca konuları tek yazıda bitirmeye özen göstereceğim. Programlarda sık sık Amiga'nın Library'lerine ve bu Library'lere ait fonksiyonlara rastlayacağız. Bu fonksiyonları yazıda basitçe tanıtacağım ama, kendi programlarını geliştirmek isteyenler mutlaka Addison Wesley'in Amiga ROM Kernal Manual - Includes and Autodocs kitabını edinmeliler. Ben koşullarımı sıraladım, dıysak hemen başlayalım. Amiga kullanıcısı ile iletişime geçmek için GUI adı verilen (Graphical User Interface) ve ekranlar, pencereler, tanımlı tuşlar ve menülerden oluşan bir sistem kullanır. Amiga kullanırken sık sık bu sistemin öğeleri ile karşılaşırız. Biraz örnek vererek açıklamaya gayret edelim. İlk etapta ekranlar vardır. Ekranların belirli bir çözünürlüğü ve renk sayısı bulunur. Aynı anda farklı özelliklere sahip ekranlar olabilir. Ekran tek başına çalışma için yetmez, o ekran içinde, içinde bulunduğu ekranın özelliklerini taşıyan pencereler bulunur. Bu pencereler sayesinde çeşitli programlar kullanıcı ile iletişime geçebilirler. (Biliyorum, biliyorum masal kısmı gerçekten sıkıcı). Bu pencereler üzerinde bazı anlamlı düğmeler vardır. Bu düğmeler kullanılarak pencerelerin boyutları değiştirilebilir, ekrandan kaldırılabilir veya içerikleri kaydırılabilir. Amiga sisteminin bir bölümü bu işlerle ilgilenir. Bu kısım Intuition Library'sinden başkası değil. Intuition Library'sini kullanarak ekranlar, pencereler ve bunlara bağlı elemanlar üzerinde tam hakimiyet kurabilirsiniz. Bu ayki amacımız bu olaya biraz açıklık getirmek.
Yukarıda kabaca belirttiğim gibi, ekranlar ve pencereler sistemin temel parçaları. Ekranlar, görüntü özelliklerini tanımlarlar. Bu ekranların içinde bu özellikte iletişim elemanları, pencereler açılır (Bir program çalışmak istiyorsa ve çıkış verecekse, mutlaka bir pencere açmalıdır.). Bir pencere, içinde bulunduğu ekranın malıdır. Başka bir ekrana geçemez. Ekrana bağlı olarak hareket eder. Bu en temel kavramların ardından ekran ve pencerelerin hafızada nasıl tanımlandığını bilmemiz gerekli. Gerek ekranlar ve gerek pencereler, hafızada özelliklerini anlatan değerlerin arka arkaya yazıldığı bir listeden ibarettir. Bu listelerin yapısı standarttır. Programlarken, bu tür listelere ulaşmak için Include dosyalarındaki tanımlardan faydalanırız. Hemen örnek veriyorum. Diyelim ki, hafızada herhangi bir ekranın listesinin başlangıç adresini bulduk (Her ne yoldan bulmuşsak, elimizde bir p_screen tipi değişken var.). Autodocs kitabından arayarak bu listedeki 16. byte'ından itibaren ilk iki byte'ın (İlk word'ün) Mouse'un x koordinatını verdiğini bulabiliriz. Ne var ki, bu bilgiyi bu şekilde kullanmayız. Bunun yerine son derece şık bir çözüm olarak Include dosyalarında yapılan tanımlardan yararlanırız.
Listenin bu elemanın adı MouseX olarak tanımlanmış. scr değişkeni p_screen tipi bir değişken olmak üzere (p_screen tipi değişken, Include dosyalarında tanımlanıyor). Mouse'un X koordinatını bulmak için: mx := scr^.MouseX; demek yeterli oluyor. Dikkat ederseniz, p_screen bir record pointer'ı olarak tanımlanmış. Gerçekten include dosyalarını karıştırarak bu tanımı bulabilirsiniz. Peki, tanım isimlerini nasıl mı bulacaksınız? Tanımlanan isimler standarttır. Autodocs kitabındaki tanımları kullanabilir veya zahmete girerek include dosyalarını karıştırabilirsiniz. Bu uygulamanın sayısız yararı var. Bir kere program anlaşılır bir hale geliyor. Ayrıca sabit değerlere bağlı değil. En önemlisi yeni Kickstart versiyonlarına kolayca uydurulabiliyor. Bakalım ekranda neler tanımlı: (Autodocs H-56) NextScreen FirstWindow LeftEdge TopEdge Width Height Mouse Flags Title Default Title BarHeight BarVborder BarHborder MenuVborder MenuHborder WBorTop WBorLeft WBorRight WBorBottom Font ViewPort RastPort BitMap LayerInfo FirstGadget DetailPen BlockPen SaveColor0 Barlayer ExtData UserData
İşte bu bilgiler sürüsü, ekranın tüm özel-
Pascal
F.Kağan Gürkaynak liklerini belirliyor. Bakın, ilginç birkaç nokta göstermek istiyorum. Tüm yapılarda ortak olan bir özellik bu: Aynı özellikte başka yapılar varsa, bunların adresi belirtiliyor. Eğer belirtilen adres NIL ise, o zaman tüm yapıları kontrol etmiş oluyorsunuz. Mesela bir ekrana ait tüm pencereleri bulmak istiyorsunuz. Dikkat edin, sadece ilk pencerenin yapısının adresi var. Ama pencere yapısında bir NextWindow bölümü var. Bu şekilde tüm yapıları taramak Buraya kadar şu sorunları hallettik: Eğer bir ekranın başlangıç adresini bulabilirsek, bu ekranın tüm özelliklerini bulmamız mümkün. Hatta bu ekrana bağlı olan tüm diğer elemanlara da buradan geçebiliriz. İsterseniz yukarıdaki bazı yapıların manaları üzerinde de bir iki kelime edelim (İsimler aslında işlevleri son derece iyi açıklıyor). Next Screen, bir sonraki ekranı işaret edecektir. First window ile, ekranın ilk window'una ulaşılabilir (Buradan da tüm window'lara). Left Edge, ekranın sol taraftan ne kadar kaydığını belirtir. Hooop hooop stop, durun bir dakika (Bunu siz söylemelisiniz). "Kağan ağır ol.", "Neden?", "Screenler istediğin yükseklikten başlayabilir, ama normal olarak soldan kayamazlar da ondan!". Bu konuda haklısınız. Ancak bu kısım ileride kullanılmak için tasarlanmış, bugünlerde (en azından 1.3'te) kullanımı yok. Listelerde bu şekilde ilerisi için ayrılmış birçok özellik bulunur. Top edge ise, ekranın üst kenardan ne kadar uzak olduğunu belirtir. Width ve Height, ekranın enini ve boyunu belirtecektir. Title, ekranın ismine bir pointer'dır. Gerisinin önemi yok diye kestirip atmayacağım, ama hepsini de konuyu dağıtmamak için açıklayamayacağım. BlockPen ve DetailPen ise ekranın arka plan rengi ve yazı rengini belirtecektir (Paletin hangi elemanı olduğu şeklinde). RastPort ve ViewPort ise, kendileri birer liste olan elemanlardır (Bunların da elemanları vardır). Sanırım yeteri kadar kafanızı ağrıttım. Gelelim program konumuza: Birden çok ekranla çalıştığınızı düşünün. İleri geri gidip gelirken bazen bir karmaşa içine düşüveriyorsunuz. Öyle bir program yazalım ki, tüm ekranları Workbench en arkada olacak şekilde dizelim. Dizerken tüm ekranların tepelerinin gözükmesini sağlayalım. Nasıl mı?, ilk olarak program: Program ScreenShuffler;
(Erhan OZTOP&FKagan GURKAY-NAK|
uses intuition;
const
MaxNScr - 41;
type
ScrArr — array (1..MaxNScr| of p. scre-
en;
var
win : p window;
scr : p screen;
Pack : SecrArr;
i,Jak : integer;
begin
win :— Open Window (20,20,200,10,-
Hayat ne kadar güzel değil mi? İlk işimiz intuition kullanacağımızı belirtmek. Bu library, Kick Pascal'da tanımlandığı için kolayca USES yardımı ile sisteme bağlayabiliyoruz. Bu library, gerekli tüm include dosyalarını da otomatikman bağlayacaktır. Ekranları bir dizi kullanarak sıralamak istiyoruz. Belki lazım olur diye bunu tip olarak tanımlıyoruz. ARRAY ifadesinde kullandığımız sabit ile, kaç ekran düzenleyebileceğimizi belirtiyoruz (Geleneklerimize bağlı kalarak 41 tavanını kullandık.). Daha sonra da birkaç değişken
$0103,0,0, SCREEN
ser :— win4, Wscreen;
Repeat
if i >> then Halt(5);
packli| :— ser;
ser :— SerA.NextScreen;
Until ser — nil;
Forj:—1toido
begin
ser :—
MoveScreen(scr,0,k-scrA.topedge);
ScreenToFront(scr);
k:— k4*ScrA Barheight-4-3;
if k >200 then k :— 0;
yoruz. Hatırlayın ekranların özelliklerine erişebilmek için ilk olarak onlara ait bir pointer bulmamız şart. İlk olarak bu sorunu hallediyoruz. Bir pencere açıyoruz. Window tanımında Workbench ekranının adresi yer alır (WSCREEN). Bu sayede bir ekrana el atmış oluruz. Gerisi son derece kolay. İlk iş NextScreen'ler yardımı ile tüm ekranları bir dolaşmak. Ekranların bittiğini Next Screen'in Nil olması ile, Nil'i sezene dek devam edecektir. Döngü içinde tüm ekran başlangıç adreslerini bir dizide topluyoruz. Hani olmaz ama, 41'den fazla ekran vardır diye de kontrol ediyoruz. Şayet böyle bir durum varsa, Halt(5) ile program hemen DOS'a geri dönecek ve 5 hata kodunu verecektir. Döngünün sonunda i değeri toplam ekran sayısını ve PACK dizisi de bu sayıda pointer'ı barındıracaktır. Şimdi bir döngü ile bu ekranları sıra ile ekrana yazalım. Ekranı hareket ettirebilmek için MoveScreen Library komutunu kullanıyoruz. Bu komut, belirtilen ekranı x (sözde) ve y düzlemlerinde kaydırabiliyor. Kaydırma için ise, kayma miktarı değeri girilmeli. Sorun ekran tepelerinin aynı kalınlıkta olmasının gerekmemesi. Bu yüzden k değişkeni ile o an yazılacak olan ekranın y koordinatını belirliyoruz. Bu = eski k değeri + ekran tepe kalınlığı + birkaç pixel (Anlaşılırlık için). Ancak Move Screen'de fark belirtmek gerekiyor. Bu amaçla ilk olarak ekranın o anki konumu bulunuyor ve gitmesi gereken yerle arasındaki fark alınıyor. Ekran kaydıktan sonra bu ekran ScreenToFront Intuition emri ile en öne çıkarılıyor. Bu şekilde tüm ekranlar üst üste yazılıyorlar. k değerinin 200'ü aşması durumunda değer tekrar sıfırlanıyor ki, ekranlar aşağıda kaybolacaklarına öbürlerinin üzerine çıksınlar. İşte bu kadar. Tabii programı çok geliştirmek mümkün: Mesela kolayca bir ekran çalıcı yapılabilir veya ekranların özellikleri sıralanabilir. Tüm bunlar, sizin hayal gücünüze bağlı olarak gelişecektir. Bu adımları atarak, bilgisayar programlamanın aslında o kadar öcü bir şey olmadığını basit adımlarla son derece iyi programlar yapılabileceğini anlamanız, beni son derece sevindirecek. Herkese bol güneşli ve keyifli bir yaz tatili dileyeyim (Tatil diye tembellik etmeyin bakalım).