Yayınlama: 29 Temmuz 2020
Güncelleme: 15 Ağustos 2020
Güncelleme: 15 Ağustos 2020
Kötü haber: Qbasic ve QuickBasicte doğrudan fare(mouse) kullanmak için bir komut bulunmuyor.
Belkide Qbasic'in piyasaya sürüldüğü tarihlerde fare kullanımı yaygın değildi ya da fare standartları tam oturmamıştı.
İyi haber: QuickBasicte DOS kesintilerini(interrupt) çalıştırmak için ve assembly kodlarını belleğe aktarıp çalıştırmak için kodlar bulunuyor. Böylece dolaylı olarak da olsa fare kullanılabiliyor.
DOS kesintisi ile fare çalıştırma
DOS işletim sistemi yapısı gereği Windows gibi çoklu görev(multitasking)
özelliği yoktur. DOS, kesinti denilen bir özelliği kullanarak sahte çoklu
görev işlevini yerine getirir.
DOS/BIOS kesinti listelerine bakıldığında çok sayıda kesinti olduğu görülecektir.
Kesinti listesi: Link1, Link2, Link3, Link4, Link5, Link6
Bu yazının konusu olan ve bize gerekli olan kesinti &H33 (51)
&H33 kesintisi bilgisayar fare donanımı ile ilgi fonksiyonları içerir.
Kullanılacak fare fonksiyonunun numarası AX yazmacına(register) aktarılır.
Yazmaç(register) nedir?
Merkezi işlem biriminin(CPU = İşlemci) işlemleri daha hızlı yürütmek için kullandığı CPU içinde bulunan bellek birimleridir. Bu birim RAM belleğe göre daha hızlıdır.
Ön hazırlık
Kesinti kullanmadan önce QuickBasic'te bazı ön hazırlıklar yapmak gereklidir.
Bunlar:
1) QuickBasic editörünü komut satırından çalıştırılırken /L parametresi
eklenerek çalıştırılır.
2) &H33 kesintisini oluşturmak için INTERRUPT alt programı çağıracağız.
Bu alt program QB.QLB ile belleğe yüklendi zaten. Yüklü olmadığı durumda "Subprogram not defined" (Alt program tanımlı değil) hatasını verir.
Kullanımı:
QB.BI dosyanız yoksa buradan indirebilirsiniz.
QB.EXE /L
Bu /L eklentisi LIB klasörü altında bulunan, belirtilmediğinde
varsayılan kütüphane(library) olan QB.QLB dosyasını belleğe yükler.
Bu dosya, kesinti kullanımı için bize gerekli olan alt rutinleri(subroutine)
içerir.
2) &H33 kesintisini oluşturmak için INTERRUPT alt programı çağıracağız.
Bu alt program QB.QLB ile belleğe yüklendi zaten. Yüklü olmadığı durumda "Subprogram not defined" (Alt program tanımlı değil) hatasını verir.
Kullanımı:
CALL INTERRUPT(kesintino, yazmaç_girdisi, yazmaç_çıktısı)
kesintino: Kullanılacak DOS kesinti numarası. Fare için
&H33 kullanılacak.
yazmaç_girdisi: Yazmaçlara veri aktarmak için kullanılır.
Gerekli olan yazmaçları kullanmak için bir TYPE tanımlaması yapılmalıdır.
Gerekli olan yazmaçları kullanmak için bir TYPE tanımlaması yapılmalıdır.
TYPE RegType ax AS INTEGER bx AS INTEGER cx AS INTEGER dx AS INTEGER bp AS INTEGER si AS INTEGER di AS INTEGER flags AS INTEGER END TYPE
Bu Regtype tanımlaması INC klasörü altında bulunan
QB.BI
dosyasında bulunmaktadır.
Üstteki kodları yazmak yerine QB.BI dosyasını INCLUDE komutu ile ekleyerek gerekli kodların yazacağımız programa dahil olmasını sağlayabiliriz.
Üstteki kodları yazmak yerine QB.BI dosyasını INCLUDE komutu ile ekleyerek gerekli kodların yazacağımız programa dahil olmasını sağlayabiliriz.
QB.BI dosyanız yoksa buradan indirebilirsiniz.
Kullanımı:
'$INCLUDE: 'qb.bi'
Genelde bu kod satırı program kodlarının ilk satırına eklenir.
yazmaç_çıktısı: Yazmaç(register) değerlerini almak için kullanılır.
yazmaç_girdisi ve yazmaç_çıktısı RegType tipinde olmalıdır.
yazmaç_çıktısı: Yazmaç(register) değerlerini almak için kullanılır.
3) RegType tipinde yeni iki değişken tanımlaması yapılmalıdır.
DIM SHARED inreg AS RegType, outreg AS RegType
Üstteki satırla RegType tipinde inreg ve
outreg değişkenleri oluşturulur. SHARED eklememizin sebebi değişkenin
alt rutinlerde(SUB ve FUNCTION) de değerini koruması içindir.
4) Belleğe yüklenen INTERRUPT alt rutinini kullanacağımızı bildirmeliyiz.
DECLARE SUB INTERRUPT (intnum AS INTEGER, inreg AS RegType, outreg AS RegType)Bu satır QB.BI içinde bulunduğu için bu satırı yazmamıza gerek yoktur. QB.BI kullanılmazsa gereklidir.
Fare kullanımı
Evet ön hazırlıklar tamam. Kodlamaya başlayalım.
Şimdiye kadar aşağıdaki satırları yazmış olmanız gerekir.
'$INCLUDE: 'qb.bi' DIM SHARED inreg AS RegType, outreg AS RegType
Fare kurulu mu?
Sistemde fare takılı ve sürücüsü kurulu mu önce onu kontrol edelim.Fare yok ise sonraki komutları çalıştırmamak gerekir.
AX yazmacına &H0 değeri aktarıp &H33 kesintisini
çağırdığımızda AX yazmaç değeri &H0 ile dönerse fare yok ya
da kurulmamış demektir.
0'dan farklı bir değer dönerse fare var demektir.
Fare varsa, kaç tuşlu olduğu dönen BX yazmacı ile öğrenilebilir.
Günümüzdeki fareler 3 veya daha fazla tuşlu olduğu için sonuç 3 çıkacaktır.
Günümüzdeki fareler 3 veya daha fazla tuşlu olduğu için sonuç 3 çıkacaktır.
'$INCLUDE: 'qb.bi' DIM SHARED inreg AS RegType, outreg AS RegType inreg.ax = &H0 CALL INTERRUPT(&H33, inreg, outreg) IF outreg.ax = &H0 THEN PRINT "Fare yok ya da kurulu değil!" END ELSE PRINT "Fare var. Kullanılabilir." END IF PRINT "Tuş sayısı:"; outreg.bx
Fareyi sıfırla
Bu ve sonraki sayfada fare ile ilgili bazı ayarlamalar ve değişiklikler
yapacağız.
Fare ayarlarında yapılan değişiklikleri(görünme, konum, hız, imleç, hassasiyet, vs.) sıfırlayıp varsayılana döndürmek için yine AX=&H0 kullanılır. Sonra kesinti çağrılır.
Fare ayarlarında yapılan değişiklikleri(görünme, konum, hız, imleç, hassasiyet, vs.) sıfırlayıp varsayılana döndürmek için yine AX=&H0 kullanılır. Sonra kesinti çağrılır.
Bu işlem donanım ve yazılım sıfırlamasını gerçekleştirir. Yalnız yazılım
sıfırlaması için: AX=&H21
Örnek 1:
inreg.ax = &H0 'fareyi sıfırla CALL INTERRUPT(&H33, inreg, outreg)
Örnek 2:
inreg.ax = &H21 'yazılım sıfırlaması CALL INTERRUPT(&H33, inreg, outreg)
Fare göster
Fare var. Kullanılabilir ancak ekranda görünmüyor değil mi?
Fareyi göstermek için AX yazmacını &H1'e eşitleyip kesintiyi
çağırmak yeterli.
Üstteki kodların altına aşağıdaki satırları ekleyiniz.
inreg.ax = &H1 'fareyi göster CALL INTERRUPT(&H33, inreg, outreg)Kodlar çalıştırıldığında içi dolu dikdörtgen kutu simgeli ikonuyla fare görünecektir.
SCREEN 0 yazı ekranı olduğu için fare ikonu bu şekilde görünür. Grafik ekranda simgesi ok şeklindedir.
Fare gizle
Fareyi gizlemek gerekirse AX yazmacına &H2 değerini aktarıp
kesintiyi çağırmak gerekir.
inreg.ax = &H2 'fareyi gizle CALL INTERRUPT(&H33, inreg, outreg)
Fark ettiyseniz kesinti ve yazmaç değerleri 16'lık sayı sistemi(hexadecimal)
ile kodlandı.
Bu şekilde olması şart değil. &H33 yerine 10'luk karşılığı olan 51 kullanılabilir ancak genel kullanım alışkanlığı bellek adresleri ve değerleri için 10'luk sayı sistemi yerine 16'lık sayı sistemini kullanmaktır.
Fare konumu
Farenin ekrandaki konumunu piksel(pixel=nokta) cinsinden almak için
AX yazmacına &H3 değerini aktarıp kesintiyi çağırmak
gerekir.
Kesinti sonrasında;
CX yazmacı farenin yatay(X) konumunu,
DX yazmacı farenin dikey(Y) konumunu verir.
Bu değerleri okumak için outreg değişkeni kullanılır.
outreg dönüş değerleri içindir.
Kodlara aşağıdaki satırları ekleyin.
COLOR 12 DO inreg.ax = &H3 'fare koordinat bilgisi al CALL INTERRUPT(&H33, inreg, outreg) x = outreg.cx 'fare X konumu y = outreg.dx 'fare Y konumu LOCATE 3 PRINT "X:"; x, "Y:"; y LOOP UNTIL INKEY$ = CHR$(27)
Fare tuşların durumu
Tuşlara basıldığında BX yazmacının değeri değişir.
0 : Herhangi bir tuş basılı değil
0 : Herhangi bir tuş basılı değil
1 : Sol fare tuşu basılı
2 : Sağ fare tuşu basılı
4 : Orta fare tuşu basılı
Aynı anda birden fazla tuşa basılırsa basılan tuşların değerleri toplamı BX değişkeninden okunabilir.
Örneğin Sol ve Sağ tuş aynı anda basılırsa 1+2 = 3 sonucu elde
edilir.
Son girilen kodların yerine aşağıdaki kodları ekleyin.
SCREEN 12 inreg.ax = &H1 'fareyi göster CALL INTERRUPT(&H33, inreg, outreg) COLOR 10 DO inreg.ax = &H3 'fare koordinat bilgisi al CALL INTERRUPT(&H33, inreg, outreg) x = outreg.cx 'fare X konumu y = outreg.dx 'fare Y konumu LOCATE 1 PRINT "X:"; x, "Y:"; y LOCATE 2 PRINT "Tuş:"; outreg.bx LOOP UNTIL INKEY$ = CHR$(27) 'ESC tuşu: Çıkış
Fare ile çizim yapma
' Fare ile grafik ekranda çizim ' ©2020 Mesut Akcan ' mesutakcan.blogspot.com '$INCLUDE: 'qb.bi' DEFINT A-Z CLS DIM SHARED inreg AS RegType, outreg AS RegType inreg.ax = &H0 CALL INTERRUPT(&H33, inreg, outreg) IF outreg.ax = &H0 THEN PRINT "Fare yok ya da kurulu değil!": END END IF SCREEN 12 inreg.ax = &H1 'fareyi göster CALL INTERRUPT(&H33, inreg, outreg) r = 14 'sarı renk DO inreg.ax = &H3 'fare koordinat bilgisi al CALL INTERRUPT(&H33, inreg, outreg) x = outreg.cx 'fare X konumu y = outreg.dx 'fare Y konumu tus = outreg.bx 'tuş bilgisi al COLOR 10 LOCATE 1: PRINT "Tuş:"; tus, "X:"; x, "Y:"; y, PRINT USING "Renk: ## "; r; COLOR r: PRINT STRING$(5, 219) SELECT CASE tus 'Sol tuş basılı. Çizgi çiz CASE 1: LINE (px, py)-(x, y), r'son konum ile şimdiki konum CASE 2: CLS 'Sağ tuş basılı. Ekranı sil CASE 4: 'Orta tuş basılı. Renk belirle LOCATE 1 INPUT "Çizim rengi (0-15):"; r IF r < 0 OR r > 15 THEN r = 15 END SELECT px = x: py = y 'son konum LOOP UNTIL INKEY$ = CHR$(27) 'ESC: çıkış
' Fare ile metin ekranda çizim ' ©2020 Mesut Akcan ' makcan@gmail.com ' mesutakcan.blogspot.com ' Sol tuş: Çizim ' Sağ tuş: Sil ' Orta tuş: Çizim karakteri ve rengi belirle ' ESC: Çıkış DEFINT A-Z '$INCLUDE: 'qb.bi' DECLARE SUB Cerceve (en%, boy%) DECLARE SUB KonumRenkYaz (yazi$, y%) DECLARE SUB Kesinti () DECLARE SUB FareGoster () DECLARE SUB FareGizle () DIM SHARED inreg AS RegType, outreg AS RegType inreg.ax = &H0 Kesinti IF outreg.ax = &H0 THEN PRINT "Fare yok ya da kurulu değil!": END END IF SCREEN 0 WIDTH 80, 25 DEF SEG = &HB800 'Ekran bellek adresi CLS FareGoster r = 15 'yazı rengi asc2 = 219 'çizim ascii karakter kodu DO inreg.ax = &H3 'fare koordinat bilgisi al Kesinti tus = outreg.bx 'tuş bilgisi al x = outreg.cx 'fare X konumu y = outreg.dx 'fare Y konumu str = y \ 8 + 1 'satır no stn = x \ 8 + 1 'sütun no LOCATE 1, 51 KonumRenkYaz "Satır:", str KonumRenkYaz " Sütun:", stn KonumRenkYaz " Renk:", r COLOR r PRINT " "; STRING$(4, asc2) SELECT CASE tus CASE 1, 2: 'Sol veya sağ tuş basılı FareGizle bellek = ((str - 1) * 80 + stn - 1) * 2 'sağ tuş ile sil IF tus = 1 THEN POKE bellek, asc2 ELSE POKE bellek, 32 IF r > 15 THEN rt = r + &H70 ELSE rt = r 'yanıp sönen renkler POKE bellek + 1, rt ' PEEK(61) FareGoster CASE 4: 'Orta tuş basılı. Renk belirle FareGizle PCOPY 0, 1 'aktif ekranı 1 e kopyala Cerceve 33, 5 LOCATE 12, 25 LINE INPUT "Çizim renk kodu (0-31):"; crk$ IF crk$ <> "" THEN rb = VAL(crk$) 'çizim renk kodu IF rb >= 0 AND rb <= 31 THEN r = rb END IF LOCATE 13, 25 LINE INPUT "Çizim karekter kodu (0-255):"; ckk$ IF ckk$ <> "" THEN a2k = VAL(ckk$) 'çizim karakter kodu. ASCII IF a2k >= 0 AND a2k <= 255 THEN asc2 = a2k END IF PCOPY 1, 0 'kopyalan ekranı aktif ekrana aktar FareGoster END SELECT LOOP UNTIL INKEY$ = CHR$(27) 'ESC: çıkış SUB Cerceve (en, boy) zr = 3 'zemin rengi satir = (25 - boy) \ 2 sutun = (80 - en) \ 2 LOCATE satir, sutun COLOR 15, zr PRINT CHR$(218); : PRINT STRING$(en, 196); : COLOR 0: PRINT CHR$(191); FOR n = 1 TO boy COLOR 15: LOCATE satir + n, sutun: PRINT CHR$(179); COLOR , zr: PRINT STRING$(en, 255); COLOR 0: PRINT CHR$(179) NEXT COLOR 15: LOCATE satir + boy, sutun: PRINT CHR$(192); COLOR 0: PRINT STRING$(en, 196); CHR$(217); END SUB DEFSNG A-Z SUB FareGizle inreg.ax = &H2 'fareyi gizle Kesinti END SUB SUB FareGoster inreg.ax = &H1 'fareyi göster Kesinti END SUB SUB Kesinti CALL INTERRUPT(&H33, inreg, outreg) END SUB SUB KonumRenkYaz (yazi$, y%) COLOR 7, 0: PRINT yazi$; COLOR 10: PRINT USING "##"; y%; END SUB
Önceki Bölüm: 19: Grafik işlemleri-7 | Sonraki Bölüm: 21: Fare (mouse) kullanımı-2 |
Hiç yorum yok:
Yorum Gönder